├── .gitignore ├── LICENSE ├── README.md ├── dk-agent ├── pom.xml └── src │ └── main │ └── java │ └── cn │ └── laoshini │ └── dk │ ├── agent │ ├── AgentMain.java │ ├── AttachProviderPlaceHolder.java │ ├── DangKangAgent.java │ └── RuntimeAgentLoader.java │ └── transform │ ├── AbstractClassFileModifier.java │ ├── ClassDefinedWrapper.java │ ├── DangKangClassFileTransformer.java │ ├── IClassByteCodeCache.java │ ├── asm │ ├── AbstractAsmModifier.java │ └── package-info.java │ ├── injection │ ├── ConfigurableFunctionInjectorProxy.java │ └── IConfigurableFunctionInjector.java │ └── javassist │ ├── AbstractJavassistModifier.java │ ├── FunctionInjectionModifier.java │ └── package-info.java ├── dk-autoconfigure ├── pom.xml └── src │ └── main │ └── java │ └── cn │ └── laoshini │ └── dk │ └── autoconfigure │ ├── DangKangBasicProperties.java │ ├── DangKangCacheProperties.java │ ├── DangKangConfigCenterProperties.java │ ├── DangKangExternalProperties.java │ ├── DangKangFunctionProperties.java │ ├── DangKangGenerateProperties.java │ ├── DangKangGmProperties.java │ ├── DangKangIdProperties.java │ ├── DangKangModuleProperties.java │ ├── DangKangPairDaoProperties.java │ └── DangKangRdbProperties.java ├── dk-common ├── pom.xml └── src │ └── main │ └── java │ └── cn │ └── laoshini │ └── dk │ ├── annotation │ ├── ConfigurableFunction.java │ ├── FunctionDependent.java │ ├── FunctionVariousWays.java │ ├── Message.java │ ├── MessageHandle.java │ └── ResourceHolder.java │ ├── common │ ├── IDkApplicationContext.java │ ├── PropertiesReader.java │ └── ResourcesHolder.java │ ├── constant │ ├── Constants.java │ ├── GameCodeEnum.java │ └── LogLabel.java │ ├── exception │ ├── BusinessException.java │ └── DkRuntimeException.java │ └── util │ ├── AngleUtil.java │ ├── ClassUtil.java │ ├── CollectionUtil.java │ ├── LogUtil.java │ ├── Md5Util.java │ ├── NetUtil.java │ ├── ReflectUtil.java │ ├── StringUtil.java │ ├── TypeUtil.java │ └── ZlibUtil.java ├── dk-core ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── laoshini │ │ └── dk │ │ ├── cache │ │ ├── CacheContainer.java │ │ ├── IDkCache.java │ │ └── impl │ │ │ └── DkCacheGuavaImpl.java │ │ ├── common │ │ ├── DkApplicationContext.java │ │ ├── DkEnvironment.java │ │ └── SpringContextHolder.java │ │ ├── condition │ │ ├── AbstractSpringCondition.java │ │ ├── ConditionRecord.java │ │ ├── ConditionalOnPropertyExists.java │ │ ├── ConditionalOnPropertyMissing.java │ │ ├── ConditionalOnPropertyValue.java │ │ ├── OnPropertyExistsCondition.java │ │ ├── OnPropertyMissingCondition.java │ │ ├── OnPropertyValueCondition.java │ │ └── package-info.java │ │ ├── constant │ │ ├── BeanTypeEnum.java │ │ ├── ConstTableSourceEnum.java │ │ ├── DBTypeEnum.java │ │ ├── ExpressionConstant.java │ │ ├── ExpressionDependEnum.java │ │ ├── GameConstant.java │ │ ├── GameServerProtocolEnum.java │ │ ├── GameServerStatus.java │ │ ├── GeneratorTypeEnum.java │ │ ├── HotfixResultEnum.java │ │ ├── InnerTableNameConst.java │ │ ├── MessageFormatEnum.java │ │ ├── ModuleConstant.java │ │ ├── PropertyKeyConstants.java │ │ ├── QueryConditionKeyEnum.java │ │ ├── RoleStatusEnum.java │ │ ├── ServerType.java │ │ ├── UseTypeEnum.java │ │ └── UserStatusEnum.java │ │ ├── dao │ │ ├── CsvFileDao.java │ │ ├── IBasicDao.java │ │ ├── IDefaultDao.java │ │ ├── IEntityClassManager.java │ │ ├── IFileDao.java │ │ ├── IPairConditional.java │ │ ├── IPairDbDao.java │ │ ├── IRelationalDbDao.java │ │ ├── IRelationalDbDaoManager.java │ │ ├── JsonFileDao.java │ │ ├── PreparedStatementSqlBuilder.java │ │ ├── SqlBuilder.java │ │ ├── TableKey.java │ │ ├── TableMapping.java │ │ ├── package-info.java │ │ ├── query │ │ │ └── QueryUtil.java │ │ └── update │ │ │ ├── SqlWrapper.java │ │ │ └── UpdateSqlWrapper.java │ │ ├── domain │ │ ├── ExecutorBean.java │ │ ├── ExecutorMethod.java │ │ ├── GameServerConfig.java │ │ ├── GameSubject.java │ │ ├── HandlerDesc.java │ │ ├── HandlerExecutorMethod.java │ │ ├── IntExecutorMethod.java │ │ └── common │ │ │ ├── ClassDescriptor.java │ │ │ ├── HotfixFile.java │ │ │ └── MethodDescriptor.java │ │ ├── entity │ │ ├── HandlerExpDescriptor.java │ │ └── HotfixRecord.java │ │ ├── exception │ │ ├── CacheException.java │ │ ├── DaoException.java │ │ ├── JitException.java │ │ └── MessageException.java │ │ ├── executor │ │ ├── AbstractOrderedWorker.java │ │ ├── IOrderedExecutor.java │ │ ├── IOrderedExecutorGroup.java │ │ ├── NonOrderedQueuePoolExecutor.java │ │ ├── OrderedQueuePool.java │ │ ├── OrderedQueuePoolExecutor.java │ │ └── TaskQueue.java │ │ ├── expression │ │ ├── BaseExpressionLogic.java │ │ ├── BaseExpressionProcessor.java │ │ ├── ExpressionLogicContext.java │ │ ├── ExpressionLogicFactory.java │ │ ├── IExpressionLogic.java │ │ ├── IExpressionProcessor.java │ │ ├── js │ │ │ ├── JavaScriptExpressionLogic.java │ │ │ └── JavaScriptExpressionProcessor.java │ │ ├── package-info.java │ │ └── spel │ │ │ ├── SpelExpressionLogic.java │ │ │ └── SpelExpressionProcessor.java │ │ ├── function │ │ ├── ConfigurableFunctionInjector.java │ │ ├── Func.java │ │ ├── FuncContainer.java │ │ ├── FunctionDependentManager.java │ │ ├── FunctionHolders.java │ │ ├── FunctionSupplier.java │ │ ├── VariousWaysFunctionBean.java │ │ ├── VariousWaysManager.java │ │ └── package-info.java │ │ ├── generator │ │ ├── id │ │ │ ├── IIdIncrementer.java │ │ │ ├── IRoleIdGenerator.java │ │ │ ├── IUserIdGenerator.java │ │ │ └── package-info.java │ │ └── name │ │ │ ├── INameGenerator.java │ │ │ └── package-info.java │ │ ├── jit │ │ ├── DynamicGenerator.java │ │ ├── JitClassLoader.java │ │ ├── compiler │ │ │ ├── DynamicCompiler.java │ │ │ └── SpringBootDynamicCompiler.java │ │ ├── generator │ │ │ ├── AbstractClassFileGenerator.java │ │ │ ├── AbstractCustomDtoClassFileGenerator.java │ │ │ ├── CustomDtoClassFileGenerator.java │ │ │ ├── HandlerClassFileGenerator.java │ │ │ ├── IClassFileGenerator.java │ │ │ └── NettyCustomDtoClassFileGenerator.java │ │ ├── package-info.java │ │ └── type │ │ │ ├── AbstractNumericTypeBean.java │ │ │ ├── AbstractTypeBean.java │ │ │ ├── BooleanBean.java │ │ │ ├── ByteBean.java │ │ │ ├── CompositeBean.java │ │ │ ├── CompositeExtendBean.java │ │ │ ├── DoubleBean.java │ │ │ ├── HandlerBean.java │ │ │ ├── ITypeBean.java │ │ │ ├── IntegerBean.java │ │ │ ├── ListBean.java │ │ │ ├── LongBean.java │ │ │ ├── OrdinaryBean.java │ │ │ ├── ShortBean.java │ │ │ ├── StringBean.java │ │ │ ├── TypeBeanFactory.java │ │ │ └── TypeBeanRecord.java │ │ ├── listener │ │ ├── DkContextEvent.java │ │ ├── DkEventPublisher.java │ │ ├── IDkContextListener.java │ │ ├── PropertyChangedEvent.java │ │ └── PropertyChangedListener.java │ │ ├── manager │ │ ├── DangKangAnnotationProcessor.java │ │ ├── EntityClassManager.java │ │ ├── HandlerExpressionManager.java │ │ ├── HotfixManager.java │ │ ├── ModuleManager.java │ │ ├── ResourceHolderManager.java │ │ ├── SpringBeanManager.java │ │ └── TypeUseManager.java │ │ ├── module │ │ ├── AbstractModuleRegistry.java │ │ ├── IModuleRegistry.java │ │ ├── loader │ │ │ ├── ModuleClassLoader.java │ │ │ ├── ModuleLoader.java │ │ │ └── ModuleLoaderContext.java │ │ ├── package-info.java │ │ └── registry │ │ │ ├── AbstractRecoverableModuleRegistry.java │ │ │ ├── AggregateModuleRegistry.java │ │ │ ├── ModuleConfigurableFunctionRegistry.java │ │ │ ├── ModuleEntityClassRegistry.java │ │ │ ├── ModuleMessageHandlerRegistry.java │ │ │ ├── ModuleMessageRegistry.java │ │ │ ├── ModuleResourceHolderRegistry.java │ │ │ └── ModuleSpringBeanRegistry.java │ │ ├── monitor │ │ └── package-info.java │ │ ├── net │ │ ├── MessageDtoClassHolder.java │ │ ├── MessageHandlerHolder.java │ │ ├── MessageHolder.java │ │ ├── codec │ │ │ ├── IByteMessageCodec.java │ │ │ ├── IByteMessageDecoder.java │ │ │ ├── IByteMessageEncoder.java │ │ │ ├── IMessageCodec.java │ │ │ ├── IMessageDecoder.java │ │ │ ├── IMessageEncoder.java │ │ │ ├── INettyMessageDecoder.java │ │ │ ├── INettyMessageEncoder.java │ │ │ ├── JsonByteMessageDecoder.java │ │ │ ├── JsonByteMessageEncoder.java │ │ │ ├── JsonNettyMessageDecoder.java │ │ │ ├── JsonNettyMessageEncoder.java │ │ │ ├── JsonShortLengthNettyMessageEncoder.java │ │ │ ├── JsonTextNettyMessageEncoder.java │ │ │ ├── ProtobufByteMessageDecoder.java │ │ │ ├── ProtobufByteMessageEncoder.java │ │ │ ├── ProtobufNettyMessageDecoder.java │ │ │ └── ProtobufNettyMessageEncoder.java │ │ ├── connect │ │ │ ├── IConnectClosedHandler.java │ │ │ ├── IConnectExceptionHandler.java │ │ │ └── IConnectOpenedHandler.java │ │ ├── handler │ │ │ ├── ExpressionMessageHandler.java │ │ │ ├── IHttpMessageHandler.java │ │ │ └── IMessageHandler.java │ │ ├── msg │ │ │ ├── CustomMsg.java │ │ │ ├── IByteDto.java │ │ │ ├── ICustomDto.java │ │ │ ├── ICustomMessage.java │ │ │ ├── IMessageDispatcher.java │ │ │ ├── IMessageInterceptor.java │ │ │ ├── ReqCustomMessage.java │ │ │ └── RespCustomMessage.java │ │ ├── package-info.java │ │ ├── server │ │ │ ├── AbstractInnerGameServer.java │ │ │ ├── AbstractInnerNettyGameServer.java │ │ │ ├── InnerGameServerFactory.java │ │ │ ├── InnerNettyHttpGameServer.java │ │ │ ├── InnerNettyTcpGameServer.java │ │ │ ├── InnerNettyUdpGameServer.java │ │ │ └── InnerNettyWebsocketGameServer.java │ │ └── session │ │ │ ├── AbstractSession.java │ │ │ ├── DefaultMessageSender.java │ │ │ ├── IMessageSender.java │ │ │ ├── ISessionCreator.java │ │ │ ├── NettyHttpSession.java │ │ │ ├── NettySession.java │ │ │ ├── NettyUdpSession.java │ │ │ └── NettyWebsocketSession.java │ │ ├── register │ │ ├── AbstractGameDataLoaderAdaptor.java │ │ ├── ClassFilters.java │ │ ├── ClassIdReader.java │ │ ├── ClassScanners.java │ │ ├── DefaultClassScanner.java │ │ ├── EntityRegisterAdaptor.java │ │ ├── GameServerRegisterAdaptor.java │ │ ├── IClassFilter.java │ │ ├── IClassScanner.java │ │ ├── IEntityRegister.java │ │ ├── IFunctionRegister.java │ │ ├── IGameDataLoader.java │ │ ├── IGameServerRegister.java │ │ ├── IGameServerStartedHandler.java │ │ ├── IGmServerRegister.java │ │ ├── IMessageDtoRegister.java │ │ ├── IMessageHandlerRegister.java │ │ ├── IMessageRegister.java │ │ ├── MessageHandlerRegisterAdaptor.java │ │ ├── MessageRegisterAdapter.java │ │ ├── Registers.java │ │ ├── UdpGameServerRegister.java │ │ └── WebsocketGameServerRegister.java │ │ ├── serialization │ │ ├── IDataSerializable.java │ │ └── StringDataSerialization.java │ │ ├── server │ │ ├── AbstractGameServer.java │ │ ├── AbstractServer.java │ │ ├── GameServerUnPauseWorker.java │ │ └── GameServers.java │ │ ├── service │ │ └── GmService.java │ │ ├── starter │ │ ├── DangKangGameProperties.java │ │ ├── DangKangGameServerProperties.java │ │ ├── DangKangGameStarter.java │ │ ├── DangKangStarter.java │ │ ├── DkGameServerAutoConfiguration.java │ │ ├── ExternalLastInitializer.java │ │ └── package-info.java │ │ ├── support │ │ ├── IPropertyRefreshable.java │ │ ├── IRefreshable.java │ │ ├── ParamSupplier.java │ │ └── RefresherContainer.java │ │ ├── text │ │ └── sensitive │ │ │ ├── AbstractDesensitizeProcessor.java │ │ │ ├── AbstractSensitiveWordProcessor.java │ │ │ ├── BankCardDesensitizeProcessor.java │ │ │ ├── ChineseNameDesensitizeProcessor.java │ │ │ ├── DefaultSensitiveWordProcessor.java │ │ │ ├── EmailDesensitizeProcessor.java │ │ │ ├── IDesensitizeProcessor.java │ │ │ ├── ISensitiveMaskPolicy.java │ │ │ ├── ISensitiveWordProcessor.java │ │ │ ├── IdCardNoDesensitizeProcessor.java │ │ │ └── MobileDesensitizeProcessor.java │ │ └── util │ │ ├── ChannelUtil.java │ │ ├── ClassHelper.java │ │ ├── DateUtil.java │ │ ├── FileUtil.java │ │ ├── HotfixUtil.java │ │ ├── HttpUtil.java │ │ ├── JsonUtil.java │ │ ├── MessageUtil.java │ │ ├── ModuleResourceUtil.java │ │ ├── ReflectHelper.java │ │ ├── SpringUtils.java │ │ ├── TypeHelper.java │ │ └── ZipUtil.java │ └── resources │ └── applicationContext-dk-default.xml ├── dk-domain ├── pom.xml └── src │ └── main │ └── java │ └── cn │ └── laoshini │ └── dk │ └── domain │ ├── common │ ├── ArrayTuple.java │ ├── ConstReadTable.java │ ├── ConstTable.java │ ├── ListTuple.java │ ├── MultiConstTableContent.java │ ├── Tuple.java │ └── TupleArray.java │ ├── dto │ ├── ExpressionBlockDTO.java │ ├── ExpressionDescriptorDTO.java │ ├── GameServerInfoDTO.java │ ├── GameServerRegisterDTO.java │ ├── HandlerExpDescriptorDTO.java │ ├── HotfixRecordDTO.java │ └── ModuleInfoDTO.java │ ├── msg │ ├── AbstractMessage.java │ ├── IMessage.java │ ├── ReqMessage.java │ └── RespMessage.java │ ├── query │ ├── AbstractQueryCondition.java │ ├── BeanQueryCondition.java │ ├── ListQueryCondition.java │ ├── Page.java │ └── PageQueryCondition.java │ └── responese │ ├── Result.java │ └── ResultCode.java ├── dk-game-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ ├── client │ │ ├── AbstractBiasCodecNettyTcpClient.java │ │ ├── AbstractNettyTcpClient.java │ │ ├── ClientException.java │ │ ├── CustomMessageNettyTcpClient.java │ │ ├── JsonNettyTcpClient.java │ │ ├── ProtobufNettyTcpClient.java │ │ └── package-info.java │ │ ├── cluster │ │ └── package-info.java │ │ ├── constant │ │ ├── AttributeKeyConstant.java │ │ ├── BtNodeType.java │ │ ├── CompositeType.java │ │ └── NodeState.java │ │ ├── domain │ │ ├── Player.java │ │ └── Role.java │ │ ├── entity │ │ ├── GameConfig.java │ │ ├── GameRole.java │ │ ├── GameUser.java │ │ ├── MixedGameServerInfo.java │ │ └── package-info.java │ │ ├── event │ │ └── ChannelCloseEvent.java │ │ ├── eventbus │ │ ├── EventMgr.java │ │ └── LoggingSubscriberExceptionHandler.java │ │ ├── id │ │ ├── DefaultRoleIdGenerator.java │ │ └── DefaultUserIdGenerator.java │ │ ├── net │ │ ├── codec │ │ │ ├── BaseProtobufMessageEncoder.java │ │ │ ├── CustomByteMessageCodec.java │ │ │ ├── CustomNettyMessageDecoder.java │ │ │ ├── CustomNettyMessageEncoder.java │ │ │ └── ProtobufByteMessageCodec.java │ │ ├── handler │ │ │ ├── ICustomMessageHandler.java │ │ │ ├── IJsonMessageHandler.java │ │ │ ├── IProtobufMessageHandler.java │ │ │ └── MessageReceiveDispatcher.java │ │ ├── msg │ │ │ ├── Base.proto │ │ │ ├── BaseProtobufMessage.java │ │ │ ├── INettyCustomMessage.java │ │ │ ├── INettyDto.java │ │ │ ├── ReqNettyCustomMessage.java │ │ │ └── RespNettyCustomMessage.java │ │ └── package-info.java │ │ ├── robot │ │ ├── bt │ │ │ ├── BehaviorTree.java │ │ │ ├── BehaviorTreeProducer.java │ │ │ ├── IBehaviorTree.java │ │ │ ├── IBtConfig.java │ │ │ ├── factory │ │ │ │ ├── AbstractBtActionNodeFactory.java │ │ │ │ ├── AbstractBtConditionNodeFactory.java │ │ │ │ ├── IBtNodeFactory.java │ │ │ │ ├── IBtRootNodeFactory.java │ │ │ │ └── impl │ │ │ │ │ ├── BtActionNodeFactoryImpl.java │ │ │ │ │ ├── BtCompositeNodeFactory.java │ │ │ │ │ ├── BtConditionNodeFactoryImpl.java │ │ │ │ │ ├── BtDecoratorNodeFactory.java │ │ │ │ │ └── BtRootNodeFactoryImpl.java │ │ │ ├── node │ │ │ │ ├── AbstractBtAction.java │ │ │ │ ├── AbstractBtCompositeNode.java │ │ │ │ ├── AbstractBtCondition.java │ │ │ │ ├── AbstractBtNode.java │ │ │ │ ├── BtConditionNode.java │ │ │ │ ├── BtRootNode.java │ │ │ │ ├── IBtNode.java │ │ │ │ ├── IBtNodeConfig.java │ │ │ │ ├── composite │ │ │ │ │ ├── EmptyNode.java │ │ │ │ │ ├── ParallelAllFail.java │ │ │ │ │ ├── ParallelAllSucceed.java │ │ │ │ │ ├── ParallelHybirdFail.java │ │ │ │ │ ├── ParallelHybirdSucceed.java │ │ │ │ │ ├── ParallelSelector.java │ │ │ │ │ ├── ParallelSequence.java │ │ │ │ │ ├── SelectorNode.java │ │ │ │ │ └── SequenceNode.java │ │ │ │ └── condition │ │ │ │ │ ├── EqualCondition.java │ │ │ │ │ └── FalseCondition.java │ │ │ └── package-info.java │ │ ├── fsm │ │ │ ├── AbstractFsmRobot.java │ │ │ ├── FsmMessage.java │ │ │ ├── IFsmRobot.java │ │ │ ├── IFsmState.java │ │ │ ├── IStateMachine.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ ├── serialization │ │ └── ProtoBufDataSerialization.java │ │ ├── server │ │ ├── AbstractNettyTcpGameServer.java │ │ ├── NettyServerFactory.java │ │ ├── channel │ │ │ ├── INettyChannelReader.java │ │ │ ├── JsonMessageChannelReader.java │ │ │ ├── LastChannelReader.java │ │ │ ├── NettyCustomMessageChannelReader.java │ │ │ └── ProtobufMessageChannelReader.java │ │ ├── impl │ │ │ ├── CustomNettyTcpGameServer.java │ │ │ ├── HttpGameServer.java │ │ │ ├── JsonNettyTcpGameServer.java │ │ │ └── ProtobufNettyTcpGameServer.java │ │ ├── package-info.java │ │ └── worker │ │ │ └── MessageReceiveWorker.java │ │ └── util │ │ └── ByteMessageUtil.java │ └── test │ └── java │ └── cn │ └── laoshini │ └── dk │ └── robot │ └── fsm │ ├── FsmTest.java │ ├── Monster.java │ ├── MonsterState.java │ └── MonsterStateMachine.java ├── dk-impl-basic ├── dk-basic-da │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ ├── cache │ │ └── DefaultCacheImpl.java │ │ └── dao │ │ ├── DefaultDaoImpl.java │ │ ├── DefaultRelationalDbDao.java │ │ ├── EmbeddedPairDao.java │ │ ├── InnerGameDataSourceConfig.java │ │ └── RelationalDbDaoManager.java ├── dk-basic-excel │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ └── excel │ │ ├── AbstractExcelExporter.java │ │ ├── ConstraintExcelExporter.java │ │ ├── ExcelConstant.java │ │ ├── ExcelExporter.java │ │ ├── ExcelFileDao.java │ │ ├── ExcelReader.java │ │ ├── ExcelUtil.java │ │ ├── MatrixExcelExporter.java │ │ └── constraint │ │ ├── ExcelDateHeader.java │ │ ├── ExcelFormulaHeader.java │ │ ├── ExcelHeader.java │ │ ├── ExcelListHeader.java │ │ └── ExcelNumericHeader.java ├── dk-config-center-jdbc │ ├── pom.xml │ ├── sql │ │ └── config-center-server.sql │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── laoshini │ │ │ └── dk │ │ │ └── config │ │ │ └── center │ │ │ ├── DkJdbcConfigCenterApplication.java │ │ │ ├── annotation │ │ │ ├── Label.java │ │ │ ├── Profile.java │ │ │ └── Property.java │ │ │ ├── constant │ │ │ ├── PropertiesConstant.java │ │ │ ├── PropertyOperation.java │ │ │ └── PropertyStatus.java │ │ │ ├── domain │ │ │ ├── PropertyField.java │ │ │ ├── PropertySource.java │ │ │ └── UpdatedProperties.java │ │ │ ├── entity │ │ │ ├── ConfigProperty.java │ │ │ ├── PropertyChange.java │ │ │ └── PropertyHistory.java │ │ │ ├── mapper │ │ │ ├── PropertiesMapper.java │ │ │ ├── PropertyHistoryMapper.java │ │ │ └── VersionHistoryMapper.java │ │ │ ├── mybatis │ │ │ └── PropertyChangeJsonTypeHandler.java │ │ │ ├── service │ │ │ ├── GameServerConfigService.java │ │ │ ├── PropertiesService.java │ │ │ └── VersionService.java │ │ │ └── web │ │ │ └── GameServerConfigController.java │ │ └── resources │ │ ├── application.properties │ │ ├── banner.txt │ │ ├── logback.xml │ │ └── mapper │ │ ├── PropertiesMapper.xml │ │ ├── PropertyHistoryMapper.xml │ │ └── VersionHistoryMapper.xml ├── dk-config-client │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── laoshini │ │ │ └── dk │ │ │ └── config │ │ │ └── client │ │ │ ├── CloudBusRefresher.java │ │ │ ├── CustomerContextRefresher.java │ │ │ ├── DkConfigClientApplicationContext.java │ │ │ └── DkConfigClientEnvironment.java │ │ └── resources │ │ ├── META-INF │ │ └── spring.factories │ │ └── applicationContext-dk-config.xml ├── dk-db-id-incrementer │ ├── pom.xml │ ├── sql │ │ └── id_incrementer.sql │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ └── generator │ │ └── id │ │ ├── ColumnIdIncrementer.java │ │ ├── DefaultIdIncrementer.java │ │ ├── IDbIdIncrementer.java │ │ ├── IdIncrementerConstant.java │ │ └── PairIdIncrementer.java ├── dk-gm-console │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── laoshini │ │ │ └── dk │ │ │ └── console │ │ │ ├── DkAdminApplication.java │ │ │ ├── service │ │ │ └── GameServerService.java │ │ │ ├── util │ │ │ └── HttpUtil.java │ │ │ ├── vo │ │ │ ├── HotfixRecordVO.java │ │ │ └── ModuleInfoVO.java │ │ │ └── web │ │ │ ├── DkCommonController.java │ │ │ ├── DkGameServerController.java │ │ │ └── DkGmController.java │ │ └── resources │ │ ├── application.properties │ │ └── logback.xml ├── dk-gm │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ ├── gm │ │ ├── GmHttpRequestUriInterceptor.java │ │ ├── constant │ │ │ └── GmConstants.java │ │ ├── handler │ │ │ ├── DoHotfixHandler.java │ │ │ ├── GetGameServerInfoHandler.java │ │ │ ├── GetHotfixHistoryHandler.java │ │ │ ├── GetModuleListHandler.java │ │ │ ├── PauseGameServerHandler.java │ │ │ ├── ReleaseGameServerHandler.java │ │ │ ├── ReloadModulesHandler.java │ │ │ └── RemoveModuleHandler.java │ │ └── message │ │ │ ├── hotfix │ │ │ ├── DoHotfixReq.java │ │ │ ├── DoHotfixRes.java │ │ │ ├── GetHotfixHistoryReq.java │ │ │ └── GetHotfixHistoryRes.java │ │ │ ├── module │ │ │ ├── GetModuleListReq.java │ │ │ ├── GetModuleListRes.java │ │ │ ├── ReloadModulesReq.java │ │ │ ├── ReloadModulesRes.java │ │ │ ├── RemoveModuleReq.java │ │ │ └── RemoveModuleRes.java │ │ │ └── server │ │ │ ├── GetGameServerInfoReq.java │ │ │ ├── GetGameServerInfoRes.java │ │ │ ├── PauseGameServerReq.java │ │ │ ├── PauseGameServerRes.java │ │ │ ├── ReleaseGameServerReq.java │ │ │ └── ReleaseGameServerRes.java │ │ └── register │ │ └── GmServerRegister.java ├── dk-name-generator-cn │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── laoshini │ │ │ └── dk │ │ │ └── generator │ │ │ └── name │ │ │ ├── AbstractLevelRandomNameGenerator.java │ │ │ ├── BasicLevelRandomNameGenerator.java │ │ │ ├── ChineseCharacter.java │ │ │ ├── ChineseNameGenerator.java │ │ │ ├── ILevelRandomNameGenerator.java │ │ │ ├── LevelRandomNameGeneratorRegistry.java │ │ │ ├── MiddleLevelRandomNameGenerator.java │ │ │ ├── NameContainer.java │ │ │ ├── SimpleLevelRandomNameGenerator.java │ │ │ └── Surname.java │ │ └── resources │ │ ├── chinese_character.json │ │ └── surname.json ├── dk-name-generator-foreign-cn │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── laoshini │ │ │ └── dk │ │ │ └── generator │ │ │ └── name │ │ │ ├── ForeignCnNameGenerator.java │ │ │ └── IniName.java │ │ └── resources │ │ └── ini_name.json ├── dk-qr-code │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── laoshini │ │ └── dk │ │ └── qrcode │ │ ├── QrCodeBuilder.java │ │ ├── QrCodeReader.java │ │ └── QrCodeUtil.java └── pom.xml ├── dk-starter └── pom.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /**/target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | /levelDB/ 5 | /logs/ 6 | /modules/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | /build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/agent/AgentMain.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.agent; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class AgentMain { 7 | 8 | public static void main(String[] args) { 9 | System.out.println("Game Agent Main execute"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/agent/AttachProviderPlaceHolder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.agent; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import com.sun.tools.attach.AttachNotSupportedException; 7 | import com.sun.tools.attach.VirtualMachine; 8 | import com.sun.tools.attach.VirtualMachineDescriptor; 9 | import com.sun.tools.attach.spi.AttachProvider; 10 | 11 | /** 12 | * @author fagarine 13 | */ 14 | class AttachProviderPlaceHolder extends AttachProvider { 15 | @Override 16 | public String name() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public String type() { 22 | return null; 23 | } 24 | 25 | @Override 26 | public VirtualMachine attachVirtualMachine(String s) throws AttachNotSupportedException, IOException { 27 | return null; 28 | } 29 | 30 | @Override 31 | public List listVirtualMachines() { 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/transform/IClassByteCodeCache.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.transform; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | /** 7 | * 类字节码缓存接口 8 | * 9 | * @author fagarine 10 | */ 11 | interface IClassByteCodeCache { 12 | 13 | /** 14 | * 缓存一些常用类的字节码信息 15 | */ 16 | Map BYTE_CODE_CACHE = new ConcurrentHashMap<>(); 17 | 18 | /** 19 | * 获取类名对应类的字节码,先尝试从缓存中查找 20 | * 21 | * @param className 类名 22 | * @return 返回类的字节码 23 | */ 24 | default byte[] getClassBytes(String className) { 25 | return BYTE_CODE_CACHE.computeIfAbsent(className, this::classToBytes); 26 | } 27 | 28 | /** 29 | * 通过类名查找类,并返回类的字节码数据 30 | * 31 | * @param className 类名 32 | * @return 返回类的字节码 33 | */ 34 | byte[] classToBytes(String className); 35 | } 36 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/transform/asm/AbstractAsmModifier.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.transform.asm; 2 | 3 | import cn.laoshini.dk.transform.AbstractClassFileModifier; 4 | 5 | /** 6 | * 使用ASM实现修改Class字节码功能的抽象类,我习惯了使用javassist,ASM不熟悉,这里只是留下扩展空间 7 | * 8 | * @author fagarine 9 | */ 10 | public abstract class AbstractAsmModifier extends AbstractClassFileModifier { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/transform/asm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 我本人更喜欢使用javassist,这个包是为喜欢使用asm技术的用户预留 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.transform.asm; -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/transform/injection/ConfigurableFunctionInjectorProxy.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.transform.injection; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class ConfigurableFunctionInjectorProxy implements IConfigurableFunctionInjector { 7 | private ConfigurableFunctionInjectorProxy() { 8 | } 9 | 10 | private static ConfigurableFunctionInjectorProxy instance = new ConfigurableFunctionInjectorProxy(); 11 | 12 | public static ConfigurableFunctionInjectorProxy getInstance() { 13 | return instance; 14 | } 15 | 16 | private IConfigurableFunctionInjector delegate; 17 | 18 | public static void setDelegate(IConfigurableFunctionInjector delegate) { 19 | instance.delegate = delegate; 20 | } 21 | 22 | @Override 23 | public void injectField(Object bean, String fieldName) { 24 | if (delegate == null) { 25 | // 功能注入实现类对象还未填入,缓存依赖注入的对象 26 | add(bean); 27 | } else { 28 | delegate.injectField(bean, fieldName); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dk-agent/src/main/java/cn/laoshini/dk/transform/javassist/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 使用javassist实现类字节码修改 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.transform.javassist; -------------------------------------------------------------------------------- /dk-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dangkang 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-autoconfigure 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-autoconfigure 18 | 2.2.0.RELEASE 19 | provided 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-configuration-processor 25 | 2.2.0.RELEASE 26 | provided 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangCacheProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.Ordered; 9 | import org.springframework.core.annotation.Order; 10 | 11 | /** 12 | * 应用内缓存相关配置项 13 | * 14 | * @author fagarine 15 | */ 16 | @Getter 17 | @Setter 18 | @Configuration 19 | @Order(Ordered.HIGHEST_PRECEDENCE) 20 | @ConfigurationProperties(prefix = "dk.cache") 21 | public class DangKangCacheProperties { 22 | 23 | /** 24 | * 选择应用内缓存数据访问对象的实现方式 25 | */ 26 | private String dao = "DEFAULT"; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangConfigCenterProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * 当康系统配置中心相关配置项 14 | * 15 | * @author fagarine 16 | */ 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Configuration 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | @ConfigurationProperties(prefix = "dk.config") 23 | public class DangKangConfigCenterProperties { 24 | 25 | /** 26 | * 配置中心URL 27 | */ 28 | private String server; 29 | 30 | /** 31 | * 项目名称(业务项目或者游戏项目的名称,例如游戏id) 32 | */ 33 | private String name; 34 | 35 | /** 36 | * 项目profile(例如游戏项目默认使用serverId作为profile) 37 | */ 38 | private String profile; 39 | 40 | /** 41 | * 项目标签(游戏项目的label表示运行环境,配置文件中可不填,默认为master) 42 | */ 43 | private String label = "master"; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangExternalProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | import org.springframework.boot.context.properties.ConfigurationProperties; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.Ordered; 12 | import org.springframework.core.annotation.Order; 13 | 14 | /** 15 | * @author fagarine 16 | */ 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Configuration 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | @ConfigurationProperties(prefix = "dk.ext") 23 | public class DangKangExternalProperties { 24 | 25 | /** 26 | * 用户游戏项目的需要扫描到的包路径前缀,可以填写多个 27 | */ 28 | private List packagePrefix; 29 | 30 | /** 31 | * 外部游戏功能注册功能实现类选择 32 | */ 33 | private String register = "DEFAULT"; 34 | } 35 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangFunctionProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * 当康系统可配置功能相关配置项 14 | * 15 | * @author fagarine 16 | */ 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Configuration 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | @ConfigurationProperties(prefix = "dk.function") 23 | public class DangKangFunctionProperties { 24 | 25 | /** 26 | * 是否允许功能的实现类缺失;注意:允许缺失的情况下,如果找不到功能的实现类,系统也不会报错,这可能导致调用处的NullPointerException 27 | */ 28 | private boolean vacant = true; 29 | } 30 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangGenerateProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * @author fagarine 14 | */ 15 | @Getter 16 | @Setter 17 | @ToString 18 | @Configuration 19 | @Order(Ordered.HIGHEST_PRECEDENCE) 20 | @ConfigurationProperties(prefix = "dk.generate") 21 | public class DangKangGenerateProperties { 22 | 23 | /** 24 | * 是否自动创建消息处理Handler类,默认为false;如果设置为true,当有新的Handler表达式创建时,将会创建一个对应的Handler类,并将表达式转变为其中的代码 25 | */ 26 | private boolean handler = false; 27 | } 28 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangGmProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * 当康系统游戏服GM功能相关配置项 14 | * 15 | * @author fagarine 16 | */ 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Configuration 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | @ConfigurationProperties(prefix = "dk.gm") 23 | public class DangKangGmProperties { 24 | 25 | /** 26 | * 游戏服进程的配置项中,记录GM服务接口的配置项名称 27 | */ 28 | private String key = "gmUrl"; 29 | 30 | /** 31 | * GM后台服务器URL根目录 32 | */ 33 | private String console; 34 | } 35 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangIdProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * @author fagarine 14 | */ 15 | @Getter 16 | @Setter 17 | @ToString 18 | @Configuration 19 | @Order(Ordered.HIGHEST_PRECEDENCE) 20 | @ConfigurationProperties(prefix = "dk.id") 21 | public class DangKangIdProperties { 22 | 23 | /** 24 | * 选择id自增器的实现方式 25 | */ 26 | private String incrementer = "DEFAULT"; 27 | 28 | /** 29 | * 选择生成用户id的实现方式 30 | */ 31 | private String user = "DEFAULT"; 32 | 33 | /** 34 | * 选择生成游戏角色id的实现方式 35 | */ 36 | private String role = "DEFAULT"; 37 | } 38 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangModuleProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | /** 13 | * 外置模块配置项(外置模块项目专用) 14 | * 15 | * @author fagarine 16 | */ 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Configuration 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | @ConfigurationProperties(prefix = "dk.module") 23 | public class DangKangModuleProperties { 24 | 25 | /** 26 | * 模块名称(仅外置模块需要配置) 27 | */ 28 | private String name; 29 | 30 | /** 31 | * 模块描述信息(仅外置模块需要配置) 32 | */ 33 | private String description; 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /dk-autoconfigure/src/main/java/cn/laoshini/dk/autoconfigure/DangKangPairDaoProperties.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.autoconfigure; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.Ordered; 9 | import org.springframework.core.annotation.Order; 10 | 11 | /** 12 | * 键值对数据库相关配置项 13 | * 14 | * @author fagarine 15 | */ 16 | @Getter 17 | @Setter 18 | @Configuration 19 | @Order(Ordered.HIGHEST_PRECEDENCE) 20 | @ConfigurationProperties(prefix = "dk.pair") 21 | public class DangKangPairDaoProperties { 22 | 23 | /** 24 | * 选择键值对数据库数据访问对象的实现方式 25 | */ 26 | private String dao = "DEFAULT"; 27 | 28 | /** 29 | * 如果使用LevelDB作为数据库,填写数据库文件保存目录路径,可以是绝对路径,也可以使相对项目根目录的相对路径 30 | *

31 | * 注意:请保证配置的目录已存在,否则系统将使用默认路径 32 | */ 33 | private String levelDbFolder; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /dk-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dangkang 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-common 13 | 14 | 15 | 16 | org.springframework 17 | spring-context 18 | ${spring.version} 19 | provided 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/annotation/ConfigurableFunction.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 可配置功能标记,使用该注解标记的类,表示是一个功能定义类,其允许有多种不同实现,用户可以通过添加功能实现类的项目依赖和配置指定,来选择具体使用哪种实现。 10 | *

11 | * 功能通过配置的好处: 12 | *

    13 | *
  • 将功能与其他依赖的功能解耦,功能之间通过接口调用,不需要知道具体实现,甚至不需要关心实现类是否是单例
  • 14 | *
  • 方便功能的统一管理,实现类的实例对象由系统统一管理
  • 15 | *
  • 实现依赖最小化,可以针对某个功能实现单独做一个项目,用户只需要单独加入这个项目的依赖即可,避免其他代码干扰
  • 16 | *
17 | *

18 | *

19 | * 注意:本注解需要与@{@link FunctionVariousWays}注解配合使用, 20 | * 本注解用来标记功能定义类(一般为接口),而{@link FunctionVariousWays}用来标记功能的实现类。
21 | * 另外:功能定义类在项目启动时,应该作为classpath的一部分,被系统类加载器加载,而不应该放在可插拔模块中。 22 | *

23 | * 24 | * @author fagarine 25 | * @see FunctionVariousWays 26 | */ 27 | @Target(ElementType.TYPE) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | public @interface ConfigurableFunction { 30 | 31 | /** 32 | * 该功能在配置项中的key,用户通过这个值作为配置项的key来选择实现方式(大小写敏感) 33 | */ 34 | String key(); 35 | 36 | /** 37 | * 功能说明 38 | */ 39 | String description() default ""; 40 | } 41 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/annotation/Message.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 用于标记类,被标记的类表示该类是一个消息类 10 | * 11 | * @author fagarine 12 | */ 13 | @Target(ElementType.TYPE) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface Message { 16 | 17 | /** 18 | * 消息id 19 | */ 20 | int id(); 21 | 22 | /** 23 | * 描述信息 24 | */ 25 | String desc() default ""; 26 | 27 | /** 28 | * 是否是GM消息 29 | */ 30 | boolean gm() default false; 31 | } 32 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/annotation/ResourceHolder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 该注解用于外置模块热更新,用来标记 外置模块中 持有数据单例枚举静态数据类 10 | *

11 | * 被该注解标记的类,意为数据或内存资源的持有者,表示该类在热更新模块时,需要保留更新前的资源数据,并拷贝到更新后的对象中 12 | *

13 | *

14 | * 该注解用于模块热更新,所以外置模块需要使用该注解;当然,非外置模块也建议使用,这有助于使用表达式获取数据;
15 | * 如果一个类已经被标记为Spring托管,则不需要再使用该注解标注,系统默认会保留Spring托管对象的数据;
16 | * 如果一个类被{@link FunctionVariousWays}标记,也不需要使用该注解;
17 | * 稍显特殊的,是被{@link MessageHandle}标记的类,如果Handler类中依赖了Spring组件,系统同样会使用Spring管理Handler对象; 18 | *

19 | * 综上,该标记适用于非Spring托管,但是又长期持有数据的对象,使用该注解的类必须是 单例枚举静态数据类; 20 | * 如外置模块中缓存了部分用户数据的manager类,在热更后需要保留热更前已缓存的数据,则需要添加该注解。 21 | * 22 | * @author fagarine 23 | */ 24 | @Target(ElementType.TYPE) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | public @interface ResourceHolder { 27 | /** 28 | * 名称、描述,可选 29 | */ 30 | String value() default ""; 31 | } 32 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/common/IDkApplicationContext.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.common; 2 | 3 | import org.springframework.context.ConfigurableApplicationContext; 4 | 5 | /** 6 | * 当康容器上下文SPI接口 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IDkApplicationContext extends ConfigurableApplicationContext { 11 | 12 | /** 13 | * 传入用户项目中Spring配置文件路径 14 | * 15 | * @param locations 配置文件路径 16 | */ 17 | void configLocations(String... locations); 18 | 19 | /** 20 | * 获取当康容器启动依赖的Spring配置文件 21 | * 22 | * @return 返回配置文件路径 23 | */ 24 | String[] dependentSpringConfigs(); 25 | } 26 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/constant/LogLabel.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum LogLabel { 7 | /** 8 | * 错误日志 9 | */ 10 | ERROR("error"), 11 | /** 12 | * 警告日志 13 | */ 14 | WARN("warn"), 15 | /** 16 | * INFO日志 17 | */ 18 | INFO("info"), 19 | /** 20 | * DEBUG日志 21 | */ 22 | DEBUG("debug"), 23 | /** 24 | * java agent日志 25 | */ 26 | AGENT("agent"), 27 | /** 28 | * session日志 29 | */ 30 | SESSION("session"), 31 | /** 32 | * 客户端发往服务端的消息日志 33 | */ 34 | C2S("c2s"), 35 | /** 36 | * 服务端发往客户端的消息日志 37 | */ 38 | S2C("s2c"), 39 | /** 40 | * 消息日志,不区分上行下行 41 | */ 42 | MESSAGE("msg"), 43 | /** 44 | * 协议处理handler相关日志 45 | */ 46 | HANDLER("handler"), 47 | ; 48 | 49 | private String label; 50 | 51 | LogLabel(String label) { 52 | this.label = label; 53 | } 54 | 55 | public String getLabel() { 56 | return label; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/exception/BusinessException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.exception; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class BusinessException extends DkRuntimeException { 7 | public BusinessException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | public BusinessException(String errorKey, String message) { 12 | super(errorKey, message); 13 | } 14 | 15 | public BusinessException(String errorKey, String message, Throwable cause) { 16 | super(errorKey, message, cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/exception/DkRuntimeException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.exception; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class DkRuntimeException extends RuntimeException { 7 | 8 | private String errorKey; 9 | 10 | public DkRuntimeException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public DkRuntimeException(String errorKey, String message) { 15 | super(message); 16 | this.errorKey = errorKey; 17 | } 18 | 19 | public DkRuntimeException(String errorKey, String message, Throwable cause) { 20 | super(message, cause); 21 | this.errorKey = errorKey; 22 | } 23 | 24 | public String getErrorKey() { 25 | return errorKey; 26 | } 27 | 28 | public void setErrorKey(String errorKey) { 29 | this.errorKey = errorKey; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/util/CollectionUtil.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.util; 2 | 3 | import java.util.Collection; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | public class CollectionUtil { 10 | private CollectionUtil() { 11 | } 12 | 13 | public static boolean isEmpty(Collection collection) { 14 | return collection == null || collection.isEmpty(); 15 | } 16 | 17 | public static boolean isNotEmpty(Collection collection) { 18 | return !isEmpty(collection); 19 | } 20 | 21 | public static boolean isEmpty(Map map) { 22 | return map == null || map.isEmpty(); 23 | } 24 | 25 | public static boolean isNotEmpty(Map map) { 26 | return !isEmpty(map); 27 | } 28 | 29 | public static boolean isEmpty(Object[] array) { 30 | return array == null || array.length == 0; 31 | } 32 | 33 | public static boolean isNotEmpty(Object[] array) { 34 | return !isEmpty(array); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dk-common/src/main/java/cn/laoshini/dk/util/NetUtil.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.util; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.net.Socket; 5 | import java.net.SocketAddress; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | public class NetUtil { 11 | private NetUtil() { 12 | } 13 | 14 | private static final String LOCAL_IP = "127.0.0.1"; 15 | 16 | /** 17 | * 远程端口是否可用 18 | * 19 | * @param ip 20 | * @param port 21 | * @return 22 | */ 23 | public static boolean remotePortAble(String ip, int port) { 24 | try (Socket s = new Socket()) { 25 | SocketAddress add = new InetSocketAddress(ip, port); 26 | s.connect(add, 3000); 27 | return true; 28 | } catch (Exception e) { 29 | return false; 30 | } 31 | } 32 | 33 | /** 34 | * 本机端口是否可用 35 | * 36 | * @param port 本机端口 37 | * @return 38 | */ 39 | public static boolean localPortAble(int port) { 40 | try (Socket s = new Socket()) { 41 | s.bind(new InetSocketAddress(LOCAL_IP, port)); 42 | return true; 43 | } catch (Exception e) { 44 | return false; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/cache/CacheContainer.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.cache; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | 5 | import cn.laoshini.dk.exception.CacheException; 6 | import cn.laoshini.dk.util.LogUtil; 7 | 8 | /** 9 | * 缓存池容器管理 10 | * 11 | * @author fagarine 12 | */ 13 | public class CacheContainer { 14 | 15 | private static ConcurrentHashMap caches = new ConcurrentHashMap<>(); 16 | 17 | private static IDkCache getCache(String cacheKey) { 18 | if (cacheKey == null) { 19 | return null; 20 | } 21 | return caches.get(cacheKey); 22 | } 23 | 24 | public static void putCache(String cacheKey, IDkCache cache) { 25 | if (cacheKey == null) { 26 | String message = String.format("缓存池的key不能为空, cache:%s", cache.getClass()); 27 | LogUtil.error(message); 28 | throw new CacheException("cache.key.null", message); 29 | } 30 | 31 | caches.put(cacheKey, cache); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/common/DkApplicationContext.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.common; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | import org.springframework.core.env.ConfigurableEnvironment; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | public class DkApplicationContext extends ClassPathXmlApplicationContext implements IDkApplicationContext { 10 | 11 | @Override 12 | protected ConfigurableEnvironment createEnvironment() { 13 | return new DkEnvironment(); 14 | } 15 | 16 | @Override 17 | public void configLocations(String... locations) { 18 | super.setConfigLocations(locations); 19 | } 20 | 21 | @Override 22 | public String[] dependentSpringConfigs() { 23 | return new String[] { "applicationContext-dk-default.xml" }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/condition/ConditionRecord.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.condition; 2 | 3 | /** 4 | * 记录条件匹配信息 5 | * 6 | * @author fagarine 7 | */ 8 | public class ConditionRecord { 9 | 10 | private StringBuilder message; 11 | 12 | public ConditionRecord(String message) { 13 | this.message = new StringBuilder(message); 14 | } 15 | 16 | public static ConditionRecord empty() { 17 | return new ConditionRecord(""); 18 | } 19 | 20 | public void append(ConditionRecord record) { 21 | if (record.notEmpty()) { 22 | if (notEmpty()) { 23 | message.append(", "); 24 | } 25 | message.append(record.getMessage()); 26 | } 27 | } 28 | 29 | public boolean isEmpty() { 30 | return message == null || message.length() == 0; 31 | } 32 | 33 | public boolean notEmpty() { 34 | return !isEmpty(); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return isEmpty() ? "" : message.toString(); 40 | } 41 | 42 | public StringBuilder getMessage() { 43 | return message; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/condition/ConditionalOnPropertyExists.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.condition; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.context.annotation.Conditional; 9 | 10 | /** 11 | * 匹配条件:指定配置项必须存在;仅当指定的所有配置项存在有效值(非空且不为空字符串)的情况下,条件成立 12 | * 13 | * @author fagarine 14 | */ 15 | @Target({ ElementType.TYPE, ElementType.METHOD }) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Conditional(OnPropertyExistsCondition.class) 18 | public @interface ConditionalOnPropertyExists { 19 | 20 | /** 21 | * 当条件只受单个配置项约束,或者有多个配置项但前缀名称不一致时,建议使用该方法; 22 | * 注意:使用该方法必须填写配置项的全名 23 | * 如果使用了该方法,还使用了{@link #prefix()}和{@link #name()},则会取他们的并集做匹配 24 | */ 25 | String[] value() default {}; 26 | 27 | /** 28 | * 如果有多个配置项,且具有同样的前缀名,建议使用该方法加{@link #name()}的形式,该方法需要与{@link #name()}联合使用 29 | */ 30 | String prefix() default ""; 31 | 32 | /** 33 | * 配置项的名称,该方法需要与{@link #prefix()}联合使用,prefix + "." + name 视为一个完整的配置项名称 34 | */ 35 | String[] name() default {}; 36 | } 37 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/condition/ConditionalOnPropertyMissing.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.condition; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.context.annotation.Conditional; 9 | 10 | /** 11 | * 匹配条件:指定配置项必须 不存在;仅当指定的所有配置项不存在的情况下,条件成立 12 | * 13 | * @author fagarine 14 | */ 15 | @Target({ ElementType.TYPE, ElementType.METHOD }) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Conditional(OnPropertyMissingCondition.class) 18 | public @interface ConditionalOnPropertyMissing { 19 | 20 | /** 21 | * 当条件只受单个配置项约束,或者有多个配置项但前缀名称不一致时,建议使用该方法; 22 | * 注意:使用该方法必须填写配置项的全名 23 | * 如果使用了该方法,还使用了{@link #prefix()}和{@link #name()},则会取他们的并集做匹配 24 | */ 25 | String[] value() default {}; 26 | 27 | /** 28 | * 如果有多个配置项,且具有同样的前缀名,建议使用该方法加{@link #name()}的形式,该方法需要与{@link #name()}联合使用 29 | */ 30 | String prefix() default ""; 31 | 32 | /** 33 | * 配置项的名称,该方法需要与{@link #prefix()}联合使用,prefix + "." + name 视为一个完整的配置项名称 34 | */ 35 | String[] name() default {}; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/condition/ConditionalOnPropertyValue.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.condition; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.context.annotation.Conditional; 9 | 10 | /** 11 | * 匹配条件:指定配置项的值,必须包含指定值 12 | * 13 | * @author fagarine 14 | */ 15 | @Target({ ElementType.TYPE, ElementType.METHOD }) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Conditional(OnPropertyValueCondition.class) 18 | public @interface ConditionalOnPropertyValue { 19 | 20 | /** 21 | * 配置项名称,全名,例如: dk.default-dao 22 | */ 23 | String[] propertyName() default {}; 24 | 25 | /** 26 | * 配置项的值中,必须包含的内容,仅在配置项的值不为空时有效。 27 | *

28 | * 注意以下特殊情况: 29 | * 如果本方法返回空字符串,表示不管配置项是否存在,都匹配成功; 30 | * 如果在配置信息中找不到对应配置项的值,则默认表示匹配成功 31 | *

32 | */ 33 | String havingValue() default ""; 34 | 35 | /** 36 | * 配置项不存在时,是否匹配;如果本方法返回true,当配置项不存在时,则匹配不通过,否则匹配通过 37 | */ 38 | boolean matchIfMissing() default false; 39 | } 40 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/condition/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下提供Spring组件部分自动配置条件 3 | *

4 | * 其实spring-boot-autoconfigure项目提供了更多更强大的条件,但是为了增加项目的可扩展性,减小项目的固定依赖,故而项目中单独实现了部分常用条件 5 | *

6 | * 7 | * @author fagarine 8 | * @see org.springframework.context.annotation.Conditional 9 | * @see org.springframework.context.annotation.Condition 10 | */ 11 | package cn.laoshini.dk.condition; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/ConstTableSourceEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 配置表单数据来源枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum ConstTableSourceEnum { 9 | /** 10 | * excel文件 11 | */ 12 | EXCEL, 13 | /** 14 | * JSON文件 15 | */ 16 | JSON, 17 | /** 18 | * 数据库 19 | */ 20 | DB, 21 | ; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/DBTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 关系数据库类型 5 | * 6 | * @author fagarine 7 | */ 8 | public enum DBTypeEnum { 9 | /** 10 | * 系统默认使用数据库 11 | */ 12 | MYSQL, 13 | SQL_SERVER, 14 | ORACLE, 15 | DB2, 16 | ; 17 | } 18 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/ExpressionConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class ExpressionConstant { 7 | private ExpressionConstant() { 8 | } 9 | 10 | public static final String REQ_MESSAGE_PARAM = "req"; 11 | 12 | public static final String REQ_MESSAGE_DATA = "reqData"; 13 | 14 | public static final String GAME_SUBJECT_PARAM = "subject"; 15 | 16 | public static final String RETURN_PARAM = "_ret"; 17 | 18 | public static final String JS_DEPENDENCY_FUNCTION = "expressionDependencies()"; 19 | 20 | /** 21 | * 表达式类型枚举 22 | */ 23 | public enum ExpressionTypeEnum { 24 | /** 25 | * Spring表达式Spel 26 | */ 27 | SPEL, 28 | /** 29 | * JavaScript脚本 30 | */ 31 | JS, 32 | ; 33 | } 34 | 35 | /** 36 | * 表达式代码分类枚举 37 | */ 38 | public enum ExpressionCodeType { 39 | /** 40 | * 逻辑代码 41 | */ 42 | LOGIC, 43 | /** 44 | * 依赖声明 45 | */ 46 | DEPENDENCY, 47 | ; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/GameServerProtocolEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 游戏服通信协议类型枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum GameServerProtocolEnum { 9 | 10 | /** 11 | * TCP 12 | */ 13 | TCP, 14 | UDP, 15 | HTTP, 16 | WEBSOCKET; 17 | } 18 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/GameServerStatus.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 游戏服状态枚举 8 | * 9 | * @author fagarine 10 | */ 11 | public enum GameServerStatus { 12 | 13 | /** 14 | * 运行中 15 | */ 16 | RUN(1), 17 | 18 | /** 19 | * 已停止业务 20 | */ 21 | PAUSE(2), 22 | 23 | /** 24 | * 已关闭,未启动 25 | */ 26 | CLOSE(3), 27 | 28 | ; 29 | 30 | private static final Map CODE_TO_STATUS = new HashMap<>(values().length); 31 | 32 | static { 33 | for (GameServerStatus status : values()) { 34 | CODE_TO_STATUS.put(status.code, status); 35 | } 36 | } 37 | 38 | private int code; 39 | 40 | GameServerStatus(int code) { 41 | this.code = code; 42 | } 43 | 44 | public static GameServerStatus getByCode(int code) { 45 | return CODE_TO_STATUS.get(code); 46 | } 47 | 48 | public int getCode() { 49 | return code; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/GeneratorTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum GeneratorTypeEnum { 7 | 8 | /** 9 | * 自定义格式消息 10 | */ 11 | CUSTOM_MESSAGE, 12 | 13 | HANDLER, 14 | 15 | ; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/HotfixResultEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 热修复执行结果枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum HotfixResultEnum { 9 | 10 | /** 11 | * 执行成功 12 | */ 13 | SUCCEED("执行成功"), 14 | 15 | /** 16 | * 类文件没有改变 17 | */ 18 | NO_CHANGE("类文件没有改变"), 19 | 20 | /** 21 | * 未找到类 22 | */ 23 | NO_CLASS("类未找到"), 24 | 25 | /** 26 | * 未找到agent 27 | */ 28 | NO_AGENT("未找到agent"), 29 | 30 | /** 31 | * 执行出错 32 | */ 33 | EXCEPTION("执行出错"), 34 | 35 | ; 36 | 37 | private String desc; 38 | 39 | HotfixResultEnum(String desc) { 40 | this.desc = desc; 41 | } 42 | 43 | public String getDesc() { 44 | return desc; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/InnerTableNameConst.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class InnerTableNameConst { 7 | private InnerTableNameConst() { 8 | } 9 | 10 | public static final String GAME_CONFIG = "game_config"; 11 | 12 | public static final String GAME_ROLE = "game_role"; 13 | 14 | public static final String GAME_USER = "game_user"; 15 | 16 | public static final String HANDLER_EXPRESSION = "handler_expression"; 17 | 18 | public static final String HOTFIX_RECORD = "hotfix_record"; 19 | 20 | public static final String MIXED_GAME_SERVER_INFO = "mixed_game_server_info"; 21 | } 22 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/MessageFormatEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 消息格式类型枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum MessageFormatEnum { 9 | 10 | /** 11 | * json,对应普通的JavaBean,比如DTO、VO等 12 | */ 13 | JSON, 14 | /** 15 | * protobuf 16 | */ 17 | PROTOBUF, 18 | /** 19 | * 自定义消息格式 20 | */ 21 | CUSTOM, 22 | ; 23 | } 24 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/ModuleConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.Set; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * 外置模块功能相关常量 9 | * 10 | * @author fagarine 11 | */ 12 | public class ModuleConstant { 13 | private ModuleConstant() { 14 | } 15 | 16 | /** 17 | * 系统可识别的,外置模块的配置文件后缀名 18 | */ 19 | public static final String[] MODULE_CONFIG_FILE_SUFFIX = { ".properties", ".yaml", ".yml" }; 20 | 21 | /** 22 | * 外置模块系统,模块配置文件名称命名规则(加载模块时,系统会去查找符合规则的配置文件,并且以先找到的配置文件中的配置信息为准) 23 | */ 24 | public static final String[] MODULE_CONFIG_FILE_REG_EXP = { "^application-[A-Za-z0-9_-]+$", "^[A-Za-z0-9_-]+$" }; 25 | 26 | public static final Set MODULE_CONFIG_FILE_PATTERNS = new LinkedHashSet<>( 27 | MODULE_CONFIG_FILE_REG_EXP.length); 28 | 29 | static { 30 | for (String regExp : MODULE_CONFIG_FILE_REG_EXP) { 31 | MODULE_CONFIG_FILE_PATTERNS.add(Pattern.compile(regExp)); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/PropertyKeyConstants.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 当康系统配置项参数key常量 5 | * 6 | * @author fagarine 7 | */ 8 | public class PropertyKeyConstants { 9 | private PropertyKeyConstants() { 10 | } 11 | 12 | /** 13 | * 当康项目所有配置参数key的前缀 14 | */ 15 | public static final String DANG_KANG_PROPERTY_KEY_PREFIX = "dk"; 16 | 17 | /** 18 | * 模块名称 19 | */ 20 | public static final String MODULE_NAME_KEY = "dk.module.name"; 21 | /** 22 | * 模块描述信息 23 | */ 24 | public static final String MODULE_DESCRIPTION_KEY = "dk.module.description"; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/QueryConditionKeyEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum QueryConditionKeyEnum { 7 | 8 | /** 9 | * 数据库名 10 | */ 11 | DB_NAME("DB_NAME", "数据库名"), 12 | TABLE_NAME("TABLE_NAME", "表名"), 13 | COLUMN_NAME("COLUMN_NAME", "列名"), 14 | UNIQUE_KEY("UNIQUE_KEY", "全表唯一标识"), 15 | ; 16 | 17 | private String key; 18 | 19 | private String cnName; 20 | 21 | QueryConditionKeyEnum(String key, String cnName) { 22 | this.key = key; 23 | this.cnName = cnName; 24 | } 25 | 26 | public String getKey() { 27 | return key; 28 | } 29 | 30 | public String getCnName() { 31 | return cnName; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/RoleStatusEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum RoleStatusEnum { 7 | /** 8 | * 正常 9 | */ 10 | NORMAL((short) 1), 11 | /** 12 | * 封号 13 | */ 14 | LOCKED((short) 10), 15 | /** 16 | * 禁止登陆 17 | */ 18 | FORBIDDEN((short) 20), 19 | /** 20 | * 无效 21 | */ 22 | INVALID((short) 30), 23 | ; 24 | 25 | public static boolean isValidStatus(short code) { 26 | return NORMAL.code == code; 27 | } 28 | 29 | private short code; 30 | 31 | RoleStatusEnum(short code) { 32 | this.code = code; 33 | } 34 | 35 | public int getCode() { 36 | return code; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/ServerType.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 游戏服务器(按功能、作用分)类型枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum ServerType { 9 | 10 | /** 11 | * 游戏服 12 | */ 13 | GAME, 14 | 15 | /** 16 | * 游戏管理服务器,与游戏服在同一进程,共用数据,一般负责与后台管理服务器通信 17 | */ 18 | GM, 19 | 20 | /** 21 | * 后台管理服务器 22 | */ 23 | CONSOLE, 24 | 25 | /** 26 | * 帐号管理,用户登录服务器 27 | */ 28 | ACCOUNT, 29 | 30 | /** 31 | * 用户充值、支付服务器 32 | */ 33 | RECHARGE, 34 | 35 | ; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/UseTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * Class用途分类枚举,按用途对Class分类 5 | * 6 | * @author fagarine 7 | */ 8 | public enum UseTypeEnum { 9 | /** 10 | * POJO类、普通实例类 11 | */ 12 | ORDINARY, 13 | 14 | /** 15 | * 静态工具类 16 | */ 17 | UTIL, 18 | 19 | /** 20 | * 自定义格式消息DTO类 21 | */ 22 | DTO, 23 | 24 | /** 25 | * Spring托管类 26 | */ 27 | SPRING_BEAN, 28 | 29 | /** 30 | * 资源持有者 31 | */ 32 | HOLDER, 33 | 34 | ; 35 | } 36 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/constant/UserStatusEnum.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 用户帐号状态枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum UserStatusEnum { 9 | 10 | /** 11 | * 正常 12 | */ 13 | NORMAL((short) 1), 14 | /** 15 | * 封号 16 | */ 17 | LOCKED((short) 10), 18 | /** 19 | * 禁止登陆 20 | */ 21 | FORBIDDEN((short) 20), 22 | /** 23 | * 无效 24 | */ 25 | INVALID((short) 30), 26 | ; 27 | 28 | public static boolean isValidStatus(short code) { 29 | return NORMAL.code == code; 30 | } 31 | 32 | private short code; 33 | 34 | UserStatusEnum(short code) { 35 | this.code = code; 36 | } 37 | 38 | public int getCode() { 39 | return code; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/IBasicDao.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao; 2 | 3 | /** 4 | * 公用数据库访问对象定义接口,用于系统内部数据(例如用户配置数据等)的访问 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IBasicDao { 9 | } 10 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/IEntityClassManager.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import cn.laoshini.dk.annotation.ConfigurableFunction; 7 | 8 | /** 9 | * 实体类管理 10 | * 11 | * @author fagarine 12 | */ 13 | @ConfigurableFunction(key = "dk.rdb.entity-manager") 14 | public interface IEntityClassManager { 15 | 16 | /** 17 | * 注册表与实体类的映射关系 18 | * 19 | * @param tableName 表名 20 | * @param tableClass 实体类 21 | */ 22 | void registerEntityClass(String tableName, Class tableClass); 23 | 24 | /** 25 | * 批量注册 26 | * 27 | * @param map key:表名称,value:对应的类 28 | */ 29 | void batchRegister(Map> map); 30 | 31 | /** 32 | * 预备批量注销 33 | * 34 | * @param classLoader 类加载器 35 | */ 36 | void prepareUnregister(ClassLoader classLoader); 37 | 38 | /** 39 | * 取消注销预备操作 40 | */ 41 | void cancelPrepareUnregister(); 42 | 43 | /** 44 | * 批量注销 45 | */ 46 | void unregister(); 47 | 48 | boolean containsClass(Class clazz); 49 | 50 | String getClassTableName(String className); 51 | 52 | Class getTableBeanClass(String tableName); 53 | 54 | List getTableNames(); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/IRelationalDbDaoManager.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | 5 | /** 6 | * 关系数据库数据访问对象管理接口 7 | * 8 | * @author fagarine 9 | */ 10 | @ConfigurableFunction(key = "dk.rdb.manager", description = "关系数据库数据访问对象管理") 11 | public interface IRelationalDbDaoManager { 12 | 13 | /** 14 | * 获取有效的数据库访问对象 15 | * 16 | * @param tableName 表名 17 | * @param clazz 实体类类型 18 | * @param 实体类类型 19 | * @return 该方法不会返回null 20 | */ 21 | IRelationalDbDao getValidDbDao(String tableName, Class clazz); 22 | 23 | /** 24 | * 验证表是否存在 25 | * 26 | * @param tableName 表名 27 | * @return 验证结果 28 | */ 29 | boolean validateTable(String tableName); 30 | } 31 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/TableKey.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 用于标记类变量,表示该字段为主键, 10 | *

11 | * 注意:使用该注解,必须保证该类已被@{@link TableMapping}标记,否则单独使用无效
12 | * 另外:如果一个类中有多个字段被标记,则会被视为联合主键看待 13 | *

14 | * 15 | * @author fagarine 16 | */ 17 | @Target(ElementType.FIELD) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface TableKey { 20 | 21 | /** 22 | * 描述信息,不可用于具体的业务逻辑 23 | */ 24 | String value() default ""; 25 | 26 | /** 27 | * 是否是自增字段 28 | */ 29 | boolean autoIncrement() default false; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/update/SqlWrapper.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao.update; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class SqlWrapper { 9 | 10 | protected String tableName; 11 | 12 | protected Class entityType; 13 | 14 | protected Map condition; 15 | 16 | public String getTableName() { 17 | return tableName; 18 | } 19 | 20 | public void setTableName(String tableName) { 21 | this.tableName = tableName; 22 | } 23 | 24 | public Class getEntityType() { 25 | return entityType; 26 | } 27 | 28 | public void setEntityType(Class entityType) { 29 | this.entityType = entityType; 30 | } 31 | 32 | public Map getCondition() { 33 | return condition; 34 | } 35 | 36 | public void setCondition(Map condition) { 37 | this.condition = condition; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/dao/update/UpdateSqlWrapper.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.dao.update; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class UpdateSqlWrapper extends SqlWrapper { 9 | 10 | protected Map updateValues; 11 | 12 | public Map getUpdateValues() { 13 | return updateValues; 14 | } 15 | 16 | public void setUpdateValues(Map updateValues) { 17 | this.updateValues = updateValues; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/domain/GameSubject.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import cn.laoshini.dk.net.session.AbstractSession; 6 | 7 | /** 8 | * 游戏主体,消息到达后的接收方,一般为玩家 9 | * 10 | * @author fagarine 11 | */ 12 | public class GameSubject implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | private AbstractSession session; 17 | 18 | public int getGameId() { 19 | return 0; 20 | } 21 | 22 | public int getServerId() { 23 | return 0; 24 | } 25 | 26 | public AbstractSession getSession() { 27 | return session; 28 | } 29 | 30 | public void setSession(AbstractSession session) { 31 | this.session = session; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/domain/common/ClassDescriptor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | @Data 11 | public class ClassDescriptor implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | private String className; 16 | 17 | private String simpleName; 18 | 19 | private String type; 20 | 21 | private String comment; 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/domain/common/HotfixFile.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * 热修复文件信息 9 | * 10 | * @author fagarine 11 | */ 12 | @Getter 13 | @Setter 14 | @ToString 15 | public class HotfixFile { 16 | 17 | /** 18 | * 类的全限定名 19 | */ 20 | private String fullClassName; 21 | 22 | /** 23 | * 类文件的绝对路径 24 | */ 25 | private String filePath; 26 | 27 | /** 28 | * 文件的最后修改时间 29 | */ 30 | private long lastModifyTime; 31 | } 32 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/domain/common/MethodDescriptor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | @Data 12 | public class MethodDescriptor implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | private String name; 17 | 18 | private String comment; 19 | 20 | private List> params; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/entity/HotfixRecord.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | 10 | import cn.laoshini.dk.constant.InnerTableNameConst; 11 | import cn.laoshini.dk.dao.TableKey; 12 | import cn.laoshini.dk.dao.TableMapping; 13 | 14 | /** 15 | * 热修复执行结果记录 16 | * 17 | * @author fagarine 18 | */ 19 | @Getter 20 | @Setter 21 | @ToString 22 | @TableMapping(value = InnerTableNameConst.HOTFIX_RECORD, description = "热修复记录") 23 | public class HotfixRecord implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | @TableKey 28 | private int id; 29 | 30 | /** 31 | * 热更key,用于区分是否是同一次热更操作,可以是热更说明信息等 32 | */ 33 | private String hotfixKey; 34 | 35 | /** 36 | * 热更类名 37 | */ 38 | private String className; 39 | 40 | /** 41 | * 热更时间 42 | */ 43 | private Date hotfixTime; 44 | 45 | /** 46 | * 热更结果 47 | */ 48 | private String result; 49 | 50 | /** 51 | * 描述信息 52 | */ 53 | private String desc; 54 | } 55 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/exception/CacheException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.exception; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class CacheException extends DkRuntimeException { 7 | public CacheException(String errorKey, String message) { 8 | super(errorKey, message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/exception/DaoException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.exception; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class DaoException extends DkRuntimeException { 7 | public DaoException(String errorKey, String message) { 8 | super(errorKey, message); 9 | } 10 | 11 | public DaoException(String errorKey, String message, Throwable cause) { 12 | super(errorKey, message, cause); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/exception/JitException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.exception; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class JitException extends DkRuntimeException { 7 | public JitException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | public JitException(String errorKey, String message) { 12 | super(errorKey, message); 13 | } 14 | 15 | public JitException(String errorKey, String message, Throwable cause) { 16 | super(errorKey, message, cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/executor/AbstractOrderedWorker.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.executor; 2 | 3 | import cn.laoshini.dk.util.LogUtil; 4 | 5 | /** 6 | * 有序队列工作者线程 7 | * 8 | * @author fagarine 9 | */ 10 | public abstract class AbstractOrderedWorker implements Runnable { 11 | 12 | @Override 13 | public void run() { 14 | try { 15 | action(); 16 | } catch (Throwable t) { 17 | LogUtil.error("有序任务执行出错", t); 18 | } 19 | } 20 | 21 | /** 22 | * 执行具体的业务逻辑 23 | */ 24 | protected abstract void action(); 25 | 26 | /** 27 | * 任务加入队列后,记录所属队列 28 | */ 29 | private TaskQueue taskQueue; 30 | 31 | public TaskQueue getTaskQueue() { 32 | return taskQueue; 33 | } 34 | 35 | public void setTaskQueue(TaskQueue taskQueue) { 36 | this.taskQueue = taskQueue; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/executor/IOrderedExecutor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.executor; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | 5 | /** 6 | * 有序线程池接口 7 | *

8 | * 该接口的实现类,需要提供一个包含三个指定参数的构造方法,这三个参数为: 9 | *

    10 | *
  • name: 线程池名称
  • 11 | *
  • corePoolSize: 核心线程数量
  • 12 | *
  • maxQueueSize: 单个任务队列的最大长度,当队列达到该长度时,新到的任务将被抛弃;仅为正整数时有效
  • 13 | *
14 | *

15 | * 16 | * @param 任务标识的类型,该类型需要与实现类使用的{@link OrderedQueuePool}中的 K 类型一致 17 | * @author fagarine 18 | */ 19 | @ConfigurableFunction(key = "dk.ordered.executor", description = "有序线程池") 20 | public interface IOrderedExecutor { 21 | 22 | /** 23 | * 添加任务 24 | * 25 | * @param key 任务的标识,用来选择任务队列 26 | * @param task 待执行任务 27 | * @return 返回是否成功加入队列 28 | */ 29 | boolean addTask(KeyType key, AbstractOrderedWorker task); 30 | } 31 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/executor/IOrderedExecutorGroup.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.executor; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public interface IOrderedExecutorGroup { 7 | 8 | IOrderedExecutor getExecutor(int index); 9 | } 10 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/executor/NonOrderedQueuePoolExecutor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.executor; 2 | 3 | import java.util.concurrent.LinkedBlockingQueue; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 非有序线程池,用于不需要严格按顺序执行的任务 9 | * 10 | * @author fagarine 11 | */ 12 | public class NonOrderedQueuePoolExecutor extends ThreadPoolExecutor { 13 | public NonOrderedQueuePoolExecutor(int corePoolSize) { 14 | super(corePoolSize, corePoolSize * 2, 30, TimeUnit.SECONDS, new LinkedBlockingQueue()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/executor/OrderedQueuePool.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.executor; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | /** 7 | * 有序任务队列池 8 | * 9 | * @author fagarine 10 | */ 11 | public class OrderedQueuePool { 12 | 13 | private final Map> taskQueueMap = new ConcurrentHashMap<>(); 14 | 15 | /** 16 | * 获得非空任务队列,如果队列不存在,则创建一个返回 17 | * 18 | * @param key 队列key 19 | * @return 该方法不会返回null 20 | */ 21 | public TaskQueue getTaskQueue(K key) { 22 | synchronized (taskQueueMap) { 23 | return taskQueueMap.computeIfAbsent(key, (k) -> new TaskQueue<>()); 24 | } 25 | } 26 | 27 | /** 28 | * 获得全部任务队列 29 | * 30 | * @return 该方法不会返回null 31 | */ 32 | public Map> getTaskQueues() { 33 | return taskQueueMap; 34 | } 35 | 36 | /** 37 | * 移除任务队列 38 | * 39 | * @param key 队列key 40 | */ 41 | public void removeTaskQueue(K key) { 42 | taskQueueMap.remove(key); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/expression/BaseExpressionProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.expression; 2 | 3 | import cn.laoshini.dk.domain.dto.ExpressionDescriptorDTO; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public abstract class BaseExpressionProcessor implements IExpressionProcessor { 9 | 10 | /** 11 | * 表达式描述信息 12 | */ 13 | protected ExpressionDescriptorDTO descriptor; 14 | 15 | public ExpressionDescriptorDTO getDescriptor() { 16 | return descriptor; 17 | } 18 | 19 | public void setDescriptor(ExpressionDescriptorDTO descriptor) { 20 | this.descriptor = descriptor; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/expression/IExpressionProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.expression; 2 | 3 | /** 4 | * 表达式处理器的接口,该接口实现具体表达式的执行 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IExpressionProcessor { 9 | 10 | /** 11 | * 准备表达式执行条件 12 | */ 13 | default void prepare() { 14 | } 15 | 16 | /** 17 | * 运行表达式,并返回执行结果 18 | * 19 | * @param logicContext 逻辑上下文内容 20 | * @return 返回执行结果 21 | */ 22 | Object action(ExpressionLogicContext logicContext); 23 | } 24 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/expression/js/JavaScriptExpressionLogic.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.expression.js; 2 | 3 | import javax.script.ScriptContext; 4 | import javax.script.SimpleScriptContext; 5 | 6 | import cn.laoshini.dk.constant.ExpressionConstant; 7 | import cn.laoshini.dk.expression.BaseExpressionLogic; 8 | import cn.laoshini.dk.expression.IExpressionProcessor; 9 | import cn.laoshini.dk.util.CollectionUtil; 10 | 11 | /** 12 | * 使用JavaScript脚本实现的表达式逻辑处理类 13 | * 14 | * @author fagarine 15 | */ 16 | public class JavaScriptExpressionLogic extends BaseExpressionLogic { 17 | 18 | public JavaScriptExpressionLogic() { 19 | super(ExpressionConstant.ExpressionTypeEnum.JS); 20 | } 21 | 22 | @Override 23 | protected void initProcessors() { 24 | super.initProcessors(); 25 | 26 | if (CollectionUtil.isNotEmpty(processors())) { 27 | ScriptContext context = new SimpleScriptContext(); 28 | for (IExpressionProcessor processor : processors()) { 29 | JavaScriptExpressionProcessor jsProcessor = (JavaScriptExpressionProcessor) processor; 30 | jsProcessor.setScriptContext(context); 31 | jsProcessor.prepare(); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/expression/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下实现表达式相关逻辑 3 | * 4 | *

5 | * 提供将表达式做为业务逻辑执行的功能,为其他需要使用表达式功能的模块提供支持 6 | *

7 | *

8 | * 由于当前有许多表达式语言,如Spel, Groovy等,所以系统不再单独去实现一套,而是封装直接使用,本系统默认使用Spel 9 | *

10 | * 11 | * @author fagarine 12 | */ 13 | package cn.laoshini.dk.expression; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/expression/spel/SpelExpressionLogic.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.expression.spel; 2 | 3 | import cn.laoshini.dk.constant.ExpressionConstant; 4 | import cn.laoshini.dk.expression.BaseExpressionLogic; 5 | 6 | /** 7 | * 使用Spring表达式实现的表达式逻辑处理类 8 | * 9 | * @author fagarine 10 | */ 11 | public class SpelExpressionLogic extends BaseExpressionLogic { 12 | 13 | public SpelExpressionLogic() { 14 | super(ExpressionConstant.ExpressionTypeEnum.SPEL); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/function/FuncContainer.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.function; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | import java.util.Vector; 6 | 7 | import cn.laoshini.dk.util.CollectionUtil; 8 | 9 | /** 10 | * @author fagarine 11 | */ 12 | enum FuncContainer { 13 | /** 14 | * 枚举实现单例 15 | */ 16 | INSTANCE; 17 | 18 | private static final List FUNC_LIST = new Vector<>(); 19 | 20 | static void add(Func func) { 21 | FUNC_LIST.add(func); 22 | } 23 | 24 | static void refreshAll(Collection changedFunctionKeys) { 25 | // 移除无效的可配置功能依赖 26 | FUNC_LIST.removeIf(func -> { 27 | boolean valid = func.isValid(); 28 | if (!valid) { 29 | func.clear(); 30 | } 31 | return !valid; 32 | }); 33 | 34 | if (!CollectionUtil.isEmpty(changedFunctionKeys)) { 35 | for (Func func : FUNC_LIST) { 36 | if (changedFunctionKeys.contains(func.getFunctionKey())) { 37 | func.refresh(); 38 | } 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/generator/id/IIdIncrementer.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.id; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | import cn.laoshini.dk.exception.BusinessException; 5 | 6 | /** 7 | * id自增功能的接口定义 8 | *

9 | * 特别需要注意的是,该类的实现类的构造方法中,必须有一个指向{@link #idName()}方法返回值相同参数的构造方法 10 | *

11 | * 12 | * @author fagarine 13 | */ 14 | @ConfigurableFunction(key = "dk.id.incrementer", description = "id自增器") 15 | public interface IIdIncrementer { 16 | 17 | /** 18 | * 返回id自增器实例对应id的名称 19 | * 20 | * @return 实现类应该保证该方法不会返回null 21 | */ 22 | String idName(); 23 | 24 | /** 25 | * 自增并返回下一个id 26 | * 27 | * @return 正整数 28 | * @throws BusinessException 所有异常都封装为BusinessException抛出 29 | */ 30 | long nextId() throws BusinessException; 31 | } 32 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/generator/id/IRoleIdGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.id; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | import cn.laoshini.dk.exception.BusinessException; 5 | import cn.laoshini.dk.function.VariousWaysManager; 6 | 7 | /** 8 | * 游戏角色id生成器(实现类实现具体的生成规则和格式) 9 | * 10 | * @author fagarine 11 | */ 12 | @ConfigurableFunction(key = "dk.id.role", description = "游戏角色id生成器") 13 | public interface IRoleIdGenerator { 14 | 15 | /** 16 | * 返回下一个角色id 17 | * 18 | * @param platNo 用户来源,渠道号 19 | * @param gameId 角色所属游戏id 20 | * @param serverId 角色所属服务器id 21 | * @return 正整数 22 | */ 23 | long nextRoleId(int platNo, int gameId, int serverId) throws BusinessException; 24 | 25 | /** 26 | * 创建并返回一个id自增器,使用缺省名称("role_id") 27 | * 28 | * @return 如果找不到IIdIncrementer的实现类,会抛出异常 29 | */ 30 | default IIdIncrementer newRoleIdIncrementer() { 31 | return VariousWaysManager.getFunctionCurrentImpl(IIdIncrementer.class, "role_id"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/generator/id/IUserIdGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.id; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | import cn.laoshini.dk.exception.BusinessException; 5 | import cn.laoshini.dk.function.VariousWaysManager; 6 | 7 | /** 8 | * 用户id生成器(实现类实现具体的生成规则和格式) 9 | * 10 | * @author fagarine 11 | */ 12 | @ConfigurableFunction(key = "dk.id.user", description = "用户id生成器") 13 | public interface IUserIdGenerator { 14 | 15 | /** 16 | * 返回下一个用户id 17 | * 18 | * @param platNo 用户来源,渠道号 19 | * @return 正整数 20 | */ 21 | long nextUserId(int platNo) throws BusinessException; 22 | 23 | /** 24 | * 创建并返回一个id自增器,使用缺省名称("user_id") 25 | * 26 | * @return 如果找不到IIdIncrementer的实现类,会抛出异常 27 | */ 28 | default IIdIncrementer newUserIdIncrementer() { 29 | return VariousWaysManager.getFunctionCurrentImpl(IIdIncrementer.class, "user_id"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/generator/id/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 自增id生成器相关 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.generator.id; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/generator/name/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 游戏角色名称生成器相关 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.generator.name; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/JitClassLoader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit; 2 | 3 | import java.io.File; 4 | import java.net.URL; 5 | 6 | import cn.laoshini.dk.exception.JitException; 7 | import cn.laoshini.dk.module.loader.ModuleClassLoader; 8 | 9 | /** 10 | * 运行时及时编译、加载的类加载器 11 | * 12 | * @author fagarine 13 | */ 14 | public class JitClassLoader extends ModuleClassLoader { 15 | public JitClassLoader(URL[] urls, ClassLoader parent) { 16 | super(urls, parent); 17 | } 18 | 19 | public Class loadClass(String classFilePath, String className) { 20 | File classFile = new File(classFilePath); 21 | if (!classFile.exists() || classFile.isDirectory()) { 22 | throw new JitException("class.file.missing", "类文件不存在:" + classFilePath); 23 | } 24 | 25 | addURL(classFile); 26 | 27 | try { 28 | return (Class) loadClass(className); 29 | } catch (ClassNotFoundException e) { 30 | throw new JitException("load.class.error", String.format("加载类[%s]失败, file:%s", className, classFilePath)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/generator/CustomDtoClassFileGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.generator; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import cn.laoshini.dk.jit.type.CompositeBean; 6 | import cn.laoshini.dk.net.msg.ICustomDto; 7 | 8 | /** 9 | * 自定义格式消息(使用JDK自带的{@link ByteBuffer}作为缓冲区)DTO类的生成器 10 | * 11 | * @author fagarine 12 | */ 13 | public class CustomDtoClassFileGenerator extends AbstractCustomDtoClassFileGenerator { 14 | 15 | public CustomDtoClassFileGenerator(CompositeBean compositeBean, ClassLoader classLoader) { 16 | super(compositeBean, classLoader, ByteBuffer.class.getName(), ICustomDto.class.getName()); 17 | } 18 | 19 | @Override 20 | public String candidateClassNamePrefix() { 21 | return "CustomDto"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/generator/NettyCustomDtoClassFileGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.generator; 2 | 3 | import cn.laoshini.dk.jit.type.CompositeBean; 4 | 5 | /** 6 | * 自定义格式消息(使用Netty的ByteBuf作为缓冲区)DTO类的生成器 7 | * 8 | * @author fagarine 9 | */ 10 | public class NettyCustomDtoClassFileGenerator extends AbstractCustomDtoClassFileGenerator { 11 | public NettyCustomDtoClassFileGenerator(CompositeBean compositeBean, ClassLoader classLoader) { 12 | super(compositeBean, classLoader, "io.netty.buffer.ByteBuf", "cn.laoshini.dk.server.message.INettyDto"); 13 | } 14 | 15 | @Override 16 | public String candidateClassNamePrefix() { 17 | return "NettyCustomDto"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包提供Java代码的动态生成和动态编译功能 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.jit; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/AbstractNumericTypeBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public abstract class AbstractNumericTypeBean extends AbstractTypeBean { 7 | 8 | private T min; 9 | 10 | private T max; 11 | 12 | public T getMin() { 13 | return min; 14 | } 15 | 16 | public void setMin(T min) { 17 | this.min = min; 18 | } 19 | 20 | public T getMax() { 21 | return max; 22 | } 23 | 24 | public void setMax(T max) { 25 | this.max = max; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "AbstractNumericTypeBean{" + "min=" + min + ", max=" + max + "} " + super.toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/BooleanBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class BooleanBean extends AbstractTypeBean { 9 | 10 | @Override 11 | public BeanTypeEnum getType() { 12 | return BeanTypeEnum.BOOLEAN; 13 | } 14 | 15 | @Override 16 | public Class getValueType() { 17 | return required() ? boolean.class : Boolean.class; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "BooleanBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 23 | + defaultVal + ", description='" + description + '\'' + '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/ByteBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class ByteBean extends AbstractNumericTypeBean { 9 | @Override 10 | public BeanTypeEnum getType() { 11 | return BeanTypeEnum.BYTE; 12 | } 13 | 14 | @Override 15 | public Class getValueType() { 16 | return required() ? byte.class : Byte.class; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "ByteBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 22 | + defaultVal + ", description='" + description + '\'' + '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/CompositeBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import cn.laoshini.dk.constant.BeanTypeEnum; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | public class CompositeBean extends AbstractTypeBean> { 12 | 13 | public CompositeBean() { 14 | super(); 15 | setDefaultVal(Collections.emptyList()); 16 | } 17 | 18 | @Override 19 | public BeanTypeEnum getType() { 20 | return BeanTypeEnum.COMPOSITE; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "CompositeBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 26 | + defaultVal + ", description='" + description + '\'' + '}'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/CompositeExtendBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.net.msg.ICustomDto; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class CompositeExtendBean extends CompositeBean { 9 | } 10 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/DoubleBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class DoubleBean extends AbstractNumericTypeBean { 9 | 10 | @Override 11 | public BeanTypeEnum getType() { 12 | return BeanTypeEnum.DOUBLE; 13 | } 14 | 15 | @Override 16 | public Class getValueType() { 17 | return required() ? double.class : Double.class; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "DoubleBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 23 | + defaultVal + ", description='" + description + '\'' + '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/IntegerBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class IntegerBean extends AbstractNumericTypeBean { 9 | 10 | @Override 11 | public BeanTypeEnum getType() { 12 | return BeanTypeEnum.INTEGER; 13 | } 14 | 15 | @Override 16 | public Class getValueType() { 17 | return required() ? int.class : Integer.class; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "IntegerBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 23 | + defaultVal + ", description='" + description + '\'' + '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/ListBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import java.util.List; 4 | 5 | import cn.laoshini.dk.constant.BeanTypeEnum; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | public class ListBean extends AbstractTypeBean> { 11 | 12 | private Class actualClass; 13 | 14 | @Override 15 | public BeanTypeEnum getType() { 16 | return BeanTypeEnum.LIST; 17 | } 18 | 19 | public Class getActualClass() { 20 | return actualClass; 21 | } 22 | 23 | public void setActualClass(Class actualClass) { 24 | this.actualClass = actualClass; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "ListBean{" + "actualClass=" + actualClass + ", name='" + name + '\'' + ", valueType=" + valueType 30 | + ", val=" + val + ", defaultVal=" + defaultVal + ", description='" + description + '\'' + '}'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/LongBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class LongBean extends AbstractNumericTypeBean { 9 | 10 | @Override 11 | public BeanTypeEnum getType() { 12 | return BeanTypeEnum.LONG; 13 | } 14 | 15 | @Override 16 | public Class getValueType() { 17 | return required() ? long.class : Long.class; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "LongBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 23 | + defaultVal + ", description='" + description + '\'' + '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/OrdinaryBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class OrdinaryBean extends AbstractTypeBean { 9 | @Override 10 | public BeanTypeEnum getType() { 11 | return BeanTypeEnum.ORDINARY; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "OrdinaryBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 17 | + defaultVal + ", description='" + description + '\'' + '}'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/ShortBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class ShortBean extends AbstractNumericTypeBean { 9 | @Override 10 | public BeanTypeEnum getType() { 11 | return BeanTypeEnum.SHORT; 12 | } 13 | 14 | @Override 15 | public Class getValueType() { 16 | return required() ? short.class : Short.class; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "ShortBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 22 | + defaultVal + ", description='" + description + '\'' + '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/StringBean.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class StringBean extends AbstractTypeBean { 9 | 10 | @Override 11 | public BeanTypeEnum getType() { 12 | return BeanTypeEnum.STRING; 13 | } 14 | 15 | @Override 16 | public Class getValueType() { 17 | return String.class; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "StringBean{" + "name='" + name + '\'' + ", valueType=" + valueType + ", val=" + val + ", defaultVal=" 23 | + defaultVal + ", description='" + description + '\'' + '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/jit/type/TypeBeanRecord.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.jit.type; 2 | 3 | import cn.laoshini.dk.constant.BeanTypeEnum; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public final class TypeBeanRecord extends AbstractNumericTypeBean { 9 | 10 | private int beanTypeCode; 11 | 12 | @Override 13 | public BeanTypeEnum getType() { 14 | return BeanTypeEnum.codeOf(beanTypeCode); 15 | } 16 | 17 | public int getBeanTypeCode() { 18 | return beanTypeCode; 19 | } 20 | 21 | public void setBeanTypeCode(int beanTypeCode) { 22 | this.beanTypeCode = beanTypeCode; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "TypeBeanRecord{" + "beanTypeCode=" + beanTypeCode + "} " + super.toString(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/listener/DkContextEvent.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.listener; 2 | 3 | import org.springframework.context.event.ApplicationContextEvent; 4 | 5 | import cn.laoshini.dk.common.SpringContextHolder; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | public class DkContextEvent extends ApplicationContextEvent { 11 | 12 | public DkContextEvent() { 13 | super(SpringContextHolder.getContext()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/listener/DkEventPublisher.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.listener; 2 | 3 | import cn.laoshini.dk.common.SpringContextHolder; 4 | 5 | /** 6 | * 当康系统事件发布者 7 | * 8 | * @author fagarine 9 | */ 10 | public class DkEventPublisher { 11 | private DkEventPublisher() { 12 | } 13 | 14 | /** 15 | * 发布事件 16 | * 17 | * @param event 事件对象 18 | */ 19 | public static void publishEvent(DkContextEvent event) { 20 | SpringContextHolder.getContext().publishEvent(event); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/listener/IDkContextListener.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.listener; 2 | 3 | import org.springframework.context.ApplicationListener; 4 | 5 | /** 6 | * 当康系统事件监听器接口 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IDkContextListener extends ApplicationListener { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/listener/PropertyChangedEvent.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.listener; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * 对应配置项有更新的事件 7 | * 8 | * @author fagarine 9 | */ 10 | public class PropertyChangedEvent extends DkContextEvent { 11 | 12 | /** 13 | * 记录改变了的配置项key 14 | */ 15 | private Collection changedPropertyKeys; 16 | 17 | public PropertyChangedEvent(Collection changedPropertyKeys) { 18 | this.changedPropertyKeys = changedPropertyKeys; 19 | } 20 | 21 | public PropertyChangedEvent() { 22 | this(null); 23 | } 24 | 25 | public Collection getChangedPropertyKeys() { 26 | return changedPropertyKeys; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/listener/PropertyChangedListener.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.listener; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.Set; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import cn.laoshini.dk.support.IPropertyRefreshable; 9 | 10 | /** 11 | * 配置项更新事件监听器 12 | * 13 | * @author fagarine 14 | */ 15 | @Component 16 | public class PropertyChangedListener implements IDkContextListener { 17 | 18 | private static Set refreshers = new LinkedHashSet<>(); 19 | 20 | public static void addRefresher(IPropertyRefreshable refresher) { 21 | refreshers.add(refresher); 22 | } 23 | 24 | @Override 25 | public void onApplicationEvent(PropertyChangedEvent event) { 26 | for (IPropertyRefreshable refresher : refreshers) { 27 | refresher.refresh(event.getChangedPropertyKeys()); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/module/AbstractModuleRegistry.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.module; 2 | 3 | import cn.laoshini.dk.module.loader.ModuleClassLoader; 4 | import cn.laoshini.dk.module.loader.ModuleLoaderContext; 5 | 6 | /** 7 | * 模块功能注册表基本实现 8 | * 9 | * @author fagarine 10 | */ 11 | public abstract class AbstractModuleRegistry implements IModuleRegistry { 12 | 13 | protected ModuleLoaderContext context; 14 | 15 | public AbstractModuleRegistry() { 16 | } 17 | 18 | public AbstractModuleRegistry(ModuleLoaderContext context) { 19 | this.context = context; 20 | } 21 | 22 | /** 23 | * 注销并清理数据,不允许子类再覆盖 24 | */ 25 | @Override 26 | public final void unregister() { 27 | unregister0(); 28 | 29 | cleanUp(); 30 | } 31 | 32 | /** 33 | * 子类通过实现该方法注销 34 | */ 35 | protected abstract void unregister0(); 36 | 37 | /** 38 | * 注销后清理数据 39 | */ 40 | protected void cleanUp() { 41 | context = null; 42 | } 43 | 44 | @Override 45 | public ModuleClassLoader getModuleClassLoader() { 46 | return context.getClassLoader(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/module/IModuleRegistry.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.module; 2 | 3 | import java.util.jar.JarFile; 4 | 5 | /** 6 | * 模块功能注册表 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IModuleRegistry { 11 | 12 | /** 13 | * 获取模块的类加载器 14 | * 15 | * @return 返回类加载器 16 | */ 17 | ClassLoader getModuleClassLoader(); 18 | 19 | void prepareRegister(JarFile moduleJarFile); 20 | 21 | /** 22 | * 执行模块相关功能的注册 23 | * 24 | * @param moduleJarFile 模块对应的jar包对象 25 | */ 26 | void register(JarFile moduleJarFile); 27 | 28 | /** 29 | * 准备注销注册信息,旧模块(热更后将被替换的模块称为旧模块)注册表调用 30 | */ 31 | void prepareUnregister(); 32 | 33 | /** 34 | * 执行注销操作,旧模块调用 35 | */ 36 | void unregister(); 37 | 38 | /** 39 | * 回退操作 40 | */ 41 | void rollback(); 42 | 43 | enum Phase { 44 | /** 45 | * 初始阶段,功能未注册 46 | */ 47 | UNREGISTERED, 48 | /** 49 | * 已做好注册准备 50 | */ 51 | PREPARE_REGISTER, 52 | /** 53 | * 已注册 54 | */ 55 | REGISTERED, 56 | /** 57 | * 准备注销 58 | */ 59 | PREPARE_UNREGISTER; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/module/loader/ModuleLoaderContext.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.module.loader; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * 插拔式功能模块加载上下文对象 7 | * 8 | * @author fagarine 9 | */ 10 | public class ModuleLoaderContext { 11 | 12 | private ModuleClassLoader classLoader; 13 | 14 | /** 15 | * 模块jar包文件 16 | */ 17 | protected File moduleFile; 18 | 19 | public ModuleLoaderContext(ModuleClassLoader classLoader, File moduleFile) { 20 | this.classLoader = classLoader; 21 | this.moduleFile = moduleFile; 22 | } 23 | 24 | public String getModuleFilePath() { 25 | return moduleFile.getAbsolutePath(); 26 | } 27 | 28 | public ModuleClassLoader getClassLoader() { 29 | return classLoader; 30 | } 31 | 32 | public void setClassLoader(ModuleClassLoader classLoader) { 33 | this.classLoader = classLoader; 34 | } 35 | 36 | public File getModuleFile() { 37 | return moduleFile; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/monitor/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 服务器状态监控相关 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.monitor; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/IByteMessageCodec.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | 5 | /** 6 | * 以字节数组形式交互的消息编解码器接口 7 | * 8 | * @param 消息体类型 9 | * @author fagarine 10 | */ 11 | public interface IByteMessageCodec extends IMessageCodec { 12 | 13 | /** 14 | * 消息解码 15 | * 16 | * @param bytes 消息内容 17 | * @param subject 消息所属主体对象 18 | * @return 返回解码后的消息体 19 | */ 20 | @Override 21 | MessageType decode(byte[] bytes, GameSubject subject); 22 | 23 | /** 24 | * 消息编码 25 | * 26 | * @param message 消息体 27 | * @param subject 消息所属主体对象 28 | * @return 返回编码后的消息内容 29 | */ 30 | @Override 31 | byte[] encode(MessageType message, GameSubject subject); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/IByteMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | 5 | /** 6 | * 将消息编码成字节数组的编码器接口,功能单一(只负责消息编码),便于lambda编程 7 | * 8 | * @author fagarine 9 | */ 10 | @FunctionalInterface 11 | public interface IByteMessageEncoder extends IMessageEncoder { 12 | 13 | /** 14 | * 创建并返回一个新的Protobuf消息编码器 15 | * 16 | * @return 返回Protobuf消息编码器 17 | */ 18 | static ProtobufByteMessageEncoder newProtobufEncoder() { 19 | return new ProtobufByteMessageEncoder(); 20 | } 21 | 22 | @Override 23 | default byte[] encode(M message, GameSubject subject) { 24 | return encode(message); 25 | } 26 | 27 | /** 28 | * 将传入消息对象编码成字节数组并返回 29 | * 30 | * @param message 消息内容 31 | * @return 返回编码后的数据,允许返回null 32 | */ 33 | byte[] encode(M message); 34 | } 35 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/IMessageCodec.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | /** 4 | * 消息编解码器接口定义类 5 | * 6 | * @param 消息进入类型 7 | * @param 消息解码后的类型或编码前的类型 8 | * @author fagarine 9 | */ 10 | public interface IMessageCodec extends IMessageEncoder, IMessageDecoder { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/IMessageDecoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | 5 | /** 6 | * 消息解码器接口定义类 7 | * 8 | * @param 消息解码前的类型 9 | * @param 消息解码后的类型 10 | * @author fagarine 11 | */ 12 | public interface IMessageDecoder { 13 | 14 | /** 15 | * 消息解码 16 | * 17 | * @param data 消息内容 18 | * @param subject 消息所属主体对象 19 | * @return 返回解码后的消息体 20 | */ 21 | M decode(T data, GameSubject subject); 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/IMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | 5 | /** 6 | * 消息编码器接口定义类 7 | * 8 | * @param 消息编码后的类型 9 | * @param 消息编码前的类型 10 | * @author fagarine 11 | */ 12 | public interface IMessageEncoder { 13 | 14 | /** 15 | * 消息编码 16 | * 17 | * @param message 消息体 18 | * @param subject 消息所属主体对象 19 | * @return 返回编码后的消息内容 20 | */ 21 | T encode(M message, GameSubject subject); 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/INettyMessageDecoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler; 5 | import io.netty.channel.ChannelHandlerContext; 6 | 7 | /** 8 | * 使用netty通信的消息到达后的解析器 9 | * 10 | * @param 解析后返回的消息类型 11 | * @author fagarine 12 | */ 13 | public interface INettyMessageDecoder extends ChannelHandler, IMessageDecoder { 14 | 15 | @Override 16 | default void handlerAdded(ChannelHandlerContext ctx) throws Exception { 17 | 18 | } 19 | 20 | @Override 21 | default void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 22 | 23 | } 24 | 25 | @Override 26 | default void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 27 | // 消息解析实现这些不需要方法,在接口中做默认实现,避免影响子类 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/INettyMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler; 5 | import io.netty.channel.ChannelHandlerContext; 6 | 7 | /** 8 | * 使用netty通信的消息发送前的编码 9 | * 10 | * @param 编码前的消息类型 11 | * @author fagarine 12 | */ 13 | public interface INettyMessageEncoder extends ChannelHandler, IMessageEncoder { 14 | 15 | @Override 16 | default void handlerAdded(ChannelHandlerContext ctx) throws Exception { 17 | // 消息编码实现这些不需要方法,在接口中做默认实现,避免影响子类 18 | } 19 | 20 | @Override 21 | default void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 22 | // 消息编码实现这些不需要方法,在接口中做默认实现,避免影响子类 23 | } 24 | 25 | @Override 26 | default void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 27 | // 消息编码实现这些不需要方法,在接口中做默认实现,避免影响子类 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/JsonByteMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import cn.laoshini.dk.domain.msg.AbstractMessage; 4 | import cn.laoshini.dk.util.MessageUtil; 5 | 6 | /** 7 | * JSON格式消息编码器 8 | * 9 | * @author fagarine 10 | */ 11 | public class JsonByteMessageEncoder implements IByteMessageEncoder> { 12 | 13 | @Override 14 | public byte[] encode(AbstractMessage message) { 15 | return MessageUtil.messageToJsonBytes(message); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/JsonShortLengthNettyMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class JsonShortLengthNettyMessageEncoder extends JsonNettyMessageEncoder { 9 | @Override 10 | protected void writeLength(ByteBuf buf, int length) { 11 | buf.writeShort(length); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/JsonTextNettyMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class JsonTextNettyMessageEncoder extends JsonNettyMessageEncoder { 9 | 10 | @Override 11 | protected void writeLength(ByteBuf buf, int length) { 12 | // 不记录长度信息 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/ProtobufByteMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import com.google.protobuf.MessageLite; 4 | import com.google.protobuf.MessageLiteOrBuilder; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | class ProtobufByteMessageEncoder implements IByteMessageEncoder { 10 | 11 | @Override 12 | public byte[] encode(MessageLiteOrBuilder message) { 13 | if (message instanceof MessageLite) { 14 | return ((MessageLite) message).toByteArray(); 15 | } 16 | if (message instanceof MessageLite.Builder) { 17 | return ((MessageLite.Builder) message).build().toByteArray(); 18 | } 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/codec/ProtobufNettyMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.codec; 2 | 3 | import com.google.protobuf.Message; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.handler.codec.protobuf.ProtobufEncoder; 6 | 7 | import cn.laoshini.dk.domain.GameSubject; 8 | 9 | import static io.netty.buffer.Unpooled.wrappedBuffer; 10 | 11 | /** 12 | * Protobuf消息编码器 13 | * 14 | * @author fagarine 15 | */ 16 | public class ProtobufNettyMessageEncoder extends ProtobufEncoder implements INettyMessageEncoder { 17 | 18 | @Override 19 | public ByteBuf encode(M message, GameSubject subject) { 20 | return wrappedBuffer(message.toByteArray()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/connect/IConnectClosedHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.connect; 2 | 3 | /** 4 | * 客户端连接关闭时的处理接口 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface IConnectClosedHandler { 10 | 11 | /** 12 | * 执行连接关闭时的操作 13 | * 14 | * @param session 连接对应的会话对象 15 | */ 16 | void onDisconnected(S session); 17 | } 18 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/connect/IConnectExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.connect; 2 | 3 | /** 4 | * 客户端连接异常处理接口 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface IConnectExceptionHandler { 10 | 11 | /** 12 | * 执行连接异常逻辑 13 | * 14 | * @param session 连接关联的会话对象 15 | * @param cause 异常原因 16 | */ 17 | void onException(S session, Throwable cause); 18 | } 19 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/connect/IConnectOpenedHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.connect; 2 | 3 | /** 4 | * 客户端连接建立时的处理接口 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface IConnectOpenedHandler { 10 | 11 | /** 12 | * 连接建立时的处理 13 | * 14 | * @param session 连接对应的会话对象 15 | */ 16 | void onConnected(S session); 17 | } 18 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/handler/IHttpMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.handler; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | import cn.laoshini.dk.domain.msg.ReqMessage; 5 | import cn.laoshini.dk.domain.msg.RespMessage; 6 | import cn.laoshini.dk.exception.MessageException; 7 | 8 | /** 9 | * 短连接消息处理接口 10 | * 11 | * @author fagarine 12 | */ 13 | public interface IHttpMessageHandler extends IMessageHandler { 14 | 15 | @Override 16 | default void action(ReqMessage reqMessage, GameSubject subject) throws MessageException { 17 | // HTTP之类的短连接不需要实现该方法 18 | } 19 | 20 | /** 21 | * 执行业务逻辑,并返回执行结果(用于需要等待返回结果的请求,比如HTTP请求,由于不能直接由服务端向客户端推送消息,处理完直接返回) 22 | * 23 | * @param reqMessage 进入消息 24 | * @param subject 消息所属主体对象 25 | * @return 返回执行结果消息,该消息用于返回客户端 26 | * @throws MessageException 如果执行中遇到可预测的错误,抛出异常,由上层统一捕获处理 27 | */ 28 | RespMessage call(ReqMessage reqMessage, GameSubject subject) throws MessageException; 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/msg/CustomMsg.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 被标记的类表示该类为一个自定义消息类型,仅用于自定义消息类型 10 | * 11 | * @author fagarine 12 | */ 13 | @Target({ ElementType.TYPE }) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface CustomMsg { 16 | 17 | /** 18 | * 消息id 19 | */ 20 | int id(); 21 | 22 | /** 23 | * 方法或功能描述信息 24 | */ 25 | String value() default ""; 26 | } 27 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/msg/IMessageDispatcher.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | /** 4 | * 消息分发、消息调度处理 5 | * 6 | * @param 对应客户端连接的会话类型 7 | * @param 消息类型 8 | * @author fagarine 9 | */ 10 | public interface IMessageDispatcher { 11 | 12 | /** 13 | * 执行消息分发,该方法没有返回值,如果用户想要立即执行逻辑并返回,需要自己使用会话对象封装一下 14 | * 15 | * @param session 会话对象 16 | * @param message 消息 17 | */ 18 | void dispatch(S session, M message); 19 | } 20 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/msg/IMessageInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | /** 4 | * 消息拦截器接口 5 | * 6 | * @param 对应客户端连接的会话类型 7 | * @param 消息类型 8 | * @author fagarine 9 | */ 10 | @FunctionalInterface 11 | public interface IMessageInterceptor { 12 | 13 | /** 14 | * 执行拦截检查操作 15 | * 16 | * @param session 会话对象 17 | * @param msg 消息 18 | * @return 返回是否要拦截消息 19 | */ 20 | boolean check(S session, M msg); 21 | } 22 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/msg/ReqCustomMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import cn.laoshini.dk.domain.msg.ReqMessage; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class ReqCustomMessage extends ReqMessage 9 | implements ICustomMessage { 10 | 11 | @Override 12 | public String toString() { 13 | return "ReqCustomMessage{" + "id=" + id + ", code=" + code + ", params='" + params + '\'' + ", data=" + data 14 | + ", dataType=" + dataType + '}'; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/msg/RespCustomMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import cn.laoshini.dk.domain.msg.RespMessage; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class RespCustomMessage extends RespMessage 9 | implements ICustomMessage { 10 | 11 | @Override 12 | public String toString() { 13 | return "RespCustomMessage{" + "id=" + id + ", code=" + code + ", params='" + params + '\'' + ", data=" + data 14 | + ", dataType=" + dataType + '}'; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/server/InnerGameServerFactory.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.server; 2 | 3 | import cn.laoshini.dk.exception.BusinessException; 4 | import cn.laoshini.dk.register.GameServerRegisterAdaptor; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | public class InnerGameServerFactory { 10 | private InnerGameServerFactory() { 11 | } 12 | 13 | public static AbstractInnerGameServer newGameServer( 14 | GameServerRegisterAdaptor gameServerRegister) { 15 | switch (gameServerRegister.protocol()) { 16 | case TCP: 17 | return new InnerNettyTcpGameServer<>(gameServerRegister); 18 | 19 | case UDP: 20 | return new InnerNettyUdpGameServer<>(gameServerRegister); 21 | 22 | case HTTP: 23 | return new InnerNettyHttpGameServer<>(gameServerRegister); 24 | 25 | case WEBSOCKET: 26 | return new InnerNettyWebsocketGameServer<>(gameServerRegister); 27 | 28 | default: 29 | throw new BusinessException("not.supported.protocol", "不支持的游戏服务器通信协议:" + gameServerRegister.protocol()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/session/IMessageSender.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.session; 2 | 3 | /** 4 | * 消息发送接口定义类 5 | * 6 | * @param 对应客户端连接的会话类型 7 | * @param 消息类型 8 | * @author fagarine 9 | */ 10 | @FunctionalInterface 11 | public interface IMessageSender { 12 | 13 | /** 14 | * 发送消息 15 | * 16 | * @param session 消息所属的会话对象 17 | * @param msg 消息 18 | */ 19 | void send(S session, M msg); 20 | 21 | /** 22 | * 创建并返回一个负责发送消息的默认实现对象 23 | * 24 | * @param coreThreads 默认实现使用了线程池,传入线程池的核心线程数 25 | * @return 返回一个负责发送消息的实现对象 26 | */ 27 | static IMessageSender defaultSender(int coreThreads) { 28 | return new DefaultMessageSender<>(coreThreads); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/session/ISessionCreator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.session; 2 | 3 | /** 4 | * 会话对象创建者接口定义 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface ISessionCreator { 10 | 11 | ISessionCreator DK_SESSION_CREATOR = s -> s; 12 | 13 | /** 14 | * 创建一个业务会话对象并返回 15 | * 16 | * @param innerSession 当康系统默认会话对象 17 | * @return 该方法不应该返回null 18 | */ 19 | S newSession(AbstractSession innerSession); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/net/session/NettySession.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.session; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import io.netty.channel.Channel; 6 | 7 | /** 8 | * 对应netty连接的会话 9 | * 10 | * @author fagarine 11 | */ 12 | public class NettySession extends AbstractSession { 13 | 14 | public NettySession(Channel channel) { 15 | super(channel); 16 | } 17 | 18 | @Override 19 | public String getIp() { 20 | InetSocketAddress address = (InetSocketAddress) getChannel().remoteAddress(); 21 | return address.getAddress().getHostAddress(); 22 | } 23 | 24 | @Override 25 | public boolean isConnect() { 26 | return channel != null && channel.isActive(); 27 | } 28 | 29 | @Override 30 | public void close() { 31 | if (isConnect()) { 32 | channel.close(); 33 | channel = null; 34 | } 35 | clear(); 36 | } 37 | 38 | @Override 39 | public void sendMessage(Object message) { 40 | if (channel != null && channel.isActive()) { 41 | channel.writeAndFlush(message); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/EntityRegisterAdaptor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | import java.util.function.Function; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class EntityRegisterAdaptor implements IEntityRegister { 9 | 10 | private IClassScanner> scanner; 11 | 12 | private Function, String> tableNameReader; 13 | 14 | @Override 15 | public IClassScanner> scanner() { 16 | return scanner; 17 | } 18 | 19 | @Override 20 | public EntityRegisterAdaptor setScanner(IClassScanner> scanner) { 21 | this.scanner = scanner; 22 | return this; 23 | } 24 | 25 | @Override 26 | public Function, String> tableNameReader() { 27 | return tableNameReader; 28 | } 29 | 30 | @Override 31 | public EntityRegisterAdaptor setTableNameReader(Function, String> tableNameReader) { 32 | this.tableNameReader = tableNameReader; 33 | return this; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/IClassFilter.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | import java.util.function.Predicate; 4 | 5 | /** 6 | * 类扫描过滤器 7 | * 8 | * @author fagarine 9 | */ 10 | @FunctionalInterface 11 | public interface IClassFilter extends Predicate> { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/IFunctionRegister.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | /** 4 | * 功能注册接口定义 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IFunctionRegister { 9 | 10 | /** 11 | * 返回功能模块名称 12 | * 13 | * @return 返回功能模块名称 14 | */ 15 | String functionName(); 16 | 17 | /** 18 | * 执行功能注册任务 19 | * 20 | * @param classLoader 执行任务使用的类加载器 21 | */ 22 | void action(ClassLoader classLoader); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/IGameDataLoader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | /** 4 | * 游戏数据加载器 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IGameDataLoader { 9 | 10 | /** 11 | * 获取游戏数据加载器名称 12 | * 13 | * @return 该方法不应该返回null,当一个游戏中有多个数据加载器时,应该使用不同的名称 14 | */ 15 | String name(); 16 | 17 | /** 18 | * 开始执行数据加载逻辑 19 | */ 20 | void load(); 21 | 22 | /** 23 | * 重新加载数据,一般用于热加载配置数据 24 | */ 25 | void reload(); 26 | 27 | /** 28 | * 清空数据 29 | */ 30 | default void clear() { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/IGameServerStartedHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | /** 4 | * 游戏服启动成功后的处理逻辑接口 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface IGameServerStartedHandler { 10 | 11 | /** 12 | * 执行逻辑 13 | */ 14 | void action(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/IGmServerRegister.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | import java.util.List; 4 | import java.util.function.Predicate; 5 | 6 | import cn.laoshini.dk.domain.dto.GameServerInfoDTO; 7 | 8 | /** 9 | * 游戏GM服务器注册器 10 | * 11 | * @param Session的首字母,表示应用内会话类型,对应一个客户端连接 12 | * @param Message的首字母,表示消息类型 13 | * @author fagarine 14 | */ 15 | public interface IGmServerRegister extends IGameServerRegister { 16 | 17 | /** 18 | * 获取向后台服务器注册游戏服的URL,如果返回不为空,将在GM服务器启动后,向后台服务器发起注册操作{@link #getServerRegisterOperation()} 19 | * 20 | * @return 返回后台服务器URL,该方法允许返回null 21 | */ 22 | String getServerRegisterUrl(); 23 | 24 | /** 25 | * 游戏服向后台管理服务器注册操作逻辑,Predicate的传入的参数为:所有受本GM服务器管理的游戏服的信息,Predicate返回结果为是否注册成功 26 | * 27 | * @return 返回服务器注册操作逻辑,该方法允许返回null 28 | */ 29 | Predicate> getServerRegisterOperation(); 30 | 31 | /** 32 | * 后台消息过滤器 33 | * 34 | * @return 返回后台消息过滤器,该方法允许返回null 35 | */ 36 | Predicate getConsoleMessageFilter(); 37 | } 38 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/register/MessageRegisterAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.register; 2 | 3 | import java.util.function.Function; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public class MessageRegisterAdapter implements IMessageRegister { 9 | 10 | private IClassScanner> scanner; 11 | 12 | private Function, Integer> idReader; 13 | 14 | @Override 15 | public IClassScanner> scanner() { 16 | return scanner; 17 | } 18 | 19 | @Override 20 | public MessageRegisterAdapter setScanner(IClassScanner> messageScanner) { 21 | this.scanner = messageScanner; 22 | return this; 23 | } 24 | 25 | @Override 26 | public Function, Integer> idReader() { 27 | return idReader; 28 | } 29 | 30 | @Override 31 | public MessageRegisterAdapter setIdReader(Function, Integer> idReader) { 32 | this.idReader = idReader; 33 | return this; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/serialization/IDataSerializable.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.serialization; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 数据序列化相关功能接口 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IDataSerializable { 11 | 12 | /** 13 | * byte空数组 14 | */ 15 | byte[] EMPTY_BYTES = new byte[0]; 16 | 17 | /** 18 | * 将数据以二进制数据形式输出 19 | * 20 | * @param object 待序列化数据 21 | * @return 返回二进制数组格式的数据 22 | */ 23 | byte[] toBytes(Object object); 24 | 25 | /** 26 | * 将二进制数据反序列化成对象输出 27 | * 28 | * @param bytes 二进制数据 29 | * @return 返回对象 30 | */ 31 | Object toObject(byte[] bytes); 32 | 33 | /** 34 | * 将二进制数据反序列化成指定类型对象输出 35 | * 36 | * @param bytes 二进制数据 37 | * @param toType 指定类型 38 | * @param 指定类型 39 | * @return 返回对象 40 | */ 41 | T toAssignedTypeObject(byte[] bytes, Class toType); 42 | 43 | /** 44 | * 将二进制数据反序列化成指定类型对象的集合输出 45 | * 46 | * @param bytes 二进制数据 47 | * @param toType 指定类型 48 | * @param 指定类型 49 | * @return 返回对象集合,该方法不会返回null 50 | */ 51 | List toAssignedBeanList(byte[] bytes, Class toType); 52 | } 53 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/starter/ExternalLastInitializer.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.starter; 2 | 3 | import cn.laoshini.dk.common.SpringContextHolder; 4 | import cn.laoshini.dk.jit.DynamicGenerator; 5 | import cn.laoshini.dk.manager.HotfixManager; 6 | import cn.laoshini.dk.manager.TypeUseManager; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | final class ExternalLastInitializer { 12 | 13 | static void afterInitializationProcess() { 14 | // 初始化热修复功能 15 | SpringContextHolder.getBean(HotfixManager.class).init(); 16 | 17 | boolean jit = SpringContextHolder.getBoolProperty("dk.jit", false); 18 | // JIT生成类加载、注册 19 | if (jit) { 20 | DynamicGenerator.loadAndRegisterGeneratedClass(); 21 | } 22 | 23 | // 常用类注册 24 | boolean expression = SpringContextHolder.getBoolProperty("dk.expression", false); 25 | if (expression) { 26 | TypeUseManager.registerIntrinsicClasses(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/starter/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下提供当康系统容器和游戏服线程快速启动功能 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.starter; -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/support/IPropertyRefreshable.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.support; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * 依赖于配置项参数,并且在配置项参数变更后,需要刷新数据的对象 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IPropertyRefreshable extends IRefreshable { 11 | 12 | /** 13 | * 刷新依赖于传入的配置项key的数据 14 | * 15 | * @param propertyKeys 需要刷新数据的配置项key 16 | */ 17 | void refresh(Collection propertyKeys); 18 | 19 | /** 20 | * 刷新任何依赖配置参数的数据 21 | */ 22 | @Override 23 | default void refresh() { 24 | refresh(null); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/support/IRefreshable.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.support; 2 | 3 | /** 4 | * 可刷新数据对象接口 5 | * 6 | * @author fagarine 7 | */ 8 | @FunctionalInterface 9 | public interface IRefreshable { 10 | 11 | /** 12 | * 执行刷新数据操作 13 | */ 14 | void refresh(); 15 | } 16 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/text/sensitive/DefaultSensitiveWordProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.text.sensitive; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import cn.laoshini.dk.annotation.FunctionVariousWays; 6 | 7 | /** 8 | * 默认敏感词处理器 9 | * 10 | * @author fagarine 11 | */ 12 | @Component 13 | @FunctionVariousWays(description = "默认敏感词处理器") 14 | public final class DefaultSensitiveWordProcessor extends AbstractSensitiveWordProcessor { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/text/sensitive/EmailDesensitizeProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.text.sensitive; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import cn.laoshini.dk.util.StringUtil; 6 | 7 | /** 8 | * Email信息脱敏(默认仅显示第一个字母,前缀其他隐藏,用星号代替) 9 | * 10 | * @author fagarine 11 | */ 12 | public class EmailDesensitizeProcessor extends AbstractDesensitizeProcessor { 13 | 14 | private static final Pattern EMAIL_PATTERN = Pattern 15 | .compile("^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-\\u4e00-\\u9fa5]+(\\.[a-zA-Z0-9_-\\u4e00-\\u9fa5]+)+$"); 16 | 17 | @Override 18 | protected String defaultMask(String text) { 19 | if (StringUtil.isEmptyString(text)) { 20 | return text; 21 | } 22 | 23 | int index = text.indexOf('@'); 24 | if (index <= 1) { 25 | return text; 26 | } 27 | 28 | if (pattern == null) { 29 | pattern = EMAIL_PATTERN; 30 | } 31 | 32 | if (!pattern.matcher(text).find()) { 33 | return text; 34 | } 35 | 36 | char[] chars = text.toCharArray(); 37 | for (int i = 1; i < index; i++) { 38 | chars[i] = '*'; 39 | } 40 | return new String(chars); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dk-core/src/main/java/cn/laoshini/dk/text/sensitive/IDesensitizeProcessor.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.text.sensitive; 2 | 3 | import cn.laoshini.dk.annotation.ConfigurableFunction; 4 | 5 | /** 6 | * 字符串脱敏处理器定义接口 7 | * 8 | * @author fagarine 9 | */ 10 | @ConfigurableFunction(key = "dk.desensitize.processor") 11 | public interface IDesensitizeProcessor { 12 | 13 | /** 14 | * 屏蔽传入字符串中的敏感信息 15 | * 16 | * @param text 字符串 17 | * @return 返回脱敏后的字符串 18 | */ 19 | String mask(String text); 20 | 21 | /** 22 | * 使用传入的正则表达式和替换字符串,通过正则匹配模式处理。注意:是否使用正则匹配依赖于实现类,如果实现类中不支持正则,则该方法无效 23 | * 24 | * @param regex 正则匹配表达式 25 | * @param replacement 脱敏数据替换字符串(或表达式) 26 | */ 27 | void useRegex(String regex, String replacement); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /dk-core/src/main/resources/applicationContext-dk-default.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dk-domain/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dangkang 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-domain 13 | 14 | 15 | 16 | cn.laoshini.dk 17 | dk-common 18 | 1.0.0-SNAPSHOT 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/common/ConstReadTable.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | /** 4 | * 记录从文件中读取出的一个表单的数据 5 | * 6 | * @author fagarine 7 | */ 8 | public class ConstReadTable extends ConstTable { 9 | 10 | /** 11 | * 读取数据时是否有错误 12 | */ 13 | private boolean faulty; 14 | 15 | /** 16 | * 读取错误记录 17 | */ 18 | private String errorMsg; 19 | 20 | public boolean isFaulty() { 21 | return faulty; 22 | } 23 | 24 | public void setFaulty(boolean faulty) { 25 | this.faulty = faulty; 26 | } 27 | 28 | public String getErrorMsg() { 29 | return errorMsg; 30 | } 31 | 32 | public void setErrorMsg(String errorMsg) { 33 | this.errorMsg = errorMsg; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "ConstReadTable{" + "faulty=" + faulty + ", errorMsg='" + errorMsg + '\'' + "} " + super.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/common/ListTuple.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 两个元素元素都为列表的元组类型 7 | * 8 | * @param 第一个列表的元素类型 9 | * @param 第二个列表的元素类型 10 | * @author fagarine 11 | */ 12 | public class ListTuple extends Tuple, List> { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | public ListTuple() { 17 | } 18 | 19 | public ListTuple(List v1s, List v2s) { 20 | super(v1s, v2s); 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "ListTuple{} " + super.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/common/Tuple.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | 7 | /** 8 | * 元组结构类型(包含两个元素的结构),使用泛型,避免每次需要一个包含两个元素的结构时都去新建类 9 | * 10 | * @param 第一个元素的类型 11 | * @param 第二个元素的类型 12 | * @author fagarine 13 | */ 14 | @Data 15 | public class Tuple implements Serializable { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private V1 v1; 20 | 21 | private V2 v2; 22 | 23 | public Tuple() { 24 | } 25 | 26 | public Tuple(V1 v1, V2 v2) { 27 | this.v1 = v1; 28 | this.v2 = v2; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/dto/ExpressionBlockDTO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * 表达式代码块 10 | * 11 | * @author fagarine 12 | */ 13 | @Data 14 | public class ExpressionBlockDTO implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | /** 19 | * 块注释 20 | */ 21 | private String comment; 22 | 23 | /** 24 | * 是否有返回值 25 | */ 26 | private Boolean returned; 27 | 28 | /** 29 | * 表达式详情 30 | */ 31 | private List expDescriptors; 32 | 33 | public int size() { 34 | return expDescriptors == null ? 0 : expDescriptors.size(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/dto/ExpressionDescriptorDTO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | 7 | /** 8 | * 表达式信息 9 | * 10 | * @author fagarine 11 | */ 12 | @Data 13 | public class ExpressionDescriptorDTO implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | /** 18 | * 表达式类型,参见:{@link cn.laoshini.dk.constant.ExpressionConstant.ExpressionCodeType} 19 | */ 20 | private String type; 21 | 22 | /** 23 | * 表达式代码 24 | */ 25 | private String expression; 26 | 27 | /** 28 | * 如果需要暂时保存执行结果,记录的参数名称 29 | */ 30 | private String recordParam; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/dto/GameServerRegisterDTO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.Map; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | @Data 12 | public class GameServerRegisterDTO implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | /** 17 | * 游戏id 18 | */ 19 | private int gameId; 20 | 21 | /** 22 | * 游戏名称 23 | */ 24 | private String gameName; 25 | 26 | /** 27 | * 本次注册的游戏服务器,key: serverId, value: serverName 28 | */ 29 | private Map servers; 30 | } 31 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/dto/HotfixRecordDTO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * 热修复执行结果记录DTO 10 | * 11 | * @author fagarine 12 | */ 13 | @Data 14 | public class HotfixRecordDTO implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private int id; 19 | 20 | /** 21 | * 热更key,用于区分是否是同一次热更操作,可以是热更说明信息等 22 | */ 23 | private String hotfixKey; 24 | 25 | /** 26 | * 热更类名 27 | */ 28 | private String className; 29 | 30 | /** 31 | * 热更时间 32 | */ 33 | private Date hotfixTime; 34 | 35 | /** 36 | * 热更结果 37 | */ 38 | private String result; 39 | 40 | /** 41 | * 描述信息 42 | */ 43 | private String desc; 44 | } 45 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/dto/ModuleInfoDTO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * 外置模块信息DTO 10 | * 11 | * @author fagarine 12 | */ 13 | @Data 14 | public class ModuleInfoDTO implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | /** 19 | * 模块名称 20 | */ 21 | private String name; 22 | 23 | /** 24 | * 模块文件路径 25 | */ 26 | private String file; 27 | 28 | /** 29 | * 文件最后修改时间 30 | */ 31 | private Date lastModified; 32 | 33 | /** 34 | * 模块最后加载成功时间 35 | */ 36 | private Date lastLoaded; 37 | } 38 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/msg/ReqMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.msg; 2 | 3 | /** 4 | * 请求消息类型(到达服务器的消息) 5 | * 6 | * @author fagarine 7 | */ 8 | public class ReqMessage extends AbstractMessage { 9 | 10 | @Override 11 | public String toString() { 12 | return "ReqMessage{" + "id=" + id + ", params='" + params + '\'' + ", data=" + data + '}'; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/msg/RespMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.msg; 2 | 3 | import cn.laoshini.dk.constant.GameCodeEnum; 4 | 5 | /** 6 | * 返回消息类型,从服务器发出的消息 7 | * 8 | * @author fagarine 9 | */ 10 | public class RespMessage extends AbstractMessage { 11 | 12 | public static RespMessage noResponse() { 13 | RespMessage message = new RespMessage<>(); 14 | message.setCode(GameCodeEnum.NO_RESPONSE.getCode()); 15 | return message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "RespMessage{" + "id=" + id + ", code=" + code + ", params='" + params + '\'' + ", data=" + data 21 | + ", dataType=" + dataType + '}'; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/query/AbstractQueryCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.query; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | public abstract class AbstractQueryCondition { 9 | 10 | protected Map filters; 11 | 12 | public Map getFilters() { 13 | return filters; 14 | } 15 | 16 | public void setFilters(Map filters) { 17 | this.filters = filters; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "AbstractQueryCondition{" + "filters=" + filters + '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/query/BeanQueryCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.query; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class BeanQueryCondition extends AbstractQueryCondition { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/query/ListQueryCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.query; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class ListQueryCondition extends AbstractQueryCondition { 7 | public ListQueryCondition() { 8 | super(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/query/PageQueryCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.query; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * 分页查询条件 9 | * 10 | * @author fagarine 11 | */ 12 | @Getter 13 | @Setter 14 | @ToString 15 | public class PageQueryCondition extends ListQueryCondition { 16 | 17 | /** 18 | * 页码,从1开始 19 | */ 20 | private Integer pageNo; 21 | 22 | /** 23 | * 单页数据条数 24 | */ 25 | private Integer pageSize; 26 | 27 | private String orderBy; 28 | 29 | private String orderSort; 30 | 31 | public Integer getStartOffset() { 32 | return (pageNo - 1) * pageSize; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /dk-domain/src/main/java/cn/laoshini/dk/domain/responese/ResultCode.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain.responese; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum ResultCode { 7 | 8 | /** 9 | * 成功 10 | */ 11 | SUCCESS(0, "成功"), 12 | 13 | FAIL(1, "业务失败"), 14 | 15 | ERROR(2, "执行错误"); 16 | 17 | private int code; 18 | private String message; 19 | 20 | ResultCode(int code, String message) { 21 | this.code = code; 22 | this.message = message; 23 | } 24 | 25 | public int getCode() { 26 | return this.code; 27 | } 28 | 29 | public String getMessage() { 30 | return this.message; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-game-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dangkang 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-game-core 13 | 14 | 15 | 16 | cn.laoshini.dk 17 | dk-core 18 | ${dangkang.version} 19 | 20 | 21 | 22 | io.netty 23 | netty-all 24 | 4.1.42.Final 25 | 26 | 27 | 28 | com.google.protobuf 29 | protobuf-java 30 | 3.11.1 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/client/ClientException.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.client; 2 | 3 | import cn.laoshini.dk.exception.DkRuntimeException; 4 | 5 | /** 6 | * 当康游戏客户端异常 7 | * 8 | * @author fagarine 9 | */ 10 | public class ClientException extends DkRuntimeException { 11 | 12 | public ClientException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public ClientException(String message) { 17 | super("client.exception.key", message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/client/CustomMessageNettyTcpClient.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.client; 2 | 3 | import cn.laoshini.dk.domain.msg.AbstractMessage; 4 | import cn.laoshini.dk.net.codec.CustomNettyMessageDecoder; 5 | import cn.laoshini.dk.net.codec.CustomNettyMessageEncoder; 6 | import cn.laoshini.dk.net.codec.INettyMessageDecoder; 7 | import cn.laoshini.dk.net.codec.INettyMessageEncoder; 8 | 9 | /** 10 | * @author fagarine 11 | */ 12 | public class CustomMessageNettyTcpClient extends AbstractBiasCodecNettyTcpClient { 13 | 14 | @Override 15 | protected void checkDepends() { 16 | if (messageEncoder() == null) { 17 | setMessageEncoder((INettyMessageEncoder) new CustomNettyMessageEncoder()); 18 | } 19 | if (messageDecoder() == null) { 20 | setMessageDecoder((INettyMessageDecoder) new CustomNettyMessageDecoder()); 21 | } 22 | 23 | super.checkDepends(); 24 | 25 | if (idReader() == null) { 26 | setIdReader(AbstractMessage::getId); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/client/JsonNettyTcpClient.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.client; 2 | 3 | import cn.laoshini.dk.domain.msg.AbstractMessage; 4 | import cn.laoshini.dk.net.codec.INettyMessageDecoder; 5 | import cn.laoshini.dk.net.codec.INettyMessageEncoder; 6 | import cn.laoshini.dk.net.codec.JsonNettyMessageDecoder; 7 | import cn.laoshini.dk.net.codec.JsonNettyMessageEncoder; 8 | 9 | /** 10 | * 使用netty + json格式消息通信的TCP客户端实现类,使用该类时,用户如果不单独设置编解码器, 11 | * 则默认使用{@link JsonNettyMessageEncoder}和{@link JsonNettyMessageDecoder} 12 | * 13 | * @author fagarine 14 | */ 15 | public class JsonNettyTcpClient extends AbstractBiasCodecNettyTcpClient { 16 | 17 | @Override 18 | protected void checkDepends() { 19 | if (messageEncoder() == null) { 20 | setMessageEncoder((INettyMessageEncoder) new JsonNettyMessageEncoder()); 21 | } 22 | if (messageDecoder() == null) { 23 | setMessageDecoder((INettyMessageDecoder) new JsonNettyMessageDecoder()); 24 | } 25 | 26 | super.checkDepends(); 27 | 28 | if (idReader() == null) { 29 | setIdReader(AbstractMessage::getId); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/client/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下提供模拟游戏客户端的功能 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.client; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/cluster/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下定义服务器集群功能 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.cluster; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/constant/AttributeKeyConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | import io.netty.util.AttributeKey; 4 | 5 | import cn.laoshini.dk.domain.Player; 6 | 7 | /** 8 | * 项目中关于netty AttributeKey 9 | * 10 | * @author fagarine 11 | */ 12 | public class AttributeKeyConstant { 13 | 14 | /** 15 | * 玩家帐号对象key 16 | */ 17 | public static final AttributeKey PLAYER = AttributeKey.valueOf("GAME_PLAYER"); 18 | 19 | /** 20 | * 玩家角色对象key 21 | */ 22 | public static final AttributeKey ROLE = AttributeKey.valueOf("GAME_ROLE"); 23 | 24 | /** 25 | * 进入消息序列化 26 | */ 27 | public static final AttributeKey REQ_MSG_ORDER = AttributeKey.valueOf("REQ_MSG_ORDER"); 28 | } 29 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/constant/NodeState.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.constant; 2 | 3 | /** 4 | * 行为树节点状态枚举 5 | * 6 | * @author fagarine 7 | */ 8 | public enum NodeState { 9 | /** 10 | * 执行中 11 | */ 12 | RUNNING, 13 | 14 | /** 15 | * 已执行完并返回成功 16 | */ 17 | SUCCEED, 18 | 19 | /** 20 | * 已执行完并返回失败 21 | */ 22 | FAILED, 23 | ; 24 | } 25 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/domain/Player.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain; 2 | 3 | import cn.laoshini.dk.constant.UserStatusEnum; 4 | import cn.laoshini.dk.entity.GameUser; 5 | 6 | /** 7 | * 玩家(帐号)对象,纯内存对象 8 | * 9 | * @author fagarine 10 | */ 11 | public class Player extends GameSubject { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | private transient GameUser user; 16 | 17 | public boolean isValid() { 18 | if (user == null || user.getStatus() == null) { 19 | return false; 20 | } 21 | return UserStatusEnum.isValidStatus(user.getStatus()); 22 | } 23 | 24 | public long getUserId() { 25 | if (user == null || user.getUserId() == null) { 26 | return 0; 27 | } 28 | return user.getUserId(); 29 | } 30 | 31 | public GameUser getUser() { 32 | return user; 33 | } 34 | 35 | public void setUser(GameUser user) { 36 | this.user = user; 37 | } 38 | 39 | @Override 40 | public int getGameId() { 41 | return user.getLoginGameId(); 42 | } 43 | 44 | @Override 45 | public int getServerId() { 46 | return 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/domain/Role.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.domain; 2 | 3 | import cn.laoshini.dk.entity.GameRole; 4 | 5 | /** 6 | * 游戏角色,纯内存对象 7 | * 8 | * @author fagarine 9 | */ 10 | public class Role extends GameSubject { 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | private transient GameRole gameRole; 15 | /** 16 | * 玩家当前是否在线 17 | */ 18 | private boolean online; 19 | 20 | public long getRoleId() { 21 | if (gameRole == null || gameRole.getRoleId() == null) { 22 | return 0; 23 | } 24 | return gameRole.getRoleId(); 25 | } 26 | 27 | @Override 28 | public int getGameId() { 29 | return gameRole.getGameId(); 30 | } 31 | 32 | @Override 33 | public int getServerId() { 34 | return gameRole.getServerId(); 35 | } 36 | 37 | public boolean isOnline() { 38 | return online; 39 | } 40 | 41 | public void setOnline(boolean online) { 42 | this.online = online; 43 | } 44 | 45 | public GameRole getGameRole() { 46 | return gameRole; 47 | } 48 | 49 | public void setGameRole(GameRole gameRole) { 50 | this.gameRole = gameRole; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/entity/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下的类都为数据库表对应的实体类,可用以记录一些通用的游戏数据,以供一些简单的游戏直接使用。
3 | * 每个类的字段名称和顺序应该严格与表相对应,即这些类都是没有任何逻辑的JavaBean;
4 | * 如果有时候需要增加字段,请单独写对应的VO、BO或DTO类,而不要在实体类中增加字段 5 | * 6 | * @author fagarine 7 | */ 8 | package cn.laoshini.dk.entity; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/event/ChannelCloseEvent.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.event; 2 | 3 | import cn.laoshini.dk.domain.Player; 4 | 5 | /** 6 | * 网络会话关闭事件 7 | * 8 | * @author fagarine 9 | */ 10 | public class ChannelCloseEvent { 11 | 12 | private final Player player; 13 | 14 | /** 15 | * @param player 玩家对象 16 | */ 17 | public ChannelCloseEvent(Player player) { 18 | this.player = player; 19 | } 20 | 21 | public Player getPlayer() { 22 | return player; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/eventbus/EventMgr.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.eventbus; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | 5 | /** 6 | * 基于google EventBus的事件管理器 7 | * 8 | * @author fagarine 9 | */ 10 | public class EventMgr extends EventBus { 11 | 12 | private static EventMgr instance = new EventMgr(); 13 | 14 | public static EventMgr getInstance() { 15 | return instance; 16 | } 17 | 18 | private EventMgr() { 19 | // guava EventBus的默认发布事件处理异常处理器LoggingSubscriberExceptionHandler没有记录异常堆栈,不能很好的定位问题 20 | super(new LoggingSubscriberExceptionHandler()); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/eventbus/LoggingSubscriberExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.eventbus; 2 | 3 | import com.google.common.eventbus.SubscriberExceptionContext; 4 | import com.google.common.eventbus.SubscriberExceptionHandler; 5 | 6 | import cn.laoshini.dk.util.LogUtil; 7 | 8 | /** 9 | * guava EventBus的默认发布事件处理异常处理器 10 | * 没有记录异常堆栈,不能很好的定位问题 11 | * 12 | * @author fagarine 13 | */ 14 | public class LoggingSubscriberExceptionHandler implements SubscriberExceptionHandler { 15 | 16 | @Override 17 | public void handleException(Throwable exception, SubscriberExceptionContext context) { 18 | LogUtil.error("Could not dispatch event: " + context.getSubscriber() + " to " + context.getSubscriberMethod(), 19 | exception); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/handler/ICustomMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.handler; 2 | 3 | import cn.laoshini.dk.net.msg.ICustomDto; 4 | 5 | /** 6 | * 自定义消息类型的消息处理handler,专为处理自定义消息设计 7 | * 8 | * @author fagarine 9 | */ 10 | public interface ICustomMessageHandler extends IMessageHandler { 11 | } 12 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/handler/IJsonMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.handler; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | 5 | /** 6 | * Json格式消息的处理handler接口 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IJsonMessageHandler extends IMessageHandler { 11 | } 12 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/handler/IProtobufMessageHandler.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.handler; 2 | 3 | import com.google.protobuf.Message; 4 | 5 | /** 6 | * protobuf消息处理handler,专为处理protobuf消息设计 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IProtobufMessageHandler extends IMessageHandler { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/msg/Base.proto: -------------------------------------------------------------------------------- 1 | // 当康系统默认的Protobuf消息格式描述文件,使用proto3语法 2 | syntax = "proto3"; 3 | 4 | // 使用google.protobuf.Any类 5 | import "google/protobuf/any.proto"; 6 | 7 | option java_package = "cn.laoshini.dk.net.msg"; 8 | option java_outer_classname = "BaseProtobufMessage"; 9 | 10 | message Base { 11 | int32 messageId = 1; // 消息id 12 | int32 code = 2; // 消息返回码,非错误消息则为200 13 | string params = 3; // 预留扩展参数,非必须,一般用于描述错误信息 14 | google.protobuf.Any detail = 4; // 消息内容数据,指向用户具体的消息格式 15 | } -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/msg/INettyCustomMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | import cn.laoshini.dk.domain.msg.IMessage; 6 | 7 | /** 8 | * 自定义消息类型接口,专为读写netty的ByteBuf设计,注意: 9 | *

10 | * 实现该接口的对象,表示服务器是通过Netty交互,HTTP服务器的消息应该实现{@link ICustomMessage}接口 11 | *

12 | *
13 | * 另外,该类的消息结构完全继承{@link ICustomMessage}中定义的消息结构,具体参见{@link ICustomMessage}接口 14 | * 15 | * @author fagarine 16 | * @see ICustomMessage 17 | * @see CustomMsg 18 | */ 19 | public interface INettyCustomMessage extends INettyDto, IMessage { 20 | 21 | @Override 22 | default void read(ByteBuf b) { 23 | setId(readInt(b)); 24 | setCode(readInt(b)); 25 | setParams(readString(b)); 26 | setData(readBean(b, getDataType(), false)); 27 | } 28 | 29 | @Override 30 | default void write(ByteBuf b) { 31 | writeInt(b, getId()); 32 | writeInt(b, getCode()); 33 | writeString(b, getParams()); 34 | writeBean(b, getData(), false); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/msg/ReqNettyCustomMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import cn.laoshini.dk.domain.msg.ReqMessage; 4 | 5 | /** 6 | * 使用netty通信的自定义格式消息类(到达服务器的消息) 7 | * 8 | * @author fagarine 9 | */ 10 | public class ReqNettyCustomMessage extends ReqMessage 11 | implements INettyCustomMessage { 12 | 13 | @Override 14 | public String toString() { 15 | return "ReqNettyCustomMessage{" + "id=" + id + ", params='" + params + '\'' + ", data=" + data + ", dataType=" 16 | + dataType + '}'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/msg/RespNettyCustomMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.net.msg; 2 | 3 | import cn.laoshini.dk.domain.msg.RespMessage; 4 | 5 | /** 6 | * 使用netty通信的自定义格式消息类(从服务器发出的消息) 7 | * 8 | * @author fagarine 9 | */ 10 | public class RespNettyCustomMessage extends RespMessage 11 | implements INettyCustomMessage { 12 | 13 | @Override 14 | public String toString() { 15 | return "RespNettyCustomMessage{" + "id=" + id + ", code=" + code + ", params='" + params + '\'' + ", data=" 16 | + data + ", dataType=" + dataType + '}'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/net/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author fagarine 3 | */ 4 | package cn.laoshini.dk.net; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/IBehaviorTree.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt; 2 | 3 | import java.util.Collection; 4 | 5 | import cn.laoshini.dk.robot.bt.node.BtRootNode; 6 | import cn.laoshini.dk.robot.bt.node.IBtNodeConfig; 7 | 8 | /** 9 | * 机器人行为树定义接口 10 | * 11 | * @author fagarine 12 | */ 13 | public interface IBehaviorTree { 14 | 15 | /** 16 | * 设置行为树配置信息 17 | * 18 | * @param config 行为树配置信息 19 | */ 20 | void setTreeConfig(IBtConfig config); 21 | 22 | /** 23 | * 根据传入的行为树节点配置信息,初始化行为树 24 | * 25 | * @param nodeConfigs 节点配置信息 26 | */ 27 | void initTree(Collection nodeConfigs); 28 | 29 | /** 30 | * 获取根节点 31 | * 32 | * @return 根节点 33 | */ 34 | BtRootNode getRoot(); 35 | 36 | /** 37 | * 设置行为树所属机器人id(仅当行为树不是共享树时有效) 38 | * 39 | * @param robotId 机器人唯一id 40 | */ 41 | void setRobotId(long robotId); 42 | 43 | /** 44 | * 执行一次行为树逻辑 45 | */ 46 | void tick(); 47 | } 48 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/IBtConfig.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt; 2 | 3 | /** 4 | * 行为树配置类接口定义 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IBtConfig { 9 | 10 | /** 11 | * 获取行为树唯一id 12 | * 13 | * @return 行为树唯一id 14 | */ 15 | int getTreeId(); 16 | 17 | /** 18 | * 获取行为树名称 19 | * 20 | * @return 行为树名称 21 | */ 22 | String getTreeName(); 23 | 24 | /** 25 | * 该配置信息是否有效 26 | * 27 | * @return 配置信息是否有效 28 | */ 29 | boolean isValid(); 30 | } 31 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/factory/IBtNodeFactory.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.factory; 2 | 3 | import cn.laoshini.dk.robot.bt.node.IBtNode; 4 | import cn.laoshini.dk.robot.bt.node.IBtNodeConfig; 5 | import cn.laoshini.dk.util.LogUtil; 6 | 7 | /** 8 | * 行为树节点对象抽象工厂接口 9 | * 10 | * @author fagarine 11 | */ 12 | public interface IBtNodeFactory { 13 | 14 | IBtNode createBtNode(int subType, boolean shared); 15 | 16 | default IBtNode createBtNode(int subType) { 17 | return createBtNode(subType, true); 18 | } 19 | 20 | default IBtNode createBtNode(IBtNodeConfig config, boolean shared) { 21 | if (null == config) { 22 | return null; 23 | } 24 | 25 | IBtNode node = createBtNode(config.getSubType(), shared); 26 | if (null != node) { 27 | node.setConfig(config); 28 | } 29 | return node; 30 | } 31 | 32 | default IBtNode createNode(Class clazz) { 33 | try { 34 | return clazz.newInstance(); 35 | } catch (InstantiationException | IllegalAccessException e) { 36 | LogUtil.error(e, "创建节点对象失败, clazz:" + clazz.getName()); 37 | } 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/factory/IBtRootNodeFactory.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.factory; 2 | 3 | import cn.laoshini.dk.robot.bt.node.BtRootNode; 4 | 5 | /** 6 | * root节点工厂基础实现类 7 | * 8 | * @author fagarine 9 | */ 10 | public interface IBtRootNodeFactory extends IBtNodeFactory { 11 | 12 | @Override 13 | default BtRootNode createBtNode(int nodeType, boolean shared) { 14 | return createRootNode(shared); 15 | } 16 | 17 | /** 18 | * 创建Root节点 19 | * 20 | * @param shared 21 | * @return 22 | */ 23 | BtRootNode createRootNode(boolean shared); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/factory/impl/BtDecoratorNodeFactory.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.factory.impl; 2 | 3 | import cn.laoshini.dk.robot.bt.factory.IBtNodeFactory; 4 | import cn.laoshini.dk.robot.bt.node.IBtNode; 5 | 6 | /** 7 | * 装饰类节点工厂 8 | * 9 | * @author fagarine 10 | */ 11 | public class BtDecoratorNodeFactory implements IBtNodeFactory { 12 | 13 | @Override 14 | public IBtNode createBtNode(int decoratorType, boolean shared) { 15 | // 暂不实现 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/factory/impl/BtRootNodeFactoryImpl.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.factory.impl; 2 | 3 | import cn.laoshini.dk.robot.bt.factory.IBtRootNodeFactory; 4 | import cn.laoshini.dk.robot.bt.node.BtRootNode; 5 | 6 | /** 7 | * Root节点工厂的简单实现 8 | * 9 | * @author fagarine 10 | */ 11 | public class BtRootNodeFactoryImpl implements IBtRootNodeFactory { 12 | 13 | @Override 14 | public BtRootNode createRootNode(boolean shared) { 15 | return new BtRootNode(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/AbstractBtAction.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import cn.laoshini.dk.constant.BtNodeType; 7 | 8 | /** 9 | * 行为树Action节点 10 | * 11 | * @author fagarine 12 | */ 13 | public abstract class AbstractBtAction extends AbstractBtNode { 14 | public AbstractBtAction() { 15 | nodeType = BtNodeType.ACTION; 16 | } 17 | 18 | @Override 19 | public List getChildren() { 20 | return Collections.emptyList(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/AbstractBtCompositeNode.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node; 2 | 3 | import cn.laoshini.dk.constant.BtNodeType; 4 | import cn.laoshini.dk.constant.CompositeType; 5 | 6 | /** 7 | * 行为树复合类型节点 8 | * 9 | * @author fagarine 10 | */ 11 | public abstract class AbstractBtCompositeNode extends AbstractBtNode { 12 | protected CompositeType compositeType; 13 | 14 | public AbstractBtCompositeNode() { 15 | nodeType = BtNodeType.COMPOSITE; 16 | } 17 | 18 | public AbstractBtCompositeNode(CompositeType compositeType) { 19 | nodeType = BtNodeType.COMPOSITE; 20 | this.compositeType = compositeType; 21 | // 默认为共享节点 22 | setShared(true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/AbstractBtCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import cn.laoshini.dk.constant.BtNodeType; 7 | 8 | /** 9 | * 行为树条件节点抽象类 10 | * 11 | * @author fagarine 12 | */ 13 | public abstract class AbstractBtCondition extends AbstractBtNode { 14 | 15 | public AbstractBtCondition() { 16 | nodeType = BtNodeType.CONDITION; 17 | } 18 | 19 | @Override 20 | public List getChildren() { 21 | return Collections.emptyList(); 22 | } 23 | 24 | /** 25 | * 不额外传入参数的条件检查,将使用节点对象自己的参数进行检查 26 | * 27 | * @return 28 | */ 29 | public abstract boolean checkCondition(); 30 | 31 | /** 32 | * 带参数条件检查,用于公用行为树节点,传入参数为具体的智能体对象(机器人)的相关参数 33 | * 34 | * @param params 35 | * @return 36 | */ 37 | public abstract boolean checkCondition(Object... params); 38 | } 39 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/BtConditionNode.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node; 2 | 3 | /** 4 | * 条件节点类 5 | * 6 | * @author fagarine 7 | */ 8 | public class BtConditionNode extends AbstractBtCondition { 9 | 10 | @Override 11 | public boolean tick() { 12 | return checkCondition(); 13 | } 14 | 15 | @Override 16 | public boolean checkCondition() { 17 | return false; 18 | } 19 | 20 | @Override 21 | public boolean checkCondition(Object... params) { 22 | return false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/BtRootNode.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node; 2 | 3 | /** 4 | * 根节点 5 | * 6 | * @author fagarine 7 | */ 8 | public class BtRootNode extends AbstractBtNode { 9 | /** 10 | * 根节点顺序执行它的所有直接子节点,执行完成后始终返回true 11 | */ 12 | @Override 13 | public boolean tick() { 14 | if (null != children) { 15 | for (IBtNode node : children) { 16 | node.tick(); 17 | } 18 | } 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/composite/EmptyNode.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node.composite; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import cn.laoshini.dk.robot.bt.node.AbstractBtCompositeNode; 7 | import cn.laoshini.dk.robot.bt.node.IBtNode; 8 | 9 | /** 10 | * 空节点 11 | * 12 | * @author fagarine 13 | */ 14 | public class EmptyNode extends AbstractBtCompositeNode { 15 | 16 | @Override 17 | public List getChildren() { 18 | return Collections.emptyList(); 19 | } 20 | 21 | @Override 22 | public boolean tick() { 23 | return true; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/condition/EqualCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node.condition; 2 | 3 | import cn.laoshini.dk.robot.bt.node.BtConditionNode; 4 | 5 | /** 6 | * Equals条件判断 7 | * 8 | * @author fagarine 9 | */ 10 | public class EqualCondition extends BtConditionNode { 11 | 12 | @Override 13 | public boolean checkCondition(Object... params) { 14 | if (null == params || params.length < 2) { 15 | return false; 16 | } 17 | 18 | if (null == params[0]) { 19 | return null == params[1]; 20 | } 21 | 22 | return params[0].equals(params[1]); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/node/condition/FalseCondition.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.bt.node.condition; 2 | 3 | import cn.laoshini.dk.robot.bt.node.BtConditionNode; 4 | 5 | /** 6 | * 返回false的条件节点 7 | * 8 | * @author fagarine 9 | */ 10 | public class FalseCondition extends BtConditionNode { 11 | @Override 12 | public boolean checkCondition(Object... params) { 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/bt/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 包名 bt 是行为树(Behavior Tree)的缩写,在该包下,行为树缩写为bt 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.robot.bt; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/AbstractFsmRobot.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public abstract class AbstractFsmRobot implements IFsmRobot { 7 | 8 | private S currentState; 9 | 10 | @Override 11 | public S currentState() { 12 | return currentState; 13 | } 14 | 15 | @Override 16 | public void changeState(S newState) { 17 | S state = currentState(); 18 | if (state != null) { 19 | state.exit(this); 20 | } 21 | 22 | this.currentState = newState; 23 | 24 | this.currentState.enter(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/FsmMessage.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class FsmMessage { 7 | 8 | private M message; 9 | 10 | public static FsmMessage build(RealMessageType message) { 11 | FsmMessage fsmMessage = new FsmMessage<>(); 12 | fsmMessage.setMessage(message); 13 | return fsmMessage; 14 | } 15 | 16 | public M getMessage() { 17 | return message; 18 | } 19 | 20 | public void setMessage(M message) { 21 | this.message = message; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/IFsmRobot.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | /** 4 | * 有限状态机中的机器人定义 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IFsmRobot { 9 | 10 | /** 11 | * 执行一次机器人逻辑(一般由定时任务调用) 12 | */ 13 | void tick(); 14 | 15 | /** 16 | * 获取机器人当前状态 17 | * 18 | * @return 该方法可能返回null 19 | */ 20 | S currentState(); 21 | 22 | /** 23 | * 变更状态 24 | * 25 | * @param newState 新状态 26 | */ 27 | void changeState(S newState); 28 | 29 | /** 30 | * 机器人当前是否正处于指定状态中 31 | * 32 | * @param state 对比状态 33 | * @return 返回对比结果 34 | */ 35 | default boolean isInState(S state) { 36 | return state != null && state.equals(currentState()); 37 | } 38 | 39 | /** 40 | * 接收到外部消息,并执行相应逻辑(该方法用于其他模块与机器人对象的交互) 41 | * 42 | * @param msg 有限状态机内部消息对象 43 | * @param 实际消息类型 44 | * @return 只要接收消息成功,即返回true,否则返回false 45 | */ 46 | default boolean onMessage(FsmMessage msg) { 47 | return true; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/IFsmState.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | /** 4 | * 有限状态机中的机器人状态接口 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IFsmState { 9 | 10 | /** 11 | * 机器人进入当前状态 12 | * 13 | * @param robot 机器人对象 14 | */ 15 | void enter(R robot); 16 | 17 | /** 18 | * 机器人在当前状态内刷新(更新)数据 19 | * 20 | * @param robot 机器人对象 21 | */ 22 | void refresh(R robot); 23 | 24 | /** 25 | * 机器人退出当前状态 26 | * 27 | * @param robot 机器人对象 28 | */ 29 | void exit(R robot); 30 | } 31 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/IStateMachine.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | /** 4 | * 状态机功能定义 5 | * 6 | * @author fagarine 7 | */ 8 | public interface IStateMachine { 9 | 10 | /** 11 | * 数据初始化操作 12 | */ 13 | default void initialize() { 14 | } 15 | 16 | /** 17 | * 状态机执行一次任务逻辑 18 | */ 19 | void tick(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/fsm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 有限状态机 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.robot.fsm; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/robot/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 该包下定义了游戏内机器人相关接口,目前常用的机器人逻辑实现有两种, 3 | * 有限状态机(Finite State Machine,包名fsm)和行为树(Behavior Tree,包名bt) 4 | * 5 | * @author fagarine 6 | */ 7 | package cn.laoshini.dk.robot; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/channel/INettyChannelReader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.channel; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | /** 6 | * Channel会话读取功能抽象类 7 | * 8 | * @param 进入时的消息类型 9 | * @author fagarine 10 | */ 11 | public interface INettyChannelReader { 12 | 13 | /** 14 | * 消息读取和处理 15 | * 16 | * @param ctx netty连接的上下文对象 17 | * @param msg 消息体 18 | */ 19 | public abstract void channelRead(ChannelHandlerContext ctx, MessageType msg); 20 | } 21 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/channel/JsonMessageChannelReader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.channel; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import cn.laoshini.dk.domain.msg.ReqMessage; 6 | 7 | /** 8 | * JSON格式消息到达读取处理 9 | * 10 | * @author fagarine 11 | */ 12 | public class JsonMessageChannelReader implements INettyChannelReader> { 13 | 14 | private LastChannelReader delegate = new LastChannelReader(); 15 | 16 | @Override 17 | public void channelRead(ChannelHandlerContext ctx, ReqMessage msg) { 18 | delegate.channelRead(ctx, msg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/channel/LastChannelReader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.channel; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import cn.laoshini.dk.constant.AttributeKeyConstant; 6 | import cn.laoshini.dk.domain.GameSubject; 7 | import cn.laoshini.dk.domain.msg.ReqMessage; 8 | import cn.laoshini.dk.net.MessageHandlerHolder; 9 | import cn.laoshini.dk.net.handler.MessageReceiveDispatcher; 10 | import cn.laoshini.dk.util.LogUtil; 11 | 12 | /** 13 | * 真正负责消息读取和转发处理的类 14 | * 15 | * @author fagarine 16 | */ 17 | class LastChannelReader implements INettyChannelReader { 18 | 19 | @Override 20 | public void channelRead(ChannelHandlerContext ctx, ReqMessage msg) { 21 | // 协议到达后处理 22 | GameSubject gameSubject = ctx.channel().attr(AttributeKeyConstant.PLAYER).get(); 23 | if (gameSubject == null) { 24 | if (!MessageHandlerHolder.allowGuestRequest(msg.getId())) { 25 | LogUtil.error("玩家未登录,msg:[{}], 关闭连接:{}", msg, ctx); 26 | ctx.close(); 27 | return; 28 | } 29 | } 30 | MessageReceiveDispatcher.messageReceived(msg, gameSubject); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/channel/NettyCustomMessageChannelReader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.channel; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import cn.laoshini.dk.net.msg.INettyDto; 6 | import cn.laoshini.dk.net.msg.ReqNettyCustomMessage; 7 | 8 | /** 9 | * 使用Netty通信的自定义消息类型读取处理 10 | * 11 | * @author fagarine 12 | */ 13 | public class NettyCustomMessageChannelReader implements INettyChannelReader> { 14 | 15 | private LastChannelReader delegate = new LastChannelReader(); 16 | 17 | @Override 18 | public void channelRead(ChannelHandlerContext ctx, ReqNettyCustomMessage reqMsg) { 19 | delegate.channelRead(ctx, reqMsg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/channel/ProtobufMessageChannelReader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.channel; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import cn.laoshini.dk.net.msg.BaseProtobufMessage; 6 | import cn.laoshini.dk.util.ByteMessageUtil; 7 | 8 | /** 9 | * Protobuf消息到达读取处理 10 | * 11 | * @author fagarine 12 | */ 13 | public class ProtobufMessageChannelReader implements INettyChannelReader { 14 | 15 | private LastChannelReader delegate = new LastChannelReader(); 16 | 17 | @Override 18 | public void channelRead(ChannelHandlerContext ctx, BaseProtobufMessage.Base msg) { 19 | // 将protobuf对象转为ReqMessage对象 20 | delegate.channelRead(ctx, ByteMessageUtil.baseToReqMessage(msg)); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 提供可直接使用的游戏服务器 3 | * 4 | * @author fagarine 5 | */ 6 | package cn.laoshini.dk.server; -------------------------------------------------------------------------------- /dk-game-core/src/main/java/cn/laoshini/dk/server/worker/MessageReceiveWorker.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.server.worker; 2 | 3 | import cn.laoshini.dk.domain.GameSubject; 4 | import cn.laoshini.dk.domain.msg.ReqMessage; 5 | import cn.laoshini.dk.executor.AbstractOrderedWorker; 6 | import cn.laoshini.dk.net.handler.MessageReceiveDispatcher; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | public class MessageReceiveWorker extends AbstractOrderedWorker { 12 | 13 | private ReqMessage reqMessage; 14 | 15 | private GameSubject gameSubject; 16 | 17 | public MessageReceiveWorker(ReqMessage reqMessage, GameSubject gameSubject) { 18 | this.reqMessage = reqMessage; 19 | this.gameSubject = gameSubject; 20 | } 21 | 22 | @Override 23 | protected void action() { 24 | MessageReceiveDispatcher.dealMessage(reqMessage, gameSubject); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dk-game-core/src/test/java/cn/laoshini/dk/robot/fsm/FsmTest.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | public class FsmTest { 10 | 11 | private IStateMachine stateMachine; 12 | 13 | @Before 14 | public void init() { 15 | stateMachine = new MonsterStateMachine(); 16 | stateMachine.initialize(); 17 | } 18 | 19 | @Test 20 | public void testFsm() throws Exception { 21 | while (true) { 22 | stateMachine.tick(); 23 | 24 | Thread.sleep(500); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dk-game-core/src/test/java/cn/laoshini/dk/robot/fsm/MonsterStateMachine.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.robot.fsm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | public class MonsterStateMachine implements IStateMachine { 10 | 11 | private static final String[] NAMES = { "妙蛙种子", "水箭龟", "小火龙", "绿毛虫", "大针蜂" }; 12 | 13 | private List monsters; 14 | 15 | @Override 16 | public void initialize() { 17 | monsters = new ArrayList<>(NAMES.length); 18 | 19 | for (String name : NAMES) { 20 | monsters.add(new Monster(name)); 21 | } 22 | } 23 | 24 | @Override 25 | public void tick() { 26 | for (Monster monster : monsters) { 27 | monster.tick(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-basic-excel/src/main/java/cn/laoshini/dk/excel/ExcelConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.excel; 2 | 3 | /** 4 | * excel导入导出功能相关常量 5 | * 6 | * @author fagarine 7 | */ 8 | public class ExcelConstant { 9 | private ExcelConstant() { 10 | } 11 | 12 | /** 13 | * excel缺省日期格式 14 | */ 15 | public static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd"; 16 | 17 | /** 18 | * 默认日期表达式,最小日期 19 | */ 20 | public static final String MIN_DATE = "1900/01/01"; 21 | 22 | /** 23 | * 默认日期表达式,最大日期 24 | */ 25 | public static final String MAX_DATE = "2999/12/31"; 26 | 27 | /** 28 | * 默认支持下拉列表的最大行数,从0开始计算 29 | */ 30 | public static final int XLS_MAX_ROW = 65535; 31 | 32 | /** 33 | * 默认列宽 34 | */ 35 | public static final int COLUMN_WIDTH = 15; 36 | } 37 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-basic-excel/src/main/java/cn/laoshini/dk/excel/constraint/ExcelDateHeader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.excel.constraint; 2 | 3 | import cn.laoshini.dk.excel.ExcelConstant; 4 | 5 | /** 6 | * 日期约束 7 | * 8 | * @author fagarine 9 | */ 10 | public class ExcelDateHeader extends ExcelNumericHeader { 11 | 12 | /** 13 | * 日期格式字符串 14 | */ 15 | private String dateFormat; 16 | 17 | public ExcelDateHeader(String name, int validationType, int comparisonOperator, String expr1, String expr2, 18 | String dateFormat) { 19 | super(name, validationType, comparisonOperator, expr1, expr2); 20 | this.dateFormat = dateFormat; 21 | } 22 | 23 | public ExcelDateHeader(String name, boolean editable, int validationType, int comparisonOperator, String expr1, 24 | String expr2, String dateFormat) { 25 | super(name, editable, validationType, comparisonOperator, expr1, expr2); 26 | this.dateFormat = dateFormat; 27 | } 28 | 29 | public String getDateFormat() { 30 | if (dateFormat == null) { 31 | dateFormat = ExcelConstant.DEFAULT_DATE_FORMAT; 32 | } 33 | return dateFormat; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-basic-excel/src/main/java/cn/laoshini/dk/excel/constraint/ExcelFormulaHeader.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.excel.constraint; 2 | 3 | import org.apache.poi.ss.usermodel.DataValidationConstraint; 4 | 5 | /** 6 | * 公式型 7 | * 8 | * @author fagarine 9 | */ 10 | public class ExcelFormulaHeader extends ExcelHeader { 11 | 12 | /** 13 | * 公式字符串 14 | */ 15 | private String textExpr; 16 | 17 | public ExcelFormulaHeader(String name, String textExpr) { 18 | super(name); 19 | this.textExpr = textExpr; 20 | } 21 | 22 | public ExcelFormulaHeader(String name, boolean editable, String textExpr) { 23 | super(name, editable); 24 | this.textExpr = textExpr; 25 | } 26 | 27 | @Override 28 | public int getValidationType() { 29 | return DataValidationConstraint.ValidationType.FORMULA; 30 | } 31 | 32 | public String getTextExpr() { 33 | return textExpr; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/DkJdbcConfigCenterApplication.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.config.server.EnableConfigServer; 6 | 7 | @EnableConfigServer 8 | @SpringBootApplication 9 | public class DkJdbcConfigCenterApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(DkJdbcConfigCenterApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/annotation/Property.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 标记配置信息表配置项的注解,使用该注解表示被标记字段数据需要保存到配置信息表中 10 | *

11 | * 该注解为使用spring cloud config功能而设计,cloud config配置源(一般为配置文件,该项目中使用数据库保存配置项)获取规则如下: 12 | *

13 |  * /{application}/{profile}[/{label}]
14 |  * /{application}-{profile}.yml
15 |  * /{label}/{application}-{profile}.yml
16 |  * /{application}-{profile}.properties
17 |  * /{label}/{application}-{profile}.properties
18 |  * 
19 | *

20 | * 以上方式的url都指向同一配置源,即通过application、profile、label三个值来区分和指向一个配置源(以键值对方式记录的多个配置项), 21 | * 系统默认的profile值为“default”,label为“master” 22 | *

23 | * 使用该注解来标注一个字段时,表示该字段为一个配置项,默认情况下该字段名称为配置项的key,值为配置项的value 24 | * 25 | * @author fagarine 26 | */ 27 | @Target({ ElementType.FIELD }) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | public @interface Property { 30 | 31 | /** 32 | * 配置项的名称(key),该值可以不设置,不设置表示使用被标记字段本身的名称作为配置项的key 33 | */ 34 | String value() default ""; 35 | } 36 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/constant/PropertiesConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class PropertiesConstant { 7 | /** 8 | * 应用默认(被所有非默认profile共享)的profile名称 9 | */ 10 | public static final String APPLICATION_DEFAULT_PROFILE = "default"; 11 | /** 12 | * 应用默认(被所有非默认label共享)的label名称 13 | */ 14 | public static final String APPLICATION_DEFAULT_LABEL = "master"; 15 | 16 | private PropertiesConstant() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/constant/PropertyOperation.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum PropertyOperation { 7 | 8 | /** 9 | * 新增 10 | */ 11 | ADDED, 12 | 13 | /** 14 | * 修改 15 | */ 16 | MODIFIED, 17 | 18 | /** 19 | * 删除 20 | */ 21 | DELETED; 22 | } 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/constant/PropertyStatus.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public enum PropertyStatus { 7 | /** 8 | * 已发布 9 | */ 10 | RELEASED, 11 | 12 | /** 13 | * 已回滚 14 | */ 15 | ROLLED_BACK; 16 | } 17 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/entity/ConfigProperty.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.entity; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | @Getter 11 | @Setter 12 | @ToString 13 | public class ConfigProperty { 14 | 15 | /** 16 | * 唯一id,自增 17 | */ 18 | private int id; 19 | 20 | /** 21 | * 配置信息的key,对应配置文件中的key 22 | */ 23 | private String key; 24 | 25 | /** 26 | * 配置信息的value,对应配置文件中的value 27 | */ 28 | private String value; 29 | 30 | /** 31 | * 应用名 32 | */ 33 | private String application; 34 | 35 | /** 36 | * 分支 37 | */ 38 | private String profile; 39 | 40 | /** 41 | * 标签 42 | */ 43 | private String label; 44 | } 45 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/mapper/VersionHistoryMapper.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.mapper; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | /** 7 | * @author fagarine 8 | */ 9 | @Mapper 10 | public interface VersionHistoryMapper { 11 | 12 | /** 13 | * 返回传入名称对应的迭代次数 14 | * 15 | * @param name name 16 | * @return 返回查询结果 17 | */ 18 | Integer selectIterations(@Param("name") String name); 19 | 20 | /** 21 | * 增加一条版本迭代信息 22 | * 23 | * @param name name 24 | * @return 返回受影响行数 25 | */ 26 | int insert(@Param("name") String name); 27 | 28 | /** 29 | * 版本迭代次数自增 30 | * 31 | * @param name name 32 | * @return 返回受影响行数 33 | */ 34 | int versionIncrement(@Param("name") String name); 35 | } 36 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/java/cn/laoshini/dk/config/center/service/VersionService.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.center.service; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import cn.laoshini.dk.config.center.mapper.VersionHistoryMapper; 8 | 9 | /** 10 | * @author fagarine 11 | */ 12 | @Service 13 | public class VersionService { 14 | 15 | @Resource 16 | private VersionHistoryMapper versionHistoryMapper; 17 | 18 | int nextVersionIterations(String name) { 19 | Integer iterations = versionHistoryMapper.selectIterations(name); 20 | if (iterations == null) { 21 | versionHistoryMapper.insert(name); 22 | return 1; 23 | } else { 24 | versionHistoryMapper.versionIncrement(name); 25 | return iterations + 1; 26 | } 27 | } 28 | 29 | public int currentVersionIterations(String name) { 30 | return versionHistoryMapper.selectIterations(name); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-center-jdbc/src/main/resources/mapper/VersionHistoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | INSERT INTO `version_history`(`name`, `iterations`) 17 | VALUES (#{name}, 1) 18 | 19 | 20 | 21 | UPDATE `version_history` 22 | SET `iterations`=`iterations` + 1 23 | WHERE `name` = #{name} 24 | 25 | 26 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-client/src/main/java/cn/laoshini/dk/config/client/CloudBusRefresher.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.client; 2 | 3 | import org.springframework.cloud.bus.event.RefreshListener; 4 | import org.springframework.cloud.context.refresh.ContextRefresher; 5 | import org.springframework.cloud.context.scope.refresh.RefreshScope; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * Spring cloud bus自动刷新相关功能支持 12 | * 13 | * @author fagarine 14 | */ 15 | @Configuration 16 | public class CloudBusRefresher { 17 | 18 | @Bean 19 | public RefreshScope refreshScope() { 20 | return new RefreshScope(); 21 | } 22 | 23 | @Bean 24 | public ContextRefresher contextRefresher(ConfigurableApplicationContext context, RefreshScope refreshScope) { 25 | // 使用自定义刷新对象 26 | return new CustomerContextRefresher(context, refreshScope); 27 | } 28 | 29 | @Bean 30 | public RefreshListener refreshListener(ContextRefresher contextRefresher) { 31 | return new RefreshListener(contextRefresher); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-client/src/main/java/cn/laoshini/dk/config/client/DkConfigClientApplicationContext.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.config.client; 2 | 3 | import org.springframework.context.support.GenericXmlApplicationContext; 4 | import org.springframework.core.env.ConfigurableEnvironment; 5 | 6 | import cn.laoshini.dk.common.IDkApplicationContext; 7 | 8 | /** 9 | * @author fagarine 10 | */ 11 | public class DkConfigClientApplicationContext extends GenericXmlApplicationContext implements IDkApplicationContext { 12 | 13 | @Override 14 | protected ConfigurableEnvironment createEnvironment() { 15 | // 使用自定义Environment对象 16 | return new DkConfigClientEnvironment(); 17 | } 18 | 19 | @Override 20 | public void configLocations(String... locations) { 21 | super.load(locations); 22 | } 23 | 24 | @Override 25 | public String[] dependentSpringConfigs() { 26 | return new String[] { "applicationContext-dk-config.xml" }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-client/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # 配置中心客户端当康容器启动类 2 | cn.laoshini.dk.common.IDkApplicationContext=cn.laoshini.dk.config.client.DkConfigClientApplicationContext 3 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-config-client/src/main/resources/applicationContext-dk-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-db-id-incrementer/sql/id_incrementer.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `id_incrementer` 2 | ( 3 | `user_id` bigint(20) NOT NULL DEFAULT '0', 4 | `role_id` bigint(20) NOT NULL DEFAULT '0' 5 | ) ENGINE = InnoDB 6 | DEFAULT CHARSET = utf8 7 | COLLATE = utf8_general_ci COMMENT ='自增id表'; 8 | INSERT INTO id_incrementer 9 | VALUES (0, 0); -------------------------------------------------------------------------------- /dk-impl-basic/dk-db-id-incrementer/src/main/java/cn/laoshini/dk/generator/id/IDbIdIncrementer.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.id; 2 | 3 | import cn.laoshini.dk.exception.BusinessException; 4 | 5 | /** 6 | * 使用数据库(键值对数据库或关系数据库)实现id自增器的接口 7 | * 8 | * @author fagarine 9 | */ 10 | interface IDbIdIncrementer { 11 | 12 | /** 13 | * 返回id自增器实例对应id的名称 14 | * 15 | * @return 实现类应该保证该方法不会返回null 16 | */ 17 | String idName(); 18 | 19 | /** 20 | * 自增并返回下一个id 21 | * 22 | * @return 正整数 23 | * @throws BusinessException 所有异常都封装为BusinessException抛出 24 | */ 25 | long nextId() throws BusinessException; 26 | 27 | /** 28 | * 返回ID缓存数量,也表示返回多少个ID写一次数据库。 29 | * 设置缓存可有效减轻数据库压力,但停服后重启可能导致索引不连续,如果是要求索引强制连续的,缓存位1,即不用缓存 30 | * 31 | * @return 缓存数量 32 | */ 33 | default int cacheSize() { 34 | return 1; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-db-id-incrementer/src/main/java/cn/laoshini/dk/generator/id/IdIncrementerConstant.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.id; 2 | 3 | /** 4 | * id自增器内部实现相关常量定义 5 | * 6 | * @author fagarine 7 | */ 8 | public class IdIncrementerConstant { 9 | /** 10 | * 关系数据库,记录id自增器序列值的表 11 | */ 12 | public static final String ID_INCREMENTER_TABLE = "id_incrementer"; 13 | /** 14 | * 键值对数据库,记录id自增器序列值的前缀 15 | */ 16 | public static final String ID_INCREMENTER_PREFIX = "ID:INCREMENTER:"; 17 | /** 18 | * 关系数据库,单次id缓存长度 19 | */ 20 | public static final int RELATION_DB_CACHE_SIZE = 100; 21 | /** 22 | * 键值对数据库,单次id缓存长度 23 | */ 24 | public static final int PAIR_DB_CACHE_SIZE = 100; 25 | 26 | private IdIncrementerConstant() { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm-console/src/main/java/cn/laoshini/dk/console/DkAdminApplication.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.console; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | @ComponentScan("cn.laoshini.dk") 9 | public class DkAdminApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(DkAdminApplication.class, args); 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm-console/src/main/java/cn/laoshini/dk/console/vo/HotfixRecordVO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.console.vo; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * 热修复执行结果记录VO 10 | * 11 | * @author fagarine 12 | */ 13 | @Data 14 | public class HotfixRecordVO implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private Integer id; 19 | 20 | /** 21 | * 热更key,用于区分是否是同一次热更操作,可以是热更说明信息等 22 | */ 23 | private String hotfixKey; 24 | 25 | /** 26 | * 热更类名 27 | */ 28 | private String className; 29 | 30 | /** 31 | * 热更时间 32 | */ 33 | private Date hotfixTime; 34 | 35 | /** 36 | * 热更结果 37 | */ 38 | private String result; 39 | 40 | /** 41 | * 描述信息 42 | */ 43 | private String desc; 44 | } 45 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm-console/src/main/java/cn/laoshini/dk/console/vo/ModuleInfoVO.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.console.vo; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import lombok.Data; 7 | 8 | /** 9 | * 外置模块信息VO 10 | * 11 | * @author fagarine 12 | */ 13 | @Data 14 | public class ModuleInfoVO implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | /** 19 | * 模块名称 20 | */ 21 | private String name; 22 | 23 | /** 24 | * 模块文件路径 25 | */ 26 | private String file; 27 | 28 | /** 29 | * 文件最后修改时间 30 | */ 31 | private Date lastModified; 32 | 33 | /** 34 | * 模块最后加载成功时间 35 | */ 36 | private Date lastLoaded; 37 | } 38 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm-console/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.http.encoding.charset=UTF-8 2 | spring.http.encoding.enabled=true 3 | spring.http.encoding.force-response=true 4 | server.tomcat.uri-encoding=UTF-8 5 | 6 | # url\u524D\u7F00\uFF0C\u9ED8\u8BA4\u4E0D\u4F7F\u7528\u4EFB\u4F55\u524D\u7F00 7 | #server.servlet.context-path= 8 | 9 | # \u5F53\u5EB7\u540E\u53F0\u7BA1\u7406\u7CFB\u7EDF\u670D\u52A1\u542F\u52A8\u5360\u7528\u7AEF\u53E3 10 | server.port=9420 11 | 12 | # logging file 13 | logging.config=classpath:logback.xml 14 | 15 | # \u5E95\u5C42debug log\u5F00\u5173 16 | debug=true 17 | 18 | # \u914D\u7F6E\u4E2D\u5FC3URL 19 | dk.config.server= 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dk-impl-basic 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-gm 13 | 14 | 提供基础的游戏GM功能 15 | 16 | 17 | 18 | cn.laoshini.dk 19 | dk-core 20 | ${dangkang.version} 21 | provided 22 | 23 | 24 | 25 | io.netty 26 | netty-all 27 | 4.1.42.Final 28 | provided 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/constant/GmConstants.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.constant; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | public class GmConstants { 7 | /** 8 | * 从GM服务器向GM后台服务器注册的HTTP请求默认URI 9 | */ 10 | public static final String GM_REGISTER_URI = "/dk/server/register"; 11 | /** 12 | * 从GM后台服务器发送到GM服务器的HTTP请求默认URI 13 | */ 14 | public static final String GM_URI = "/dk/gm"; 15 | /** GM消息id基础值 */ 16 | public static final int GM_HEAD = 100; 17 | 18 | // *********************消息ID相关常量 Begin********************** // 19 | public static final int GET_MODULE_LIST_REQ = 1; 20 | public static final int RELOAD_MODULES_REQ = 3; 21 | public static final int REMOVE_MODULE_REQ = 5; 22 | public static final int DO_HOTFIX_REQ = 7; 23 | public static final int GET_HOTFIX_HISTORY_REQ = 9; 24 | public static final int GET_GAME_SERVER_INFO_REQ = 11; 25 | public static final int PAUSE_GAME_SERVER_REQ = 13; 26 | public static final int RELEASE_GAME_SERVER_REQ = 15; 27 | 28 | private GmConstants() { 29 | } 30 | 31 | // **********************消息ID相关常量 End*********************** // 32 | } 33 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/hotfix/DoHotfixReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.hotfix; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = DoHotfixReq.MESSAGE_ID, gm = true) 17 | public class DoHotfixReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.DO_HOTFIX_REQ; 20 | 21 | private String hotfixKey; 22 | } 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/hotfix/DoHotfixRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.hotfix; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = DoHotfixRes.MESSAGE_ID, gm = true) 17 | public class DoHotfixRes { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.DO_HOTFIX_REQ; 20 | 21 | private String message; 22 | } 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/hotfix/GetHotfixHistoryReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.hotfix; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = GetHotfixHistoryReq.MESSAGE_ID, gm = true) 17 | public class GetHotfixHistoryReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_HOTFIX_HISTORY_REQ; 20 | 21 | /** 22 | * 页码,从1开始 23 | */ 24 | private Integer pageNo; 25 | 26 | /** 27 | * 单页数据条数 28 | */ 29 | private Integer pageSize; 30 | } 31 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/hotfix/GetHotfixHistoryRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.hotfix; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | import cn.laoshini.dk.annotation.Message; 10 | import cn.laoshini.dk.domain.dto.HotfixRecordDTO; 11 | import cn.laoshini.dk.gm.constant.GmConstants; 12 | 13 | /** 14 | * @author fagarine 15 | */ 16 | @Getter 17 | @Setter 18 | @ToString 19 | @Message(id = GetHotfixHistoryRes.MESSAGE_ID, gm = true) 20 | public class GetHotfixHistoryRes { 21 | 22 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_HOTFIX_HISTORY_REQ + 1; 23 | 24 | /** 25 | * 页码,从1开始 26 | */ 27 | private Integer pageNo; 28 | 29 | /** 30 | * 单页数据条数 31 | */ 32 | private Integer pageSize; 33 | 34 | /** 35 | * 总数据条数 36 | */ 37 | private Long total; 38 | 39 | /** 40 | * hotfix执行记录 41 | */ 42 | private List records; 43 | } 44 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/GetModuleListReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = GetModuleListReq.MESSAGE_ID, gm = true) 17 | public class GetModuleListReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_MODULE_LIST_REQ; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/GetModuleListRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | import cn.laoshini.dk.annotation.Message; 10 | import cn.laoshini.dk.domain.dto.ModuleInfoDTO; 11 | import cn.laoshini.dk.gm.constant.GmConstants; 12 | 13 | /** 14 | * @author fagarine 15 | */ 16 | @Getter 17 | @Setter 18 | @ToString 19 | @Message(id = GetModuleListRes.MESSAGE_ID, gm = true) 20 | public class GetModuleListRes { 21 | 22 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_MODULE_LIST_REQ + 1; 23 | 24 | private List modules; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/ReloadModulesReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = ReloadModulesReq.MESSAGE_ID, gm = true) 17 | public class ReloadModulesReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.RELOAD_MODULES_REQ; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/ReloadModulesRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = ReloadModulesRes.MESSAGE_ID, gm = true) 17 | public class ReloadModulesRes { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.RELOAD_MODULES_REQ + 1; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/RemoveModuleReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = RemoveModuleReq.MESSAGE_ID, gm = true) 17 | public class RemoveModuleReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.REMOVE_MODULE_REQ; 20 | 21 | private String moduleName; 22 | } 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/module/RemoveModuleRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = RemoveModuleRes.MESSAGE_ID, gm = true) 17 | public class RemoveModuleRes { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.REMOVE_MODULE_REQ + 1; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/GetGameServerInfoReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = GetGameServerInfoReq.MESSAGE_ID, gm = true) 17 | public class GetGameServerInfoReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_GAME_SERVER_INFO_REQ; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/GetGameServerInfoRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | import cn.laoshini.dk.annotation.Message; 10 | import cn.laoshini.dk.domain.dto.GameServerInfoDTO; 11 | import cn.laoshini.dk.gm.constant.GmConstants; 12 | 13 | /** 14 | * @author fagarine 15 | */ 16 | @Getter 17 | @Setter 18 | @ToString 19 | @Message(id = GetGameServerInfoRes.MESSAGE_ID, gm = true) 20 | public class GetGameServerInfoRes { 21 | 22 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.GET_GAME_SERVER_INFO_REQ + 1; 23 | 24 | private List servers; 25 | } 26 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/PauseGameServerReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import java.util.Date; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | import cn.laoshini.dk.annotation.Message; 10 | import cn.laoshini.dk.gm.constant.GmConstants; 11 | 12 | /** 13 | * @author fagarine 14 | */ 15 | @Getter 16 | @Setter 17 | @ToString 18 | @Message(id = PauseGameServerReq.MESSAGE_ID, gm = true) 19 | public class PauseGameServerReq { 20 | 21 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.PAUSE_GAME_SERVER_REQ; 22 | 23 | private String tips; 24 | 25 | private Date openTime; 26 | } 27 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/PauseGameServerRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = PauseGameServerRes.MESSAGE_ID, gm = true) 17 | public class PauseGameServerRes { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.PAUSE_GAME_SERVER_REQ + 1; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/ReleaseGameServerReq.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = ReleaseGameServerReq.MESSAGE_ID, gm = true) 17 | public class ReleaseGameServerReq { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.RELEASE_GAME_SERVER_REQ; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-gm/src/main/java/cn/laoshini/dk/gm/message/server/ReleaseGameServerRes.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.gm.message.server; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | import cn.laoshini.dk.annotation.Message; 8 | import cn.laoshini.dk.gm.constant.GmConstants; 9 | 10 | /** 11 | * @author fagarine 12 | */ 13 | @Getter 14 | @Setter 15 | @ToString 16 | @Message(id = ReleaseGameServerRes.MESSAGE_ID, gm = true) 17 | public class ReleaseGameServerRes { 18 | 19 | public static final int MESSAGE_ID = GmConstants.GM_HEAD + GmConstants.RELEASE_GAME_SERVER_REQ + 1; 20 | } 21 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dk-impl-basic 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-name-generator-cn 13 | 14 | 简体中文名称生成器实现项目,该项目生成的名称符合中国传统起名习惯 15 | 16 | 17 | 18 | cn.laoshini.dk 19 | dk-core 20 | ${dangkang.version} 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/BasicLevelRandomNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | class BasicLevelRandomNameGenerator extends AbstractLevelRandomNameGenerator { 7 | 8 | @Override 9 | Surname randomSurname() { 10 | return randomInAllSurname(); 11 | } 12 | 13 | @Override 14 | String randomName(int nameLen) { 15 | StringBuilder name = new StringBuilder(); 16 | for (int i = 0; i < nameLen; i++) { 17 | name.append(randomCharacter().getCharacter()); 18 | } 19 | return name.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/ChineseCharacter.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | @Getter 11 | @Setter 12 | @ToString 13 | class ChineseCharacter { 14 | 15 | private int id; 16 | 17 | /** 18 | * 汉字 19 | */ 20 | private String character; 21 | 22 | /** 23 | * 拼音 24 | */ 25 | private String spelling; 26 | 27 | /** 28 | * 笔画数 29 | */ 30 | private int strokes; 31 | 32 | /** 33 | * 等级,在名字中越常见的字等级越高 34 | */ 35 | private int level; 36 | 37 | /** 38 | * 随机权重 39 | */ 40 | private int weight; 41 | } 42 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/ILevelRandomNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author fagarine 7 | */ 8 | interface ILevelRandomNameGenerator { 9 | 10 | /** 11 | * 生成一个新的名称并返回 12 | * 13 | * @param surname 传入姓氏,传入null则随机姓氏 14 | * @param maxLen 名称最大长度(包含姓氏) 15 | * @return 返回名称 16 | */ 17 | String newName(String surname, int maxLen); 18 | 19 | /** 20 | * 批量生成名称 21 | * 22 | * @param surname 传入姓氏,传入null则随机姓氏 23 | * @param maxLen 名称最大长度(包含姓氏) 24 | * @param count 生成数量 25 | * @return 返回结果,该方法不会返回null 26 | */ 27 | List batchName(String surname, int maxLen, int count); 28 | 29 | /** 30 | * 设置名字(不包含姓氏)的最大长度 31 | * 32 | * @param nameLimit 长度限制 33 | */ 34 | void setNameLimit(int nameLimit); 35 | } 36 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/MiddleLevelRandomNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | class MiddleLevelRandomNameGenerator extends AbstractLevelRandomNameGenerator { 7 | 8 | @Override 9 | Surname randomSurname() { 10 | return randomInHundredSurname(); 11 | } 12 | 13 | @Override 14 | String randomName(int nameLen) { 15 | StringBuilder name = new StringBuilder(); 16 | for (int i = 0; i < nameLen; i++) { 17 | name.append(randomCharacterByWeight().getCharacter()); 18 | } 19 | return name.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/SimpleLevelRandomNameGenerator.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | /** 4 | * @author fagarine 5 | */ 6 | class SimpleLevelRandomNameGenerator extends AbstractLevelRandomNameGenerator { 7 | 8 | @Override 9 | Surname randomSurname() { 10 | return randomInHundredSurname(); 11 | } 12 | 13 | @Override 14 | String randomName(int nameLen) { 15 | StringBuilder name = new StringBuilder(); 16 | for (int i = 0; i < nameLen; i++) { 17 | name.append(randomCharacter().getCharacter()); 18 | } 19 | return name.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-cn/src/main/java/cn/laoshini/dk/generator/name/Surname.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | @Getter 11 | @Setter 12 | @ToString 13 | class Surname { 14 | 15 | private int id; 16 | 17 | private String surname; 18 | 19 | private int len; 20 | 21 | private int level; 22 | } 23 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-foreign-cn/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dk-impl-basic 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-name-generator-foreign-cn 13 | 14 | 简体中文形式的外国人名称生成器实现项目 15 | 16 | 17 | 18 | cn.laoshini.dk 19 | dk-core 20 | ${dangkang.version} 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-name-generator-foreign-cn/src/main/java/cn/laoshini/dk/generator/name/IniName.java: -------------------------------------------------------------------------------- 1 | package cn.laoshini.dk.generator.name; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | * @author fagarine 9 | */ 10 | @Getter 11 | @Setter 12 | @ToString 13 | public class IniName { 14 | 15 | private String familyName; 16 | 17 | private String manName; 18 | 19 | private String womanName; 20 | 21 | private String mark; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dk-impl-basic/dk-qr-code/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dk-impl-basic 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-qr-code 13 | 二维码生成和解析功能 14 | 15 | 16 | 17 | cn.laoshini.dk 18 | dk-common 19 | 1.0.0-SNAPSHOT 20 | 21 | 22 | com.google.zxing 23 | core 24 | 3.3.0 25 | 26 | 27 | com.google.zxing 28 | javase 29 | 3.3.0 30 | 31 | 32 | -------------------------------------------------------------------------------- /dk-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dangkang 7 | cn.laoshini.dk 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | dk-starter 13 | 14 | 15 | 16 | cn.laoshini.dk 17 | dk-core 18 | ${dangkang.version} 19 | 20 | 21 | 22 | io.netty 23 | netty-all 24 | 4.1.42.Final 25 | 26 | 27 | 28 | --------------------------------------------------------------------------------