From 914bc3923d4c9d1640d2efcdc2b19058ce26d1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=B3=BD=E5=B8=86?= <411641460@qq.com> Date: Tue, 16 Dec 2025 14:40:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=9E=9B=E5=9E=9B?= =?UTF-8?q?=E7=89=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_cache/config/log4j.properties | 20 + data_cache/config/mpnet-tools.xml | 93 + data_cache/pom.xml | 63 + .../main/java/com/data/bean/AccountBean.java | 37 + .../src/main/java/com/data/bean/BaseBean.java | 34 + .../src/main/java/com/data/bean/GameBean.java | 105 + .../main/java/com/data/bean/GroupBean.java | 113 + .../java/com/data/bean/GroupMemberBean.java | 50 + .../java/com/data/bean/GroupPlayBean.java | 141 + .../java/com/data/cache/AccountCache.java | 43 + .../main/java/com/data/cache/BaseCache.java | 229 + .../main/java/com/data/cache/GameCache.java | 44 + .../main/java/com/data/cache/GroupCache.java | 125 + .../java/com/data/cache/GroupMemberCache.java | 32 + .../java/com/data/cache/GroupPlayCache.java | 106 + .../main/java/com/data/util/ConsumeCode.java | 51 + .../main/java/com/data/util/CountUtil.java | 262 + .../main/java/com/data/util/ErrorCode.java | 172 + .../main/java/com/data/util/EventType.java | 60 + .../src/main/java/com/data/util/Utility.java | 399 ++ event_mgr/build/local/taurus-core.xml | 96 + event_mgr/build/pro/log4j.properties | 20 + event_mgr/build/pro/taurus-core.xml | 96 + event_mgr/build/test/log4j.properties | 20 + event_mgr/build/test/taurus-core.xml | 96 + event_mgr/pom.xml | 117 + .../java/com/evt/mgr/EventController.java | 149 + .../main/java/com/evt/mgr/EventReceiver.java | 101 + .../main/java/com/evt/mgr/EventServer.java | 105 + .../com/evt/mgr/GroupPublisherService.java | 75 + .../src/main/java/com/evt/mgr/IHandler.java | 10 + .../src/main/java/com/evt/mgr/Utils.java | 221 + .../mgr/handler/HandlerGroupMemberRound.java | 104 + .../evt/mgr/handler/HandlerGroupRound.java | 72 + .../com/evt/mgr/handler/HandlerHpConsume.java | 551 ++ .../java/com/evt/mgr/handler/HandlerLose.java | 18 + .../java/com/evt/mgr/handler/HandlerOver.java | 90 + .../java/com/evt/mgr/handler/HandlerPay.java | 84 + .../java/com/evt/mgr/handler/HandlerWin.java | 18 + .../com/evt/mgr/job/CleanGroupLogJob.java | 94 + .../com/evt/mgr/job/CleanTimeOutRoomJob.java | 323 + event_mgr/src/main/webapp/WEB-INF/web.xml | 19 + .../src/main/webapp/config/log4j.properties | 20 + .../src/main/webapp/config/taurus-core.xml | 98 + event_mgr/src/test/java/MainEventMgr.java | 12 + game_common/.idea/compiler.xml | 13 + game_common/.idea/encodings.xml | 7 + game_common/.idea/jarRepositories.xml | 20 + game_common/.idea/misc.xml | 12 + game_common/.idea/vcs.xml | 6 + game_common/pom.xml | 85 + .../src/main/java/com/game/ActionEvent.java | 51 + .../src/main/java/com/game/Constant.java | 62 + .../main/java/com/game/EventController.java | 376 ++ .../src/main/java/com/game/GPSUtil.java | 63 + .../main/java/com/game/GameController.java | 1022 +++ .../main/java/com/game/GameInterceptor.java | 55 + .../src/main/java/com/game/Global.java | 104 + .../java/com/game/GroupPublisherService.java | 95 + .../src/main/java/com/game/MainServer.java | 172 + .../src/main/java/com/game/Router.java | 183 + game_common/src/main/java/com/game/Util.java | 302 + .../main/java/com/game/data/BasePlayBack.java | 108 + .../src/main/java/com/game/data/Hp.java | 24 + .../main/java/com/game/data/JoinRoomData.java | 12 + .../src/main/java/com/game/data/Player.java | 614 ++ .../src/main/java/com/game/data/Room.java | 2202 ++++++ .../main/java/com/game/data/RoomDismiss.java | 158 + .../src/main/java/com/game/data/Score.java | 54 + .../src/main/java/com/game/data/Timer.java | 75 + .../java/com/game/manager/RoomManager.java | 302 + .../java/com/game/manager/SessionManager.java | 114 + .../com/game/player/state/PlayerEndState.java | 53 + .../game/player/state/PlayerInitState.java | 51 + .../game/player/state/PlayerPauseState.java | 21 + .../game/player/state/PlayerPopupState.java | 35 + .../game/player/state/PlayerReadyState.java | 31 + .../game/player/state/PlayerReloadState.java | 25 + .../player/state/PlayerSpectatorState.java | 44 + .../game/player/state/PlayerWaitState.java | 11 + .../game/room/state/RoomDestoryGameState.java | 17 + .../com/game/room/state/RoomEndState.java | 42 + .../com/game/room/state/RoomInitState.java | 42 + .../com/game/room/state/RoomReloadState.java | 39 + .../game/room/state/RoomStartGameState.java | 12 + .../com/game/room/state/RoomWaitState.java | 31 + .../main/java/com/game/state/StateBase.java | 51 + .../java/com/game/state/StateMachine.java | 64 + game_mj_hongzhong/config/game-config.xml | 11 + game_mj_hongzhong/config/log4j.properties | 20 + game_mj_hongzhong/config/taurus-core.xml | 50 + game_mj_hongzhong/config/taurus-permanent.xml | 75 + game_mj_hongzhong/pom.xml | 44 + .../src/main/java/extend/mj/CardNiao.java | 19 + .../src/main/java/extend/mj/Config.java | 120 + .../main/java/extend/mj/EXActionEvent.java | 18 + .../main/java/extend/mj/EXGameController.java | 279 + .../src/main/java/extend/mj/EXMainServer.java | 98 + .../src/main/java/extend/mj/EXPlayBack.java | 68 + .../src/main/java/extend/mj/EXPlayer.java | 142 + .../src/main/java/extend/mj/EXRoom.java | 694 ++ .../src/main/java/extend/mj/EXScore.java | 47 + .../src/main/java/extend/mj/OpCard.java | 19 + .../java/extend/mj/PlayerRuleManager.java | 103 + .../src/main/java/extend/mj/RoomCard.java | 190 + .../src/main/java/extend/mj/RuleWeight.java | 20 + .../src/main/java/extend/mj/SettleLog.java | 44 + .../extend/mj/player/rule/RuleOtherKong.java | 50 + .../extend/mj/player/rule/RuleOtherWin.java | 61 + .../java/extend/mj/player/rule/RulePong.java | 53 + .../extend/mj/player/rule/RulePongKong.java | 59 + .../extend/mj/player/rule/RuleSelfKong.java | 56 + .../extend/mj/player/rule/RuleSelfWin.java | 49 + .../mj/player/rulestate/PROtherKongState.java | 89 + .../mj/player/rulestate/PROtherWinState.java | 73 + .../mj/player/rulestate/PRPongKongState.java | 77 + .../mj/player/rulestate/PRPongState.java | 67 + .../mj/player/rulestate/PRSelfKongState.java | 53 + .../mj/player/rulestate/PRSelfWinState.java | 93 + .../player/state/EXPlayerDisCardTipState.java | 54 + .../mj/player/state/EXPlayerDiscardState.java | 146 + .../mj/player/state/EXPlayerDrawState.java | 232 + .../mj/player/state/EXPlayerDrawTipState.java | 43 + .../mj/player/state/EXPlayerKongWinState.java | 42 + .../state/EXPlayerPiaoNiaoTipState.java | 54 + .../mj/player/state/EXPlayerTipState.java | 49 + .../state/EXPlayerWaitKongWinState.java | 24 + .../mj/player/state/EXPlayerWaitState.java | 39 + .../extend/mj/room/state/EXRoomDealState.java | 147 + .../extend/mj/room/state/EXRoomSetpState.java | 42 + .../mj/room/state/EXRoomStartGameState.java | 33 + .../src/main/java/extend/mj/tip/Action.java | 27 + .../main/java/extend/mj/tip/IRuleBase.java | 27 + .../src/main/java/extend/mj/tip/Tip.java | 40 + .../main/java/extend/mj/tip/TipManager.java | 125 + .../main/java/extend/mj/uitl/CardUtil.java | 32 + .../src/main/java/extend/mj/uitl/WinCard.java | 363 + .../java/game_mj_hongzhong/MainHongzhong.java | 9 + game_pk_duoduo/.idea/compiler.xml | 13 + game_pk_duoduo/.idea/encodings.xml | 7 + game_pk_duoduo/.idea/jarRepositories.xml | 20 + game_pk_duoduo/.idea/misc.xml | 12 + game_pk_duoduo/.idea/vcs.xml | 6 + game_pk_duoduo/config/game-config.xml | 10 + game_pk_duoduo/config/log4j.properties | 20 + game_pk_duoduo/config/taurus-core.xml | 95 + game_pk_duoduo/config/taurus-permanent.xml | 75 + game_pk_duoduo/pom.xml | 44 + .../src/main/java/extend/pk/CardGroup.java | 45 + .../src/main/java/extend/pk/CardObj.java | 21 + .../src/main/java/extend/pk/Config.java | 140 + .../main/java/extend/pk/EXActionEvent.java | 10 + .../main/java/extend/pk/EXGameController.java | 878 +++ .../src/main/java/extend/pk/EXMainServer.java | 59 + .../src/main/java/extend/pk/EXPlayBack.java | 61 + .../src/main/java/extend/pk/EXPlayer.java | 137 + .../src/main/java/extend/pk/EXRoom.java | 430 ++ .../src/main/java/extend/pk/EXScore.java | 18 + .../src/main/java/extend/pk/RoomCard.java | 1192 ++++ .../src/main/java/extend/pk/SettleLog.java | 44 + .../pk/player/state/EXPlayerDiscardState.java | 394 ++ .../pk/player/state/EXPlayerPassState.java | 52 + .../extend/pk/room/state/EXRoomDealState.java | 112 + .../extend/pk/room/state/EXRoomSetpState.java | 35 + .../pk/room/state/EXRoomStartGameState.java | 38 + .../main/java/extend/pk/uitl/CardCheck.java | 859 +++ .../main/java/extend/pk/uitl/CardConfig.java | 39 + .../main/java/extend/pk/uitl/CardUtil.java | 419 ++ .../java/game_pk_paodekuai/MainPaodekuai.java | 9 + game_pk_paodekuai/.idea/compiler.xml | 13 + game_pk_paodekuai/.idea/encodings.xml | 7 + game_pk_paodekuai/.idea/jarRepositories.xml | 20 + game_pk_paodekuai/.idea/misc.xml | 12 + game_pk_paodekuai/.idea/vcs.xml | 6 + game_pk_paodekuai/config/game-config.xml | 10 + game_pk_paodekuai/config/log4j.properties | 20 + game_pk_paodekuai/config/taurus-core.xml | 95 + game_pk_paodekuai/config/taurus-permanent.xml | 75 + game_pk_paodekuai/pom.xml | 44 + .../src/main/java/extend/pk/CardGroup.java | 45 + .../src/main/java/extend/pk/CardObj.java | 21 + .../src/main/java/extend/pk/Config.java | 248 + .../main/java/extend/pk/EXActionEvent.java | 10 + .../main/java/extend/pk/EXGameController.java | 950 +++ .../src/main/java/extend/pk/EXMainServer.java | 66 + .../src/main/java/extend/pk/EXPlayBack.java | 61 + .../src/main/java/extend/pk/EXPlayer.java | 137 + .../src/main/java/extend/pk/EXRoom.java | 455 ++ .../src/main/java/extend/pk/EXScore.java | 18 + .../src/main/java/extend/pk/RoomCard.java | 1192 ++++ .../src/main/java/extend/pk/SettleLog.java | 44 + .../pk/player/state/EXPlayerDiscardState.java | 427 ++ .../pk/player/state/EXPlayerPassState.java | 52 + .../state/EXPlayerPiaoNiaoTipState.java | 64 + .../extend/pk/room/state/EXRoomDealState.java | 112 + .../extend/pk/room/state/EXRoomPiaoState.java | 31 + .../extend/pk/room/state/EXRoomSetpState.java | 35 + .../pk/room/state/EXRoomStartGameState.java | 43 + .../main/java/extend/pk/uitl/CardCheck.java | 1429 ++++ .../main/java/extend/pk/uitl/CardConfig.java | 46 + .../main/java/extend/pk/uitl/CardUtil.java | 419 ++ .../java/game_pk_paodekuai/MainPaodekuai.java | 9 + group_mgr/build/local/log4j.properties | 20 + group_mgr/build/local/mgr-config.xml | 6 + group_mgr/build/local/taurus-core.xml | 99 + group_mgr/build/local/taurus-permanent.xml | 75 + group_mgr/build/pro/log4j.properties | 20 + group_mgr/build/pro/mgr-config.xml | 6 + group_mgr/build/pro/taurus-core.xml | 98 + group_mgr/build/pro/taurus-permanent.xml | 75 + group_mgr/build/test/log4j.properties | 20 + group_mgr/build/test/mgr-config.xml | 6 + group_mgr/build/test/taurus-core.xml | 98 + group_mgr/build/test/taurus-permanent.xml | 75 + group_mgr/pom.xml | 126 + .../src/main/java/com/mgr/group/Config.java | 9 + .../src/main/java/com/mgr/group/Global.java | 28 + .../java/com/mgr/group/GroupController.java | 1805 +++++ .../java/com/mgr/group/GroupSubscriber.java | 314 + .../main/java/com/mgr/group/MainServer.java | 184 + .../src/main/java/com/mgr/group/Router.java | 155 + .../java/com/mgr/group/SessionManager.java | 80 + .../src/main/java/com/mgr/group/WebMain.java | 34 + .../java/com/mgr/group/data/CommandData.java | 36 + .../main/java/com/mgr/group/data/Group.java | 386 ++ .../main/java/com/mgr/group/data/Player.java | 38 + .../java/com/mgr/group/data/PlayerCache.java | 25 + .../main/java/com/mgr/group/data/Room.java | 175 + .../java/com/mgr/group/data/RoomCache.java | 87 + .../main/java/com/mgr/group/data/User.java | 131 + group_mgr/src/main/webapp/WEB-INF/web.xml | 19 + .../src/main/webapp/config/log4j.properties | 20 + .../src/main/webapp/config/mgr-config.xml | 6 + .../src/main/webapp/config/taurus-core.xml | 98 + .../main/webapp/config/taurus-permanent.xml | 75 + .../java/group_room_mgr/MainGroupMgr.java | 12 + pack_tools/pom.xml | 119 + .../src/main/java/com/pack/MainServer.java | 63 + pack_tools/src/main/java/com/pack/Utils.java | 98 + .../java/com/pack/service/CommandService.java | 69 + .../com/pack/service/PackServerProject.java | 103 + .../com/pack/service/PackUtilService.java | 289 + .../java/com/pack/service/ServletAllGame.java | 56 + pack_tools/src/main/webapp/WEB-INF/web.xml | 38 + .../src/main/webapp/config/log4j.properties | 20 + .../src/main/webapp/config/mpnet-tools.xml | 97 + .../src/main/webapp/config/pack-config.xml | 28 + .../src/main/webapp/config/taurus-core.xml | 94 + pack_tools/src/test/java/pack_tools/Main.java | 9 + pack_tools/src/test/java/pack_tools/TT.java | 9 + taurus-permanent/config/log4j.properties | 20 + taurus-permanent/config/taurus-core.xml | 96 + taurus-permanent/config/taurus-permanent.xml | 75 + taurus-permanent/pom.xml | 36 + .../main/java/com/taurus/permanent/Main.java | 9 + .../java/com/taurus/permanent/TPServer.java | 319 + .../permanent/core/BaseCoreService.java | 46 + .../taurus/permanent/core/BitSwarmEngine.java | 337 + .../permanent/core/ConnectionFilter.java | 159 + .../permanent/core/DefaultConstants.java | 20 + .../permanent/core/IConnectionFilter.java | 61 + .../taurus/permanent/core/ServerConfig.java | 181 + .../taurus/permanent/core/ServerState.java | 11 + .../taurus/permanent/core/SessionManager.java | 313 + .../permanent/core/SystemController.java | 338 + .../com/taurus/permanent/core/TPEvents.java | 28 + .../taurus/permanent/data/BindableSocket.java | 37 + .../taurus/permanent/data/IPacketQueue.java | 66 + .../taurus/permanent/data/ISocketChannel.java | 21 + .../data/NonBlockingPacketQueue.java | 82 + .../taurus/permanent/data/PackDataType.java | 6 + .../com/taurus/permanent/data/Packet.java | 94 + .../com/taurus/permanent/data/Session.java | 467 ++ .../taurus/permanent/data/SessionType.java | 17 + .../taurus/permanent/io/BinaryIoHandler.java | 242 + .../com/taurus/permanent/io/IOHandler.java | 73 + .../taurus/permanent/io/PacketReadState.java | 21 + .../taurus/permanent/io/PendingPacket.java | 37 + .../taurus/permanent/io/ProcessedPacket.java | 23 + .../taurus/permanent/io/ProtocolHandler.java | 42 + .../permanent/normal/NormalSocketChannel.java | 71 + .../permanent/normal/SocketAcceptor.java | 259 + .../taurus/permanent/normal/SocketReader.java | 233 + .../taurus/permanent/normal/SocketWriter.java | 278 + .../permanent/util/GhostUserHunter.java | 82 + .../websocket/UndertowWebSocketChannel.java | 56 + .../permanent/websocket/WebSocketService.java | 195 + .../test/java/com/taurus/T1Controller.java | 16 + .../test/java/com/taurus/T2Controller.java | 22 + .../test/java/com/taurus/TestExtension.java | 43 + taurus-server/pom.xml | 124 + .../taurus-core/config/log4j.properties | 20 + .../taurus-core/config/taurus-core.xml | 96 + taurus-server/taurus-core/pom.xml | 117 + .../java/com/taurus/core/entity/ITArray.java | 83 + .../java/com/taurus/core/entity/ITObject.java | 87 + .../java/com/taurus/core/entity/TArray.java | 226 + .../com/taurus/core/entity/TArrayLite.java | 28 + .../taurus/core/entity/TDataSerializer.java | 646 ++ .../com/taurus/core/entity/TDataType.java | 41 + .../com/taurus/core/entity/TDataWrapper.java | 30 + .../java/com/taurus/core/entity/TObject.java | 291 + .../com/taurus/core/entity/TObjectLite.java | 33 + .../java/com/taurus/core/events/Event.java | 60 + .../taurus/core/events/EventDispatcher.java | 93 + .../com/taurus/core/events/EventManager.java | 63 + .../taurus/core/events/IEventDispatcher.java | 40 + .../taurus/core/events/IEventListener.java | 14 + .../java/com/taurus/core/plugin/IPlugin.java | 23 + .../com/taurus/core/plugin/PluginService.java | 149 + .../taurus/core/plugin/database/DataBase.java | 62 + .../core/plugin/database/DataBasePlugin.java | 132 + .../com/taurus/core/plugin/database/Db.java | 807 +++ .../com/taurus/core/plugin/redis/Cache.java | 1220 ++++ .../com/taurus/core/plugin/redis/Redis.java | 70 + .../taurus/core/plugin/redis/RedisLock.java | 76 + .../taurus/core/plugin/redis/RedisPlugin.java | 141 + .../java/com/taurus/core/routes/Action.java | 68 + .../com/taurus/core/routes/ActionKey.java | 23 + .../com/taurus/core/routes/ActionMapping.java | 94 + .../com/taurus/core/routes/Extension.java | 57 + .../com/taurus/core/routes/IController.java | 11 + .../com/taurus/core/routes/Interceptor.java | 10 + .../java/com/taurus/core/routes/Routes.java | 155 + .../taurus/core/service/AbstractService.java | 48 + .../com/taurus/core/service/IService.java | 39 + .../java/com/taurus/core/util/Base64.java | 239 + .../java/com/taurus/core/util/ByteArray.java | 259 + .../java/com/taurus/core/util/DateUtils.java | 191 + .../java/com/taurus/core/util/FileUtil.java | 89 + .../core/util/FixedIndexThreadPool.java | 136 + .../java/com/taurus/core/util/ICallback.java | 13 + .../java/com/taurus/core/util/Logger.java | 214 + .../main/java/com/taurus/core/util/MD5.java | 48 + .../main/java/com/taurus/core/util/SHA1.java | 54 + .../java/com/taurus/core/util/StringUtil.java | 233 + .../main/java/com/taurus/core/util/Utils.java | 313 + .../com/taurus/core/util/json/JSONParser.java | 370 ++ .../com/taurus/core/util/json/JSONUtils.java | 15 + .../com/taurus/core/util/json/JSONWriter.java | 314 + .../taurus/core/util/task/ITaskHandler.java | 16 + .../java/com/taurus/core/util/task/Task.java | 45 + .../taurus/core/util/task/TaskScheduler.java | 139 + .../taurus-core/src/test/java/Test.java | 221 + .../taurus-permanent/config/log4j.properties | 20 + .../taurus-permanent/config/taurus-core.xml | 96 + .../config/taurus-permanent.xml | 75 + taurus-server/taurus-permanent/pom.xml | 36 + .../main/java/com/taurus/permanent/Main.java | 9 + .../java/com/taurus/permanent/TPServer.java | 319 + .../permanent/core/BaseCoreService.java | 46 + .../taurus/permanent/core/BitSwarmEngine.java | 337 + .../permanent/core/ConnectionFilter.java | 159 + .../permanent/core/DefaultConstants.java | 20 + .../permanent/core/IConnectionFilter.java | 61 + .../taurus/permanent/core/ServerConfig.java | 181 + .../taurus/permanent/core/ServerState.java | 11 + .../taurus/permanent/core/SessionManager.java | 313 + .../permanent/core/SystemController.java | 322 + .../com/taurus/permanent/core/TPEvents.java | 28 + .../taurus/permanent/data/BindableSocket.java | 37 + .../taurus/permanent/data/IPacketQueue.java | 66 + .../taurus/permanent/data/ISocketChannel.java | 21 + .../data/NonBlockingPacketQueue.java | 82 + .../taurus/permanent/data/PackDataType.java | 6 + .../com/taurus/permanent/data/Packet.java | 94 + .../com/taurus/permanent/data/Session.java | 467 ++ .../taurus/permanent/data/SessionType.java | 17 + .../taurus/permanent/io/BinaryIoHandler.java | 242 + .../com/taurus/permanent/io/IOHandler.java | 73 + .../taurus/permanent/io/PacketReadState.java | 21 + .../taurus/permanent/io/PendingPacket.java | 37 + .../taurus/permanent/io/ProcessedPacket.java | 23 + .../taurus/permanent/io/ProtocolHandler.java | 42 + .../permanent/normal/NormalSocketChannel.java | 71 + .../permanent/normal/SocketAcceptor.java | 259 + .../taurus/permanent/normal/SocketReader.java | 233 + .../taurus/permanent/normal/SocketWriter.java | 278 + .../permanent/util/GhostUserHunter.java | 82 + .../websocket/UndertowWebSocketChannel.java | 56 + .../permanent/websocket/WebSocketService.java | 195 + .../test/java/com/taurus/T1Controller.java | 16 + .../test/java/com/taurus/T2Controller.java | 22 + .../test/java/com/taurus/TestExtension.java | 43 + taurus-server/taurus-web/pom.xml | 38 + .../main/java/com/taurus/web/Controller.java | 133 + .../main/java/com/taurus/web/JettyServer.java | 157 + .../com/taurus/web/ServletHealthCheck.java | 23 + .../main/java/com/taurus/web/SessionInfo.java | 11 + .../java/com/taurus/web/StatusServlet.java | 66 + .../main/java/com/taurus/web/TWebServer.java | 233 + .../java/com/taurus/web/WebException.java | 17 + .../main/java/com/taurus/web/WebFilter.java | 72 + .../main/java/com/taurus/web/WebUtils.java | 42 + .../src/test/java/com/taurus/Test.java | 14 + web_group/build/local/taurus-core.xml | 100 + web_group/build/pro/bank_hp.lua | 19 + web_group/build/pro/log4j.properties | 20 + web_group/build/pro/mgr.lua | 25 + web_group/build/pro/take_hp.lua | 10 + web_group/build/pro/taurus-core.xml | 100 + web_group/build/pro/trade.lua | 12 + web_group/build/test/bank_hp.lua | 19 + web_group/build/test/log4j.properties | 20 + web_group/build/test/mgr.lua | 25 + web_group/build/test/take_hp.lua | 10 + web_group/build/test/taurus-core.xml | 100 + web_group/build/test/trade.lua | 12 + web_group/pom.xml | 118 + .../src/main/java/com/group/MainServer.java | 142 + .../src/main/java/com/group/Protocol.java | 279 + .../main/java/com/group/WebInterceptor.java | 241 + .../com/group/controller/GroupController.java | 1775 +++++ .../group/controller/GroupLogController.java | 804 +++ .../group/controller/GroupRoomController.java | 114 + .../java/com/group/job/UpdatePlayRoomJob.java | 889 +++ .../com/group/service/GroupLogService.java | 2722 ++++++++ .../group/service/GroupPublisherService.java | 328 + .../com/group/service/GroupRoomService.java | 1596 +++++ .../java/com/group/service/GroupService.java | 5908 +++++++++++++++++ web_group/src/main/webapp/WEB-INF/web.xml | 19 + web_group/src/main/webapp/config/bank_hp.lua | 19 + .../src/main/webapp/config/log4j.properties | 20 + web_group/src/main/webapp/config/mgr.lua | 25 + web_group/src/main/webapp/config/take_hp.lua | 10 + .../src/main/webapp/config/taurus-core.xml | 100 + web_group/src/main/webapp/config/trade.lua | 12 + web_group/src/test/java/etty-contexts.xml | 9 + .../test/java/web_group/DataClearUtils.java | 146 + .../src/test/java/web_group/MainWebGroup.java | 9 + web_login/.idea/artifacts/web_login_war.xml | 14 + .../artifacts/web_login_war_exploded.xml | 23 + web_login/.idea/compiler.xml | 16 + web_login/.idea/misc.xml | 14 + web_login/.idea/modules.xml | 8 + web_login/.idea/workspace.xml | 42 + web_login/build/adduser | 0 web_login/build/local/log4j.properties | 20 + web_login/build/local/taurus-core.xml | 96 + web_login/build/pro/log4j.properties | 20 + web_login/build/pro/taurus-core.xml | 96 + web_login/build/test/log4j.properties | 20 + web_login/build/test/taurus-core.xml | 96 + web_login/config/log4j.properties | 20 + web_login/config/taurus-core.xml | 96 + web_login/god | 0 web_login/pom.xml | 130 + .../src/main/java/com/mjlogin/MainServer.java | 73 + .../src/main/java/com/mjlogin/Protocol.java | 78 + .../main/java/com/mjlogin/WebInterceptor.java | 56 + .../com/mjlogin/service/AccountService.java | 1625 +++++ .../com/mjlogin/service/IndexService.java | 69 + .../com/mjlogin/service/MilitaryService.java | 118 + .../java/com/mjlogin/service/RoomService.java | 338 + .../java/com/mjlogin/util/sms/RedisKey.java | 8 + .../java/com/mjlogin/util/sms/SMSThread.java | 64 + .../com/mjlogin/util/sms/SMSVerification.java | 120 + web_login/src/main/webapp/WEB-INF/web.xml | 19 + .../src/main/webapp/config/log4j.properties | 20 + .../src/main/webapp/config/taurus-core.xml | 96 + .../src/test/java/web_login/MainWebLogin.java | 9 + 461 files changed, 70261 insertions(+) create mode 100644 data_cache/config/log4j.properties create mode 100644 data_cache/config/mpnet-tools.xml create mode 100644 data_cache/pom.xml create mode 100644 data_cache/src/main/java/com/data/bean/AccountBean.java create mode 100644 data_cache/src/main/java/com/data/bean/BaseBean.java create mode 100644 data_cache/src/main/java/com/data/bean/GameBean.java create mode 100644 data_cache/src/main/java/com/data/bean/GroupBean.java create mode 100644 data_cache/src/main/java/com/data/bean/GroupMemberBean.java create mode 100644 data_cache/src/main/java/com/data/bean/GroupPlayBean.java create mode 100644 data_cache/src/main/java/com/data/cache/AccountCache.java create mode 100644 data_cache/src/main/java/com/data/cache/BaseCache.java create mode 100644 data_cache/src/main/java/com/data/cache/GameCache.java create mode 100644 data_cache/src/main/java/com/data/cache/GroupCache.java create mode 100644 data_cache/src/main/java/com/data/cache/GroupMemberCache.java create mode 100644 data_cache/src/main/java/com/data/cache/GroupPlayCache.java create mode 100644 data_cache/src/main/java/com/data/util/ConsumeCode.java create mode 100644 data_cache/src/main/java/com/data/util/CountUtil.java create mode 100644 data_cache/src/main/java/com/data/util/ErrorCode.java create mode 100644 data_cache/src/main/java/com/data/util/EventType.java create mode 100644 data_cache/src/main/java/com/data/util/Utility.java create mode 100644 event_mgr/build/local/taurus-core.xml create mode 100644 event_mgr/build/pro/log4j.properties create mode 100644 event_mgr/build/pro/taurus-core.xml create mode 100644 event_mgr/build/test/log4j.properties create mode 100644 event_mgr/build/test/taurus-core.xml create mode 100644 event_mgr/pom.xml create mode 100644 event_mgr/src/main/java/com/evt/mgr/EventController.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/EventReceiver.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/EventServer.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/GroupPublisherService.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/IHandler.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/Utils.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupMemberRound.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupRound.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerHpConsume.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerLose.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerOver.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerPay.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/handler/HandlerWin.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/job/CleanGroupLogJob.java create mode 100644 event_mgr/src/main/java/com/evt/mgr/job/CleanTimeOutRoomJob.java create mode 100644 event_mgr/src/main/webapp/WEB-INF/web.xml create mode 100644 event_mgr/src/main/webapp/config/log4j.properties create mode 100644 event_mgr/src/main/webapp/config/taurus-core.xml create mode 100644 event_mgr/src/test/java/MainEventMgr.java create mode 100644 game_common/.idea/compiler.xml create mode 100644 game_common/.idea/encodings.xml create mode 100644 game_common/.idea/jarRepositories.xml create mode 100644 game_common/.idea/misc.xml create mode 100644 game_common/.idea/vcs.xml create mode 100644 game_common/pom.xml create mode 100644 game_common/src/main/java/com/game/ActionEvent.java create mode 100644 game_common/src/main/java/com/game/Constant.java create mode 100644 game_common/src/main/java/com/game/EventController.java create mode 100644 game_common/src/main/java/com/game/GPSUtil.java create mode 100644 game_common/src/main/java/com/game/GameController.java create mode 100644 game_common/src/main/java/com/game/GameInterceptor.java create mode 100644 game_common/src/main/java/com/game/Global.java create mode 100644 game_common/src/main/java/com/game/GroupPublisherService.java create mode 100644 game_common/src/main/java/com/game/MainServer.java create mode 100644 game_common/src/main/java/com/game/Router.java create mode 100644 game_common/src/main/java/com/game/Util.java create mode 100644 game_common/src/main/java/com/game/data/BasePlayBack.java create mode 100644 game_common/src/main/java/com/game/data/Hp.java create mode 100644 game_common/src/main/java/com/game/data/JoinRoomData.java create mode 100644 game_common/src/main/java/com/game/data/Player.java create mode 100644 game_common/src/main/java/com/game/data/Room.java create mode 100644 game_common/src/main/java/com/game/data/RoomDismiss.java create mode 100644 game_common/src/main/java/com/game/data/Score.java create mode 100644 game_common/src/main/java/com/game/data/Timer.java create mode 100644 game_common/src/main/java/com/game/manager/RoomManager.java create mode 100644 game_common/src/main/java/com/game/manager/SessionManager.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerEndState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerInitState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerPauseState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerPopupState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerReadyState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerReloadState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerSpectatorState.java create mode 100644 game_common/src/main/java/com/game/player/state/PlayerWaitState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomDestoryGameState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomEndState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomInitState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomReloadState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomStartGameState.java create mode 100644 game_common/src/main/java/com/game/room/state/RoomWaitState.java create mode 100644 game_common/src/main/java/com/game/state/StateBase.java create mode 100644 game_common/src/main/java/com/game/state/StateMachine.java create mode 100644 game_mj_hongzhong/config/game-config.xml create mode 100644 game_mj_hongzhong/config/log4j.properties create mode 100644 game_mj_hongzhong/config/taurus-core.xml create mode 100644 game_mj_hongzhong/config/taurus-permanent.xml create mode 100644 game_mj_hongzhong/pom.xml create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/CardNiao.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/Config.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXActionEvent.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXGameController.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXMainServer.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXPlayBack.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXPlayer.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXRoom.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/EXScore.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/OpCard.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/PlayerRuleManager.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/RoomCard.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/RuleWeight.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/SettleLog.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherKong.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherWin.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePong.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePongKong.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfKong.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfWin.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherKongState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherWinState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongKongState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfKongState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfWinState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDisCardTipState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDiscardState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawTipState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerKongWinState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerPiaoNiaoTipState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerTipState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitKongWinState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomDealState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomSetpState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomStartGameState.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/tip/Action.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/tip/IRuleBase.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/tip/Tip.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/tip/TipManager.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/uitl/CardUtil.java create mode 100644 game_mj_hongzhong/src/main/java/extend/mj/uitl/WinCard.java create mode 100644 game_mj_hongzhong/src/test/java/game_mj_hongzhong/MainHongzhong.java create mode 100644 game_pk_duoduo/.idea/compiler.xml create mode 100644 game_pk_duoduo/.idea/encodings.xml create mode 100644 game_pk_duoduo/.idea/jarRepositories.xml create mode 100644 game_pk_duoduo/.idea/misc.xml create mode 100644 game_pk_duoduo/.idea/vcs.xml create mode 100644 game_pk_duoduo/config/game-config.xml create mode 100644 game_pk_duoduo/config/log4j.properties create mode 100644 game_pk_duoduo/config/taurus-core.xml create mode 100644 game_pk_duoduo/config/taurus-permanent.xml create mode 100644 game_pk_duoduo/pom.xml create mode 100644 game_pk_duoduo/src/main/java/extend/pk/CardGroup.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/CardObj.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/Config.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXActionEvent.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXGameController.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXMainServer.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXPlayBack.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXPlayer.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXRoom.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/EXScore.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/RoomCard.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/SettleLog.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerPassState.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomDealState.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomSetpState.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomStartGameState.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/uitl/CardCheck.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/uitl/CardConfig.java create mode 100644 game_pk_duoduo/src/main/java/extend/pk/uitl/CardUtil.java create mode 100644 game_pk_duoduo/src/test/java/game_pk_paodekuai/MainPaodekuai.java create mode 100644 game_pk_paodekuai/.idea/compiler.xml create mode 100644 game_pk_paodekuai/.idea/encodings.xml create mode 100644 game_pk_paodekuai/.idea/jarRepositories.xml create mode 100644 game_pk_paodekuai/.idea/misc.xml create mode 100644 game_pk_paodekuai/.idea/vcs.xml create mode 100644 game_pk_paodekuai/config/game-config.xml create mode 100644 game_pk_paodekuai/config/log4j.properties create mode 100644 game_pk_paodekuai/config/taurus-core.xml create mode 100644 game_pk_paodekuai/config/taurus-permanent.xml create mode 100644 game_pk_paodekuai/pom.xml create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/CardGroup.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/CardObj.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/Config.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXActionEvent.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXGameController.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXMainServer.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXPlayBack.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXPlayer.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXRoom.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/EXScore.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/RoomCard.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/SettleLog.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPassState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPiaoNiaoTipState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomDealState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomPiaoState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomSetpState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomStartGameState.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/uitl/CardCheck.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/uitl/CardConfig.java create mode 100644 game_pk_paodekuai/src/main/java/extend/pk/uitl/CardUtil.java create mode 100644 game_pk_paodekuai/src/test/java/game_pk_paodekuai/MainPaodekuai.java create mode 100644 group_mgr/build/local/log4j.properties create mode 100644 group_mgr/build/local/mgr-config.xml create mode 100644 group_mgr/build/local/taurus-core.xml create mode 100644 group_mgr/build/local/taurus-permanent.xml create mode 100644 group_mgr/build/pro/log4j.properties create mode 100644 group_mgr/build/pro/mgr-config.xml create mode 100644 group_mgr/build/pro/taurus-core.xml create mode 100644 group_mgr/build/pro/taurus-permanent.xml create mode 100644 group_mgr/build/test/log4j.properties create mode 100644 group_mgr/build/test/mgr-config.xml create mode 100644 group_mgr/build/test/taurus-core.xml create mode 100644 group_mgr/build/test/taurus-permanent.xml create mode 100644 group_mgr/pom.xml create mode 100644 group_mgr/src/main/java/com/mgr/group/Config.java create mode 100644 group_mgr/src/main/java/com/mgr/group/Global.java create mode 100644 group_mgr/src/main/java/com/mgr/group/GroupController.java create mode 100644 group_mgr/src/main/java/com/mgr/group/GroupSubscriber.java create mode 100644 group_mgr/src/main/java/com/mgr/group/MainServer.java create mode 100644 group_mgr/src/main/java/com/mgr/group/Router.java create mode 100644 group_mgr/src/main/java/com/mgr/group/SessionManager.java create mode 100644 group_mgr/src/main/java/com/mgr/group/WebMain.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/CommandData.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/Group.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/Player.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/PlayerCache.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/Room.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/RoomCache.java create mode 100644 group_mgr/src/main/java/com/mgr/group/data/User.java create mode 100644 group_mgr/src/main/webapp/WEB-INF/web.xml create mode 100644 group_mgr/src/main/webapp/config/log4j.properties create mode 100644 group_mgr/src/main/webapp/config/mgr-config.xml create mode 100644 group_mgr/src/main/webapp/config/taurus-core.xml create mode 100644 group_mgr/src/main/webapp/config/taurus-permanent.xml create mode 100644 group_mgr/src/test/java/group_room_mgr/MainGroupMgr.java create mode 100644 pack_tools/pom.xml create mode 100644 pack_tools/src/main/java/com/pack/MainServer.java create mode 100644 pack_tools/src/main/java/com/pack/Utils.java create mode 100644 pack_tools/src/main/java/com/pack/service/CommandService.java create mode 100644 pack_tools/src/main/java/com/pack/service/PackServerProject.java create mode 100644 pack_tools/src/main/java/com/pack/service/PackUtilService.java create mode 100644 pack_tools/src/main/java/com/pack/service/ServletAllGame.java create mode 100644 pack_tools/src/main/webapp/WEB-INF/web.xml create mode 100644 pack_tools/src/main/webapp/config/log4j.properties create mode 100644 pack_tools/src/main/webapp/config/mpnet-tools.xml create mode 100644 pack_tools/src/main/webapp/config/pack-config.xml create mode 100644 pack_tools/src/main/webapp/config/taurus-core.xml create mode 100644 pack_tools/src/test/java/pack_tools/Main.java create mode 100644 pack_tools/src/test/java/pack_tools/TT.java create mode 100644 taurus-permanent/config/log4j.properties create mode 100644 taurus-permanent/config/taurus-core.xml create mode 100644 taurus-permanent/config/taurus-permanent.xml create mode 100644 taurus-permanent/pom.xml create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/Main.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java create mode 100644 taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java create mode 100644 taurus-permanent/src/test/java/com/taurus/T1Controller.java create mode 100644 taurus-permanent/src/test/java/com/taurus/T2Controller.java create mode 100644 taurus-permanent/src/test/java/com/taurus/TestExtension.java create mode 100644 taurus-server/pom.xml create mode 100644 taurus-server/taurus-core/config/log4j.properties create mode 100644 taurus-server/taurus-core/config/taurus-core.xml create mode 100644 taurus-server/taurus-core/pom.xml create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITArray.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITObject.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArray.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArrayLite.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataSerializer.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataType.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataWrapper.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObject.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObjectLite.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/events/Event.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventDispatcher.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventManager.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventDispatcher.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventListener.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/IPlugin.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/PluginService.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBase.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBasePlugin.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/Db.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Cache.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Redis.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisLock.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisPlugin.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Action.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionKey.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionMapping.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Extension.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/IController.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Interceptor.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Routes.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/service/AbstractService.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/service/IService.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/Base64.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/ByteArray.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/DateUtils.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/FileUtil.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/FixedIndexThreadPool.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/ICallback.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/Logger.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/MD5.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/SHA1.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/StringUtil.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/Utils.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONParser.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONUtils.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONWriter.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/ITaskHandler.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/Task.java create mode 100644 taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/TaskScheduler.java create mode 100644 taurus-server/taurus-core/src/test/java/Test.java create mode 100644 taurus-server/taurus-permanent/config/log4j.properties create mode 100644 taurus-server/taurus-permanent/config/taurus-core.xml create mode 100644 taurus-server/taurus-permanent/config/taurus-permanent.xml create mode 100644 taurus-server/taurus-permanent/pom.xml create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/Main.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java create mode 100644 taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java create mode 100644 taurus-server/taurus-permanent/src/test/java/com/taurus/T1Controller.java create mode 100644 taurus-server/taurus-permanent/src/test/java/com/taurus/T2Controller.java create mode 100644 taurus-server/taurus-permanent/src/test/java/com/taurus/TestExtension.java create mode 100644 taurus-server/taurus-web/pom.xml create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/Controller.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/JettyServer.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/ServletHealthCheck.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/SessionInfo.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/StatusServlet.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/TWebServer.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/WebException.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/WebFilter.java create mode 100644 taurus-server/taurus-web/src/main/java/com/taurus/web/WebUtils.java create mode 100644 taurus-server/taurus-web/src/test/java/com/taurus/Test.java create mode 100644 web_group/build/local/taurus-core.xml create mode 100644 web_group/build/pro/bank_hp.lua create mode 100644 web_group/build/pro/log4j.properties create mode 100644 web_group/build/pro/mgr.lua create mode 100644 web_group/build/pro/take_hp.lua create mode 100644 web_group/build/pro/taurus-core.xml create mode 100644 web_group/build/pro/trade.lua create mode 100644 web_group/build/test/bank_hp.lua create mode 100644 web_group/build/test/log4j.properties create mode 100644 web_group/build/test/mgr.lua create mode 100644 web_group/build/test/take_hp.lua create mode 100644 web_group/build/test/taurus-core.xml create mode 100644 web_group/build/test/trade.lua create mode 100644 web_group/pom.xml create mode 100644 web_group/src/main/java/com/group/MainServer.java create mode 100644 web_group/src/main/java/com/group/Protocol.java create mode 100644 web_group/src/main/java/com/group/WebInterceptor.java create mode 100644 web_group/src/main/java/com/group/controller/GroupController.java create mode 100644 web_group/src/main/java/com/group/controller/GroupLogController.java create mode 100644 web_group/src/main/java/com/group/controller/GroupRoomController.java create mode 100644 web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java create mode 100644 web_group/src/main/java/com/group/service/GroupLogService.java create mode 100644 web_group/src/main/java/com/group/service/GroupPublisherService.java create mode 100644 web_group/src/main/java/com/group/service/GroupRoomService.java create mode 100644 web_group/src/main/java/com/group/service/GroupService.java create mode 100644 web_group/src/main/webapp/WEB-INF/web.xml create mode 100644 web_group/src/main/webapp/config/bank_hp.lua create mode 100644 web_group/src/main/webapp/config/log4j.properties create mode 100644 web_group/src/main/webapp/config/mgr.lua create mode 100644 web_group/src/main/webapp/config/take_hp.lua create mode 100644 web_group/src/main/webapp/config/taurus-core.xml create mode 100644 web_group/src/main/webapp/config/trade.lua create mode 100644 web_group/src/test/java/etty-contexts.xml create mode 100644 web_group/src/test/java/web_group/DataClearUtils.java create mode 100644 web_group/src/test/java/web_group/MainWebGroup.java create mode 100644 web_login/.idea/artifacts/web_login_war.xml create mode 100644 web_login/.idea/artifacts/web_login_war_exploded.xml create mode 100644 web_login/.idea/compiler.xml create mode 100644 web_login/.idea/misc.xml create mode 100644 web_login/.idea/modules.xml create mode 100644 web_login/.idea/workspace.xml create mode 100644 web_login/build/adduser create mode 100644 web_login/build/local/log4j.properties create mode 100644 web_login/build/local/taurus-core.xml create mode 100644 web_login/build/pro/log4j.properties create mode 100644 web_login/build/pro/taurus-core.xml create mode 100644 web_login/build/test/log4j.properties create mode 100644 web_login/build/test/taurus-core.xml create mode 100644 web_login/config/log4j.properties create mode 100644 web_login/config/taurus-core.xml create mode 100644 web_login/god create mode 100644 web_login/pom.xml create mode 100644 web_login/src/main/java/com/mjlogin/MainServer.java create mode 100644 web_login/src/main/java/com/mjlogin/Protocol.java create mode 100644 web_login/src/main/java/com/mjlogin/WebInterceptor.java create mode 100644 web_login/src/main/java/com/mjlogin/service/AccountService.java create mode 100644 web_login/src/main/java/com/mjlogin/service/IndexService.java create mode 100644 web_login/src/main/java/com/mjlogin/service/MilitaryService.java create mode 100644 web_login/src/main/java/com/mjlogin/service/RoomService.java create mode 100644 web_login/src/main/java/com/mjlogin/util/sms/RedisKey.java create mode 100644 web_login/src/main/java/com/mjlogin/util/sms/SMSThread.java create mode 100644 web_login/src/main/java/com/mjlogin/util/sms/SMSVerification.java create mode 100644 web_login/src/main/webapp/WEB-INF/web.xml create mode 100644 web_login/src/main/webapp/config/log4j.properties create mode 100644 web_login/src/main/webapp/config/taurus-core.xml create mode 100644 web_login/src/test/java/web_login/MainWebLogin.java diff --git a/data_cache/config/log4j.properties b/data_cache/config/log4j.properties new file mode 100644 index 0000000..60b65bc --- /dev/null +++ b/data_cache/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/evt_mgr.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/data_cache/config/mpnet-tools.xml b/data_cache/config/mpnet-tools.xml new file mode 100644 index 0000000..0fc606d --- /dev/null +++ b/data_cache/config/mpnet-tools.xml @@ -0,0 +1,93 @@ + + + + + + 80 + + 2 + + 10 + + -1 + + true + + true + + true + + select 1 + + 180000 + + 60000 + + 30000 + + false + + 300000 + + false + + -1 + + + + + db1 + com.mysql.jdbc.Driver + jdbc:mysql://127.0.0.1:8060/wb_game + root + root + + + + + + + + 80 + + 8 + + 2 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + \ No newline at end of file diff --git a/data_cache/pom.xml b/data_cache/pom.xml new file mode 100644 index 0000000..33adc3c --- /dev/null +++ b/data_cache/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + + com.data + data_cache + 1.0.1 + jar + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 3.8.1 + test + + + + + com.taurus + taurus-core + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + log4j + log4j + 1.2.17 + + + + + data_cache + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + UTF-8 + + + + + + diff --git a/data_cache/src/main/java/com/data/bean/AccountBean.java b/data_cache/src/main/java/com/data/bean/AccountBean.java new file mode 100644 index 0000000..5976064 --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/AccountBean.java @@ -0,0 +1,37 @@ +package com.data.bean; + +import java.util.Map; + +import com.taurus.core.util.StringUtil; + + +/** + * account bean class + * + */ +public class AccountBean extends BaseBean{ + + public String nick; + public String portrait; + public int type; + public int mng; + public int sex; + public String ip; + + public void fillData(Map redis_map) { + String _id = redis_map.get("id"); + if(StringUtil.isEmpty(_id)) { + this.del = true; + return; + } + this.id =Integer.parseInt(_id); + this.nick = redis_map.get("nick"); + this.portrait = redis_map.get("portrait"); + this.ip = redis_map.get("ip"); + this.type = Integer.parseInt(redis_map.get("type")); + this.sex = Integer.parseInt(redis_map.get("sex")); + if(this.sex == 0)this.sex = 1; + } + + +} diff --git a/data_cache/src/main/java/com/data/bean/BaseBean.java b/data_cache/src/main/java/com/data/bean/BaseBean.java new file mode 100644 index 0000000..f36ec34 --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/BaseBean.java @@ -0,0 +1,34 @@ +package com.data.bean; + +import java.util.Map; + +/** + * base bean class. + */ +public class BaseBean { + /** + * id + */ + public int id; + /** + * redis key + */ + public String redis_key; + /** + * cache version. + */ + public volatile long cache_ver; + + /** + * cache last time. + */ + public volatile long cache_time; + /** + * 标记是否删除 + */ + public volatile boolean del; + + public void fillData(Map map) { + + } +} diff --git a/data_cache/src/main/java/com/data/bean/GameBean.java b/data_cache/src/main/java/com/data/bean/GameBean.java new file mode 100644 index 0000000..cef648f --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/GameBean.java @@ -0,0 +1,105 @@ +package com.data.bean; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; + + + +/** + * game bean class. + * + */ +public class GameBean extends BaseBean{ + + /** + * name + */ + public String name; + /** + * 最大人数 + */ + public int maxPlayers; + /** + * 体力值类型 + */ + public int hpType; + /** + * 包名 + */ + public String bundle; + /** + * 局数设置 + */ + public Map opt; + /** + * 版本 + */ + public String version; + + public int gameType; + + /** + * 服务器列表 + */ + public Set svr_list; + /** + * 支付设置 + */ + public Map pay; + /**不可负分*/ + public int isNonnegative ; + + + + public void fillData(Map redis_map) { +// Map redis_map = jedis.hgetAll(redis_key); + if(redis_map.isEmpty()) { + this.del = true; + return; + } + this.id = Integer.parseInt(redis_map.get("id")); + this.name = redis_map.get("name"); + this.bundle = redis_map.get("bundle"); + this.maxPlayers =Integer.parseInt(redis_map.get("maxPlayers")); + this.hpType =Integer.parseInt(redis_map.get("hpType")); + this.opt = new HashMap<>(); + for(int i=1;i<=5;++i) { + String key = "opt"+i; + this.opt.put(i, Integer.parseInt(redis_map.get(key))); + } + this.version = redis_map.get("version"); + this.gameType =Integer.parseInt( redis_map.get("gameType")); + this.isNonnegative = Integer.parseInt(redis_map.get("isNonnegative")); + this.svr_list = Redis.use("group1_db1").smembers("game_svr:" + id); + + this.pay = new HashMap<>(); + for (Entry entry : redis_map.entrySet()) { + String key = entry.getKey(); + if(key.startsWith("pay")) { + this.pay.put(key, Integer.parseInt(entry.getValue())); + } + } + } + + public ITObject getTObject() { + ITObject obj = TObject.newInstance(); + obj.putInt("game_id", id); + obj.putString("name", name); + obj.putString("bundle", bundle); + obj.putInt("hpType", hpType); + obj.putString("version", version); + obj.putInt("gameType", gameType); + obj.putInt("isNonnegative", isNonnegative); + return obj; + } + + public static String genKey(int gid) { + return "game:" + gid; + } +} diff --git a/data_cache/src/main/java/com/data/bean/GroupBean.java b/data_cache/src/main/java/com/data/bean/GroupBean.java new file mode 100644 index 0000000..3918807 --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/GroupBean.java @@ -0,0 +1,113 @@ +package com.data.bean; + +import java.util.Map; + +import com.data.cache.GroupMemberCache; +import com.data.cache.GroupPlayCache; +import com.taurus.core.util.Logger; + +public class GroupBean extends BaseBean { + + private final static Logger log; + + static { + log = Logger.getLogger(GroupBean.class); + } + /** + * name + */ + public String name; + public int owner; + public int type; + public int create_time; + public int ban; + public int gms; + public int pay_type; + public int stop; + public int ban_apply; + public int dissolve_opt; + public int kick_opt; + public boolean ban_chat1; + public boolean ban_chat2; + public int exit_opt; + public int option; + public int show_num; + public GroupMemberCache memberCache; + + public GroupPlayCache playCache; + public int isShow; + public int isOpenChatRoom; + public int isShowBeginRoom = 0; + + // 微信号 + public String wechatId; + + public int isWatch; + + public void fillData(Map map) { + if (map.isEmpty()) { + this.del = true; + return; + } + int opt = Integer.parseInt(map.get("opt")); + if (opt != 1) { + this.del = true; + return; + } + this.id = Integer.parseInt(map.get("id")); + this.name = map.get("name"); + this.type = Integer.parseInt(map.get("type")); + this.create_time = Integer.parseInt(map.get("create_time")); + this.ban = Integer.parseInt(map.get("ban")); + this.gms = Integer.parseInt(map.get("gms")); + this.owner = Integer.parseInt(map.get("owner")); + this.pay_type = Integer.parseInt(map.get("pay_type")); + this.wechatId = map.get("wechatId"); +// this.messageCount =map.get("messageCount"); + if (map.containsKey("wechatId")) { + this.wechatId = map.get("wechatId"); + } + + if (map.containsKey("isOpenChatRoom")) { + this.isOpenChatRoom = Integer.parseInt(map.get("isOpenChatRoom")); + } + if (map.containsKey("isShowBeginRoom")) { + this.isShowBeginRoom = Integer.parseInt(map.get("isShowBeginRoom")); + } + + if (map.containsKey("isWatch")) { + this.isWatch = Integer.parseInt(map.get("isWatch")); + } + + if (map.containsKey("isShow")) { + this.isShow = Integer.parseInt(map.get("isShow")); + } + + if (map.containsKey("stop")) { + this.stop = Integer.parseInt(map.get("stop")); + } + if (map.containsKey("ban_apply")) { + this.ban_apply = Integer.parseInt(map.get("ban_apply")); + } + kick_opt = Integer.parseInt(map.get("kick_opt")); + dissolve_opt = Integer.parseInt(map.get("dissolve_opt")); + if (map.containsKey("ban_chat1")) { + this.ban_chat1 = Boolean.parseBoolean(map.get("ban_chat1")); + } + if (map.containsKey("ban_chat2")) { + this.ban_chat2 = Boolean.parseBoolean(map.get("ban_chat2")); + } + if (map.containsKey("exit_opt")) { + this.exit_opt = Integer.parseInt(map.get("exit_opt")); + } + + if (map.containsKey("option")) { + this.option = Integer.parseInt(map.get("option")); + } + + if (map.containsKey("show_num")) { + this.show_num = Integer.parseInt(map.get("show_num")); + } + + } +} diff --git a/data_cache/src/main/java/com/data/bean/GroupMemberBean.java b/data_cache/src/main/java/com/data/bean/GroupMemberBean.java new file mode 100644 index 0000000..5755a5a --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/GroupMemberBean.java @@ -0,0 +1,50 @@ +package com.data.bean; + +import java.util.Map; + +public class GroupMemberBean extends BaseBean{ + public int groupId; + public int parentId; + public int partnerLev; + public int lev; + public int ban; + public int top_time; + public int join_time; + public int last_time; + public int permission; + public int score; + public int mj_score; + public int pk_score; + public GroupMemberBean(int gid) { + this.groupId = gid; + } + + public void fillData(Map map) { + if(map.isEmpty()) { + this.del = true; + return; + } + int opt = Integer.parseInt(map.get("opt")); + if(opt!=1) { + this.del = true; + return; + } + this.id = Integer.parseInt(map.get("uid")); + this.parentId = Integer.parseInt(map.get("parentId")); + this.partnerLev = Integer.parseInt(map.get("partnerLev")); + this.lev = Integer.parseInt(map.get("lev")); + this.ban = Integer.parseInt(map.get("ban")); + this.top_time = Integer.parseInt(map.get("top_time")); + this.join_time = Integer.parseInt(map.get("join_time")); + if(map.containsKey("last_time")) { + this.last_time = Integer.parseInt(map.get("last_time")); + } + if(map.containsKey("permission")) { + this.permission = Integer.parseInt(map.get("permission")); + } + if(map.containsKey("score")) { + this.score = Integer.parseInt(map.get("score")); + } + + } +} diff --git a/data_cache/src/main/java/com/data/bean/GroupPlayBean.java b/data_cache/src/main/java/com/data/bean/GroupPlayBean.java new file mode 100644 index 0000000..c7a5d9e --- /dev/null +++ b/data_cache/src/main/java/com/data/bean/GroupPlayBean.java @@ -0,0 +1,141 @@ +package com.data.bean; + +import java.util.Map; + +import com.data.cache.GameCache; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +public class GroupPlayBean extends BaseBean { + public ITObject data = null; + public ITObject simp_data = null; + public int pay_type; + public int gameType; + public int gameId; + public int maxPlayers; + public String config; + public String hpConfig; + public int hp_times; + public int hpOnOff; + public int ban; + public boolean mark; + public String name; + public int deskId; + public int reward; + public int xipai_reward; + public int rewardType; + public int rewardValueType; + public int xipai_rewardType; + public int xipai_rewardValueType; + public int robot_room; + public ITObject configData; + + public int BanChat; + public int BanMissile; + + + + + + public void fillData(Map map) { + if(!map.get("opt").equals("1")) { + this.del = true; + return; + } + ITObject obj = data; + if(obj==null) { + obj = TObject.newInstance(); + this.data = obj; + } + this.id = Integer.parseInt(map.get("id")); + this.name = map.get("name"); + this.gameId = Integer.parseInt(map.get("gameId")); + this.config = map.get("config"); + this.hpConfig = map.get("hpData"); + this.hpOnOff = Integer.parseInt(map.get("hpOnOff")); + this.hp_times = Integer.parseInt(map.get("hp_times")); + this.ban = map.containsKey("ban") ? Integer.parseInt(map.get("ban")) : 0; + + + + int iMark = map.containsKey("mark") ? Integer.parseInt(map.get("mark")) : 0; + this.mark = iMark==1 ? true : false; + + this.reward = Integer.parseInt(map.get("reward")); + this.xipai_reward = 100000000; + if(map.get("xipai_reward") != null) { + this.xipai_reward = Integer.parseInt(map.get("xipai_reward")); + } + this.rewardType = Integer.parseInt(map.get("rewardType")); + this.rewardValueType = 1; + if(map.get("rewardValueType") != null) { + this.rewardValueType = Integer.parseInt(map.get("rewardValueType")); + } + + this.xipai_rewardType = 1; + if(map.get("xipai_rewardType") != null) { + this.xipai_rewardType = Integer.parseInt(map.get("xipai_rewardType")); + } + + this.xipai_rewardValueType = 1; + if(map.get("xipai_rewardValueType") != null) { + this.xipai_rewardValueType = Integer.parseInt(map.get("xipai_rewardValueType")); + } + + this.robot_room = 0; + if(map.get("robot_room") != null) { + this.robot_room = Integer.parseInt(map.get("robot_room")); + } + if(map.get("deskId") != null) { + this.deskId = Integer.parseInt(map.get("deskId")); + } + + if (map.get("BanMissile") != null){ + this.BanMissile = Integer.parseInt(map.get("BanMissile")); + } + + if (map.get("BanChat") != null){ + this.BanChat = Integer.parseInt(map.get("BanChat")); + } + + obj.putInt("id", this.id); + obj.putString("name", this.name); + obj.putInt("gameId", gameId); + obj.putInt("deskId", this.deskId); + obj.putString("config", config); + obj.putString("hpData", hpConfig); + obj.putInt("hp_times", hp_times); + obj.putInt("hpOnOff", hpOnOff); + obj.putInt("reward", reward); + obj.putInt("xipai_reward", xipai_reward); + obj.putInt("rewardType", rewardType); + obj.putInt("rewardValueType", rewardValueType); + obj.putInt("xipai_rewardType", xipai_rewardType); + obj.putInt("xipai_rewardValueType", xipai_rewardValueType); + obj.putInt("ban", ban); + obj.putBoolean("mark", mark); + + GameBean gb = GameCache.getGame(gameId); + obj.putString("game_name", gb.name); + + + + configData = TObject.newFromJsonData(map.get("config")); + maxPlayers = gb.maxPlayers; + if(configData.containsKey("maxPlayers")) { + maxPlayers = configData.getInt("maxPlayers"); + } + obj.putInt("maxPlayers", maxPlayers); + + if(simp_data==null) { + simp_data = TObject.newInstance(); + } + + simp_data.putInt("gameId", gameId); + simp_data.putInt("id", this.id); + simp_data.putInt("hpOnOff", obj.getInt("hpOnOff")); + simp_data.putInt("maxPlayers", maxPlayers); + simp_data.putString("name", obj.getString("name")); + simp_data.putInt("deskId", this.deskId); + } +} diff --git a/data_cache/src/main/java/com/data/cache/AccountCache.java b/data_cache/src/main/java/com/data/cache/AccountCache.java new file mode 100644 index 0000000..d6b7ca0 --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/AccountCache.java @@ -0,0 +1,43 @@ +package com.data.cache; + +import com.data.bean.AccountBean; +import com.data.bean.BaseBean; + +/** + * account cache class. + */ +public class AccountCache extends BaseCache{ + + protected AccountCache() { + super("{user}:","group1_db0"); + } + + + static AccountCache inst; + + + public static AccountBean getAccount(int id) { + if(inst==null)inst = new AccountCache(); + return inst.getBean(id); + } + + public static AccountBean getAccount(String session) { + if(inst==null)inst = new AccountCache(); + return inst.getBean(session); + } + + + @Override + protected BaseBean newBean() { + return new AccountBean(); + } + + public static void clearData() { + if(inst==null)inst = new AccountCache(); + inst.clearExpireData(); + } + + public static String genKey(int gid) { + return "{user}:" + gid; + } +} diff --git a/data_cache/src/main/java/com/data/cache/BaseCache.java b/data_cache/src/main/java/com/data/cache/BaseCache.java new file mode 100644 index 0000000..0cb1ffc --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/BaseCache.java @@ -0,0 +1,229 @@ +package com.data.cache; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.data.bean.BaseBean; +import com.data.bean.GroupBean; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; + +/** + * base cache class. + * + */ +public abstract class BaseCache { + private final static Logger log; + + static { + log = Logger.getLogger(BaseCache.class); + } + private static final String VER_KEY= "cache_ver"; + private static final String MAIN_KEY= "id"; + protected ConcurrentMap mapByKey = new ConcurrentHashMap<>(); + protected ConcurrentMap mapById = new ConcurrentHashMap<>(); + protected String key; + protected String cacheKey; + protected int fillSize; + /**默认1秒*/ + protected int readTime = 1000; + + protected BaseCache(String key,String cacheKey) { + this.key = key; + this.cacheKey = cacheKey; + } + + private long readVersion(String str_ver) { + if(StringUtil.isEmpty(str_ver)) { + return -1; + } + int cache_ver = Integer.parseInt(str_ver); + return cache_ver; + } + + /** + * 版本KEY更新 + * @param jedis + * @param key + */ + public static void updateCacheVer(Jedis jedis,String key) { + jedis.hincrBy(key, VER_KEY, 1); + } + + /** + * new bean class + * @return + */ + protected abstract BaseBean newBean(); + + /** + * 主键KEY + * @return + */ + protected String mainKey() { + return MAIN_KEY; + } + + protected BaseBean fillBean(BaseBean bean){ + Jedis jedis = Redis.use(cacheKey).getJedis(); + try { + String str_ver = null; + long cache_ver = -1; + if(System.currentTimeMillis() - bean.cache_time >= readTime) { + List list = jedis.hmget(bean.redis_key, mainKey(),VER_KEY); + if(StringUtil.isEmpty(list.get(0))) { + bean.del = true; + }else { + str_ver = list.get(1); + cache_ver = readVersion(str_ver); + if(bean.cache_ver > 0 && cache_ver==-1) { + cache_ver = bean.cache_ver; + } + + bean.cache_time = System.currentTimeMillis(); + } + }else { + cache_ver = bean.cache_ver; + } + + if(!bean.del && (cache_ver == -1 || bean.cache_ver < cache_ver)) { + Map map = jedis.hgetAll(bean.redis_key); + try { + if(map==null || map.size() == 0){ + bean.del = true; + }else { + bean.fillData(map); + } + }catch (Exception e) { + throw new RuntimeException(bean.redis_key, e); + } + + if(!bean.del) { + mapById.put(bean.id, bean); + mapByKey.put(bean.redis_key, bean); + bean.del = false; + str_ver = map.get(VER_KEY); + cache_ver = readVersion(str_ver); + bean.cache_ver = bean.cache_ver > cache_ver ? bean.cache_ver : cache_ver; + } + } + + if(bean.del) { + mapById.remove(bean.id); + mapByKey.remove(bean.redis_key); + return null; + } + + }finally { + jedis.close(); + } + return bean; + } + + private String genKey(int id) { + String s_id = fillSize>0?(String.format("%0"+fillSize+"d", id)):(id+StringUtil.Empty); + String key = this.key + s_id; + return key; + } + + /** + * get bean by id + * @param id + * @return + */ + @SuppressWarnings("unchecked") + public T getBean(int id){ + String key = genKey(id); + synchronized (key) { + BaseBean bean = mapById.get(id); + if(bean==null) { + bean = newBean(); + bean.id = id; + bean.redis_key = key; + }else { + if(bean.del) { + return null; + } + } + return (T) fillBean(bean); + } + } + + /** + * get bean by key + * @param key + * @return + */ + @SuppressWarnings("unchecked") + public T getBean(String key){ + synchronized (key) { + BaseBean bean = mapByKey.get(key); + if(bean==null) { + bean = newBean(); + bean.redis_key = key; + }else { + if(bean.del) { + return null; + } + } + return (T) fillBean(bean); + } + } + + /** + * delete bean by id + * @param id + * @return + */ + public boolean delBean(int id) { + BaseBean bean = mapById.get(id); + if(bean!=null) { + bean.del = true; + return true; + } + return false; + } + + /** + * delete bean by key + * @param key + * @return + */ + public boolean delBean(String key) { + BaseBean bean = mapByKey.get(key); + if(bean!=null) { + bean.del = true; + return true; + } + return false; + } + + /** + * clear expire data + */ + public synchronized void clearExpireData() { + List list = new ArrayList<>(mapById.values()); + for(BaseBean bean : list) { + if(bean.del || System.currentTimeMillis() - bean.cache_time > 180000) { + bean.del = true; + mapById.remove(bean.id); + mapByKey.remove(bean.redis_key); + } + } + } + + /** + * clear all + */ + public synchronized void clear() { + this.mapById.clear(); + this.mapByKey.clear(); + } + +} diff --git a/data_cache/src/main/java/com/data/cache/GameCache.java b/data_cache/src/main/java/com/data/cache/GameCache.java new file mode 100644 index 0000000..ba49b37 --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/GameCache.java @@ -0,0 +1,44 @@ +package com.data.cache; + +import com.data.bean.BaseBean; +import com.data.bean.GameBean; + +/** + * game cache class. + */ +public class GameCache extends BaseCache{ + + protected GameCache() { + super("game:","group1_db1"); + } + + static GameCache inst; + + public static GameBean getGame(int id) { + if(inst==null) { + inst = new GameCache(); + } + return inst.getBean(id); + } + + public static GameBean getGame(String key) { + if(inst==null) { + inst = new GameCache(); + } + return inst.getBean(key); + } + + @Override + protected BaseBean newBean() { + return new GameBean(); + } + + public static void clearData() { + if(inst==null)inst = new GameCache(); + inst.clearExpireData(); + } + + public static String genKey(int gid) { + return "game_" + gid; + } +} diff --git a/data_cache/src/main/java/com/data/cache/GroupCache.java b/data_cache/src/main/java/com/data/cache/GroupCache.java new file mode 100644 index 0000000..af8527b --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/GroupCache.java @@ -0,0 +1,125 @@ +package com.data.cache; + +import com.data.bean.BaseBean; +import com.data.bean.GroupBean; +import com.data.bean.GroupMemberBean; +import com.data.bean.GroupPlayBean; + +public class GroupCache extends BaseCache{ + static GroupCache inst; + + protected GroupCache() { + super("group:", "group1_db11"); + this.readTime = 0; + } + + @Override + protected BaseBean newBean() { + return new GroupBean(); + } + + private static GroupCache me() { + if (inst == null) { + inst = new GroupCache(); + } + return inst; + } + + public static void clearData() { + me().clearExpireData(); + } + + public static GroupBean getGroup(int id) { + return me().getBean(id); + } + + public static GroupBean getGroup(String key) { + return me().getBean(key); + } + + public static GroupMemberBean getMember(int gid, int uid) { + GroupBean gb = getGroup(gid); + if (gb != null) { + synchronized (gb) { + if (gb.memberCache == null) { + gb.memberCache = new GroupMemberCache(gid); + } + } + return gb.memberCache.getBean(uid); + } + return null; + } + + public static GroupPlayBean getPlay(int gid, int pid) { + GroupBean gb = getGroup(gid); + if (gb != null) { + synchronized (gb) { + if (gb.playCache == null) { + gb.playCache = new GroupPlayCache(gid,gb.pay_type); + } + } + return gb.playCache.getBean(pid); + } + return null; + } + + public static String genGroupsKey(int uid) { + return "groups:" + uid; + } + + public static String genKey(int gid) { + return "group:" + gid; + } + + public static String genRewardKey(int gid,int pid) { + return "g{" + gid+"}:reward:"+pid; + } + + public static String genXiPaiRewardKey(int gid,int pid) { + return "g{" + gid+"}:xipai_reward:"+pid; + } + + public static String genRoomsKey(int gid) { + return "g{" + gid+"}:rooms"; + } + + public static String genPidsKey(int gid) { + return "g{" + gid + "}:pids"; + } + + public static String genPlayKey(int gid,int pid) { + return "g{" + gid + "}:play:" + pid; + } + + public static String genBanKey(int gid,int uid) { + return "g{" + gid+"}:ban:"+uid; + } + + public static String genMemberListKey(int gid,int uid) { + return "g{"+gid+"}:member_list:"+uid; + } + + public static String genParListKey(int gid,int uid) { + return "g{"+gid+"}:par_list:"+uid; + } + + public static String genJoinsKey(int gid) { + return "gmjs_"+gid; + } + + public static String genRemarkKey(int gid) { + return "g{"+gid+"}:gremark"; + } + + public static String genReadStatusKey(int gid) { + return "g{"+gid+"}:greadStatus"; + } + + public static String genMailKey(int gid,int uid) { + return "g{"+gid+"}:mail:"+uid; + } + + public static String genMailTipKey(int gid) { + return "g{"+gid+"}:mail_tip"; + } +} diff --git a/data_cache/src/main/java/com/data/cache/GroupMemberCache.java b/data_cache/src/main/java/com/data/cache/GroupMemberCache.java new file mode 100644 index 0000000..3a42942 --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/GroupMemberCache.java @@ -0,0 +1,32 @@ +package com.data.cache; + +import com.data.bean.BaseBean; +import com.data.bean.GroupMemberBean; + +public class GroupMemberCache extends BaseCache{ + private static final String MAIN_KEY= "join_time"; + private int groupId; + + public GroupMemberCache(int gid) { + super("g{"+gid+"}:m", "group1_db10"); + this.groupId = gid; + this.readTime = 0; + } + + @Override + protected BaseBean newBean() { + return new GroupMemberBean(groupId); + } + + /** + * 主键KEY + * @return + */ + protected String mainKey() { + return MAIN_KEY; + } + + public static String genKey(int gid, int uid) { + return String.format("g{%s}:m%s", gid, uid); + } +} diff --git a/data_cache/src/main/java/com/data/cache/GroupPlayCache.java b/data_cache/src/main/java/com/data/cache/GroupPlayCache.java new file mode 100644 index 0000000..4c4d54e --- /dev/null +++ b/data_cache/src/main/java/com/data/cache/GroupPlayCache.java @@ -0,0 +1,106 @@ +package com.data.cache; + +import java.util.Map.Entry; +import java.util.Set; + +import com.data.bean.BaseBean; +import com.data.bean.GroupPlayBean; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; + +import redis.clients.jedis.Jedis; + +public class GroupPlayCache extends BaseCache{ + private ITArray playList; + private ITArray simpPlayList; + private int groupId; + private long last_time; + private int pay_type; + private int gameType; + + public GroupPlayCache(int groupId,int pay_type) { + super("g{"+groupId+"}:play:","group1_db11"); + this.groupId = groupId; + this.pay_type = pay_type; + playList = TArray.newInstance(); + simpPlayList = TArray.newInstance(); + } + + @Override + protected BaseBean newBean() { + GroupPlayBean p = new GroupPlayBean(); + p.pay_type = pay_type; + return p; + } + + /** + * update play data. + * @param play_data + */ + public void updatePlay() { + playList.clear(); + simpPlayList.clear(); + Set> set = this.mapById.entrySet(); + for(Entry entry : set) { + GroupPlayBean gp =(GroupPlayBean)entry.getValue(); + if(!gp.del) { + playList.addTObject(gp.data); + simpPlayList.addTObject(gp.simp_data); + }else { + this.mapById.remove(gp.id); + this.mapByKey.remove(gp.redis_key); + } + } + + } + + /** + * 获取玩法列表 + * @return + */ + public final ITArray getPlayList(int lev){ + /*if(System.currentTimeMillis() - last_time < 180000) { + if(lev < 3) { + return playList; + }else { + return simpPlayList; + } + }*/ + + last_time = System.currentTimeMillis(); + playList.clear(); + simpPlayList.clear(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + String gpids_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gpids_key, 10, 11); + String key = "g{"+this.groupId + "}:play:"; + for(String tem : pids) { + String gp_key = key+tem; + GroupPlayBean gp = this.getBean(gp_key); + if(gp!=null) { + String gkey = "game:"+gp.gameId ; + int gameType = Integer.parseInt(jedis1.hget(gkey,"gameType")); + //gp.gameType = gameType; + gp.data.putInt("gameType",gameType); + playList.addTObject(gp.data); + simpPlayList.addTObject(gp.simp_data); + } + } + }finally { + jedis11.close(); + jedis1.close(); + } + + +// if(lev < 3) { +// return playList; +// }else { +// return simpPlayList; +// } + + return playList; + } +} diff --git a/data_cache/src/main/java/com/data/util/ConsumeCode.java b/data_cache/src/main/java/com/data/util/ConsumeCode.java new file mode 100644 index 0000000..a466b81 --- /dev/null +++ b/data_cache/src/main/java/com/data/util/ConsumeCode.java @@ -0,0 +1,51 @@ +package com.data.util; + +public class ConsumeCode { + + /** 普通创建房间 **/ + public final static int DIAMO_CREAT_ROOM = 1; + /** AA加入房 **/ + public final static int DIAMO_JOIN_ROOM = 4; + /** 反还**/ + public final static int DIAMO_REFUND = 5; + /** 代开房 **/ + public final static int DIAMO_AGENT_ROOM = 2; + /** 结算 **/ + public final static int HP_CLEARING = 6; + /** 抽水 **/ + public final static int HP_PUMP = 7; + /** 管理员上分 **/ + public final static int HP_MGR_UPPER = 8; + /** 管理员下分 **/ + public final static int HP_MGR_SUB = 9; + /** 合伙人上分 **/ + public final static int HP_PARTNER_UPPER = 10; + /** 合伙人下分 **/ + public final static int HP_PARTNER_SUB = 11; + /** 合伙人奖励 **/ + public final static int HP_PARTNER_REWARD = 12; + /** 转账 **/ + public final static int HP_TRADE = 13; + /** 体力值提取 **/ + public final static int HP_TAKE_REWARD = 14; + /**大局游戏hp的变化总值*/ + public final static int HP_PUMP_TOTAL = 15; + /***/ + public final static int HP_TAKE_BANK = 16; + + public final static int HP_SAVE_BANK = 17; + + /** 洗牌 **/ + public final static int HP_XIPAI_PUMP = 20; + /** 合伙人洗牌奖励 **/ + public final static int HP_PARTNER_XIPAI_REWARD = 21; + + /** 邮件 **/ + public final static int DIAMO_MAIL = 50; + /** 转盘**/ + public final static int DIAMO_WHEEL = 51; + /** 分享**/ + public final static int DIAMO_SH = 52; + /** 后台充值**/ + public final static int DIAMO_ADD = 99; +} diff --git a/data_cache/src/main/java/com/data/util/CountUtil.java b/data_cache/src/main/java/com/data/util/CountUtil.java new file mode 100644 index 0000000..ea3cb60 --- /dev/null +++ b/data_cache/src/main/java/com/data/util/CountUtil.java @@ -0,0 +1,262 @@ +package com.data.util; + + + +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +public class CountUtil { + + public static final int LOG_FOREVER = 0; + public static final int LOG_DAY = 1; + public static final int LOG_LASTDAY = 2; + public static final int LOG_WEEK = 3; + public static final int LOG_LASTWEEK = 4; + public static final int LOG_MONTH = 5; + public static final int LOG_LASTMONTH = 6; + + private static final int DAY2 = 172800; + private static final int DAY3 = 259200; + private static final int DAY10 = 864000; + private static final int MONTH = 2592000; +// private static final int WEEK2 = 1209600; + private static final int MONTH2 = 2678400; + + public static int getCountLog(String key,int type,Jedis jedis) { + String value = jedis.get(key); + if(StringUtil.isNotEmpty(value)) { + return Integer.parseInt(value); + } + return 0; + } + + + + + /** + * 获取天数据 + * @param key + * @param jedis + * @return + */ + public static int getCountLogByDay(String key,Jedis jedis) { + String day_key = key + ":d"+DateUtils.getBeginDay(); + String value = jedis.get(day_key); + if(StringUtil.isEmpty(value))return 0; + return Integer.parseInt(value); + } + + + + + /** + * 统计 + * @param key + * @param num + * @param jedis + */ + public static void countLog(String key,int num,Jedis jedis) { + countLog(key,num,jedis,false); + } + + public static void countLog(String key,int num,Pipeline pipeline) { + countLog(key,num,pipeline,false); + } + + /** + * 统计 + * @param key + * @param num + * @param jedis + * @param day_expire_month 天数据保存一个月 + */ + public static void countLog(String key,int num,Jedis jedis,boolean day_expire_month) { + + String day_key = key + ":d"+DateUtils.getBeginDay(); +// String week_key = key + ":w"+DateUtils.getBeginWeek(); +// String month_key = key + ":m"+DateUtils.getBeginMonth(); + jedis.incrBy(day_key,num); + jedis.expire(day_key, day_expire_month?MONTH2:DAY10); +// jedis.incrBy(week_key,num); +// jedis.expire(week_key, WEEK2); +// jedis.incrBy(month_key,num); +// jedis.expire(month_key, MONTH2); + } + + /** + * 统计 + * @param key + * @param num + * @param jedis + * @param day_expire_month 天数据保存一个月 + */ + public static void countLog(String key,int num,Pipeline pipeline,boolean day_expire_month) { + + String day_key = key + ":d"+DateUtils.getBeginDay(); +// String week_key = key + ":w"+DateUtils.getBeginWeek(); +// String month_key = key + ":m"+DateUtils.getBeginMonth(); + pipeline.incrBy(day_key,num); + pipeline.expire(day_key, day_expire_month?MONTH2:DAY10); +// pipeline.incrBy(week_key,num); +// pipeline.expire(week_key, WEEK2); +// pipeline.incrBy(month_key,num); +// pipeline.expire(month_key, MONTH2); + } + + public static void countLog(String key,int num,Jedis jedis,boolean day_expire_month,boolean total) { + + if(total) { + jedis.incrBy(key,num); + } + countLog(key,num,jedis,day_expire_month); + } + + public static void countLog(String key,int num,Pipeline pipeline,boolean day_expire_month,boolean total) { + + if(total) { + pipeline.incrBy(key,num); + } + countLog(key,num,pipeline,day_expire_month); + } + + /** + * 统计天数据(存10天) + * @param key + * @param num + * @param jedis + */ + public static long countLogByDay(String key,int num,Jedis jedis) { + return countLogByDay(key,num,jedis,DAY10); + } + + + /** + * 统计天数据(存10天) + * @param key + * @param num + * @param jedis + */ + public static void countLogByDay(String key,int num,Pipeline pipeline) { + countLogByDay(key,num,pipeline,DAY10); + } + + /** + * 统计天数据(存10天) + * @param key + * @param num + * @param jedis + */ + public static void countLogByDay30(String key,int num,Pipeline pipeline) { + + countLogByDay(key,num,pipeline,MONTH); + + String month_key = key + ":m"+DateUtils.getBeginMonth(); + pipeline.incrBy(month_key,num); + pipeline.expire(month_key, MONTH2); + } + + /** + * 统计天数据(存10天) + * @param key + * @param num + * @param jedis + */ + public static void countLogByDay(String key,int num,Pipeline pipeline,boolean total) { + + if(total) { + pipeline.incrBy(key,num); + } + + countLogByDay(key,num,pipeline,DAY10); + } + + /** + * 统计天数据(存30天) + * @param key + * @param num + * @param jedis + */ + public static void countLogByDay30(String key,int num,Pipeline pipeline,boolean total) { + + if(total) { + pipeline.incrBy(key,num); + } + + countLogByDay(key,num,pipeline,MONTH); + + String month_key = key + ":m"+DateUtils.getBeginMonth(); + pipeline.incrBy(month_key,num); + pipeline.expire(month_key, MONTH2); + } + + /** + * 统计天数据(存10天) + * @param key + * @param num + * @param jedis + */ + public static long countLogByDay(String key,int num,Jedis jedis,boolean total) { + + if(total) { + jedis.incrBy(key,num); + } + + return countLogByDay(key,num,jedis,DAY10); + } + + /** + * 统计天数据 + * @param key + * @param num + * @param jedis + */ + public static long countLogByDay(String key,int num,Jedis jedis,int time) { + String day_key = key + ":d"+DateUtils.getBeginDay(); + + long value = jedis.incrBy(day_key,num); + jedis.expire(day_key, time); + return value; + } + + /** + * 统计天数据 + * @param key + * @param num + * @param jedis + */ + public static void countLogByDay(String key,int num,Pipeline pipeline,int time) { + String day_key = key + ":d"+DateUtils.getBeginDay(); + + pipeline.incrBy(day_key,num); + pipeline.expire(day_key, time); + } + + /** + * 统计天数据(存2天) + * @param key + * @param num + * @param jedis + */ + public static long countLogByDay2(String key,int num,Jedis jedis) { + String day_key = key + ":d"+DateUtils.getBeginDay(); + long value = jedis.incrBy(day_key,num); + jedis.expire(day_key, DAY2); + return value; + } + + /** + * 统计天数据(存2天) + * @param key + * @param num + * @param jedis + */ + public static long countLogByDay3(String key,int num,Jedis jedis) { + String day_key = key + ":d"+DateUtils.getBeginDay(); + long value = jedis.incrBy(day_key,num); + jedis.expire(day_key, DAY3); + return value; + } +} diff --git a/data_cache/src/main/java/com/data/util/ErrorCode.java b/data_cache/src/main/java/com/data/util/ErrorCode.java new file mode 100644 index 0000000..e8fc526 --- /dev/null +++ b/data_cache/src/main/java/com/data/util/ErrorCode.java @@ -0,0 +1,172 @@ +package com.data.util; + +public class ErrorCode { + // 成功 + public final static int _SUCC = 0; + // 失败 + public final static int _FAILED = 1; + /** session 不存在 */ + public final static int _NO_SESSION = 2; + // 已经在房间可重连(创建房间协议) + public final static int BE_IN_ROOM = 3; + // 已创建房间可进入(创建房间协议) + public final static int CREATED_ROOM = 4; + // 不可选游�? + public final static int NO_GAME = 5; + // 无游戏服�? + public final static int NO_SERVICE = 6; + // 缺钻�? + public final static int NO_DIAMO = 7; + // 房间不可进入 + public final static int ROOM_CLOSE = 10; + // 房间号错�? + public final static int NO_ROOM_NUM = 11; + // 邮件不存�? + public final static int NO_MAIL = 12; + // 邮件已领�? + public final static int RECEIVED_MAIL = 13; + // 任务不存�? + public final static int NO_TASK = 14; + // 任务已领�? + public final static int TASK_COMPLETE = 16; + // 缺奖�? + public final static int NO_RAFFLE = 17; + // 没有战绩 + public final static int NO_MILITARY = 19; + // 没有回放 + public final static int NO_REC = 25; + //多次登录失败,禁止登录, 半个小时后再试 + public final static int BAN_LOGIN = 28; + + /** 无效的手机号码 **/ + public final static int INVALID_PHONE = 58; + /** 无效的验证码 **/ + public final static int INVALID_CODE = 59; + /** 手机号码已发短信手机不一致 **/ + public final static int ATYPISM_PHONE = 60; + /** 手机号码已绑定玩家 **/ + public final static int BINDED_PHONE = 61; + /** 该手机号码未绑定游戏 **/ + public final static int NO_BINDED_PHONE = 62; + /** ACC已存在 **/ + public final static int EXIST_ACC = 63; + + + /** 房间已删除 */ + public final static int ROOM_DEL = 80; + /** 是圈子房间 */ + public final static int ROOM_IS_GROUP = 81; + /** 玩家申请解散已达上限次数 **/ + public final static int ROOM_DIS_UPPER_LIMIT = 82; + /** 坐下体力值不足*/ + public final static int ROOM_NOT_HP = 83; + /** 是否禁止解散房间*/ + public final static int ROOM_DIS_NOT_ALLOWED = 84; + + + + /** 是否已申请加入 */ + public final static int GROUP_JOIN_EXIST = 1000; + /** 成员已存在 */ + public final static int GROUP_MEMBER_EXIST = 1001; + /** 成员不存在 */ + public final static int GROUP_NOT_MEMBER = 1002; + /** 成员存在上级合伙人 */ + public final static int GROUP_MEMBER_EXIST_PARTENER = 1003; + /** 玩法已满 */ + public final static int GROUP_PLAY_FULL = 1004; + /** 房间被删除 */ + public final static int GROUP_ROOM_DEL = 1005; + /** 玩法不存在 */ + public final static int GROUP_PLAY_EXIST = 1007; + /** 不是管理员 */ + public final static int GROUP_MGR_EXIST = 1008; + /** 合伙人有成员 */ + public final static int GROUP_PARTNER_MEMBERS = 1009; + /** 目标是管理员 */ + public final static int GROUP_TAG_ISMGR = 1010; + /** 目标是合伙人 */ + public final static int GROUP_TAG_ISPARTENER = 1011; + /** 目标体力值不够 */ + public final static int GROUP_TAG_NO_HP = 1012; + /** 操作人体力值不够 */ + public final static int GROUP_TAG_MGR_HP = 1013; + /** 没有权限 */ + public final static int GROUP_NOT_PERMISSION = 1014; + /** 体力值不为0 */ + public final static int GROUP_HP_NOT_0 = 1015; + /** 成员在房间内 */ + public final static int GROUP_MEMBER_ROOM_EXIST = 1016; + /** 成员体力值事件正在执行 */ + public final static int GROUP_MEMBER_HPEVT_RUNING = 1017; + /** 圈子不存在 */ + public final static int GROUP_NO_EXIST = 1018; + /** 圈子已满 */ + public final static int GROUP_FULL = 1019; + /** 圈子还有房间 */ + public final static int GROUP_EXIST_ROOMS = 1020; + /** 圈子禁止娱乐 */ + public final static int GROUP_BAN = 1021; + /** 不是圈主 */ + public final static int GROUP_NOT_OWNER = 1022; + /** 目標玩家是合伙人 */ + public final static int GROUP_ALREADY_PARTNER = 1023; + /** 目標玩家不是合伙人 */ + public final static int GROUP_NOT_PARTNER = 1024; + /** 圈子成员禁止娱乐 */ + public final static int GROUP_MEMBER_BAN = 1025; + /** 进入房间体力值不足 */ + public final static int GROUP_LIMIT_NO_HP = 1026; + /** 大联盟只能创建一个 */ + /** 大联盟只能创建5个 */ + public final static int GROUP_TYPE2_ONLY_1 = 1027; + /** 大联盟必须开启体力值 */ + public final static int GROUP_TYPE2_MUST_HP = 1028; + /** 改玩法还存在房间 */ + public final static int GROUP_PLAY_EXIST_ROOM = 1029; + /** 不在此圈子房间中 */ + public final static int GROUP_NOT_CURGROUP_ROOM = 1030; + /** 玩家关闭被邀请 */ + public final static int GROUP_CLOSE_INVITATION = 1031; + /** 圈子已满 */ + public final static int GROUP_IS_FULL = 1032; + /** 圈子成员已满 */ + public final static int GROUP_MEMBER_IS_FULL = 1033; + /** 玩家正在游戏 不能上下分 **/ + public final static int GROUP_DONOT_SUB_HP = 1034; + /** 奖励池体力值不足 **/ + public final static int GROUP_REWARD_NO_HP = 1035; + /** 奖励池没提取 **/ + public final static int GROUP_REWARD_NO_TAKE = 1036; + /** 禁止同桌 **/ + public final static int GROUP_BAN_DESK = 1037; + /** 玩法禁止娱乐 **/ + public final static int GROUP_BAN_PLAY = 1038; + /** 禁止申请加入圈子 **/ + public final static int GROUP_BAN_APPLY = 1039; + /** 圈子停止服务 **/ + public final static int GROUP_STOP_SERVICE = 1040; + /** 大联盟不能退出 **/ + public final static int GROUP_TYPE2_NOT_EXIT = 1041; + /** 玩法存在推广奖励 **/ + public final static int GROUP_PAY_TYPE3_EXIST = 1042; + /** 全民推广已开启,不能转移 **/ + public final static int GROUP_PROMOTION_ACTIVE = 1043; + /** 全民推广为开启 **/ + public final static int GROUP_PROMOTION_NOT_ACTIVE = 1044; + /** 有下级合伙人给其合伙人的分成高于此比例 **/ + public final static int GROUP_HAS_MEMBER_OVERFLOW = 1045; + /** 合伙人体力值不足 **/ + public final static int GROUP_PARTNER_HP_NOT_ENOUGH = 1046; + /** 体力值超越上线, 请保存到保险箱里 **/ + public final static int GROUP_PARTNER_HP_THAN_LIMIET = 1047; + /** 玩家体力值超越上线, 请提醒他保存到上线 **/ + public final static int GROUP_PARTNER_OTHER_HP_THAN_LIMIET = 1048; + + //禁止表情 + public final static int GROUP_BAN_EMOJI = 1049; + + + //禁止聊天 + public final static int GROUP_BAN_CHAT = 1050; +} diff --git a/data_cache/src/main/java/com/data/util/EventType.java b/data_cache/src/main/java/com/data/util/EventType.java new file mode 100644 index 0000000..21dc418 --- /dev/null +++ b/data_cache/src/main/java/com/data/util/EventType.java @@ -0,0 +1,60 @@ +package com.data.util; + +public class EventType { + /** + * 扣房卡事件 + */ + public static final int REDIS_EVENT_PAY = 1; + /** + * 反还房卡事件 + */ + public static final int REDIS_EVENT_BACK_PAY = 4; + /** + * 赢事件 + */ + public static final int REDIS_EVENT_WIN = 2; + /** + * 输事件 + */ + public static final int REDIS_EVENT_LOSE = 3; + /** + * 游戏结束事件 + */ + public static final int REDIS_EVENT_OVER = 5; + /** + * 牌友圈局数事件 + */ + public static final int REDIS_EVENT_GROUP_ROUND = 6; + /** + * 牌友圈成员局数事件 + */ + public static final int REDIS_EVENT_GROUP_MEMBER_ROUND = 7; + /** + * 牌友圈体力值事件 + */ + public static final int REDIS_EVENT_GROUP_HP = 8; + /** + * + */ + public static final int REDIS_EVENT_GROUP_HP_DB = 90; + /** + * 邮件 + */ + public static final int REDIS_EVENT_MAIL = 95; + /** + * 转盘 + */ + public static final int REDIS_EVENT_WHEEL = 96; + /** + * 圈子创房 + */ + public static final int REDIS_EVENT_GROUP_ROOM = 97; + /** + * 普通创房 + */ + public static final int REDIS_EVENT_CREATE_ROOM = 98; + /** + * 后台充钻石 + */ + public static final int REDIS_EVENT_ADDPAY = 99; +} diff --git a/data_cache/src/main/java/com/data/util/Utility.java b/data_cache/src/main/java/com/data/util/Utility.java new file mode 100644 index 0000000..3159f44 --- /dev/null +++ b/data_cache/src/main/java/com/data/util/Utility.java @@ -0,0 +1,399 @@ + +package com.data.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.data.bean.GameBean; +import com.data.bean.GroupMemberBean; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +import jdk.nashorn.internal.objects.Global; +import redis.clients.jedis.Jedis; + +public class Utility { + /** + * API 版本 + */ + public static int API_VER = 2; + + /** + * 获取战绩数据 + * + * @param jedis5 + * @param key + * @param platform + * @return + */ + public final static ITObject getMilitaryList(Jedis jedis5, String key, String platform) { + Map military = jedis5.hgetAll(key); + if (military == null || military.isEmpty()) { + return null; + } + ITObject obj = TObject.newInstance(); + obj.putString("military_id", key); + String strData = military.get("game_id"); + if (strData == null) { + return null; + } + obj.putString("game_id", strData); + obj.putString("room_id", military.get("room_id")); + obj.putString("round", military.get("round")); + obj.putString("agreeDismisUserId", military.get("agreeDismisUserId")); + obj.putString("applyDismisUserId", military.get("applyDismisUserId")); + obj.putInt("dismisType", military.get("dismisType") == null ? 0 : Integer.parseInt(military.get("dismisType"))); + +// obj.putString("is_read", military.get("is_read")); + String totalScore = military.get("totalScore"); + ITArray players = TArray.newFromJsonData(totalScore); + for (int j = 0; j < players.size(); j++) { + ITObject player = players.getTObject(j); + int playerId = player.getInt("accId"); + obj.putString("is_read_" + playerId, military.get("is_read_" + playerId)); + + } + + int hp_times = 10; + if (military.containsKey("hp_times")) { + hp_times = Integer.parseInt(military.get("hp_times")); + } + int groupPid = 0; + String pname = ""; + if (military.containsKey("groupPid")) { + groupPid = Integer.parseInt(military.get("groupPid")); + pname = military.get("groupPname"); + } + obj.putString("pname", pname); + + obj.putDouble("valid_diamo", + military.get("valid_diamo") == null ? 0 : Double.parseDouble(military.get("valid_diamo"))); + + obj.putInt("hp_times", hp_times); + obj.putInt("groupPid", groupPid); + GameBean gb = GameCache.getGame(Integer.parseInt(strData)); + ITObject gameObj = gb.getTObject(); + obj.putTObject("game_info", gameObj); + obj.putString("create_time", military.get("create_time")); + strData = military.get("totalScore"); + String strDatas = military.get("hpData"); + obj.putString("hpData", strDatas); + if (strData != null) { + obj.putString("totalScore", strData); + } + String hpOnOff = military.get("hpOnOff"); + if (StringUtil.isNotEmpty(hpOnOff)) { + obj.putInt("hpOnOff", Integer.parseInt(hpOnOff)); + } else { + obj.putInt("hpOnOff", 0); + } + + strData = military.get("groupId"); + if (strData == null) { + strData = "0"; + } + obj.putString("groupId", strData); + for (int i = 1; i <= Integer.parseInt(military.get("round")); i++) { + String roundKey = "round_" + i; + try { + obj.putString(roundKey, military.get(roundKey)); + } catch (Exception e) { + } + } + return obj; + } + + /** + * 获取成员上级列表 + * + * @param groupId + * @param uid + * @return + */ + public static List getMemberParents(int groupId, int uid) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + return getMemberParents(jedis10, groupId, uid, false); + } finally { + jedis10.close(); + } + } + + /** + * 获取成员上级列表 + * + * @param groupId + * @param uid + * @return + */ + public static List getMemberParents(Jedis jedis10, int groupId, int uid, boolean self) { + return getMemberParents(jedis10, groupId, uid, self, 1); + } + + public static int getParentsinfo(int groupId, int uid) { + // Jedis jedis10 = Redis.use("group1_db10").getJedis(); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + return 0; + } + int parentId = 0; + parentId = gmb.parentId; + return parentId; + } + + /** + * 获取成员上级列表 + * + * @param groupId + * @param uid + * @return + */ + public static List getMemberParents(Jedis jedis10, int groupId, int uid, boolean self, int start_par_lev) { + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + return null; + } + + int partnerLev = 0; + int parentId = 0; + if (self) { + partnerLev = gmb.partnerLev; + if (partnerLev > 0) { + parentId = uid; + } else { + parentId = gmb.parentId; + } + } else { + parentId = gmb.parentId; + } + + if (parentId > 0) { + if (parentId != uid) { + gmb = GroupCache.getMember(groupId, parentId); + partnerLev = gmb.partnerLev; + } + if (partnerLev == 0) + return null; + List list = new ArrayList(partnerLev); + for (int i = start_par_lev - 1; i < partnerLev; ++i) { + list.add(parentId); + parentId = gmb.parentId; + gmb = GroupCache.getMember(groupId, parentId); + } + return list; + } + return null; + } + + /** + * 获取子合伙人Sql + * + * @param groupId + * @param uid + * @return + */ + public static String getChildParentSql(int groupId, int uid, boolean self) { + String pl_key = String.format("g{%s}:par_list:%s", groupId, uid); + Set child_list = Redis.use("group1_db10").smembers(pl_key); + String p = self ? uid + "" : StringUtil.Empty; + for (String str : child_list) { + p += "," + str; + } + return p; + } + + /** + * 获取子合伙人Sql + * + * @param groupId + * @param uid + * @return + */ + public static List getChildParentList(int groupId, int uid, boolean self) { + String pl_key = String.format("g{%s}:par_list:%s", groupId, uid); + Set child_list = Redis.use("group1_db10").smembers(pl_key); + List list = new ArrayList<>(); + if (self) { + list.add(uid); + } + for (String str : child_list) { + list.add(Integer.parseInt(str)); + } + return list; + } + + /** + * + * @param type 1 update 2 call + * @param sql + */ + public static void evtdb(int gid, int type, String sql) { + if (StringUtil.isEmpty(sql)) + return; + String str = type + sql; + Redis.use(CHACHE_KEY).lpush("evt_db_" + (gid % 10), str); + } + + /** + * + * @param type 1 update 2 call 插入不是很重要的LOG, 可以走随机线程 + * @param sql + */ + public static void evtdbLog(int gid, int type, String sql) { + if (StringUtil.isEmpty(sql)) + return; + String str = type + sql; + int id = (int) (gid * Math.random() * 100); + id = id % 10; + Redis.use(CHACHE_KEY).lpush("evt_db_" + (id), str); + } + + private final static String EVT_TYPE = "E"; + private final static String EVT_UID = "uid"; + private final static String CHACHE_KEY = "group1_db8"; + + /** + * 支付钻石事件 + * + * @param type + * @param uid + * @param game + * @param pay + * @param gid + * @param pid + */ + public static void payDiamo(int type, int uid, int game, int pay, int gid, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("pay", pay); + data.putInt("game", game); + data.putInt("group", gid); + if (pid > 0) { + data.putInt("pid", pid); + } + data.putInt(EVT_UID, uid); + data.putInt(EVT_TYPE, type); + Redis.use(CHACHE_KEY).lpush("event_" + (uid % 10), data.toJson()); + } + + /** + * 支付钻石事件 + * + * @param type + * @param uid + * @param game + * @param pay + * @param cur_diamo + * @param gid + * @param pid + */ + public static void payDiamo(int type, int uid, int game, int pay, int cur_diamo, int gid, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("pay", pay); + data.putInt("game", game); + data.putInt("diamo", cur_diamo); + data.putInt("group", gid); + if (pid > 0) { + data.putInt("pid", pid); + } + data.putInt(EVT_UID, uid); + data.putInt(EVT_TYPE, type); + Redis.use(CHACHE_KEY).lpush("event_" + (uid % 10), data.toJson()); + } + + final static String pay_lua = "local diamo = tonumber(redis.call('hget', KEYS[1],'diamo'))\n" + + "local pay = tonumber(ARGV[1]) \n" + "if pay > diamo then \n" + "return {2,0}\n" + "end\n" + + "diamo = redis.call('hincrBy',KEYS[1],'diamo',-pay)\n" + "return {0,diamo}"; + + @SuppressWarnings("unchecked") + public static ArrayList payDiamo(Jedis jedis0, String session, int pay) { + Object obj = jedis0.eval(pay_lua, Arrays.asList(session), Arrays.asList(pay + "")); + if (obj == null) + return null; + return (ArrayList) obj; + } + + /** + * 检测房间钻石 + * + * @param jedis0 + * @param session + * @param pay + * @param opt + * @param AA + * @param maxPlayers + * @return + * @throws Exception + */ + public static int checkRoomDiamo(Jedis jedis0, String session, int pay) throws Exception { + if (pay <= 0) { + return 0; + } + int p_diamo = Integer.parseInt(jedis0.hget(session, "diamo")); + if (p_diamo < pay) { + return ErrorCode.NO_DIAMO; + } + return 0; + } + + /** + * 获取session 已在房间 + * + * @param jedis0 + * @param groupId + * @param session + * @param uid + * @return + */ + public static final String getOldRoomV2(Jedis jedis0, int groupId, String session, int uid) { + String oldRoom = jedis0.hget(session, "room"); + boolean enter_old = false; + if (StringUtil.isNotEmpty(oldRoom)) { + enter_old = true; + } + if (enter_old) { + List _list = jedis0.hmget(oldRoom, "status", "score_" + uid); + String status = _list.get(0); + if (StringUtil.isEmpty(status) || status.equals("2") || status.equals("3")) { + jedis0.hdel(session, "room"); + return null; + } + String s_uid = _list.get(1); + if (StringUtil.isNotEmpty(s_uid)) { + return oldRoom; + } + } + return null; + } + + /** + * 删除session房间 + * + * @param jedis0 + * @param session_key + * @param room_key + * @return + */ + public static final boolean delRoomBySession(Jedis jedis0, String session_key, String room_key) { + String cur_room = jedis0.hget(session_key, "room"); + if (StringUtil.isNotEmpty(cur_room)) { + if (cur_room.equals(room_key)) { + if (API_VER == 1) { + jedis0.hdel(session_key, "room", "seat"); + } else { + jedis0.hdel(session_key, "room"); + } + return true; + } + } + return false; + } +} diff --git a/event_mgr/build/local/taurus-core.xml b/event_mgr/build/local/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/event_mgr/build/local/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/event_mgr/build/pro/log4j.properties b/event_mgr/build/pro/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/event_mgr/build/pro/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/event_mgr/build/pro/taurus-core.xml b/event_mgr/build/pro/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/event_mgr/build/pro/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/event_mgr/build/test/log4j.properties b/event_mgr/build/test/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/event_mgr/build/test/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/event_mgr/build/test/taurus-core.xml b/event_mgr/build/test/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/event_mgr/build/test/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/event_mgr/pom.xml b/event_mgr/pom.xml new file mode 100644 index 0000000..86389d3 --- /dev/null +++ b/event_mgr/pom.xml @@ -0,0 +1,117 @@ + + 4.0.0 + com.evt + event_mgr + war + 1.0.0 + + UTF-8 + 1.8 + 1.8 + pro + + + + + junit + junit + 3.8.1 + test + + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + org.quartz-scheduler + quartz + 2.2.3 + + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + + + ROOT + + + org.apache.maven.plugins + maven-war-plugin + + 1.8 + 1.8 + UTF-8 + logs/**,config/** + + + config/ + ${project.basedir}/build/${build.type}/ + + + + + + + + diff --git a/event_mgr/src/main/java/com/evt/mgr/EventController.java b/event_mgr/src/main/java/com/evt/mgr/EventController.java new file mode 100644 index 0000000..07c7f2c --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/EventController.java @@ -0,0 +1,149 @@ +package com.evt.mgr; + +import java.sql.SQLException; + +import com.data.util.CountUtil; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; + +public class EventController { + private static final String EVENT_TYPE = "E"; + private static final String EVENT_GID = "gid"; + private static final String EVENT_UID = "uid"; + + public static final int execEvt(String key,boolean isGroupEvt) { + int count = 0; + do { + String jsonStr = Redis.use(EventReceiver.CHACHE_KEY).rpop(key); + if(StringUtil.isEmpty(jsonStr)) + { + break; + } + + long startTime = System.currentTimeMillis(); + ITObject data = null; + try { + data = TObject.newFromJsonData(jsonStr); + } catch (Exception e) { + EventServer.log.error(jsonStr + ":event json error!", e); + } + int type = 0; + int uid = 0; + int groupId =0; + int reulst = 0; + try { + type = data.getInt(EVENT_TYPE); + + if(isGroupEvt) { + groupId = data.getInt(EVENT_GID); + }else { + uid = data.getInt(EVENT_UID); + } + + IHandler handler = EventServer.eventReceiver.getHandler(type); + if(handler!=null) { + if(isGroupEvt) { + reulst = handler.processGroup(groupId, data); + EventServer.log.info(jsonStr + " use time:" + (System.currentTimeMillis() - startTime) + " ms"); + }else { + reulst = handler.process(uid, data); + EventServer.log.info(jsonStr + " use time:" + (System.currentTimeMillis() - startTime) + " ms"); + } + if(reulst!=0) { + if(reulst == -1) { + jsonStr = data.toJson(); + } + Redis.use(EventReceiver.CHACHE_KEY).lpush(key, jsonStr); + } + } + }catch (Exception e) { + e.printStackTrace(); + Redis.use("group1_db15").lpush(key, jsonStr); + break; + } + + if(reulst == 0) { + count++; + } + } while(true); + + return count; + } + + /** + * + * @param uid + * @param pay + * @param cur_diamo + * @param reason + * @param gameId + * @param groupId + * @param pid + * @throws SQLException + */ + public static final void payDiamo(int uid,int pay,int cur_diamo,int reason,int gameId,int groupId,int pid) throws SQLException{ + ITArray data = TArray.newInstance(); + data.addInt(uid); + data.addInt(pay); + data.addInt(reason); + data.addInt(gameId); + data.addInt(groupId); + data.addInt(cur_diamo); + DataBase.use().prepareCallNonResult("sp_transfer_diamo", data); + if(groupId>0) { + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + CountUtil.countLog(String.format("g%s:diamo_cost",groupId), pay, jedis9); + if(pid > 0) { + CountUtil.countLog(String.format("g%s:diamo_cost:p%s",groupId,pid), pay, jedis9,false,true); + } + }finally { + jedis9.close(); + } + } + } + + public static final int execSql(String key) { + int count = 0; + do { + String str = Redis.use(EventReceiver.CHACHE_KEY).rpop(key); +// EventServer.log.info( " execsql:"+str); + if(StringUtil.isEmpty(str)) + { + break; + } + + int reulst = 0; + long startTime = System.currentTimeMillis(); + try { + int type = Integer.parseInt(str.substring(0,1)); + String sql = str.substring(1); + if(type==1) { + DataBase.use().executeUpdate(sql); + EventServer.log.info(sql + " use time:" + (System.currentTimeMillis() - startTime) + " ms"); + }else { + DataBase.use().executeCall(sql, false); + EventServer.log.info(sql + " use time:" + (System.currentTimeMillis() - startTime) + " ms"); + } + + }catch (Exception e) { + e.printStackTrace(); + Redis.use("group1_db15").lpush(key, str); + break; + } + + if(reulst == 0) { + count++; + } + } while(true); + + return count; + } +} diff --git a/event_mgr/src/main/java/com/evt/mgr/EventReceiver.java b/event_mgr/src/main/java/com/evt/mgr/EventReceiver.java new file mode 100644 index 0000000..cd5f251 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/EventReceiver.java @@ -0,0 +1,101 @@ +package com.evt.mgr; + +import java.util.HashMap; +import java.util.Map; + +import com.taurus.core.util.Logger; + +public class EventReceiver { + private final static String GROUP_EVT_KEY = "evt_group_"; + private final static String EVT_KEY = "event_"; + private final static String EVT_DB_KEY = "evt_db_"; + public final static String CHACHE_KEY = "group1_db8"; + + Map handlerMap; + volatile boolean run; + + public EventReceiver() { + handlerMap = new HashMap<>(); + } + + void start() { + run = true; + for (int i = 0; i < 10; ++i) { + new GroupRunnable(i, this, 1); + } + + for (int i = 0; i < 10; ++i) { + new GroupRunnable(i, this, 2); + } + + for (int i = 0; i < 10; ++i) { + new GroupRunnable(i, this, 3); + } + } + + void destroy() { + run = false; + } + + IHandler getHandler(int type) { + IHandler handler = handlerMap.get(type); + return handler; + } + + private static final class GroupRunnable implements Runnable { + private Logger log = Logger.getLogger(GroupRunnable.class); + EventReceiver receiver; + int type; + int id; + Thread thread; + + public GroupRunnable(int id, EventReceiver receiver, int type) { + this.receiver = receiver; + this.type = type; + this.id = id; + this.thread = new Thread(this, id + ""); + this.thread.start(); + } + + @Override + public void run() { + while (receiver.run) { + int count=0; + long startTime = System.currentTimeMillis(); + try { + switch (type) { + case 1: + count = EventController.execEvt(GROUP_EVT_KEY + this.id, true); + break; + case 2: + count = EventController.execEvt(EVT_KEY + id, false); + break; + case 3: + count = EventController.execSql(EVT_DB_KEY+id); + break; + } + + long useTime = (System.currentTimeMillis() - startTime); + if (count > 0) + { + EventServer.log.info("handle event:" + count + " use time:" + useTime + " ms"); + } + if (useTime >= 30 || count >= 30) + { + Thread.sleep(1); + } + else if (count > 0){ + Thread.sleep(5); + } + else { + Thread.sleep(20); + } + } catch (Exception e) { + log.error(e); + } + } + } + + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/EventServer.java b/event_mgr/src/main/java/com/evt/mgr/EventServer.java new file mode 100644 index 0000000..115535a --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/EventServer.java @@ -0,0 +1,105 @@ +package com.evt.mgr; + +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + +import com.evt.mgr.job.CleanGroupLogJob; +import org.quartz.CronTrigger; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerFactory; +import org.quartz.impl.StdSchedulerFactory; + +import com.data.util.ConsumeCode; +import com.data.util.EventType; +import com.evt.mgr.handler.HandlerGroupMemberRound; +import com.evt.mgr.handler.HandlerGroupRound; +import com.evt.mgr.handler.HandlerHpConsume; +import com.evt.mgr.handler.HandlerLose; +import com.evt.mgr.handler.HandlerOver; +import com.evt.mgr.handler.HandlerPay; +import com.evt.mgr.handler.HandlerWin; +import com.evt.mgr.job.CleanTimeOutRoomJob; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.Logger; + +public class EventServer extends Extension{ + static EventReceiver eventReceiver; + public static Logger log; + + @Override + public void onStart() { + log = Logger.getLogger(EventServer.class); + eventReceiver = new EventReceiver(); + initHandler(); + + initJob(); + + eventReceiver.start(); + } + + @Override + public void configRoute(Routes me) { + } + + public void initJob() { + + try { + log.info("clean invalid room, no diamond"); + + SchedulerFactory sf = new StdSchedulerFactory(); + Scheduler sched = sf.getScheduler(); + + JobDetail job = newJob(CleanTimeOutRoomJob.class).withIdentity("clean_group_room", "group").build(); + CronTrigger trigger= newTrigger().withIdentity("clean_group_room_trigger", "group").withSchedule(cronSchedule("0 0 5 * * ? ")).build(); + sched.scheduleJob(job, trigger); + + job = newJob(CleanTimeOutRoomJob.class).withIdentity("clean_invalid_room", "group").build(); + trigger= newTrigger().withIdentity("clean_invalid_room_trigger", "group").withSchedule(cronSchedule("0 30 5 * * ? ")).build(); + sched.scheduleJob(job, trigger); + + JobDetail log_job = newJob(CleanGroupLogJob.class).withIdentity("clean_group_member_log", "group").build(); + CronTrigger log_trigger= newTrigger().withIdentity("clean_group_member_log_trigger", "group").withSchedule(cronSchedule("0 0 0/1 * * ? ")).build(); + sched.scheduleJob(log_job, log_trigger); + + log_job = newJob(CleanGroupLogJob.class).withIdentity("clean_group_hp_log", "group").build(); + log_trigger= newTrigger().withIdentity("clean_group_hp_log_trigger", "group").withSchedule(cronSchedule("0 0 0/1 * * ? ")).build(); + sched.scheduleJob(log_job, log_trigger); + + log_job = newJob(CleanGroupLogJob.class).withIdentity("clean_rec_room_log", "group").build(); + log_trigger= newTrigger().withIdentity("clean_rec_room_log_trigger", "group").withSchedule(cronSchedule("0 0 0/1 * * ? ")).build(); + sched.scheduleJob(log_job, log_trigger); + + sched.start(); + } + catch(Exception e) { + + } + } + + + private void initHandler() { + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_OVER, new HandlerOver()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_LOSE, new HandlerLose()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_WIN, new HandlerWin()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_PAY, new HandlerPay(ConsumeCode.DIAMO_JOIN_ROOM,true)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_BACK_PAY, new HandlerPay(ConsumeCode.DIAMO_REFUND,false)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_GROUP_ROOM, new HandlerPay(ConsumeCode.DIAMO_AGENT_ROOM,true)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_CREATE_ROOM, new HandlerPay(ConsumeCode.DIAMO_CREAT_ROOM,true)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_MAIL, new HandlerPay(ConsumeCode.DIAMO_MAIL,false)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_WHEEL, new HandlerPay(ConsumeCode.DIAMO_WHEEL,false)); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_GROUP_ROUND, new HandlerGroupRound()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_GROUP_MEMBER_ROUND, new HandlerGroupMemberRound()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_GROUP_HP, new HandlerHpConsume()); + eventReceiver.handlerMap.put(EventType.REDIS_EVENT_ADDPAY, new HandlerPay(ConsumeCode.DIAMO_ADD,false)); + } + + @Override + public void onStop() { + eventReceiver.destroy(); + } + + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/GroupPublisherService.java b/event_mgr/src/main/java/com/evt/mgr/GroupPublisherService.java new file mode 100644 index 0000000..73c6ebc --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/GroupPublisherService.java @@ -0,0 +1,75 @@ +package com.evt.mgr; + +import com.data.util.EventType; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; + +import redis.clients.jedis.Jedis; + +public class GroupPublisherService { + public static final String CHANNEL_NAME = "mgr_group"; + + private static final String CMD_UPDATE_MEMBER = "update_member"; + + private static final String CMD_DEL_ROOM = "del_room"; + + private final static String EVT_TYPE = "E"; + private final static String EVT_UID = "uid"; + + private final static String EVT_KEY = "event_"; + + /** + * 1 hp 2 等级 3 合伙人等级 + * + * @param groupId + * @param uid + * @param type + * @param value + */ + public static void updateMemberEvt(int groupId, int uid, int type, int value) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("uid", uid); + data.putInt("type", type); + data.putInt("value", value); + data.putString("cmd", CMD_UPDATE_MEMBER); + Jedis jedis11 =Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void delRoomEvt(int groupId, String roomid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("roomid", roomid); + data.putString("cmd", CMD_DEL_ROOM); + Jedis jedis11 =Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + /** + * 返还钻石 + * + * @param uid + * @param pay + * @param groupId + */ + public static void refundDiamo(int uid, int pay, int groupId, int gameId) { + ITObject data = TObject.newInstance(); + data.putInt("pay", -pay); + data.putInt("game", gameId); + if (groupId > 0) { + data.putInt("group", groupId); + } + //sendEvt(EventType.REDIS_EVENT_BACK_PAY, uid, data); + } + + private static void sendEvt(int type, int uid, ITObject data) { + int id = uid % 10; + data.putInt(EVT_UID, uid); + data.putInt(EVT_TYPE, type); + Redis.use(EventReceiver.CHACHE_KEY).lpush(EVT_KEY + id, data.toJson()); + } +} diff --git a/event_mgr/src/main/java/com/evt/mgr/IHandler.java b/event_mgr/src/main/java/com/evt/mgr/IHandler.java new file mode 100644 index 0000000..3c47eff --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/IHandler.java @@ -0,0 +1,10 @@ +package com.evt.mgr; + +import com.taurus.core.entity.ITObject; + +public interface IHandler { + + public int process(int uid,ITObject param) throws Exception; + + public int processGroup(int groupId,ITObject param) throws Exception; +} diff --git a/event_mgr/src/main/java/com/evt/mgr/Utils.java b/event_mgr/src/main/java/com/evt/mgr/Utils.java new file mode 100644 index 0000000..cc877a7 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/Utils.java @@ -0,0 +1,221 @@ +package com.evt.mgr; + +import java.util.List; + +import org.eclipse.jetty.util.log.Log; + +import com.data.cache.GroupCache; +import com.data.util.CountUtil; +import com.data.util.Utility; +import com.evt.mgr.handler.HandlerHpConsume; +import com.taurus.core.entity.ITArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.Logger; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +public class Utils { + static Logger log = Logger.getLogger(Utils.class); + + public static final void countValidAndTotal(Jedis jedis10, Pipeline pipeline9, int uid, int groupId, int pid, + int valid_count, int valid_diamo, int all_count) { + + if (valid_count > 0) { + String gmv = String.format("g{%s}:m%s:valid_round", groupId, uid); + CountUtil.countLogByDay30(gmv, valid_count, pipeline9); + CountUtil.countLogByDay30(gmv + "_self", valid_count, pipeline9); + } + + if (valid_diamo > 0) { + String gmv = String.format("g{%s}:m%s:valid_diamo", groupId, uid); + CountUtil.countLogByDay30(gmv, valid_diamo, pipeline9); + CountUtil.countLogByDay30(gmv + "_self", valid_diamo, pipeline9); + +// CountUtil.countLogByDay30(groupDiamo + "_self", valid_diamo, pipeline9); + + } + + String gmr = String.format("g{%s}:m%s:round_log", groupId, uid); + CountUtil.countLogByDay30(gmr, 1, pipeline9, true); + CountUtil.countLogByDay30(gmr + "_self", 1, pipeline9, true); + + List temp = Utility.getMemberParents(jedis10, groupId, uid, true); + if (temp != null && temp.size() > 0) { + + if (valid_count > 0) { + + for (int i = 0; i < temp.size(); ++i) { + + int par = temp.get(i); + if (par != uid) { + String gmv = String.format("g{%s}:m%s:valid_round", groupId, par); + CountUtil.countLogByDay30(gmv, valid_count, pipeline9); + } + + String gmvp = String.format("g{%s}:m%s:valid_round:p%s", groupId, par, pid); + CountUtil.countLogByDay30(gmvp, valid_count, pipeline9); + + String gmvp2 = String.format("g{%s}:m%s:valid_round2:p%s", groupId, par, pid); + CountUtil.countLogByDay30(gmvp2, valid_count, pipeline9); + + boolean add_uid = (uid == par || i == 0); + if (add_uid == true) { + String gmv = String.format("g{%s}:m%s:d_valid_round", groupId, par); + CountUtil.countLogByDay30(gmv, valid_count, pipeline9); + } + } + } + + for (int i = 0; i < temp.size(); ++i) { + int par = temp.get(i); + if (par != uid) { + gmr = String.format("g{%s}:m%s:round_log", groupId, par); + CountUtil.countLogByDay30(gmr, 1, pipeline9, true); + } + + gmr = String.format("g{%s}:m%s:valid_diamo:p%s", groupId, par, pid); + CountUtil.countLogByDay30(gmr, valid_diamo, pipeline9); + + gmr = String.format("g{%s}:m%s:all_count:p%s", groupId, par, pid); + CountUtil.countLogByDay30(gmr, all_count, pipeline9, true); + + boolean add_uid = (uid == par || i == 0); + if (add_uid == true) { + gmr = String.format("g{%s}:m%s:d_round_log", groupId, par); + CountUtil.countLogByDay30(gmr, 1, pipeline9, true); + } + } + } + } + + public static final void countValidAndTotal(Pipeline pipeline9, ITArray playerList, int groupId, int pid, + int valid_count, int valid_diamo, int all_count) { + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + + for (int i = 0; i < playerList.size(); i++) { + + int uid = playerList.getInt(i); + countValidAndTotal(jedis10, pipeline9, uid, groupId, pid, valid_count, valid_diamo, all_count); + } + log.info("消耗房卡:"+valid_diamo); + //保存消耗房卡 + String groupDiamo = String.format("g{%s}:valid_diamo", groupId); + CountUtil.countLogByDay30(groupDiamo, valid_diamo, pipeline9); + + } finally { + jedis10.close(); + } + } + + /** + * 统计合伙人局数和赢 + * + * @param jedis9 + * @param groupId + * @param uid + * @param win + */ + public static final void countRoundWin(Pipeline pipeline9, int groupId, int pid, int uid, boolean win, int score) { + List par_list = null; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + par_list = Utility.getMemberParents(jedis10, groupId, uid, true); + + Pipeline pipeline10 = jedis10.pipelined(); + + if (par_list == null) + return; + + String key = String.format("g{%s}:m%s:total_win", groupId, uid); + CountUtil.countLogByDay30(key, score, pipeline9); + CountUtil.countLogByDay30(key + "_self", score, pipeline9); + + for (int i = 0; i < par_list.size(); ++i) { + + int par = par_list.get(i); + + boolean add_uid = (uid == par || i == 0); + if (add_uid == true) { + + key = String.format("g{%s}:m%s:d_total_win", groupId, par); + CountUtil.countLogByDay30(key, score, pipeline9); + } + + String mlk = GroupCache.genMemberListKey(groupId, par); + pipeline10.sadd(mlk, uid + ""); + + if (par != uid) { + key = String.format("g{%s}:m%s:total_win", groupId, par); + CountUtil.countLogByDay30(key, score, pipeline9); + } + } + + pipeline10.sync(); + + } finally { + jedis10.close(); + } + } + + /** + * 统计合伙人体力值消耗,输赢统计 + * + * @param jedis9 + * @param groupId + * @param uid + * @param pump + * @param hp + */ + public static final void countHpconsume(Pipeline pipeline9, int groupId, int uid, int pump, int hp) { + List par_list = null; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + par_list = Utility.getMemberParents(jedis10, groupId, uid, true); + } finally { + jedis10.close(); + } + if (par_list == null) + return; + String key; + + key = String.format("g{%s}:m%s:hp_consume_log", groupId, uid); + CountUtil.countLogByDay(key, hp, pipeline9); + + int day = DateUtils.getBeginDay(); + boolean self = par_list.get(0) == uid; + for (int i = 0; i < par_list.size(); ++i) { + + int par = par_list.get(i); + boolean add_uid = i == 0 || (i <= 1 && self); + + if (pump > 0) { + + key = String.format("g%s:hp_cost:par%s_%s", groupId, par, day); + pipeline9.hincrBy(key, "total", pump); + if (add_uid) { + pipeline9.hincrBy(key, uid + "", pump); + } + + pipeline9.expire(key, 3600 * 24 * 2); + } + + if (uid != par) { + key = String.format("g{%s}:m%s:hp_consume_log", groupId, par); + CountUtil.countLogByDay(key, hp, pipeline9); + } + + key = String.format("g%s:hp_consume:par%s_%s", groupId, par, day); + pipeline9.hincrBy(key, "total", hp); + if (add_uid) { + pipeline9.hincrBy(key, uid + "", hp); + } + + pipeline9.expire(key, 3600 * 24 * 2); + } + + } +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupMemberRound.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupMemberRound.java new file mode 100644 index 0000000..820e817 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupMemberRound.java @@ -0,0 +1,104 @@ +package com.evt.mgr.handler; + +import com.data.util.ConsumeCode; +import com.data.util.CountUtil; +import com.data.util.Utility; +import com.evt.mgr.IHandler; +import com.evt.mgr.Utils; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +import java.sql.SQLException; + +public class HandlerGroupMemberRound implements IHandler{ + + @Override + public int process(int uid, ITObject param) throws Exception { + // TODO Auto-generated method stub + return 0; + } + + private static boolean addMemberLog(int gid, int pid,int uid, int score, int win, int time, int perfectRound,int valid_count) throws SQLException { + String sql = String.format("{call sp_add_member_log(%s,%s,%s,%s,%s,%s,%s,%s)}", + gid,pid,uid,score,win,time,perfectRound,valid_count); + Utility.evtdbLog(gid, 2, sql); + return false; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + + int pid = param.getInt("pid"); + int score = param.getInt("score"); + int uid = param.getInt("uid"); + int win = param.getInt("win"); + int time = DateUtils.getBeginDay(); + int perfectRound = param.getInt("perfect_round"); + int valid_count = param.getInt("valid_count"); + int pump = param.getInt("pump"); + int cur_hp = param.getInt("cur_hp"); + int xipai_total = param.getInt("xi_pai_total"); + String roomid = param.getString("room"); + int cur_time = (int)(System.currentTimeMillis() / 1000); + if (param.containsKey("time")) + { + cur_time = param.getInt("time"); + } + + //ITArray param1 = TArray.newInstance(); + //param1.addInt(groupId); + //param1.addInt(pid); + //param1.addInt(uid); + //param1.addInt(score - pump - xipai_total); + //param1.addInt(win); + //param1.addInt(time); + //param1.addInt(perfectRound); + //param1.addInt(valid_count); + //DataBase.use().prepareCallNonResult("sp_add_member_log", param1); +// addMemberLog(groupId, pid, uid, score - pump - xipai_total, win, time, perfectRound, valid_count); + addMemberLog(groupId, pid, uid, score, win, time, perfectRound, valid_count); + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s)", + groupId,uid,ConsumeCode.HP_PUMP_TOTAL,score - pump - xipai_total, + cur_hp,pid,gameid,roomid,(int) (cur_time)); + Utility.evtdb(groupId, 1, sql); + //DataBase.use().executeUpdate(sql); + + String gmrp_key = String.format("g%s:m%s:round:p%s",groupId,uid,pid); + String gmr_key = String.format("g%s:m%s:round",groupId,uid); + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + + try { + CountUtil.countLog(gmrp_key, 1, jedis9); + CountUtil.countLog(gmr_key, 1, jedis9); + + Pipeline pipeline9 = jedis9.pipelined(); + Utils.countRoundWin(pipeline9, groupId, pid, uid, win==1,score - pump); + pipeline9.sync(); + + }finally { + jedis9.close(); + } + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupRound.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupRound.java new file mode 100644 index 0000000..8f99d59 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerGroupRound.java @@ -0,0 +1,72 @@ +package com.evt.mgr.handler; + +import com.data.util.CountUtil; +import com.evt.mgr.IHandler; +import com.evt.mgr.Utils; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.redis.Redis; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +public class HandlerGroupRound implements IHandler{ + + @Override + public int process(int uid, ITObject param) throws Exception { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + int pid = param.getInt("pid"); + int valid = param.getInt("valid"); + ITArray playerList = param.getTArray("player_list"); + int valid_count = param.getInt("valid_count"); + int valid_diamo = 0; + int all_count = 0; + if (param.containsKey("valid_diamo")) + { + valid_diamo = param.getInt("valid_diamo"); + } + + if (param.containsKey("all_count")) + { + all_count = param.getInt("all_count"); + } + + String rp_key = String.format("g%s:round:p%s",groupId,pid); + String round_key = String.format("g%s:round",groupId); + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + Pipeline pipeline9 = jedis9.pipelined(); + + CountUtil.countLog(rp_key, 1, pipeline9,false,true); + CountUtil.countLog(round_key, 1, pipeline9,true); + + if(valid == 1) { + + String valid_key = String.format("g%s:valid_room",groupId); + String p_valid_key = String.format("g%s:valid_room:p%s",groupId,pid); + CountUtil.countLogByDay(p_valid_key, 1, pipeline9,true); + CountUtil.countLog(valid_key, 1, pipeline9); + }else { + + String no_valid_key = String.format("g%s:no_valid_room",groupId); + String p_no_valid_key = String.format("g%s:no_valid_room:p%s",groupId,pid); + CountUtil.countLogByDay(p_no_valid_key, 1, pipeline9,true); + CountUtil.countLog(no_valid_key, 1, pipeline9); + } + Utils.countValidAndTotal(pipeline9, playerList, groupId, pid, valid_count, valid_diamo, all_count); + + pipeline9.sync(); + + }finally { + jedis9.close(); + } + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerHpConsume.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerHpConsume.java new file mode 100644 index 0000000..3f0077a --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerHpConsume.java @@ -0,0 +1,551 @@ +package com.evt.mgr.handler; + +import java.sql.SQLException; + +import com.data.bean.GroupBean; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ConsumeCode; +import com.data.util.CountUtil; +import com.data.util.Utility; +import com.evt.mgr.IHandler; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +public class HandlerHpConsume implements IHandler{ + static Logger log = Logger.getLogger(HandlerHpConsume.class); + final static String DB = "group1_db10"; + + private static boolean hpConsume(int gid, int uid,int pid, int hp,int cur_hp,int reason, String roomid, int time,String desc) throws SQLException { + String sql = String.format("{call sp_update_hp(%s,%s,%s,%s,%s,%s,'%s',%s,'%s')}", + gid,uid,hp,cur_hp,reason,pid,roomid,time,desc); + Utility.evtdb(gid, 2, sql); + return false; + } + + @Override + public int process(int uid, ITObject param) throws Exception { + return 0; + } + + private void to_reward(Pipeline pipeline, int uid, String prs,int rewardType, int valueType, int real_pump, int pump,int groupId,int pid,String roomid,int time,int max_player) throws Exception { + + int useValue = 0; + if(StringUtil.isNotEmpty(prs)) { + + int round = 100 / max_player; + ITArray list = TArray.newFromJsonData(prs); + + for(int i=list.size()-1;i>=0;--i) { + + ITObject obj1 = list.getTObject(i); + int parentId = obj1.getInt("p"); + int rewardPercent = 0; + if (obj1.containsKey("r")) + { + rewardPercent = obj1.getInt("r"); + } + int rv = 0; + if(i > 0) { + ITObject obj2 = list.getTObject(i - 1); + if (!obj2.containsKey("r")) + { + rv =rewardPercent - 0; + } + else { + rv =rewardPercent -obj2.getInt("r"); + } + }else { + + rv=rewardPercent; + } + int reward_value = rv; + if(valueType == 1) { + reward_value = Math.round(pump * (rv / 100f)); + } + else { + if(rewardType == 2) { + reward_value = reward_value / max_player; + } + } + + if (reward_value < 0) + { + continue; + } + + String key = String.format("g{%s}:m%s:reward_hp", groupId,parentId); + Redis.use(DB).incrBy(key, reward_value); + String rewardsql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", Redis.use(DB).get(key), parentId,groupId); + Utility.evtdb(groupId, 1, rewardsql); + //String all_key = String.format("g{%s}:m%s:all_reward_hp", groupId,parentId); + //Redis.use(DB).incrBy(all_key, reward_value); + useValue += reward_value; + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String desc = "" + uid; + long cur_hp = CountUtil.countLogByDay3(String.format("g%s:hp_reward:m%s",groupId,parentId), reward_value, jedis9); + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time,round, info) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", groupId,parentId,ConsumeCode.HP_PARTNER_REWARD,reward_value,cur_hp,pid,gameid,roomid,time,round, desc); + DataBase.use().executeUpdate(sql); + }finally { + jedis9.close(); + } + + // 记录代理每天的推广奖励 + CountUtil.countLogByDay30(key, reward_value, pipeline); + + key = String.format("g{%s}:m%s:reward_log", groupId,parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + key = String.format("g{%s}:m%s:p%s:reward_log", groupId,parentId,pid); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + // 记录每个人对上级的推广奖励是多少 + key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId,uid, parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + boolean add_uid = (uid == parentId || i == 0); + if(add_uid == true) { + key = String.format("g{%s}:m%s:d_reward", groupId,parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + } + + if(i>0) { + + for(int j = i - 1; j >= 0; j--) { + + ITObject obj2 = list.getTObject(j); + int temp = obj2.getInt("p"); + if(temp != uid) { + key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId,temp, parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + } + } + } + + + //某个玩法的抽水总值 + CountUtil.countLogByDay30(String.format("g%s:hp_cost:m%s:p%s",groupId,parentId,pid),pump,pipeline); + + CountUtil.countLogByDay30(String.format("g%s:hp_reward",groupId), reward_value, pipeline); + } + } + + GroupBean gb = GroupCache.getGroup(groupId); + if (gb != null) { + int round = 100 / max_player; + int leftValue = real_pump - useValue; + String key = String.format("g{%s}:m%s:reward_hp", groupId,gb.owner); + Redis.use(DB).incrBy(key, leftValue); + String rewardsql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", Redis.use(DB).get(key), gb.owner,groupId); + Utility.evtdb(groupId, 1, rewardsql); + //String all_key = String.format("g{%s}:m%s:all_reward_hp", groupId,gb.owner); + //Redis.use(DB).incrBy(all_key, leftValue); + // 记录代理每天的推广奖励 + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:reward_log", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:p%s:reward_log", groupId,gb.owner,pid); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + // 记录每个人对上级的推广奖励是多少 + key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId,uid, gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + boolean add_uid = (uid == gb.owner); + if(add_uid == true) { + key = String.format("g{%s}:m%s:d_reward", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + } + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String desc = "" + uid; + long cur_hp = CountUtil.countLogByDay3(String.format("g%s:hp_reward:m%s",groupId,gb.owner), leftValue, jedis9); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time,round,info) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", groupId,gb.owner,ConsumeCode.HP_PARTNER_REWARD,leftValue,cur_hp,pid,gameid,roomid,time,round,desc); + DataBase.use().executeUpdate(sql); + }finally { + jedis9.close(); + } + } + } + + private void xipai_to_reward(Pipeline pipeline, int uid, String prs,int rewardType, int valueType, int real_pump, int pump,int groupId,int pid,String roomid,int time,int max_player) throws Exception { + + int useValue = 0; + if(StringUtil.isNotEmpty(prs)) { + + int round = 100 / max_player; + ITArray list = TArray.newFromJsonData(prs); + + for(int i=list.size()-1;i>=0;--i) { + + ITObject obj1 = list.getTObject(i); + int parentId = obj1.getInt("p"); + int rewardPercent = 0; + if (obj1.containsKey("x")) + { + rewardPercent = obj1.getInt("x"); + } + int rv = 0; + if(i > 0) { + ITObject obj2 = list.getTObject(i - 1); + if (!obj2.containsKey("x")) + { + rv = rewardPercent - 0; + } + else { + rv = rewardPercent -obj2.getInt("x"); + } + }else { + + rv=rewardPercent; + } + int reward_value = rv; + if(valueType == 1) { + reward_value = Math.round(pump * (rv / 100f)); + } + + if (reward_value < 0) + { + continue; + } + + String key = String.format("g{%s}:m%s:reward_hp", groupId,parentId); + Redis.use(DB).incrBy(key, reward_value); + String rewardsql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", Redis.use(DB).get(key), parentId,groupId); + Utility.evtdb(groupId, 1, rewardsql); + //String all_key = String.format("g{%s}:m%s:all_reward_hp", groupId,parentId); + //Redis.use(DB).incrBy(all_key, reward_value); + useValue += reward_value; + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String desc = "" + uid; + long cur_hp = CountUtil.countLogByDay3(String.format("g%s:hp_reward:m%s",groupId,parentId), reward_value, jedis9); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time,round,info) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", groupId,parentId,ConsumeCode.HP_PARTNER_XIPAI_REWARD,reward_value,cur_hp,pid,gameid,roomid,time,round,desc); + DataBase.use().executeUpdate(sql); + }finally { + jedis9.close(); + } + + // 记录代理每天的推广奖励 + CountUtil.countLogByDay30(key, reward_value, pipeline); + + key = String.format("g{%s}:m%s:xipai_reward_log", groupId,parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + key = String.format("g{%s}:m%s:p%s:xipai_reward_log", groupId,parentId,pid); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + // 记录每个人对上级的推广奖励是多少 + key = String.format("g{%s}:m%s:xipai_reward_log_to:par%s", groupId,uid, parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + + boolean add_uid = (uid == parentId || i == 0); + if(add_uid == true) { + key = String.format("g{%s}:m%s:d_xipai_reward", groupId,parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + } + + if(i>0) { + + for(int j = i - 1; j >= 0; j--) { + + ITObject obj2 = list.getTObject(j); + int temp = obj2.getInt("p"); + if(temp != uid) { + key = String.format("g{%s}:m%s:xipai_reward_log_to:par%s", groupId,temp, parentId); + CountUtil.countLogByDay30(key, reward_value, pipeline); + } + } + } + + //某个玩法的抽水总值 + CountUtil.countLogByDay30(String.format("g%s:xipai_hp_cost:m%s:p%s",groupId,parentId,pid),pump,pipeline); + + CountUtil.countLogByDay30(String.format("g%s:xipai_hp_reward",groupId), reward_value, pipeline); + } + } + GroupBean gb = GroupCache.getGroup(groupId); + if (gb != null) { + int round = 100 / max_player; + int leftValue = real_pump - useValue; + String key = String.format("g{%s}:m%s:reward_hp", groupId,gb.owner); + Redis.use(DB).incrBy(key, leftValue); + String rewardsql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", Redis.use(DB).get(key), gb.owner,groupId); + Utility.evtdb(groupId, 1, rewardsql); + //String all_key = String.format("g{%s}:m%s:all_reward_hp", groupId,gb.owner); + //Redis.use(DB).incrBy(all_key, leftValue); + // 记录代理每天的推广奖励 + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:xipai_reward_log", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:p%s:xipai_reward_log", groupId,gb.owner,pid); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + // 记录每个人对上级的推广奖励是多少 + key = String.format("g{%s}:m%s:xipai_reward_log_to:par%s", groupId,uid, gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + boolean add_uid = (uid == gb.owner); + if(add_uid == true) { + key = String.format("g{%s}:m%s:d_xipai_reward", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + } + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String desc = "" + uid; + long cur_hp = CountUtil.countLogByDay3(String.format("g%s:hp_reward:m%s",groupId,gb.owner), leftValue, jedis9); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time,round,info) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", groupId,gb.owner,ConsumeCode.HP_PARTNER_XIPAI_REWARD,leftValue,cur_hp,pid,gameid,roomid,time,round,desc); + DataBase.use().executeUpdate(sql); + }finally { + jedis9.close(); + } + } + } + + private void to_mengzhu_reward(Pipeline pipeline, int uid, String prs,int rewardType, int valueType, int real_pump, int pump,int groupId,int pid,String roomid,int time,int max_player) throws Exception { + GroupBean gb = GroupCache.getGroup(groupId); + if (gb != null) { + int round = 100 / max_player; + int leftValue = real_pump; + String key = String.format("g{%s}:m%s:reward_hp", groupId,gb.owner); + Redis.use(DB).incrBy(key, leftValue); + String rewardsql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", Redis.use(DB).get(key), gb.owner,groupId); + Utility.evtdb(groupId, 1, rewardsql); + //String all_key = String.format("g{%s}:m%s:all_reward_hp", groupId,gb.owner); + //Redis.use(DB).incrBy(all_key, leftValue); + // 记录代理每天的推广奖励 + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:reward_log", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + key = String.format("g{%s}:m%s:p%s:reward_log", groupId,gb.owner,pid); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + // 记录每个人对上级的推广奖励是多少 + key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId,uid, gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + + boolean add_uid = (uid == gb.owner); + if(add_uid == true) { + key = String.format("g{%s}:m%s:d_reward", groupId,gb.owner); + CountUtil.countLogByDay30(key, leftValue, pipeline); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String desc = "" + uid; + long cur_hp = CountUtil.countLogByDay3(String.format("g%s:hp_reward:m%s",groupId,gb.owner), leftValue, jedis9); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int gameid = 0; + try { + String gameIdstr = jedis11.hget("g{" + groupId + "}:play:" + pid, "gameId"); + gameid = StringUtil.isEmpty(gameIdstr)?0:Integer.parseInt(gameIdstr); + }finally { + jedis11.close(); + } + String sql = String.format("INSERT INTO group_hp_log(gid,uid,reason,hp,cur_hp,pid,gameid,roomid,time,round,info) " + + "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", groupId,gb.owner,ConsumeCode.HP_PARTNER_REWARD,leftValue,cur_hp,pid,gameid,roomid,time,round,desc); + DataBase.use().executeUpdate(sql); + }finally { + jedis9.close(); + } + } + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + int uid = param.getInt("uid"); + try { + int hp = param.getInt("hp"); + int cur_hp = param.getInt("cur_hp"); + boolean is_pump = param.containsKey("pump"); + int pump = 0; + String roomid = param.getString("room"); + int pid = param.getInt("pid"); + int time = param.getInt("time"); + int reward_value = 0; + int xipai_reward_value = 0; + int max_player = 0; + int rewardValueType = 0; + int xipai_rewardValueType = 0; + int rewardType = 1; + int xipai_rewardType = 1; + + boolean is_xipai = param.containsKey("xipai"); + int xipai = 0; + + String prs =null; + if(is_pump) { + pump = param.getInt("pump"); + max_player = param.getInt("max_player"); + if(param.containsKey("reward_value")) { + reward_value = param.getInt("reward_value"); + prs = param.getString("prs"); + } + if(param.containsKey("reward_type")) { + rewardType = param.getInt("reward_type"); + } + if(param.containsKey("rewardValueType")) { + rewardValueType = param.getInt("rewardValueType"); + } + } + + if (is_xipai) + { + xipai = param.getInt("xipai"); + max_player = param.getInt("max_player"); + if(param.containsKey("xipai_reward_value")) { + xipai_reward_value = param.getInt("xipai_reward_value"); + prs = param.getString("prs"); + } + if(param.containsKey("xipai_reward_type")) { + xipai_rewardType = param.getInt("xipai_reward_type"); + } + if(param.containsKey("xipai_rewardValueType")) { + xipai_rewardValueType = param.getInt("xipai_rewardValueType"); + } + } + + if (param.containsKey("hp_than_max_value")) + { + int more_hp = param.getInt("hp_than_max_value"); + String gm_key = GroupMemberCache.genKey(groupId, uid); + String bank_hp = Redis.use("group1_db10").hget(gm_key, "bank_hp"); + String sql = String.format("{call sp_bank_hp(%s,%s,%s,%s)}", groupId, uid, more_hp, cur_hp); + Utility.evtdb(groupId, 2, sql); + String sql2 = String.format("update group_member set bank_hp = %s where uid = %s AND groupId = %s", bank_hp, uid, groupId); + Utility.evtdb(groupId, 1, sql2); + } + + String desc = param.getString("desc"); + desc = StringUtil.isNotEmpty(desc) ? desc : StringUtil.Empty; + if(hp!=0) { + hpConsume(groupId, uid,pid, hp,cur_hp + pump,ConsumeCode.HP_CLEARING, roomid,time, desc); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + String key = String.format("g%s:m%s:consume_hp", groupId,uid); + if(hp!=0) { + CountUtil.countLogByDay(key, hp, jedis9, 691200); + } + + if(pump>0) { + + CountUtil.countLogByDay(key, -pump, jedis9, 691200); + time += 1; + hpConsume(groupId, uid,pid, -pump,cur_hp, ConsumeCode.HP_PUMP, roomid,time, desc); + + CountUtil.countLog(String.format("g%s:hp_cost",groupId), pump, jedis9); + CountUtil.countLogByDay(String.format("g%s:hp_cost:p%s",groupId,pid),pump,jedis9); + CountUtil.countLogByDay(String.format("g%s:hp_cost:m%s",groupId,uid),pump,jedis9); + } + + if (xipai > 0) + { + CountUtil.countLogByDay(key, -xipai, jedis9, 691200); + time += 1; + hpConsume(groupId, uid,pid, -xipai,cur_hp, ConsumeCode.HP_XIPAI_PUMP, roomid,time, desc); + + CountUtil.countLog(String.format("g%s:hp_cost",groupId), xipai, jedis9); + CountUtil.countLogByDay(String.format("g%s:hp_cost:p%s",groupId,pid),xipai,jedis9); + CountUtil.countLogByDay(String.format("g%s:hp_cost:m%s",groupId,uid),xipai,jedis9); + } + + Pipeline pipeline = jedis9.pipelined(); + if(reward_value > 0 || (rewardValueType == 2 && is_pump)) { + + time += 1; + to_reward(pipeline,uid,prs,rewardType,rewardValueType, pump, reward_value ,groupId,pid,roomid,time,max_player); + } + /* + else { + if (is_pump && pump > 0) + { + log.error("pump to_mengzhu_reward:"+pump+" uid:" + uid + " groupId:" + groupId); + to_mengzhu_reward(pipeline,uid,prs,rewardType,rewardValueType, pump, reward_value ,groupId,pid,roomid,time,max_player); + } + } + */ + if(xipai_reward_value > 0 || (xipai_rewardValueType == 2 && is_xipai)) { + + time += 1; + xipai_to_reward(pipeline,uid,prs,xipai_rewardType,xipai_rewardValueType, xipai, xipai_reward_value ,groupId,pid,roomid,time,max_player); + } + /* + else { + if (is_xipai && xipai > 0) + { + log.error("xipai to_mengzhu_reward:"+pump+" uid:" + uid + " groupId:" + groupId); + to_mengzhu_reward(pipeline,uid,prs,xipai_rewardType,xipai_rewardValueType, xipai, xipai_reward_value ,groupId,pid,roomid,time,max_player); + } + } + */ + pipeline.sync(); + + }finally { + jedis9.close(); + } + }catch (Exception e) { + e.printStackTrace(); + } + + return 0; + } +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerLose.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerLose.java new file mode 100644 index 0000000..6cf37c8 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerLose.java @@ -0,0 +1,18 @@ +package com.evt.mgr.handler; + +import com.evt.mgr.IHandler; +import com.taurus.core.entity.ITObject; + +public class HandlerLose implements IHandler{ + + @Override + public int process(int uid, ITObject param) throws Exception { + return 0; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerOver.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerOver.java new file mode 100644 index 0000000..138772e --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerOver.java @@ -0,0 +1,90 @@ +package com.evt.mgr.handler; + +import java.awt.Event; + +import com.data.cache.GroupMemberCache; +import com.evt.mgr.EventServer; +import com.evt.mgr.IHandler; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import redis.clients.jedis.Jedis; + +public class HandlerOver implements IHandler { + + public static final int _SHARE_NUM = 20; + + private static void share(String id) throws Exception { + if (!Redis.use("group1_db1").sismember("shares", id)) { + return; + } + String sql = "SELECT succ,playtimes FROM shares WHERE uid = " + id; + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + if (resultArray.size() == 0) { + return; + } + ITObject dbData = resultArray.getTObject(0); + if (dbData.getInt("succ") != 0) { + Redis.use("group1_db1").srem("shares", id); + return; + } + int playTimes = dbData.getInt("playtimes") + 1; + dbData.putInt("playtimes", playTimes); + if (playTimes >= _SHARE_NUM) { + dbData.putInt("succ", 1); + Redis.use("group1_db1").srem("shares", id); + } + DataBase.use().update("shares", dbData, "uid=" + id); + + } + + @Override + public int process(int uid, ITObject param) throws Exception { + int is_rec = param.getInt("is_rec"); + if (is_rec == 1) { + String roomid = param.getString("roomid"); + String rec_key = param.getString("rec_key"); + int gid = param.containsKey("gid") ? param.getInt("gid") : 0; + int time = param.getInt("time"); + int par = 0; + if (gid > 0) { + String gm_key = GroupMemberCache.genKey(gid, uid); + String parentId = Redis.use("group1_db10").hget(gm_key, "parentId"); + par = StringUtil.isEmpty(parentId) ? 0 : Integer.parseInt(parentId); + } + + + String sql = String.format( + "insert into room_rec_log(roomid,gid,uid,rec_key,time,parentId) values('%s',%s,%s,'%s',%s,%s)", + roomid, gid, uid, rec_key, time, par); + DataBase.use().executeUpdate(sql); + ITArray array = param.getTArray("tagIds"); + EventServer.log.info("param:" + param); + EventServer.log.info("array:" + array); + + String sqls = ""; + for (int i = 0; i < array.size(); i++) { + EventServer.log.info("array.getInt(i):" + array.getInt(i)); + + sqls = String.format( + "insert into room_rec_log_new(roomid,gid,uid,rec_key,time,parentId,tagId) values('%s',%s,%s,'%s',%s,%s,%s)", + roomid, gid, uid, rec_key, time, par, array.getInt(i)); + EventServer.log.info("sqls:" + sqls); + + DataBase.use().executeUpdate(sqls); + } + + } + + share(uid + ""); + return 0; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerPay.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerPay.java new file mode 100644 index 0000000..5a8f32a --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerPay.java @@ -0,0 +1,84 @@ +package com.evt.mgr.handler; + +import java.util.ArrayList; + +import com.data.cache.AccountCache; +import com.data.util.ConsumeCode; +import com.data.util.Utility; +import com.evt.mgr.EventController; +import com.evt.mgr.IHandler; +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; + +import redis.clients.jedis.Jedis; + +public class HandlerPay implements IHandler{ + + int reason; + boolean isPay; + public HandlerPay(int reason,boolean isPay) { + this.reason = reason; + this.isPay = isPay; + } + private static final Logger log = Logger.getLogger(HandlerPay.class); + + @Override + public int process(int uid, ITObject param) throws Exception { + int pay = param.getInt("pay"); + if(pay==0) { + return 0; + } + int result = 1; + int gameId =param.getInt("game"); + int groupId = 0; + int pid = 0; + if(param.containsKey("group")) { + groupId = param.getInt("group"); + } + if(param.containsKey("pid")) { + pid = param.getInt("pid"); + } + + if(reason == ConsumeCode.DIAMO_JOIN_ROOM) { + pay = Math.abs(pay); + } + if(reason == ConsumeCode.DIAMO_REFUND) { + pay = -Math.abs(pay); + } + if(reason == ConsumeCode.DIAMO_ADD) { + pay = -pay; + } + + if(isPay) { + int cur_diamo = param.getInt("diamo"); + EventController.payDiamo(uid, pay, cur_diamo, reason, gameId, groupId, pid); + result = 0; + }else { + String session = AccountCache.genKey(uid); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + ArrayList result_list = Utility.payDiamo(jedis0, session,pay); + if(result_list!=null) { + result = result_list.get(0).intValue(); + if(result ==0) { + long cur_diamo = result_list.get(1); + EventController.payDiamo(uid, pay, (int)cur_diamo, reason, gameId, groupId, pid); + } + result = 0; + } + }finally { + jedis0.close(); + } + } + + return result; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/handler/HandlerWin.java b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerWin.java new file mode 100644 index 0000000..dffc80f --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/handler/HandlerWin.java @@ -0,0 +1,18 @@ +package com.evt.mgr.handler; + +import com.evt.mgr.IHandler; +import com.taurus.core.entity.ITObject; + +public class HandlerWin implements IHandler{ + + @Override + public int process(int uid, ITObject param) throws Exception { + return 0; + } + + @Override + public int processGroup(int groupId, ITObject param) throws Exception { + return 0; + } + +} diff --git a/event_mgr/src/main/java/com/evt/mgr/job/CleanGroupLogJob.java b/event_mgr/src/main/java/com/evt/mgr/job/CleanGroupLogJob.java new file mode 100644 index 0000000..a0ed0d9 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/job/CleanGroupLogJob.java @@ -0,0 +1,94 @@ +package com.evt.mgr.job; + +import java.util.List; +import java.util.Set; + +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.util.DateUtils; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; + +import com.data.util.EventType; +import com.data.util.Utility; +import com.evt.mgr.GroupPublisherService; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.ScanParams; +import redis.clients.jedis.ScanResult; + +public class CleanGroupLogJob implements Job { + private Logger logger = Logger.getLogger(CleanGroupLogJob.class); + + public CleanGroupLogJob() { + + } + + /** + * 清除亲友圈中无效的房间 + */ + private void cleanGroupMemberLog() { + int time = DateUtils.getBeginDay() - 5 * 24 * 3600; + String deleteSql = String.format("delete from group_member_log where time < %s", time); + try { + long startTime = System.currentTimeMillis(); + DataBase.use().executeUpdate(deleteSql); +// logger.info("cleanGroupMemberLog use time:"+(System.currentTimeMillis()-startTime)+ " " + deleteSql); + } + catch (Exception e) + { + logger.error(e); + } + } + + private void CleanGroupHpLog() { + int time = DateUtils.getBeginDay() - 20 * 24 * 3600; + String deleteSql3 = String.format("delete from group_hp_log where time < %s limit 1000000", time); + try { + long startTime = System.currentTimeMillis(); + DataBase.use().executeUpdate(deleteSql3); +// logger.info("CleanGroupHpLog use time:"+(System.currentTimeMillis()-startTime)+ " " + deleteSql3); + } + catch (Exception e) + { + logger.error(e); + } + } + + private void CleanRecRoomLog() { + int time = DateUtils.getBeginDay() - 5 * 24 * 3600; + String deleteSql2 = String.format("delete from room_rec_log where time < %s limit 1000000", time); + try { + long startTime = System.currentTimeMillis(); + DataBase.use().executeUpdate(deleteSql2); +// logger.info("CleanRecRoomLog use time:"+(System.currentTimeMillis()-startTime) + " " + deleteSql2); + } + catch (Exception e) + { + logger.error(e); + } + } + + @Override + public void execute(JobExecutionContext context) { + JobKey jobKey = context.getJobDetail().getKey(); + if(jobKey.getName().equals("clean_group_member_log")) { + logger.info("执行成功" + jobKey.getName()); + cleanGroupMemberLog(); + } + if(jobKey.getName().equals("clean_group_hp_log")) { + logger.info("执行成功" + jobKey.getName()); + CleanGroupHpLog(); + } + if(jobKey.getName().equals("clean_rec_room_log")) { + logger.info("执行成功" + jobKey.getName()); + CleanRecRoomLog(); + } + } +} diff --git a/event_mgr/src/main/java/com/evt/mgr/job/CleanTimeOutRoomJob.java b/event_mgr/src/main/java/com/evt/mgr/job/CleanTimeOutRoomJob.java new file mode 100644 index 0000000..e500016 --- /dev/null +++ b/event_mgr/src/main/java/com/evt/mgr/job/CleanTimeOutRoomJob.java @@ -0,0 +1,323 @@ +package com.evt.mgr.job; + +import java.util.List; +import java.util.Set; + +import com.taurus.core.util.DateUtils; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; + +import com.data.util.EventType; +import com.data.util.Utility; +import com.evt.mgr.GroupPublisherService; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.ScanParams; +import redis.clients.jedis.ScanResult; + +public class CleanTimeOutRoomJob implements Job{ + + private Logger logger = Logger.getLogger(CleanTimeOutRoomJob.class); + + public CleanTimeOutRoomJob() { + + } + + private void deleteRoomFromRedis(String tag_key,Jedis jedis0) { + + RedisLock room_lock = new RedisLock(tag_key, jedis0); + try { + // 0 1 2 3 4 5 6 7 8 9 + List paramList = jedis0.hmget(tag_key, "AA", "payer", "pay", "group","game","delete_status","status","create_time","id","players"); + + if(StringUtil.isEmpty(paramList.get(4))) { + Redis.use().expire(tag_key, 20); + return; + } + + String delete_status = paramList.get(5); + if(StringUtil.isEmpty(delete_status)) { + + String status = paramList.get(6); + int _status = Integer.parseInt(status); + if(_status == 2 || _status == 3) { +// logger.info(tag_key + "房间的状态不对,此时房间的状态["+status + "]"); + Redis.use().expire(tag_key, 20); + return; + } + + // 如果房间的存活时间小于4个小时,考虑到游戏服务器也在删除 所以延时10分钟 + String create_time = paramList.get(7); + String roomid = paramList.get(8); + long now = System.currentTimeMillis() / 1000; + if((now - Long.parseLong(create_time)) > 14400 + 600) { + + deleteRoomFromServer(tag_key,jedis0,false); + } + + return; + } + + boolean pay_AA = Integer.parseInt(paramList.get(0)) == 1; + int payer = Integer.parseInt(paramList.get(1)); + int pay = Integer.parseInt(paramList.get(2)); + int gameId = Integer.parseInt(paramList.get(4)); + String group = paramList.get(3); + int _gid = 0; + if(StringUtil.isNotEmpty(group)) { + _gid = Integer.parseInt(group); + } + int _delete_status = Integer.parseInt(delete_status); + if(_delete_status == 0) { + + // 如果需要支付钻石 + if(pay > 0) { + + if (pay_AA) { + + String players_json = paramList.get(9); + if(StringUtil.isEmpty(players_json) == false) { + ITArray players = TArray.newFromJsonData(players_json); + for (int i = 0; i < players.size(); i++) { + //GroupPublisherService.refundDiamo(players.getInt(i), pay, _gid, gameId); + } + } + }else{ + + if(_gid == 0) { + //GroupPublisherService.refundDiamo(payer, pay, _gid, gameId); + } + } + } + } + + Redis.use().hset(tag_key, "status", 3 + ""); + Redis.use().hincrBy(tag_key, "cache_ver", 1); + Redis.use().expire(tag_key, 20); + } + catch(Exception e) { + logger.info(tag_key + "删除房间发生异常["+e.getMessage() + "]"); + } + finally { + room_lock.unlock(false); + } + } + + private boolean deleteRoomFromServer(String roomid,Jedis jedis0,boolean lock) { + + String tag_key = roomid; + RedisLock room_lock = null; + + if(lock) { + room_lock = new RedisLock(tag_key, jedis0); + } + + try { + + if( jedis0.exists(tag_key) == false) { + return false; + } + // 0 1 2 3 4 5 6 7 + List paramList = jedis0.hmget(tag_key, "AA", "payer", "pay", "group","game","status","create_time","id"); + + String status = paramList.get(5); + int _status = Integer.parseInt(status); + if(_status == 2 || _status == 3) { + logger.info("删除房间" + roomid + "失败,原因状态不对,此时的状态是[" + _status +"]"); + return true; + } + + String group = paramList.get(3); + int _gid = 0; + if(StringUtil.isNotEmpty(group)) { + _gid = Integer.parseInt(group); + } + + // 如果房间的存活时间小于4个小时,考虑到游戏服务器也在删除 所以延时10分钟 + String create_time = paramList.get(6); + long now = System.currentTimeMillis() / 1000; + if((now - Long.parseLong(create_time)) < 14400 + 600) { + logger.info("删除房间" + roomid + "失败,房间距离创建没有超过4个小时"); + return true; + } + + if(_gid != 0) { + + // 如果游戏没有开始_status = 0 + // 不是aa支付,则退出回创建者创建钻石的费用 + // aa支付,设置status=2之后,则交给游戏服务器去做(如果游戏服务器挂了呢,或者房间在游戏服务器中根本就不存在呢), + // 如果游戏已经开始_status = 1,则不用考虑钻石回退的问题,下一次执行的时候,如果redis还存在房间的信息,则直接从redis删除就可以了 + if(_status==0) { + + int gameId = Integer.parseInt(paramList.get(4)); + boolean pay_AA = Integer.parseInt(paramList.get(0)) == 1; + if (!pay_AA) { + int payer = Integer.parseInt(paramList.get(1)); + int pay = Integer.parseInt(paramList.get(2)); + //Utility.payDiamo(EventType.REDIS_EVENT_BACK_PAY, payer, gameId, pay, _gid,0); + } + } + String strRoomID = ""; + if(StringUtil.isNotEmpty(paramList.get(7))) { + strRoomID =paramList.get(7); + } + GroupPublisherService.delRoomEvt(_gid, strRoomID); + } + + jedis0.hset(tag_key, "status", "2"); + jedis0.hset(tag_key, "delete_status", "" + status); + jedis0.hincrBy(tag_key, "cache_ver", 1); + + logger.info("删除房间" + roomid + "成功"); + } + catch(Exception e){ + + } + finally { + + if(room_lock != null) { + room_lock.unlock(false); + } + } + + return true; + } + + /** + * 清除无效的房间 + */ + private void cleanInvalidRoom() { + try { + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + + String cursor = ScanParams.SCAN_POINTER_START; + String key = "room:*"; + ScanParams scanParams = new ScanParams(); + scanParams.match(key); + scanParams.count(1000); + + // 处理所有redis的房间 + while (true){ + + ScanResult scanResult = jedis0.scan(cursor, scanParams); + cursor = scanResult.getStringCursor(); + List list = scanResult.getResult(); + + for(int m = 0; m < list.size(); m++){ + + String mapentry = list.get(m); + logger.info("正在检查房间 " + mapentry); + deleteRoomFromRedis(mapentry,jedis0); + } + + if ("0".equals(cursor)){ + break; + } + } + } + finally { + jedis0.close(); + } + } + catch(Exception e) { + + } + } + + /** + * 清除亲友圈中无效的房间 + */ + private void cleanGroupRoom() { + + try { + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + RedisLock lock = new RedisLock("room_clean", jedis11); + try { + + String cursor = ScanParams.SCAN_POINTER_START; + String key = "*:rooms*"; + ScanParams scanParams = new ScanParams(); + scanParams.match(key); + scanParams.count(1000); + + // 处理亲友圈的房间 + while (true){ + + ScanResult scanResult = jedis11.scan(cursor, scanParams); + cursor = scanResult.getStringCursor(); + List list = scanResult.getResult(); + + for(int m = 0; m < list.size(); m++){ + + + String mapentry = list.get(m); + logger.info("正在查询群" +mapentry + "的无效房间"); + Set rooms = jedis11.zrangeByScore(mapentry, 100000, 1000000); + + for (String roomId : rooms) { + logger.info("正在查询群" +mapentry + "的无效房间" + roomId); + boolean existed = deleteRoomFromServer(roomId,jedis0,true); + if(!existed) { + jedis11.zrem(mapentry, roomId); + logger.info("删除群" +mapentry + "的无效房间" + roomId + "因为房间不存在"); + } + } + } + + if ("0".equals(cursor)){ + break; + } + } + } + finally { + lock.unlock(); + jedis0.close(); + jedis11.close(); + } + } + catch(Exception e) { + + } + } + + /** + * 清除亲友圈中无效的房间 + */ + private void cleanGroupMemberLog() { + int time = DateUtils.getBeginDay() - 5 * 24 * 3600; + String deleteSql = String.format("delete from group_member_log where time < %s", time); + Utility.evtdbLog(1, 1, deleteSql); + String deleteSql2 = String.format("delete from room_rec_log where time < %s and time > %s", time, time - 24 * 3600); + Utility.evtdbLog(1, 1, deleteSql2); + String deleteSql3 = String.format("delete from group_hp_log where time < %s and time > %s", time, time - 24 * 3600); + Utility.evtdbLog(1, 1, deleteSql3); + } + + @Override + public void execute(JobExecutionContext context) { + + JobKey jobKey = context.getJobDetail().getKey(); + if(jobKey.getName().equals("clean_group_room") || jobKey.getName().equals("clean_group_room1")) { + logger.info("执行成功" + jobKey.getName()); + cleanGroupRoom(); + logger.info("执行成功cleanGroupMemberLog"); + cleanGroupMemberLog(); + } + else if(jobKey.getName().equals("clean_invalid_room")|| jobKey.getName().equals("clean_invalid_room1")) { + logger.info("执行成功" + jobKey.getName()); + cleanInvalidRoom(); + } + } +} diff --git a/event_mgr/src/main/webapp/WEB-INF/web.xml b/event_mgr/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..7b0149b --- /dev/null +++ b/event_mgr/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ + + + + + taurus-web + com.taurus.web.WebFilter + + main + com.evt.mgr.EventServer + + + + + taurus-web + /* + + diff --git a/event_mgr/src/main/webapp/config/log4j.properties b/event_mgr/src/main/webapp/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/event_mgr/src/main/webapp/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/event_mgr/src/main/webapp/config/taurus-core.xml b/event_mgr/src/main/webapp/config/taurus-core.xml new file mode 100644 index 0000000..6d5a892 --- /dev/null +++ b/event_mgr/src/main/webapp/config/taurus-core.xml @@ -0,0 +1,98 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/event_mgr/src/test/java/MainEventMgr.java b/event_mgr/src/test/java/MainEventMgr.java new file mode 100644 index 0000000..ccdf5ee --- /dev/null +++ b/event_mgr/src/test/java/MainEventMgr.java @@ -0,0 +1,12 @@ + + +import com.taurus.web.JettyServer; + +public class MainEventMgr { + + public static void main(String[] args) { + new JettyServer("src/main/webapp",8083,"/").start(); + + } + +} diff --git a/game_common/.idea/compiler.xml b/game_common/.idea/compiler.xml new file mode 100644 index 0000000..7fa5e4b --- /dev/null +++ b/game_common/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/game_common/.idea/encodings.xml b/game_common/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/game_common/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/game_common/.idea/jarRepositories.xml b/game_common/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/game_common/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/game_common/.idea/misc.xml b/game_common/.idea/misc.xml new file mode 100644 index 0000000..d5cd614 --- /dev/null +++ b/game_common/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/game_common/.idea/vcs.xml b/game_common/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/game_common/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/game_common/pom.xml b/game_common/pom.xml new file mode 100644 index 0000000..d4bb088 --- /dev/null +++ b/game_common/pom.xml @@ -0,0 +1,85 @@ + + 4.0.0 + + com.game + game_common + 1.0.0 + jar + game_common + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 3.8.1 + test + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-permanent + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + + game_common-${version} + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + diff --git a/game_common/src/main/java/com/game/ActionEvent.java b/game_common/src/main/java/com/game/ActionEvent.java new file mode 100644 index 0000000..19bd769 --- /dev/null +++ b/game_common/src/main/java/com/game/ActionEvent.java @@ -0,0 +1,51 @@ +package com.game; + +/** + * 服务器内部事件常量表 + * + */ +public class ActionEvent { + + /** + * 准备 + */ + public static final String EVENT_READY = "ready"; + + /** + * 准备洗牌 + */ + public static final String EVENT_READY_AND_XIPAI = "ready_and_xipai"; + + /** + * 开始游戏 + */ + public static final String EVENT_START_GAME = "start_game"; + + /** + * 退出房间 + */ + public static final String EVENT_EXIT_ROOM = "exit_room"; + + /** + * 自动 + */ + public static final String EVENT_TIMER_AUTO = "timer_auto"; + /** + * 托管 + */ + public static final String EVENT_ENTRUST = "entrust"; + /** + * 离线 + */ + public static final String EVENT_OFFLINE = "offline"; + + /** + * 洗牌 + */ + public static final String EVENT_XIPAI = "xi_pai"; + + /** + * 观战 + */ + public static final String EVENT_SPECTATOR = "spectator"; +} diff --git a/game_common/src/main/java/com/game/Constant.java b/game_common/src/main/java/com/game/Constant.java new file mode 100644 index 0000000..41be2a2 --- /dev/null +++ b/game_common/src/main/java/com/game/Constant.java @@ -0,0 +1,62 @@ +package com.game; + +public interface Constant { + /** + * 当局大结算 + */ + int ENTRUST_CURREN_RESULT = 1; + /** + * 满2局大结算 + */ + int ENTRUST_TWO_RESULT = 2; + /** + * 满3局大结算 + */ + int ENTRUST_THREE_RESULT = 3; + /** + * 满局大结算 + */ + int ENTRUST_TOTAL_RESULT1 = 4; + + /** + * 未开始 + */ + int ROOM_STATUS_NOBEGIN = 0; + /** + * 游戏中 + */ + int ROOM_STATUS_PLAYING = 1; + /** + * 正准备删除 + */ + int ROOM_STATUS_DEL_FALG = 2; + /** + * 已删除 + */ + int ROOM_STATUS_DEL = 3; + /** + * 正常大结算 + */ + int END_TYPE_NORMAL = 1; + /** + * 托管当局大结算 + */ + int END_TYPE_ENTRUST = 2; + /** + * 体力值不足大结算 + */ + int END_TYPE_HP = 3; + /** + * 申请解散大结算 + */ + int END_TYPE_DISSMISS = 4; + + /** + * 管理员解散大结算 + */ + int END_TYPE_ADMIN = 5; + /** + * 体力值不足 + */ + int HP_NOT_ENOUGH = -1; +} diff --git a/game_common/src/main/java/com/game/EventController.java b/game_common/src/main/java/com/game/EventController.java new file mode 100644 index 0000000..ace150e --- /dev/null +++ b/game_common/src/main/java/com/game/EventController.java @@ -0,0 +1,376 @@ +package com.game; + +import java.sql.SQLException; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import com.data.bean.GameBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.EventType; +import com.game.data.Player; +import com.game.data.Room; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; + +/** + * redis 事件控制器 + */ +public class EventController { + private final static String GROUP_EVT_KEY = "evt_group_"; + private final static String EVT_KEY = "event_"; + private final static String CHACHE_KEY = "group1_db8"; + + private final static String EVT_TYPE = "E"; + private final static String EVT_GID = "gid"; + private final static String EVT_UID = "uid"; + + private static void sendGroupEvt(int type, int gid, ITObject data) { + int id = gid % 10; + data.putInt(EVT_GID, gid); + data.putInt(EVT_TYPE, type); + Redis.use(CHACHE_KEY).lpush(GROUP_EVT_KEY + id, data.toJson()); + } + + private static void sendEvt(int type, int uid, ITObject data) { + int id = uid % 10; + data.putInt(EVT_UID, uid); + data.putInt(EVT_TYPE, type); + Redis.use(CHACHE_KEY).lpush(EVT_KEY + id, data.toJson()); + } + + /** + * 注册redis事件 + * + * @param uid + * @param type + * @param num + */ + public void redisEvent(int uid, int type, int num) { + ITObject data = TObject.newInstance(); + data.putInt("N", num); + sendEvt(type, uid, data); + } + + /** + * 圈子一局结束事件 + * + * @param gid + * @param pid + * @param valid + */ + public void redisGroupRound(Room room, int gid, int pid, int valid) { + ITObject data = TObject.newInstance(); + data.putInt("pid", pid); + data.putInt("valid", valid); + data.putTArray("player_list", room.getValidPlayerList()); + data.putInt("perfect_round", room.endType == Constant.END_TYPE_NORMAL ? 1 : 0); + int maxPlayer = room.getValidPlayer(); + if (valid == 1 && maxPlayer > 0) { + data.putInt("valid_count", 100 / maxPlayer); + } else { + data.putInt("valid_count", 0); + } + + if (maxPlayer > 0) { + data.putInt("all_count", 100 / maxPlayer); + } + + try { + GroupPlayBean gpb = GroupCache.getPlay(gid, pid); + if (gpb != null) { + int maxPlayers = gpb.maxPlayers; + ITObject configData = TObject.newFromJsonData(gpb.config); + int opt = configData.getInt("opt"); + int gameId = gpb.gameId; + GameBean gb = GameCache.getGame(gameId); + if (gb != null) { + + int score = 0; + for (Entry entry : room.playerMapById.entrySet()) { + Player player = entry.getValue(); + + if (player.score.total_score > score) { + score += Math.abs(player.score.total_score); + } + } + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int diamo = Integer.parseInt(jedis10.hget("g{" + gid + "}:diamo", "diamo")); + if (room.round <= 1 && score == 0) { + data.putInt("valid_diamo", 0); + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + jedis10.hset("g{" + gid + "}:diamo", "diamo", (diamo + pay) + ""); + // 保存预扣房卡消息 + Global.logger.info("返回全部房卡-----------------------"); + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + gid, 1, diamo + pay, pay, System.currentTimeMillis(),0, 0,gb.name,""); + if (DataBase.use() != null) { + DataBase.use().executeUpdate(messagesql); + } + + } else { + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + if (pay != null && pay > 0 && maxPlayer > 0) { + int maxRound = room.hpData.getInt("maxRound"); + + if (maxRound > room.round) { + double payDiamo = Math.ceil((double) pay / room.hpData.getInt("maxRound") * room.round); + data.putInt("valid_diamo", (int) payDiamo * 100); + int backDiamo = (pay - (int) payDiamo); + jedis10.hset("g{" + gid + "}:diamo", "diamo", (diamo + backDiamo) + ""); + // 保存预扣房卡消息 + Global.logger.info("返回部分房卡-----------------------"); + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + gid, 1, diamo+backDiamo, backDiamo, System.currentTimeMillis(),0, 0,gb.name,""); + + DataBase.use().executeUpdate(messagesql); + } else { + data.putInt("valid_diamo", pay * 100); + } + + } + } + } + } + } catch (Exception e) { + Global.logger.error(e); + } + + sendGroupEvt(EventType.REDIS_EVENT_GROUP_ROUND, gid, data); + } + + /** + * 圈子玩家一局结束事件 + * + * @param owner + * @param pid + * @param win + */ + public void redisGroupMemberRound(Player owner, int pid, boolean win, boolean hpPump, int cur_hp) { + + Room room = owner.room; + ITObject data = TObject.newInstance(); + data.putInt("pid", pid); + data.putInt("uid", owner.playerid); +// if (owner.hp != null) { +// data.putInt("score", owner.hp.total_hp); +// } else { +// data.putInt("score", owner.score.total_score); +// } + data.putInt("score", owner.score.total_score); + data.putInt("time", (int) (System.currentTimeMillis() / 1000)); + data.putInt("pump", owner.practicalHpPump); + data.putInt("xi_pai_total", owner.xi_pai_total); + data.putInt("win", win ? 1 : 0); + data.putInt("perfect_round", owner.room.endType == Constant.END_TYPE_NORMAL ? 1 : 0); + data.putInt("cur_hp", cur_hp); + data.putUtfString("room", room.roomid); + int maxPlayer = owner.room.getValidPlayer(); + if (hpPump && maxPlayer > 0) { + data.putInt("valid_count", 100 / maxPlayer); + } else { + data.putInt("valid_count", 0); + } + + sendGroupEvt(EventType.REDIS_EVENT_GROUP_MEMBER_ROUND, owner.room.groupId, data); + } + + /** + * 注册redis体力值事件 reward以前没有用到,现在表示抽水值只给盟主,不给合伙人参与分成 + */ + public long redisFag(Player owner, int hp, boolean hpPump, boolean mengzhu_reward, int xipai_score, boolean xipai, + String desc) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + Room room = owner.room; + String gm_key = GroupMemberCache.genKey(room.groupId, owner.playerid); + + long cur_hp = 0; + if (hpPump) { + String strCurHp = Redis.use("group1_db10").hget(gm_key, "hp"); + if (StringUtil.isNotEmpty(strCurHp)) { + cur_hp = Long.parseLong(strCurHp); + if (cur_hp < owner.practicalHpPump) { + owner.practicalHpPump = (int) cur_hp; + if (owner.practicalHpPump < 0) { + owner.practicalHpPump = 0; + } + } + } + cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", -owner.practicalHpPump); + } else if (xipai) { + String strCurHp = Redis.use("group1_db10").hget(gm_key, "hp"); + if (StringUtil.isNotEmpty(strCurHp)) { + cur_hp = Long.parseLong(strCurHp); + if (cur_hp < xipai_score) { + xipai_score = (int) cur_hp; + if (xipai_score < 0) { + xipai_score = 0; + } + } + } + cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", -xipai_score); + } else { + cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", hp); + } + + ITObject data = TObject.newInstance(); + if (cur_hp > Integer.MAX_VALUE) { + long del_value = cur_hp - (long) Integer.MAX_VALUE; + cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", -del_value); + Redis.use("group1_db10").hincrBy(gm_key, "bank_hp", del_value); + data.putInt("hp_than_max_value", (int) del_value); + } + data.putInt("hp", hp); + data.putInt("cur_hp", (int) cur_hp); + data.putInt("pid", room.groupPid); + data.putInt("uid", owner.playerid); + data.putInt("time", (int) (System.currentTimeMillis() / 1000)); + data.putUtfString("room", room.roomid); + // 临时处理 + data.putUtfString("desc", StringUtil.isNotEmpty(desc) ? desc : Global.gameName + " " + room.roomid); + data.putInt("rewardType", room.rewardType); + data.putInt("rewardValueType", room.rewardValueType); + data.putInt("xipai_rewardType", room.xipai_rewardType); + data.putInt("xipai_rewardValueType", room.xipai_rewardValueType); + if (xipai) { + data.putInt("xipai", xipai_score); + int xipai_reward_value = 0; + if (room.xipai_rewardValueType == 1) { + xipai_reward_value = xipai_score; + } + + data.putInt("max_player", room.maxPlayers); + data.putInt("xipai_reward_type", room.xipai_rewardType); + data.putInt("xipai_reward_value", xipai_reward_value); + if (StringUtil.isNotEmpty(owner.prs) && !mengzhu_reward) { + data.putUtfString("prs", owner.prs); + } + } + if (hpPump) { + data.putInt("pump", owner.practicalHpPump); + int reward_value = 0; + int max_player = room.getValidPlayer(); + if (room.rewardValueType == 1) { + + if (room.rewardType == 1) { + if (room.totalPump + room.basePump != 0) { + reward_value = owner.practicalHpPump + - room.basePump * owner.practicalHpPump / (room.totalPump + room.basePump); + } else { + reward_value = owner.practicalHpPump; + } + } else { + reward_value = room.totalPump / max_player; + if (room.basePump > 0) { + if (reward_value + (room.basePump / max_player) > owner.practicalHpPump) { + reward_value = owner.practicalHpPump - (room.basePump / max_player); + if (reward_value < 0) { + reward_value = 0; + } + } + } else { + if (reward_value > owner.practicalHpPump) { + reward_value = owner.practicalHpPump; + } + } + } + } + + data.putInt("max_player", room.getValidPlayer()); + data.putInt("reward_type", room.rewardType); + data.putInt("reward_value", reward_value); + if (StringUtil.isNotEmpty(owner.prs) && !mengzhu_reward) { + data.putUtfString("prs", owner.prs); + } + } + sendGroupEvt(EventType.REDIS_EVENT_GROUP_HP, room.groupId, data); + return cur_hp; + + } finally { + jedis10.close(); + } + + } + + /** + * 返还钻石 + * + * @param uid + * @param pay + * @param groupId + */ + public void refundDiamo(int uid, int pay, int groupId, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("pay", -pay); + data.putInt("game", Global.gameId); + if (groupId > 0) { + data.putInt("group", groupId); + data.putInt("pid", pid); + } +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// try { +// int diamo = Integer.parseInt(jedis0.hget("{user}:" + uid, "diamo")); +// String sql = String.format("insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid)" +// + " values(%s,%s,%s,%s,%s,%s,%s)", 0, 1, diamo, pay, System.currentTimeMillis(), 0,uid); +// DataBase.use().executeUpdate(sql); +// +// } catch (SQLException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// }finally { +// jedis0.close(); +// } + +// sendEvt(EventType.REDIS_EVENT_BACK_PAY, uid, data); + } + + /** + * 大局结束事件 + * + * @param + * @param + * @param + */ + public void redisOver(Player owner, int time, String rec_key) { + Room room = owner.room; + ITObject data = TObject.newInstance(); + if (StringUtil.isNotEmpty(rec_key)) { + data.putInt("is_rec", 1); + data.putUtfString("roomid", room.roomid); + data.putInt("gid", room.groupId); + data.putUtfString("rec_key", rec_key); + data.putInt("time", time); + } else { + data.putInt("is_rec", 0); + } + // 保存聊天室在线人员 + String groupIdKey = "g{" + room.groupId + "}:onlines"; + Map onlines = Redis.use("group1_db10").hgetAll(groupIdKey); + ITArray array = TArray.newInstance(); + Set keys = onlines.keySet(); + for (String key : keys) { + int uid = Integer.parseInt(key); + array.addInt(uid); + } + data.putTArray("tagIds", array); + + sendEvt(EventType.REDIS_EVENT_OVER, owner.playerid, data); + } +} diff --git a/game_common/src/main/java/com/game/GPSUtil.java b/game_common/src/main/java/com/game/GPSUtil.java new file mode 100644 index 0000000..36637fd --- /dev/null +++ b/game_common/src/main/java/com/game/GPSUtil.java @@ -0,0 +1,63 @@ +package com.game; + +import com.taurus.core.util.StringUtil; + +/** + * @author dong.teng + */ +public class GPSUtil { + // 地球半径 + private static final double EARTH_RADIUS = 6378137; + + private static double radian(double lngLat) { + return lngLat * Math.PI / 180.0; + } + + /** + * 根据两点间经纬度坐标,计算直线距离 单位 :米 + */ + public static double getDistance(String gps1, String gps2) { + double distance = 0; + if (isOpenGPS(gps1) && isOpenGPS(gps2)) { + String[] gps1Arr = gps1.split(","); + String[] gps2Arr = gps2.split(","); + Double lat1 = Double.parseDouble(gps1Arr[1]); + Double lng1 = Double.parseDouble(gps1Arr[0]); + Double lat2 = Double.parseDouble(gps2Arr[1]); + Double lng2 = Double.parseDouble(gps2Arr[0]); + double radLat1 = radian(lat1); + double radLat2 = radian(lat2); + double a = radLat1 - radLat2; + double b = radian(lng1) - radian(lng2); + distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); + distance *= EARTH_RADIUS; + distance = Math.round(distance * 10000) / 10000; + } + return distance; + } + + /** + * 两位置是否过近 + * + * @param gps1 + * @param gps2 + * @param measure + * 衡量过近米 + * @return + */ + public static boolean isDistanceNear(String gps1, String gps2, int measure) { + return getDistance(gps1, gps2) <= measure; + } + + /** + * 是否打开gps + */ + public static boolean isOpenGPS(String gps) { + return StringUtil.isNotEmpty(gps) && gps.contains(","); + } + + public static void main(String[] args) { + System.out.println(isDistanceNear("109.19300079346,27.710248947144", "100.23030090332,25.59494972229",50)); + } + +} diff --git a/game_common/src/main/java/com/game/GameController.java b/game_common/src/main/java/com/game/GameController.java new file mode 100644 index 0000000..fc33379 --- /dev/null +++ b/game_common/src/main/java/com/game/GameController.java @@ -0,0 +1,1022 @@ +package com.game; + +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import com.data.bean.AccountBean; +import com.data.bean.GameBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ErrorCode; +import com.data.util.EventType; +import com.data.util.Utility; +import com.game.data.JoinRoomData; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerInitState; +import com.game.player.state.PlayerReadyState; +import com.game.player.state.PlayerSpectatorState; +import com.game.room.state.RoomDestoryGameState; +import com.mysql.cj.xdevapi.JsonParser; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.core.util.StringUtil; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +import redis.clients.jedis.Jedis; + +/** + * 基本游戏控制器 + * + */ +public class GameController implements IController { + + /** + * 聊天 + */ + @ActionKey(Router.GAME_INTERACTION) + public void routerChat(Session sender, ITObject params, int gid, Player owner) { + int canMissile = owner.room.hpData.getInt("BanMissile"); + int canChat = owner.room.hpData.getInt("BanChat"); + int type = params.getInt("type"); + TObject data = new TObject(); + data.putInt("canMissile", canMissile); + + // 禁止表情 + if (canMissile == 1 && type == 7) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_EMOJI, data, sender); + } else if (canMissile == 0 && type == 7) { + owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + + // 禁止聊天 + if (canChat == 1 && type == 2) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_CHAT, data, sender); + } else if (canChat == 0 && (type == 2 || type == 4 || type == 3)) { + owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + + // 禁止聊天 + if (canChat == 1 && type == 1) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_CHAT, data, sender); + } else if (canChat == 0 && (type == 2 || type == 4 || type == 3 || type == 1)) { + owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + + // 禁止表情 + if (canMissile == 1 && type == 7) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_EMOJI, data, sender); + } else if (canMissile == 0 && type == 7) { + + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + + // 禁止聊天 + if (canChat == 1 && type == 2) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_CHAT, data, sender); + } else if (canChat == 0 && (type == 2 || type == 4 || type == 3)) { + + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + + // 禁止聊天 + if (canChat == 1 && type == 1) { + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_BAN_CHAT, data, sender); + } else if (canChat == 0 && (type == 2 || type == 4 || type == 3 || type == 1)) { + + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_INTERACTION, params); + + } + } + + /** + * 请求准备 + * + */ + @ActionKey(Router.GAME_READY) + public void routerReady(Session sender, ITObject params, int gid, Player owner) { + System.out.println("---------------参数session为null,参数params:" + params); + + owner.stateMachine.execute(ActionEvent.EVENT_READY, gid, params); + } + + /** + * 请求准备 + * + */ + @ActionKey(Router.GAME_READY_AND_XIPAI) + public void routerReadyAndXiPai(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(ActionEvent.EVENT_READY_AND_XIPAI, gid, params); + } + + /** + * 请求开始游戏 + */ + @ActionKey(Router.GAME_START) + public void routerStartGame(Session sender, ITObject params, int gid, Player owner) { + owner.room.stateMachine.execute(ActionEvent.EVENT_START_GAME, gid, params); + } + + @ActionKey(Router.GAME_XIPAI) + public void RouterXiPai(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(ActionEvent.EVENT_XIPAI, 0, params); + owner.room.stateMachine.execute(ActionEvent.EVENT_XIPAI, 0, params); + } + + /** + * 托管 + * + */ + @ActionKey(Router.GAME_ENTRUST) + @SuppressWarnings("unchecked") + public void routerEntrust(Session sender, ITObject params, int gid, Player owner) { + if (owner.room.status == Constant.ROOM_STATUS_PLAYING && owner.room.isEntrust()) { + owner.entrust = params.getBoolean("ok"); + Global.gameCtr.updatePlayerEntrust(owner); + Global.logger.info(owner + " manual " + (owner.entrust ? "entrust" : "quitEntrust")); + if (owner.entrust) { + owner.setEntrustData(params); + owner.stateMachine.curState.execute(owner, ActionEvent.EVENT_ENTRUST, gid, params); + } else { + owner.exitEntrust(); + } + } + } + + /** + * 请求进入房间 + */ + @ActionKey(value = Router.GAME_JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER) + public void routerJoinRoom(Session sender, ITObject params, int gid) { + String session_id = params.getUtfString("session"); + String[] sourceStrArrays = session_id.split(","); + String uid = sourceStrArrays[0]; + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + jedis0.hset(uid, "online", "startPlaying"); + String userOnline = jedis0.hget(uid, "online"); + TObject param = new TObject(); + param.putString("online", userOnline); + String[] split = uid.split(":"); + String uids = split[1]; + param.putString("uid", uids); + String key = GroupCache.genGroupsKey(Integer.parseInt(uids)); + Set groups = jedis11.zrevrange(key, 0, -1); + for (String tem : groups) { + GroupPublisherService.playerGameState(Integer.parseInt(tem), param); + } + } catch (Exception e) { + Global.logger.error("setGroupHeartbeat error-------", e); + } finally { + jedis0.close(); + jedis11.close(); + } + +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// try { +// Global.logger.info("进入房间---------------"); +// jedis0.hset("{user}:" + acc.id, "online", "startPlaying"); +// } catch (Exception e) { +// Global.logger.error("setGroupHeartbeat error", e); +// }finally { +// jedis0.close(); +// } + + // String sessionToken = Utils.getUniqueSessionToken(sender); + String token = null; + if (StringUtil.isEmpty(session_id)) { + session_id = ""; + } else { + String[] sourceStrArray = session_id.split(","); + if (sourceStrArray.length == 2) { + session_id = sourceStrArray[0]; + token = sourceStrArray[1]; + } + + if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session_id)) { + String token_session = Redis.use("group1_db0").hget(token, "user"); + if (StringUtil.isEmpty(token_session)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } else { + if (!token_session.equals(session_id)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + } else { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + sender.setHashId(session_id); + String pos = params.getUtfString("pos"); +// if (!pos.equals("")){ + Global.roomMgr.joinRoom(sender, session_id, gid, pos); +// } + + } + + /** + * 请求进入房间 + */ + @ActionKey(value = Router.GAME_JOIN_SPECTATOR, validate = GameInterceptor.NOT_PLAYER) + public void routerJoinRoom1(Session sender, ITObject params, int gid) { + String session_id = params.getUtfString("session"); + String token = null; + if (StringUtil.isEmpty(session_id)) { + session_id = ""; + } else { + String[] sourceStrArray = session_id.split(","); + if (sourceStrArray.length == 2) { + session_id = sourceStrArray[0]; + token = sourceStrArray[1]; + } + + if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session_id)) { + String token_session = Redis.use("group1_db0").hget(token, "user"); + if (StringUtil.isEmpty(token_session)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } else { + if (!token_session.equals(session_id)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + } else { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + sender.setHashId(session_id); + String pos = params.getUtfString("pos"); + Global.roomMgr.joinRoomOfSpectator(sender, session_id, gid, pos); + } + + /** + * 自动出牌 + */ + @ActionKey(Router.GAME_AUTO_CARD) + public void routerAutoCard(Session sender, ITObject params, int gid, Player owner) { + owner.manualAutoCard = params.getBoolean("autoCard"); + + if (owner.manualAutoCard) { + if (!owner.room.openEntrust) { + owner.manualAutoCard = false; + return; + } + } + + owner.entrust = owner.manualAutoCard; + + Global.gameCtr.updatePlayerEntrust(owner); + Global.logger.info(owner + " manualAutoCard " + (owner.entrust ? "entrust" : "quitEntrust")); + + if (owner.manualAutoCard) { + owner.stateMachine.curState.execute(owner, ActionEvent.EVENT_ENTRUST, gid, params); + } else { + owner.exitEntrust(); + } + } + + /** + * 请求删除解散房间(外部) + * + */ + @ActionKey(value = Router.GAME_REMOVE_ROOM, validate = GameInterceptor.NOT_PLAYER) + public void routerRemoveRoom(Session sender, ITObject params, int gid) { + try { + String roomid = params.getUtfString("room"); + MainServer.instance.sendResponse(gid, 0, null, sender); + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 1, null, sender); + } + } + + /** + * 请求退出房间 + */ + @ActionKey(Router.GAME_EXIT_ROOM) + public void routerExitRoom(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(ActionEvent.EVENT_EXIT_ROOM, gid, params); + + } + + /** + * 请求解散房间 + */ + @ActionKey(Router.GAME_ASK_DISMISS_ROOM) + public void routerAskDismiss(Session sender, ITObject params, int gid, Player owner) { + owner.room.dismissRunable.askDismiss(owner, gid); + } + + /** + * 房间解散投票请求 + */ + @ActionKey(Router.GAME_DISMISS_ROOM_VOTE) + public void routerDismissRoomVote(Session sender, ITObject params, int gid, Player owner) { + boolean agree = params.getBoolean("result"); +// if (agree){ + owner.room.agreeDismisUserId.add(owner.nick); +// }else { +// owner.room.applyDismisUserId =""; +// owner.room.agreeDismisUserId.clear(); +// } + owner.room.dismissRunable.responseDismiss(owner, agree); + } + + /** + * 请求更新GPS位置 + * + */ + @ActionKey(Router.GAME_UPDATE_POS) + public void routerUpdatePos(Session sender, ITObject params, int gid, Player owner) { + owner.gps_pos = params.getUtfString("pos"); + updatePlayerPos(owner); + } + + /** + * 入座 + */ + @ActionKey(Router.GAME_JOIN_SEAT) + public void routerJoinSeat(Session sender, ITObject params, int gid, Player owner) { + Global.gameCtr.joinSeat(owner, gid); + } + +// /** +// * 观战 +// */ +// @ActionKey(Router.GAME_JOIN_SPECTATOR) +// public void routerJoinSpectator(Session sender, ITObject params, int gid) { +// +//// player.seat = 0; +// System.out.println("---------------参数session为null,参数params:"+params); +// Global.logger.info("---------------参数session为null,参数params:{}", params); +//// //进入房间 +//// player.room.addPlayer(player, true, false); +//// ITObject data = new TObject(); +//// data.putInt("player", player.playerid); +//// player.room.loadRedisPlayer(); +//// player.room.broadCastToClient(0, Router.GAME_EVT_JOIN_SPECTATOR, data); +//// Global.roomMgr.joinRoom(sender, session_id, gid, pos); +//// Global.gameCtr.joinSpectator(owner, gid); +// String session_id = params.getUtfString("session"); +// // String sessionToken = Utils.getUniqueSessionToken(sender); +// String token = null; +// if (StringUtil.isEmpty(session_id)) { +// Global.logger.info("---------------参数session为null,参数params:{}", params); +// session_id = ""; +// } else { +// String[] sourceStrArray = session_id.split(","); +// if (sourceStrArray.length == 2) { +// session_id = sourceStrArray[0]; +// token = sourceStrArray[1]; +// } +// +// if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session_id)) { +// String token_session = Redis.use("group1_db0").hget(token, "user"); +// if (StringUtil.isEmpty(token_session)) { +// MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); +// return; +// } else { +// if (!token_session.equals(session_id)) { +// MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); +// return; +// } +// } +// } else { +// MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); +// return; +// } +// } +// sender.setHashId(session_id); +// String pos = params.getUtfString("pos"); +// Global.roomMgr.joinRoomOfSpectator(sender, session_id, gid, pos); +// } + + /** + * 退出观战 + */ + @ActionKey(value = Router.GAME_OUT_SPECTATOR) + public void routerOutSpectator(Session sender, ITObject params, int gid, Player owner) { + + String session_id = "{user}:" + owner.playerid; + Global.roomMgr.outRoomOfSpectator(sender, session_id, gid, owner.playerid); + + } + + /** + * 进入房间 + * + * @param parm + * @param gid + * @return + */ + @SuppressWarnings("unchecked") + public int joinRoom(JoinRoomData parm, int gid) { + Room owner = parm.room; + String session_key = parm.session_key; + Session sender = parm.sender; + String gps_pos = parm.gps_pos; + AccountBean acc = AccountCache.getAccount(session_key); + int playerid = acc.id; + + boolean full = owner.playerMapBySeat.size() >= owner.maxPlayers; + boolean reload = owner.status == Constant.ROOM_STATUS_PLAYING; + + String ip = acc.ip; + if (StringUtil.isEmpty(ip)) { + ip = sender.getAddress(); + } + + Player player = null; + boolean new_player = false; + if (owner.playerMapById.containsKey(playerid)) { + player = owner.playerMapById.get(playerid); + if (player.isReload) { + player.isReload = false; + player.stateMachine.changeState(Global.getState(PlayerInitState.class)); + } + player.setSender(sender); + Global.gameCtr.playerNetState(player); + Global.gameCtr.updatePlayerPos(player); + } else { + if (full) { + sender.setHashId(null); + delRoomSeat(session_key, owner.room_key); + return ErrorCode.ROOM_CLOSE; + } + // 检测是否打开GPS 、IP检测 + boolean openGps = owner.isOpenGPSCheck(), openIP = owner.isOpenIPCheck(); + if (openGps || openIP) { + int errResult = 0; + if (openGps) { + Global.warn("room:{},playid:{},gps:{}", owner.room_key, playerid, gps_pos); + // 开了检测GPS 但是未获取到位置、或未打开 + if (!GPSUtil.isOpenGPS(gps_pos)) { + errResult = 55; + } + // 距离过近 + if (errResult == 0 && owner.checkGps(gps_pos)) { + errResult = 54; + } + } + if (openIP) { + // 相同IP + + if (errResult == 0 && owner.checkIp(ip)) { + errResult = 53; + } + } + if (errResult != 0) { + delRoomSeat(session_key, owner.room_key); + return errResult; + } + } + boolean onseat = true; + long cur_hp = 0; + if (onseat && owner.hpData != null) { + cur_hp = Util.readRedisHp(owner.groupId, playerid); + if (!checkHplimitInRoom(owner, cur_hp)) { + return ErrorCode.GROUP_LIMIT_NO_HP; + } + } + + player = MainServer.instance.newPlayer(playerid, owner, session_key); + player.hp.cur_hp = cur_hp; + + owner.addPlayer(player, false, onseat); + player.setSender(sender); + player.stateMachine.changeState(Global.getState(PlayerInitState.class)); + new_player = true; + } + + player.nick = acc.nick; + player.portrait = acc.portrait; + player.sex = acc.sex; + player.ip = ip; + if (StringUtil.isNotEmpty(gps_pos)) + player.gps_pos = gps_pos; + + ITObject data = new TObject(); + if (reload) { + data.putTObject("reloadInfo", owner.getReloadInfo(player)); + } + data.putBoolean("reload", reload); + data.putInt("owner", owner.owner_id); + data.putInt("agent", owner.agent ? 1 : 0); + data.putInt("createTime", Integer.parseInt(owner.redis_room_map.get("create_time"))); +// data.putInt("jing", owner.); + data.putTObject("tableInfo", owner.getRoomInfo()); + data.putString("userIp", ip); + player.response(data, gid, 0); + + if (new_player && player.seat != 0) { + owner.broadCastToClient(player.playerid, Router.GAME_EVT_PLAYER_JOIN, player.getInfo()); + owner.broadCastToClientOfSpectator(Router.GAME_EVT_PLAYER_JOIN, player.getInfo()); + + } + + if (reload) { + owner.join_player = player; + owner.dismissRunable.reload(player); + owner.stateMachine.curState.reload(owner); + player.stateMachine.curState.reload(player); + owner.join_player = null; + } + return 0; + + } + + /** + * 进入房间(观战) + * + * @param parm + * @param gid + * @return + */ + @SuppressWarnings("unchecked") + public int joinRoomOfSpectator(JoinRoomData parm, int gid) { + Room owner = parm.room; + String session_key = parm.session_key; + Session sender = parm.sender; + String gps_pos = parm.gps_pos; + AccountBean acc = AccountCache.getAccount(session_key); + int playerid = acc.id; + + boolean reload = owner.status == Constant.ROOM_STATUS_PLAYING; + + String ip = acc.ip; + if (StringUtil.isEmpty(ip)) { + ip = sender.getAddress(); + } + + Player player = MainServer.instance.newPlayer(playerid, owner, session_key); + player.setSender(sender); + + player.nick = acc.nick; + player.portrait = acc.portrait; + player.sex = acc.sex; + player.ip = ip; +// if (StringUtil.isNotEmpty(gps_pos)) +// player.gps_pos = gps_pos; + owner.addPlayer(player, false, false); + ITObject data = new TObject(); + data.putBoolean("reload", reload); + data.putInt("owner", owner.owner_id); + data.putInt("agent", owner.agent ? 1 : 0); + data.putInt("createTime", Integer.parseInt(owner.redis_room_map.get("create_time"))); + data.putTObject("tableInfo", owner.getRoomInfo()); + player.responseSpectator(data, gid, 0); + + player.room.broadCastToClient(0, Router.GAME_EVT_JOIN_SPECTATOR, data); + player.room.broadCastToClientOfSpectator(Router.GAME_EVT_JOIN_SPECTATOR, data); + + return 0; + + } + + /** + * 进入房间 + * + * @param + * @param gid + * @return + */ + @SuppressWarnings("unchecked") + public int spectator(Player owner, int gid) { + owner.stateMachine.changeState(Global.getState(PlayerSpectatorState.class)); + return 0; + + } + + /** + * 玩家不能进入房间,删除redis 玩家身上room、seat + * + * @param session_key + * @param owner + */ + public void delRoomSeat(String session_key, String room_key) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock(session_key, jedis0); + try { + lock.lock(); + String cur_room = jedis0.hget(session_key, "room"); + if (StringUtil.isNotEmpty(cur_room)) { + if (cur_room.equals(room_key)) { + jedis0.hdel(session_key, "room", "seat"); + } + } + } finally { + lock.unlock(); + } + } + + /** + * 检测加人房间限制 + * + * @param owner + * @return + */ + public boolean checkHplimitInRoom(Room room, long cur_hp) { +// if (room.hpData != null) { +// int limitInRoom = room.hpData.getInt("limitInRoom"); +// if (cur_hp < (long) limitInRoom) { +// return false; +// } +// } + return true; + } + + /** + * 检测加人房间限制 + * + * @param owner + * @return + */ + public boolean checkHplimitPlay(Room room, int cur_hp) { +// if (room.hpData != null) { +// int limitInRoom = room.hpData.getInt("limitInRoom"); +// if (cur_hp < limitInRoom) { +// return false; +// } +// } + return true; + } + + /** + * 坐下 + * + * @param owner + * @param gid + */ + public void joinSeat(Player owner, int gid) { + + } + + /** + * 聊天转发 + * + * @param owner + * @param params + */ + public void chat(Player owner, ITObject params) { + owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); + } + + /** + * 托管事件 + * + * @param owner + */ + public void entrust(Player owner, int time) { + ITObject broadParam = new TObject(); + broadParam.putInt("aid", owner.playerid); + broadParam.putInt("time", time); + owner.room.broadCastToClient(0, Router.GAME_EVT_READY_ENTRUST, broadParam); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_READY_ENTRUST, broadParam); + Global.info("{} Ready Entrust, left time:{}", owner.playerid, time); + } + + /** + * 取消托管事件 + * + * @param owner + */ + public void cancelEntrust(Player owner) { + ITObject broadParam = new TObject(); + broadParam.putInt("aid", owner.playerid); + owner.room.broadCastToClient(0, Router.GAME_EVT_CANCEL_READY_ENTRUST, broadParam); + // Global.info("{} Cancel Ready Entrust", owner.playerid); + } + + /** + * 准备事件 + * + * @param owner + */ + public void ready(Player owner) { + ITObject broadParam = new TObject(); + broadParam.putInt("aid", owner.playerid); + long cur_hp = Util.readRedisHp(owner.room.groupId, owner.playerid); + if (cur_hp < owner.hp.cur_hp) { + Global.logger.error("cur hp:" + cur_hp + " < hp.cur_hp:" + owner.hp.cur_hp + " playerId:" + owner.playerid); + if (owner.room.round == 0 && (!checkHplimitInRoom(owner.room, cur_hp) || cur_hp == 0)) { + owner.room.saveMilitaryTotal(true); + owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + String gm_key = GroupMemberCache.genKey(owner.room.groupId, owner.playerid); + Redis.use("group1_db10").hset(gm_key, "ban", "1"); + Redis.use("group1_db10").hset(gm_key, "group_ban", "1"); + return; + } + } + owner.hp.cur_hp = cur_hp; + + boolean flag = true; + if (owner.room.maxPlayers == owner.room.playerMapBySeat.size()) { + for (Map.Entry entry : owner.room.playerMapBySeat.entrySet()) { + if (entry.getValue().playerid != owner.playerid + && !(entry.getValue().stateMachine.curState instanceof PlayerReadyState)) { + flag = false; + break; + } + } + } else { + flag = false; + } + + if (flag) { + broadParam.putInt("start", 1); + } else { + broadParam.putInt("start", 0); + } + owner.room.broadCastToClient(0, Router.GAME_EVT_READY, broadParam); + owner.stateMachine.changeState(Global.getState(PlayerReadyState.class)); + } + + /** + * 准备和洗牌事件 + * + * @param owner + */ + public void readyAndXipai(Player owner) { + if (owner.xi_pai == false) { + owner.xi_pai = true; + owner.room.redisUpdateXiPaiPlayer(owner); + } + long cur_hp = Util.readRedisHp(owner.room.groupId, owner.playerid); + if (cur_hp < owner.hp.cur_hp || cur_hp == 0) { + Global.logger.error("cur hp:" + cur_hp + " < hp.cur_hp:" + owner.hp.cur_hp + " playerId:" + owner.playerid); + if (owner.room.round == 0 && (!checkHplimitInRoom(owner.room, cur_hp) || cur_hp == 0)) { + owner.room.saveMilitaryTotal(true); + owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + String gm_key = GroupMemberCache.genKey(owner.room.groupId, owner.playerid); + Redis.use("group1_db10").hset(gm_key, "ban", "1"); + Redis.use("group1_db10").hset(gm_key, "group_ban", "1"); + return; + } + } + owner.hp.cur_hp = cur_hp; + ITObject broadParam = new TObject(); + broadParam.putInt("aid", owner.playerid); + + boolean flag = true; + if (owner.room.maxPlayers == owner.room.playerMapById.size()) { + for (Map.Entry entry : owner.room.playerMapById.entrySet()) { + if (entry.getValue().playerid != owner.playerid + && !(entry.getValue().stateMachine.curState instanceof PlayerReadyState)) { + flag = false; + break; + } + } + } else { + flag = false; + } + + if (flag) { + broadParam.putInt("start", 1); + } else { + broadParam.putInt("start", 0); + } + owner.room.broadCastToClient(0, Router.GAME_EVT_READY_AND_XIPAI, broadParam); + owner.stateMachine.changeState(Global.getState(PlayerReadyState.class)); + } + + /** + * 解散房间通知 + * + * @param askPlayer + * @param sender + * @param time + */ + public void dismissRoom(Player askPlayer, Player sender, List playerList, int time) { + ITObject parm = TObject.newInstance(); + parm.putInt("req_aid", askPlayer.playerid); + parm.putInt("time", time); + ITArray list = TArray.newInstance(); + parm.putTArray("list", list); + askPlayer.room.applyDismisUserId = askPlayer.nick; + askPlayer.room.dismisType = 1; + for (Player player : playerList) { + ITObject tem = TObject.newInstance(); + tem.putInt("aid", player.playerid); + tem.putInt("result", player.dismissState); + list.addTObject(tem); + } + if (sender != null) { + sender.sendEvent(Router.GAME_EVT_DISMISS_ROOM, parm); + } else { + askPlayer.room.broadCastToClient(0, Router.GAME_EVT_DISMISS_ROOM, parm); + } + +// if (askPlayer.already_round == 1) { +// int groupId = askPlayer.room.groupId; +// int pid = askPlayer.room.groupPid; +// +// GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); +// int gameId = gpb.gameId; +// +// GameBean gb = GameCache.getGame(gameId); +// int maxPlayers = gpb.maxPlayers; +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// int groupDiamo = Integer +// .parseInt(jedis10.hget("g{" + askPlayer.room.groupId + "}:diamo", "diamo") == null ? "0" +// : jedis10.hget("g{" + askPlayer.room.groupId + "}:diamo", "diamo")); +// +// ITObject configData = TObject.newFromJsonData(gpb.config); +// int opt = configData.getInt("opt"); +// Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); +// +// jedis10.hset("g{" + askPlayer.room.groupId + "}:diamo", "diamo", (groupDiamo + pay) + ""); +// +// } +// Utility.payDiamo(EventType.REDIS_EVENT_GROUP_ROOM, group.owner, gameId, pay, (int) cur_diamo, groupId, pid); + + } + +// /** +// * 观众席 +// * +// * @param owner +// */ +// public void joinSpectator(Player player, int gid) { +//// if (Global.loggerDebug) { +//// Global.logger.info(player + " exit seat!"); +//// } +// player.seat = 0; +// player.room.addPlayer(player, true, false); +// +//// player.room.broadCastToClient(0, Router.GAME_EVT_JOIN_SPECTATOR, data); +//// player.room.stateMachine.execute(ActionEvent.EVENT_READY, 0, null); +// } + + /** + * 解散失败 + * + * @param owner + */ + public void dismisRoomFail(Room owner, List playerList, Player askPlayer, int time) { + ITObject parm = TObject.newInstance(); + parm.putInt("req_aid", askPlayer.playerid); + ITArray list = TArray.newInstance(); + parm.putTArray("list", list); + + for (Player player : playerList) { + ITObject tem = TObject.newInstance(); + tem.putInt("aid", player.playerid); + tem.putInt("result", player.dismissState); + list.addTObject(tem); + } + + owner.broadCastToClient(0, Router.GAME_EVT_DISMISS_ROOM_FAIL, parm); + } + + /** + * 退出房间 + * + * @param owner + * @param gid + */ + public void exitRoom(Player owner, int gid, boolean kick) { + if (kick) { + owner.sendEvent(Router.GAME_EVT_KICK_PLAYER, null); + } else { + owner.response(null, gid, 0); + } + if (owner.room.status == Constant.ROOM_STATUS_NOBEGIN || owner.spectator) { + + owner.room.dismisType = 1; + owner.room.applyDismisUserId = owner.nick; + int owner_id = owner.room.owner_id; + if (!owner.room.agent && owner.playerid == owner_id) { + owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + } else { + // 在座位上 + if (owner.room.playerMapBySeat.containsKey(owner.seat)) { + ITObject data = new TObject(); + data.putInt("aid", owner.playerid); + owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_PLAYER_EXIT, data); + owner.destroy(true); + } + + } + // 观战 + for (Entry entry : owner.room.playerMapBySpectator.entrySet()) { + ITObject data = new TObject(); + data.putInt("aid", owner.playerid); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_PLAYER_EXIT, data); + owner.destroy(true); + } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + jedis0.hset("{user}:" + owner.playerid, "online", "stopPlaying"); + + String userOnline = jedis0.hget("{user}:" + owner.playerid, "online"); + + ITObject params = new TObject(); + params.putString("online", userOnline); + params.putString("uid", String.valueOf(owner.playerid)); + String key = GroupCache.genGroupsKey(owner.playerid); + Set groups = jedis11.zrevrange(key, 0, -1); + for (String tem : groups) { + GroupPublisherService.playerGameState(Integer.parseInt(tem), params); + } + } catch (Exception e) { + Global.logger.error("setGroupHeartbeat error", e); + } finally { + jedis0.close(); + jedis11.close(); + } + + } + } + + /** + * 玩家网络状态通知 + * + * @param owner + */ + public void playerNetState(Player owner) { + ITObject param = new TObject(); + param.putInt("aid", owner.playerid); + param.putInt("online", owner.isConnect ? 1 : 0); + owner.room.updatePlayerOffline(owner); + owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_PLAYER_NET_STATE, param); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_PLAYER_NET_STATE, param); + + } + + /** + * 更新玩家GPS位置 + * + * @param owner + */ + public void updatePlayerPos(Player owner) { + ITObject param = new TObject(); + param.putInt("seat", owner.seat); + param.putUtfString("pos", owner.gps_pos); + owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_UPDATE_POS, param); + } + + /** + * 更新玩家托管 + * + * @param owner + */ + public void updatePlayerEntrust(Player owner) { + ITObject param = new TObject(); + param.putInt("aid", owner.playerid); + param.putInt("type", 5); + param.putBoolean("entrust", owner.entrust); + owner.room.broadCastToClient(0, Router.GAME_EVT_UPDATE_PLAYERINFO, param); + owner.room.broadCastToClientOfSpectator(Router.GAME_EVT_UPDATE_PLAYERINFO, param); + } + +// @ActionKey(Router.SET_HOME_MEMBER_COUNT) +// public void setHomeMemberCount(Session sender, ITObject params, int gid, Player owner) { +// Global.logger.info("setHomeMemberCount----------------------进来了"); +// int uids = params.getInt("uid"); +// String gameStatus = params.getString("gameStatus"); +// +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// +// try { +// jedis0.hset("{user}:" + uids, "setHome", gameStatus); +// jedis0.hset("{user}:" + uids+ "_online", "online", "0"); +// String setHome = jedis0.hget("{user}:" + uids, "setHome"); +// params.putString("setHome", setHome); +// owner.room.broadCastToClient(0, Router.GAME_PUSH_HOME_MEMBER_COUNT, params); +// }catch (Exception e){ +// Global.logger.error("setGroupHeartbeat error", e); +// }finally { +// jedis0.close(); +// } +// } +} diff --git a/game_common/src/main/java/com/game/GameInterceptor.java b/game_common/src/main/java/com/game/GameInterceptor.java new file mode 100644 index 0000000..32dee42 --- /dev/null +++ b/game_common/src/main/java/com/game/GameInterceptor.java @@ -0,0 +1,55 @@ +package com.game; + +import java.lang.reflect.Method; + +import com.game.data.Player; +import com.game.data.Room; +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.IController; +import com.taurus.core.routes.Interceptor; +import com.taurus.permanent.data.Session; + +public class GameInterceptor implements Interceptor{ + public final static int NOT_PLAYER = 1; + + @Override + public void intercept(Action action, IController controller,Object... args) throws Exception{ + int validate = action.getActionKeyObj().validate(); + Session sender = (Session)args[0]; + TObject params = (TObject)args[1]; + int gid = (int)args[2]; + Method method = action.getMethod(); + if((validate&NOT_PLAYER)!=0) { + method.invoke(controller,sender,params,gid); + }else { + Player player = Global.sessionMgr.getPlayer(sender); + if (player != null) { + Room room = player.room; + if (room == null)return; + if (room.isDestroy)return; + room.enqueueRunnable(new Runnable() { + @Override + public void run() { + if(player.isDestroy)return; + if(player.room.playerMapById.containsKey(player.playerid)) { + try { + method.invoke(controller, sender,params,gid,player); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + if(player.room.playerMapBySpectator.containsKey(player.playerid)) { + try { + method.invoke(controller, sender,params,gid,player); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + }); + } + } + } + +} diff --git a/game_common/src/main/java/com/game/Global.java b/game_common/src/main/java/com/game/Global.java new file mode 100644 index 0000000..86b80a0 --- /dev/null +++ b/game_common/src/main/java/com/game/Global.java @@ -0,0 +1,104 @@ +package com.game; + +import java.util.HashMap; +import java.util.Map; + +import com.game.manager.RoomManager; +import com.game.manager.SessionManager; +import com.game.player.state.PlayerEndState; +import com.game.player.state.PlayerInitState; +import com.game.player.state.PlayerPauseState; +import com.game.player.state.PlayerPopupState; +import com.game.player.state.PlayerReadyState; +import com.game.player.state.PlayerReloadState; +import com.game.player.state.PlayerSpectatorState; +import com.game.player.state.PlayerWaitState; +import com.game.room.state.RoomDestoryGameState; +import com.game.room.state.RoomEndState; +import com.game.room.state.RoomInitState; +import com.game.room.state.RoomReloadState; +import com.game.room.state.RoomStartGameState; +import com.game.room.state.RoomWaitState; +import com.game.state.StateBase; +import com.taurus.core.util.Logger; + +public class Global { + /** + * debug模式 + */ + public static boolean loggerDebug = false; + // 日志 + public static Logger logger; + // session管理器 + public static SessionManager sessionMgr; + // 桌子管理器 + public static RoomManager roomMgr; + + public static GameController gameCtr; + + public static EventController eventCtr; + /** + * 游戏ID + */ + public static int gameId = 1; + /** + * 游戏名字 + */ + public static String gameName = ""; + + + + public static void init() { + + Global.sessionMgr = new SessionManager(); + Global.roomMgr = new RoomManager(); + Global.eventCtr = new EventController(); + + registerState(RoomInitState.class, new RoomInitState()); + registerState(RoomEndState.class, new RoomEndState()); + registerState(RoomDestoryGameState.class, new RoomDestoryGameState()); + registerState(RoomWaitState.class, new RoomWaitState()); + registerState(RoomReloadState.class, new RoomReloadState()); + registerState(RoomStartGameState.class, new RoomStartGameState()); + + registerState(PlayerInitState.class, new PlayerInitState()); + registerState(PlayerPauseState.class, new PlayerPauseState()); + registerState(PlayerReadyState.class, new PlayerReadyState()); + registerState(PlayerReloadState.class, new PlayerReloadState()); + registerState(PlayerWaitState.class, new PlayerWaitState()); + registerState(PlayerSpectatorState.class, new PlayerSpectatorState()); + registerState(PlayerPopupState.class, new PlayerPopupState()); + registerState(PlayerEndState.class, new PlayerEndState()); + } + + private static Map, StateBase> state_map = new HashMap<>(); + + public static void registerState(Class cls, StateBase state) { + state_map.put(cls, state); + } + + public static StateBase getState(Class cls) { + StateBase state = state_map.get(cls); + return state; + } + + + + public static void info(String msg, Object... params) { + if (loggerDebug) { + logger.info(Util.stringFormat(msg, params)); + } + } + + public static void warn(String msg, Object... params) { + if (loggerDebug) { + logger.warn(Util.stringFormat(msg, params)); + } + } + + public static void error(String msg, Object... params) { + if (loggerDebug) { + logger.error(Util.stringFormat(msg, params)); + } + } +} diff --git a/game_common/src/main/java/com/game/GroupPublisherService.java b/game_common/src/main/java/com/game/GroupPublisherService.java new file mode 100644 index 0000000..7270de0 --- /dev/null +++ b/game_common/src/main/java/com/game/GroupPublisherService.java @@ -0,0 +1,95 @@ +package com.game; + +import com.data.util.Utility; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.permanent.TPServer; +import redis.clients.jedis.Jedis; + +import java.sql.SQLException; + +/** + * 圈子订阅服务 + */ +public class GroupPublisherService { + public static final String CHANNEL_NAME = "mgr_group"; + + private static final String CMD_DEL_ROOM = "del_room"; + private static final String CMD_UPDATE_ROOM = "update_room"; + // 实时推送数据 + public static final String CMD_PUSH_CHAT_ROOM = "push_chat_room"; + +// 玩家游戏状态推送 + public static final String CMD_PLAYER_GAME_STATE = "player_game_state"; + + /** + * 删除房间事件 + * + * @param groupId + * @param roomid + */ + public static void delRoomEvt(int groupId, String roomid) { + if (groupId == 0) + return; + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putUtfString("roomid", roomid); + data.putUtfString("cmd", CMD_DEL_ROOM); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + /** + * 更新房间事件 + * + * @param groupId + * @param roomid + */ + public static void updateRoomEvt(int groupId, String roomid) { + if (groupId == 0) + return; + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putUtfString("roomid", roomid); + data.putUtfString("cmd", CMD_UPDATE_ROOM); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void pushChatRoom(int groupId, ITObject data, String messageCount) { + if (groupId == 0) + return; + ITObject datas = TObject.newInstance(); + datas.putInt("gid", groupId); + datas.putUtfString("messageCount", messageCount); +// datas.putInt("uid",); + datas.putTObject("datas", data); + datas.putUtfString("cmd", CMD_PUSH_CHAT_ROOM); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, datas.toJson()); + jedis11.close(); + } + + // 游戏中状态推送 + public static void playerGameState(int groupId, ITObject data) { + if (groupId == 0) + return; + ITObject datas = TObject.newInstance(); + datas.putString("uid", data.getString("uid")); + datas.putInt("gid", groupId); + datas.putString("playing", data.getString("online")); + datas.putUtfString("cmd", CMD_PLAYER_GAME_STATE); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, datas.toJson()); + jedis11.close(); + } + +} diff --git a/game_common/src/main/java/com/game/MainServer.java b/game_common/src/main/java/com/game/MainServer.java new file mode 100644 index 0000000..1b02d41 --- /dev/null +++ b/game_common/src/main/java/com/game/MainServer.java @@ -0,0 +1,172 @@ +package com.game; + +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import com.game.data.Player; +import com.game.data.Room; +import com.taurus.core.entity.ITObject; +import com.taurus.core.events.Event; +import com.taurus.core.events.IEventListener; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.TPEvents; +import com.taurus.permanent.data.Session; + +/** + * + * + */ +public abstract class MainServer extends Extension implements IEventListener{ + + public static MainServer instance; + + private static final String GMAE_CONFIG = "config/game-config.xml"; + public GameSetting gameSetting; + + @Override + public void onStart() { + instance = this; + + Global.logger = Logger.getLogger(getClass()); + try { + loadConfig(); + } catch (Exception e) { + Global.logger.error(e); + } + + Global.init(); + + TPServer.me().getEventManager().addEventListener(TPEvents.EVENT_SESSION_DISCONNECT, this); + + Map svr_info = new HashMap<>(); + svr_info.put("ip", gameSetting.host); + svr_info.put("port", gameSetting.port + ""); + svr_info.put("intranet", gameSetting.intranet); + svr_info.put("conns", "0"); + String svr_key = "svr" +gameSetting.serverId; + Global.gameId = gameSetting.gameId; + Global.gameName = Redis.use("group1_db1").hget("game:" + Global.gameId, "name"); + Global.loggerDebug = gameSetting.loggerDebug; + Redis.use().hmset(svr_key, svr_info); + Redis.use().expire(svr_key, 60); + TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + svr_info.put("conns", Global.sessionMgr.size() + ""); + Redis.use().hmset(svr_key, svr_info); + Redis.use().expire(svr_key, 60); + } catch (Exception e) { + Global.logger.error(e); + } + } + }, 30, 30, TimeUnit.SECONDS); + + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + + @Override + public void run() { + List list = Global.sessionMgr.getPlayerList(); + for (Player p : list) { + Global.sessionMgr.deleteSession(p.sender); + } + } + })); + } + + public abstract Room newRoom(String roomid, Map redis_room_map); + + public abstract Player newPlayer(int playerid, Room room, String session_id); + + /** + * 创建游戏控制器 + * @return + */ + protected abstract GameController newController(); + + + /** + * 发送事件给单一客户端 + * @param cmdName 事件协议号 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendEvent(String cmdName, ITObject params, Session recipient) { + TPServer.me().getController().sendEvent(cmdName, params, recipient); + } + + /** + * 发送事件给客户端 + * @param cmdName 事件协议号 + * @param params 数据参数 + * @param recipients 客户端session列表 + */ + public void sendEvent(String cmdName, ITObject params, List recipients) { + TPServer.me().getController().sendEvent(cmdName, params, recipients); + } + + /** + * 动态响应客户端请示 + * @param gid 响应标识ID + * @param result 响应结果 0成功 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendResponse(int gid, int result, ITObject params, Session recipient) { + TPServer.me().getController().sendResponse(gid, result, params, recipient); + } + + protected void loadConfig() throws Exception { + FileInputStream is = new FileInputStream(GMAE_CONFIG); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + GameSetting config = new GameSetting(); + config.host = root.getChildTextTrim("host"); + config.port = Integer.parseInt(root.getChildTextTrim("port")); + config.serverId = Integer.parseInt(root.getChildTextTrim("serverId")); + config.gameId = Integer.parseInt(root.getChildTextTrim("gameId")); + config.loggerDebug =Boolean.parseBoolean(root.getChildTextTrim("loggerDebug")); + config.intranet = root.getChildTextTrim("intranet"); + this.gameSetting = config; + } + + @Override + public void handleEvent(Event event) { + if (event.getName() == TPEvents.EVENT_SESSION_DISCONNECT) { + Session session = (Session) event.getParameter(TPEvents.PARAM_SESSION); + Global.sessionMgr.disconnect(session); + } + } + + + + + @Override + public void configRoute(Routes me) { + me.setInterceptor(new GameInterceptor()); + Global.gameCtr = newController(); + me.add("",Global.gameCtr); + } + + public static final class GameSetting { + public String host = "127.0.0.1"; + public String intranet = "127.0.0.1"; + public int port = 6379; + public int serverId = 1; + public int gameId = 1; + public boolean loggerDebug = true; + } +} diff --git a/game_common/src/main/java/com/game/Router.java b/game_common/src/main/java/com/game/Router.java new file mode 100644 index 0000000..3180b25 --- /dev/null +++ b/game_common/src/main/java/com/game/Router.java @@ -0,0 +1,183 @@ +package com.game; + +import com.game.data.Player; +import com.taurus.core.entity.ITObject; +import com.taurus.permanent.data.Session; + +/** + * 网络路由处理 + * + */ +public abstract class Router { + /** + * 删除房间 + */ + public static final String GAME_REMOVE_ROOM = "1000"; + /** + * 更新GPS位置 + */ + public static final String GAME_UPDATE_POS = "1001"; + /** + * 更新GPS位置事件 + */ + public static final String GAME_EVT_UPDATE_POS = "2000"; + /** + * 进入房 + */ + public static final String GAME_JOIN_ROOM = "1002"; + /** + * 玩家进入房间 + */ + public static final String GAME_EVT_PLAYER_JOIN = "2001"; + /** + * 玩家退出 + */ + public static final String GAME_EVT_PLAYER_EXIT = "2002"; + /** + * 玩家网络状态 + */ + public static final String GAME_EVT_PLAYER_NET_STATE = "2003"; + /** + * 发送聊天 + */ + public static final String GAME_INTERACTION = "1006"; + /** + * 聊天事件 + */ + public static final String GAME_EVT_INTERACTION = "2017"; + /** + * 退出房间 + */ + public static final String GAME_EXIT_ROOM = "1005"; + /** + * 房主退出房间解散 + */ + public static final String GAME_EVT_EXIT_ROOM_DISMISS = "2008"; + + /** + * 发送准备 + */ + public static final String GAME_READY = "1003"; + + /** + * 发送准备加洗牌 + */ + public static final String GAME_READY_AND_XIPAI = "201004"; + + /** + * 准备加洗牌 返回 + */ + public static final String GAME_EVT_READY_AND_XIPAI = "202009"; + + /** + * 准备事件 + */ + public static final String GAME_EVT_READY = "2009"; + + + + + /** + * 通知托管倒计时 + */ + public static final String GAME_EVT_READY_ENTRUST = "22010"; + public static final String GAME_EVT_CANCEL_READY_ENTRUST = "22011"; + + + public static final String GAME_XIPAI = "20836"; + + public static final String GAME_EVENT_XIPAI = "20837"; + + public static final String GAME_EVENT_NOTIFY_XIPAI = "20838"; + + /** + * 请求开始游戏 + */ + public static final String GAME_START = "1004"; + /** + * 请求解散房间 + */ + public static final String GAME_ASK_DISMISS_ROOM = "1007"; + /** + * 解散房间 + */ + public static final String GAME_EVT_DISMISS_ROOM = "2005"; + /** + * 请求解散房间投票 + */ + public static final String GAME_DISMISS_ROOM_VOTE = "1008"; + /** + * 解散房间投票事件 + */ + public static final String GAME_EVT_DISMISS_ROOM_VOTE = "2006"; + /** + * 解散房间失败 + */ + public static final String GAME_EVT_DISMISS_ROOM_FAIL= "2027"; + /** + * + */ + public static final String GAME_EVT_SEND_REDPACKET= "3000"; + /** + * 玩家被退出 + */ + public static final String GAME_EVT_KICK_PLAYER= "3001"; + + /** + * 玩家缺体力值弹起 + */ + public static final String GAME_EVT_STAND_UP= "3004"; + + /** + * 托管 + */ + public static final String GAME_ENTRUST= "1301"; + /** + * 入座 + */ + public static final String GAME_JOIN_SEAT= "1302"; + /** + * 自动 + */ + public static final String GAME_AUTO_CARD = "1303"; + + /** + * 玩家进入观众席 + */ + public static final String GAME_EVT_JOIN_SPECTATOR= "3012"; + + /** + * 玩家退出观众席 + */ + public static final String GAME_EVT_OUT_SPECTATOR= "3022"; + /** + * 玩家进入观众席 + */ + public static final String GAME_JOIN_SPECTATOR= "3013"; + /** + * 玩家退出观众席 + */ + public static final String GAME_OUT_SPECTATOR= "3023"; +// public static final String SET_HOME_MEMBER_COUNT= "3009"; + //推送 +// public static final String GAME_PUSH_HOME_MEMBER_COUNT= "3010"; + /** + * 更新玩家信息 + */ + public static final String GAME_EVT_UPDATE_PLAYERINFO= "3003"; + /** + * 客户端数据出错,需要重连服务器,更新关键数据 + */ + public static final String GAME_EVT__UPDATE_RECONECT = "3005"; + + + + + + + public void handel(Session sender, ITObject params, int gid){ + + } + + public abstract void handelRoom(Player owner, ITObject params, int gid); +} diff --git a/game_common/src/main/java/com/game/Util.java b/game_common/src/main/java/com/game/Util.java new file mode 100644 index 0000000..ef8ffcb --- /dev/null +++ b/game_common/src/main/java/com/game/Util.java @@ -0,0 +1,302 @@ +package com.game; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import com.data.cache.GroupMemberCache; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; + +public class Util { + public final static Random random = new Random(); + static { + random.setSeed(System.currentTimeMillis()); + } + + /** + * list to TArray + * @param list + * @return + */ + public static final ITArray toTArray(List list) { + ITArray result = new TArray(); + for (Integer card : list) { + result.addInt(card); + } + return result; + } + + /** + * call checkCard + * @param eventCard + * @param cardList + * @return + */ + @Deprecated + public static boolean cardInList(int eventCard, List cardList) { + return checkCard(eventCard, cardList); + } + + @Deprecated + public static final ITArray toMPGroup(List list) { + ITArray result = new TArray(); + for (int[] card : list) { + result.addInt(card[0]); + } + return result; + } + + /** + * list to mod 100 list + * @param list + * @return + */ + public static final List toModList(List list){ + List tem = new ArrayList(); + for(Integer card : list) { + tem.add(card % 100); + } + return tem; + } + + /** + * TArray to mod 100 list + * @param list + * @return + */ + public static final List toModList(ITArray list){ + List tem = new ArrayList<>(); + for(int i=0;i cardList) { + int result = 0; + for (Integer card : cardList) { + if (card == eventCard) { + result += 1; + } + } + return result; + } + + /** + * 检测牌是否存在 + * @param eventCard + * @param cardList + * @return + */ + public static final boolean checkCard(int eventCard, List cardList) { + for (Integer card : cardList) { + if (card == eventCard) { + return true; + } + } + return false; + } + + /** + * 检测牌数量 + * @param eventCard + * @param cardList + * @param num + * @return + */ + public static final boolean checkCard(int eventCard, List cardList, int num) { + int result = 0; + for (Integer card : cardList) { + if (card == eventCard) { + result++; + if (result == num) + return true; + } + } + return false; + } + + /** + * 检测牌数量并将满足条件的删除 + * @param eventCard + * @param cardList + * @param num + * @return + */ + public static final boolean checkCardAndRomve(int eventCard, List cardList, int num) { + if (checkCard(eventCard, cardList, num)) { + removeCard(cardList, eventCard, num); + return true; + } + return false; + } + + /** + * 获取每张牌的数量MAP + * @param cardList + * @return + */ + public static final Map getCardNumMap(List cardList) { + Map result = new HashMap(); + for (Integer card : cardList) { + if (!result.containsKey(card)) { + result.put(card, 1); + } else { + int num = result.get(card); + result.put(card, (num + 1)); + } + } + return result; + } + + /** + * 检测牌数量 + * @param map + * @param card + * @param num + * @return + */ + public static boolean cardNum(Map map, int card, int num) { + Integer _num = map.get(card); + if (_num != null && _num >= num) { + return true; + } + return false; + } + + /** + * 移除指定数量的牌 + * @param cardList + * @param card + * @param count + */ + public static final void removeCard(List cardList, int card, int count) { + int curCount = 0; + for (int i = 0; i < cardList.size(); i++) { + if (cardList.get(i) == card) { + cardList.remove(i); + i--; + curCount++; + } + + if (count == curCount) { + return; + } + } + } + + static final public void addCard(ITArray opcard, int card, int num) { + for (int i = 0; i < num; ++i) { + opcard.addInt(card); + } + } + + static final public void addCard(List cardList, int card, int num) { + for (int i = 0; i < num; ++i) { + cardList.add(card); + } + } + + /** + * 获取今天凌晨0点时间戳 + * @return + */ + public static int todayTimeSec() { + Calendar cal = Calendar.getInstance(); + cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); + int timeSec = (int) (cal.getTimeInMillis() / 1000); + return timeSec; + } + + /** + * 根据时间戳获取指定当天凌晨10位时间戳 + * @param timeSec + * @return + */ + public static int todayTimeSec(Long timeSec) { + Calendar cal = Calendar.getInstance(); + // 指定日期 + cal.setTime(new Date(timeSec)); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return (int) (cal.getTimeInMillis() / 1000); + } + + /** + * msg ps : param:{},param:{} + * ==> param: abc,param:abced + * @param msg + * @param params + * @return + */ + public static String stringFormat(String msg, Object... params) { + try { + if (StringUtil.isNotEmpty(msg)) { + msg = msg.replaceAll("\\{}", "\\%s"); + return String.format(msg, params); + } + } catch (Exception e) { + return ""; + } + return ""; + } + +// public static void countLog(String key,int num,Jedis jedis) { +// String day_key = key + ":d"+DateUtils.getBeginDay(); +// String week_key = key + ":w"+DateUtils.getBeginWeek(); +// String month_key = key + ":m"+DateUtils.getBeginMonth(); +// jedis.incrBy(day_key,num); +// jedis.expire(day_key, 11*3600*24); +// jedis.incrBy(week_key,num); +// jedis.expire(week_key, 15*3600*24); +// jedis.incrBy(month_key,num); +// jedis.expire(month_key, 63*3600*24); +// } + + /** + * 获取玩家体力值 + * @param gid + * @param uid + * @return + */ + public static long readRedisHp(int gid,int uid) { + String key = GroupMemberCache.genKey(gid, uid); + String hp = Redis.use("group1_db10").hget(key, "hp"); + long cur_hp = StringUtil.isNotEmpty(hp) ? Long.parseLong(hp) : 0; + return cur_hp; + } +} diff --git a/game_common/src/main/java/com/game/data/BasePlayBack.java b/game_common/src/main/java/com/game/data/BasePlayBack.java new file mode 100644 index 0000000..c721e31 --- /dev/null +++ b/game_common/src/main/java/com/game/data/BasePlayBack.java @@ -0,0 +1,108 @@ +package com.game.data; + +import java.util.Map.Entry; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Utils; + +/** + * 回放数据记录 + * + */ +public abstract class BasePlayBack { + /** + * 房间信息 + */ + protected ITObject info; + /** + * 指令列表 + */ + protected ITArray cmdList; + + protected BasePlayBack(Room room) { + info = TObject.newInstance(); + cmdList = TArray.newInstance(); + info.putUtfString("roomid", room.roomid); + info.putInt("round", room.round); + info.putTObject("config", room.config); + info.putInt("banker_seat", room.bankerSeat); + info.putInt("active_seat", room.activeSeat); + info.putInt("game_id", Global.gameId); + + ITArray infoList = new TArray(); + for (Entry entry : room.playerMapByPlaying.entrySet()) { + Player player = entry.getValue(); + if(player.already_round==0)continue; + ITObject obj = getPlayerInfo(player); + infoList.addTObject(obj); + } + info.putTArray("playerData", infoList); + } + + protected ITObject getPlayerInfo(Player player) { + ITObject obj = TObject.newInstance(); + obj.putInt("aid", player.playerid); + obj.putUtfString("nick", player.nick); + obj.putInt("sex", player.sex); + obj.putUtfString("portrait", player.portrait); + obj.putInt("seat", player.seat); + player.hp_info(obj); + return obj; + } + + protected void addCommand(String cmd, int seat, ITObject data) { + ITObject cmdObj = TObject.newInstance(); + cmdObj.putUtfString("cmd", cmd); + cmdObj.putInt("seat", seat); + cmdObj.putTObject("data", data); + cmdList.addTObject(cmdObj); + } + + /** + * 获取战绩回放数据,保存到redisd + * + * @return + */ + public ITObject getData() { + ITObject data = TObject.newInstance(); + data.putTObject("info", info); + data.putTArray("cmdList", cmdList); + return data; + } + /** + * 给客户端的提示按钮 + * @param seat + * @param cmdData + */ + public void addTipCommand(int seat, ITObject cmdData) { + addCommand("Tip", seat, cmdData); + } + + /** + * 玩家操作点击的提示 + * @param seat + * @param type + * @param weight + */ + public void addClickTipCommand(int seat, int type, int weight) { + ITObject cmdData = TObject.newInstance(); + cmdData.putInt("weight", weight); + cmdData.putInt("type", type); + addCommand("ClickTip", seat, cmdData); + } + + /** + * 小结算数据 + */ + public void addResult(ITObject resultData) { + ITObject data = TObject.newInstance(); + Utils.objectCopyDeep(resultData, data); + data.putInt("type", 0); + addCommand("Result", 0, data); + } + +} diff --git a/game_common/src/main/java/com/game/data/Hp.java b/game_common/src/main/java/com/game/data/Hp.java new file mode 100644 index 0000000..14fda27 --- /dev/null +++ b/game_common/src/main/java/com/game/data/Hp.java @@ -0,0 +1,24 @@ +package com.game.data; + +public class Hp { + /** + * 当前体力值,每局更新,用于判断当局能输赢多少 + */ + public long cur_hp = 0; + /** + * 牌局开始到结束,总输赢体力值,不包括奖励体力值。因命名之前没有奖励一说 + */ + public int total_hp = 0; + /** + * 当局实际输赢体力值 + */ + public int round_actual_hp = 0; + /** + * 当局本应输赢体力值 + */ + public int round_answer_hp = 0; + /** + * 输赢是否已达上限 + */ + public boolean upper_limit = false; +} diff --git a/game_common/src/main/java/com/game/data/JoinRoomData.java b/game_common/src/main/java/com/game/data/JoinRoomData.java new file mode 100644 index 0000000..9e9fbea --- /dev/null +++ b/game_common/src/main/java/com/game/data/JoinRoomData.java @@ -0,0 +1,12 @@ +package com.game.data; + +import com.taurus.permanent.data.Session; + +public class JoinRoomData { + public Room room; + public String session_key; + public Session sender; + public String gps_pos; + public boolean test_user; + +} diff --git a/game_common/src/main/java/com/game/data/Player.java b/game_common/src/main/java/com/game/data/Player.java new file mode 100644 index 0000000..82e4653 --- /dev/null +++ b/game_common/src/main/java/com/game/data/Player.java @@ -0,0 +1,614 @@ +package com.game.data; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.MainServer; +import com.game.player.state.PlayerPopupState; +import com.game.player.state.PlayerReloadState; +import com.game.state.StateMachine; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.StringUtil; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +/** + * 基本玩家对象 + * + * + */ +public class Player { + /** + * 所在房间对象 + */ + public Room room = null; + /** + * 用户id + */ + public int playerid = 0; + + public String ip = null; + /** + * redis session id + */ + public String session_id = StringUtil.Empty; + public String score_key = StringUtil.Empty; + public String net_key = StringUtil.Empty; + /** + * 玩家状态机 + */ + public StateMachine stateMachine = null; + + /** + * mpnet session + */ + public volatile Session sender = null; + /** + * 是否正在链接 + */ + public volatile boolean isConnect = false; + /** + * 是否是重连 + */ + public boolean isReload = false; + /** + * 是否被摧毁 + */ + public volatile boolean isDestroy = false; + + /** + * 当前座位号 + */ + public int seat = 0; + public int nextSeat = 0; + public int lastSeat = 0; + + /** + * 昵称 + */ + public String nick = StringUtil.Empty; + /** + * 性别 + */ + public int sex = 1; + /** + * 头像 + */ + public String portrait = StringUtil.Empty; + /** + * GPS位置 + */ + public String gps_pos = StringUtil.Empty; + + /** + * 0 无 1 胡 2 输 + */ + public int winer = 0; + + /** + * 胡牌统计 + */ + public int winCount = 0; + /** + * 准备状态 + */ + public boolean ready = false; + + public boolean is_white = false; + + public int black_white_status = 0; + + public double black_white_rate = 10; + + /** + * 解散房间状态 + */ + public int dismissState = 0; + /** + * 申请解散次数 + */ + public int dismissCount = 0; + /** + * 计分统计 + */ + public Score score; + /** + * action计时器 + */ + public Timer actionTimer; + /** + * 计时器 + */ + public Timer timer; + public volatile long offlineTime; + /** + * 抽水值 + */ + public int practicalHpPump = 0; + /** + * 奖励数据 + */ + public String prs = StringUtil.Empty; + /** + * 托管 + */ + public volatile boolean entrust = false; + /** + * 自动出牌 + */ + public volatile boolean manualAutoCard = false; + /** + * 是否正在观看 + */ + public volatile boolean spectator = false; + /** + * 已玩局数 + */ + public int already_round = 0; + /** + * 体力值 + */ + public Hp hp; + /** + * 托管局数 + */ + public int entrust_round = 0; + /** + * 是否检测退出限制 + */ + public boolean check_exit_limit = true; + + public boolean xi_pai = false; + /** + * 抽水值total + */ + public int xi_pai_total = 0; + + public Player(int playerid, Room table, String session_id) { + this.room = table; + this.playerid = playerid; + this.session_id = session_id; + this.score_key = "score_" + playerid; + this.net_key = "net_" + playerid; + this.score = newScore(); + this.stateMachine = new StateMachine(this); + this.isReload = false; + this.hp = new Hp(); + this.xi_pai = false; + } + + protected Score newScore() { + return new Score(this); + } + + /** + * 设置玩家session + * + * @param sender + */ + public void setSender(Session sender) { + // 服务器从崩溃中重启 + if (sender == null) { + this.isReload = true; + this.isConnect = false; + this.stateMachine.changeState(Global.getState(PlayerReloadState.class)); + return; + } + if (this.isConnect && this.sender != null && this.sender != sender) { + Global.sessionMgr.deleteSession(this.sender); + TPServer.me().getController().disconnect(this.sender); + } + // 已经连接 + this.sender = sender; + Global.sessionMgr.putPlayer(sender, this); + this.isConnect = true; + // if (this.stateMachine.curState == null || this.isReload) { + // this.stateMachine.changeState(Global.getState(PlayerInitState.class)); + this.isReload = false; + // } + } + + /** + * 计时器,Ps 到某状态自动执行某操作 + * + * @param time 时间 ms + * @param cmd 计时完执行事件 + * @param param 执行事件参数 + */ + public void startTimer(int time, String cmd, Object param) { + stopTimer(); + this.timer = new Timer(time, new Timer.ITaskHandler() { + @SuppressWarnings("unchecked") + @Override + public void doTask(Timer timer) { + Global.info("{} [{}] Timer Excute ActionEvent [{}] param :{}", Player.this.toString(), + stateMachine.curState.getClass().getSimpleName(), cmd, + param == null ? "null" : param.toString()); + stateMachine.curState.execute(Player.this, cmd, 0, param); + } + }); + room.addTimer(this.timer); + } + + /** + * 指定时间计时, cmd :timer_auto + * + * @param time + */ + public void startTimer(int time) { + startTimer(time, ActionEvent.EVENT_TIMER_AUTO, null); + } + + /** + * 默认配置计时器 time : 1000ms cmd : timer_auto + */ + public void startTimer() { + startTimer(room.def_actionTimer_time, ActionEvent.EVENT_TIMER_AUTO, null); + } + + public void stopTimer() { + if (this.timer != null) { + this.timer.stop(); + this.timer = null; + } + } + + /** + * 停止所有计时器,如玩家退出某状态时 + */ + public void stopAllTimer() { + stopTimer(); + stopActionTimer(); + } + + /** + * 托管计时器 + * + * @param time 单位毫秒 + */ + public void startActionTimer(int time, Object param) { + stopActionTimer(); + this.actionTimer = new Timer(time, new Timer.ITaskHandler() { + @SuppressWarnings("unchecked") + @Override + public void doTask(Timer timer) { + String type = ""; + if (param != null) { + ITObject netParam = (ITObject) param; + if (netParam.containsKey("type")) { + type = netParam.getUtfString("type"); + } + } + if (ActionEvent.EVENT_ENTRUST.equals(type) && !entrust) { + entrust = true; + Global.gameCtr.updatePlayerEntrust(Player.this); + } + Global.info("{} [{}] Entrust Auto Execute ActionEvent", Player.this.toString(), + stateMachine.curState.getClass().getSimpleName()); + stateMachine.curState.execute(Player.this, ActionEvent.EVENT_TIMER_AUTO, 0, param); + } + }); + String type = ""; + int broad = 0; + if (param != null) { + ITObject netParam = (ITObject) param; + if (netParam.containsKey("type")) { + type = netParam.getUtfString("type"); + } + if (netParam.containsKey("broad")) { + broad = netParam.getInt("broad"); + } + } + if (ActionEvent.EVENT_ENTRUST.equals(type) && broad == 1) { + this.actionTimer.parameters.put("param", param); + } + room.addTimer(this.actionTimer); + } + + /** + * + * @param time 单位毫秒 + */ + public void startActionTimer(int time) { + startActionTimer(time, null); + } + + public boolean isEntrust() { + return this.room.isEntrust() && this.entrust; + } + + /** + * 托管. + */ + public void startActionTimer() { + stopActionTimer(); + if (room.isEntrust()) { + ITObject param = TObject.newInstance(); + param.putUtfString("type", ActionEvent.EVENT_ENTRUST); + if (isEntrust()) { + param.putInt("broad", 0); + startActionTimer(this.room.default_entrust_time, param); + } else { + param.putInt("broad", 1); + startActionTimer(this.room.entrustTime, param); + Global.gameCtr.entrust(Player.this, this.room.entrustTime / 1000); + } + } + } + + public void stopActionTimer() { + if (this.actionTimer != null) { + if (this.actionTimer.parameters.containsKey("param")) { + ITObject param = (ITObject) this.actionTimer.parameters.get("param"); + String type = ""; + if (param != null) { + ITObject netParam = (ITObject) param; + if (netParam.containsKey("type")) { + type = netParam.getUtfString("type"); + } + } + if (ActionEvent.EVENT_ENTRUST.equals(type)) { + Global.gameCtr.cancelEntrust(Player.this); + } + } + this.actionTimer.stop(); + this.actionTimer = null; + } + } + + public int getActionLeftTime() { + if (this.actionTimer != null) { + return Math.abs(this.actionTimer.getCountdownTime() / 1000); + } + return 0; + } + + public int getEntrustActionLeftTime() { + if (this.actionTimer != null) { + if (this.actionTimer.parameters.containsKey("param")) { + ITObject param = (ITObject) this.actionTimer.parameters.get("param"); + String type = ""; + if (param != null) { + ITObject netParam = (ITObject) param; + if (netParam.containsKey("type")) { + type = netParam.getUtfString("type"); + } + } + if (ActionEvent.EVENT_ENTRUST.equals(type)) { + return Math.abs(this.actionTimer.getCountdownTime() / 1000); + } + } + } + return 0; + } + + /** + * 返回结果 + * + * @param params + * @param gid + * @param error + */ + public void response(ITObject params, int gid, int error) { + if (!this.isConnect) + return; + if (error == 0) { + MainServer.instance.sendResponse(gid, error, params, this.sender); + } else { + MainServer.instance.sendResponse(gid, error, null, this.sender); + } + } + + /** + * 返回结果 + * + * @param params + * @param gid + * @param error + */ + public void responseSpectator(ITObject params, int gid, int error) { + if (error == 0) { + MainServer.instance.sendResponse(gid, error, params, this.sender); + } else { + MainServer.instance.sendResponse(gid, error, null, this.sender); + } + } + + /** + * 发送事件给客户端 + * + * @param cmd + * @param param + */ + public void sendEvent(String cmd, ITObject param) { + if (!this.isConnect) + return; + MainServer.instance.sendEvent(cmd, param, this.sender); + } + + /** + * 获取玩家信息 + * + * @return + */ + public ITObject getInfo() { + ITObject playerData = new TObject(); + playerData.putInt("aid", this.playerid); + playerData.putUtfString("nick", this.nick); + playerData.putInt("sex", this.sex); + playerData.putUtfString("portrait", this.portrait); + if (StringUtil.isNotEmpty(gps_pos)) { + playerData.putUtfString("pos", gps_pos); + } + String ip = this.ip; + if (this.ip == null && this.sender != null) { + ip = sender.getAddress(); + } + playerData.putInt("ready", this.ready ? 1 : 0); + playerData.putUtfString("ip", ip); + playerData.putInt("seat", this.seat); + playerData.putInt("online", this.isConnect ? 1 : 0); + playerData.putBoolean("spectator", spectator); + if (this.room.openEntrust) { + playerData.putBoolean("entrust", this.entrust); + playerData.putInt("entrust_time", getEntrustActionLeftTime()); + } + hp_info(playerData); + // if (Redis.use().hexists(this.session_id, "offLineTime")) { + // int offLineTime = Integer.parseInt(Redis.use().hget(this.session_id, + // "offLineTime")); + // playerData.putInt("offLineTime", Utils.differSecond(offLineTime)); + // } + return playerData; + } + + public ITObject getReloadInfo() { + ITObject playerData = new TObject(); + playerData.putInt("playerid", playerid); + if (this.room.openEntrust && this.room.isEntrust) { + playerData.putBoolean("entrust", this.entrust); + playerData.putInt("entrust_time", getEntrustActionLeftTime()); + +// Global.logger.info("entrust_time getEntrustActionLeftTime() : " + getEntrustActionLeftTime()); + } + playerData.putBoolean("popup", this.stateMachine.curState instanceof PlayerPopupState); + hp_info(playerData); + return playerData; + } + + /** + * 玩家销毁时调用 + * + * @param sysredis + */ + public void destroy(boolean sysredis) { + if (isDestroy) + return; + isDestroy = true; + stopActionTimer(); + this.room.removePlayer(this, sysredis); + if (this.sender != null) { + Global.sessionMgr.deleteSession(sender); + } + } + + private int __checkSeat(int seat, int count, boolean add) { + if (seat > this.room.maxPlayers) { + seat = 1; + } else if (seat <= 0) { + seat = this.room.maxPlayers; + } + if (count == this.room.maxPlayers) + return seat; + Player player = this.room.playerMapBySeat.get(seat); + if (player == null || player.spectator) { + if (add) + seat = seat + 1; + else + seat = seat - 1; + count++; + return __checkSeat(seat, count, add); + } + return seat; + } + + /** + * 初始化座位信息 + */ + public void initSeat() { + this.nextSeat = __checkSeat(this.seat + 1, 1, true); + this.lastSeat = __checkSeat(this.seat - 1, 1, false); + } + + /** + * 清理玩家数据 + */ + public void clear() { + this.winer = 0; + this.check_exit_limit = true; + this.is_white = false; + this.manualAutoCard = false; + + stopActionTimer(); + } + + /** + * 注册redis事件,总服处理 + * + * @param type + * @param num + */ + public void redisEvent(int type, int num) { + Global.eventCtr.redisEvent(playerid, type, num); + } + + public String toString() { + return session_id; + } + + public void hp_info(ITObject param) { + ITObject hp_info = TObject.newInstance(); + // 下局体力值 + hp_info.putLong("cur_hp", hp.cur_hp); + // 本局实际输赢体力值 + hp_info.putInt("round_actual_hp", hp.round_actual_hp); + // 输赢是否已达上限 + hp_info.putBoolean("upper_limit", hp.upper_limit); + // 总输赢体力值 + hp_info.putInt("total_hp", hp.total_hp); + param.putTObject("hp_info", hp_info); + + } + + /** + * 获取当前体力值 + */ + public Long getHp() { + return this.hp.cur_hp + (long) this.hp.round_actual_hp; + } + +// public void updateHp() { +// this.hp.cur_hp = this.hp.cur_hp + this.hp.round_actual_hp; +// } + + public void clearHp() { + this.hp.round_actual_hp = 0; + this.hp.round_answer_hp = 0; + this.hp.upper_limit = false; + } + + /** + * 设置托管数据 + * + * @param data + */ + public void setEntrustData(ITObject data) { + + } + + public void exitEntrust() { + if (this.room.isEntrust()) { + this.entrust_round = 0; + stopActionTimer(); + this.entrust = false; + if (room.activeSeat == this.seat) { + startActionTimer(); + } + } + } + + /** + * 牌局结束输赢总体力值,包括奖励体力值 + */ + public int totalHp() { + return hp.total_hp; + } + + /** + * 需要抽水的具体体力值,不可负分 - 实际赢体力值,可负分 - 实际赢积分 换算成赢总体力值 + */ + public int hpPumpValue() { + return hp.total_hp; + } + +} diff --git a/game_common/src/main/java/com/game/data/Room.java b/game_common/src/main/java/com/game/data/Room.java new file mode 100644 index 0000000..c5e9e47 --- /dev/null +++ b/game_common/src/main/java/com/game/data/Room.java @@ -0,0 +1,2202 @@ +package com.game.data; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import com.data.bean.AccountBean; +import com.data.bean.GameBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.game.Constant; +import com.game.GPSUtil; +import com.game.Global; +import com.game.GroupPublisherService; +import com.game.MainServer; +import com.game.Router; +import com.game.Util; +import com.game.player.state.PlayerPopupState; +import com.game.room.state.RoomDestoryGameState; +import com.game.room.state.RoomEndState; +import com.game.room.state.RoomInitState; +import com.game.state.StateMachine; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import com.taurus.permanent.data.Session; + +import redis.clients.jedis.Jedis; + +/** + * 基本房间对象 + * + * + */ +public class Room implements Runnable { + /** + * 房间ID + */ + public String roomid = ""; + /** + * 房间redis_key + */ + public String room_key = ""; + /** + * 房间状态机 + */ + public StateMachine stateMachine; + /** + * 玩家列表ID映射 + */ + public final Map playerMapById = new HashMap(); + /** + * 玩家列表Seat映射 + */ + public final Map playerMapBySeat = new HashMap(); + /** + * 游戏中玩家列表 + */ + public final Map playerMapByPlaying = new HashMap(); + /** + * 观看列表 + */ + public final Map playerMapBySpectator = new HashMap(); + /** + * 房间配置数据 + */ + public ITObject config; + /** + * 房间最大人数 + */ + public int maxPlayers; + /** + * 开始游戏数量 0 首位开始 > + */ + public int startGameNum; + + private Thread roomUpdateThread; + /** + * 房间是否被激活 + */ + private volatile boolean isActive = false; + /** + * 房间是否被销毁 + */ + public volatile boolean isDestroy = false; + final BlockingQueue updateHandleList = new LinkedBlockingQueue(); + final List timerList = new ArrayList<>(); + /** + * 当前激活的座位号 + */ + public int activeSeat = 0; + /** + * 庄家座位号 + */ + public int bankerSeat = 0; + /** + * 房主ID + */ + public int owner_id = 0; + /** + * 局數 + */ + public Integer round = 0; + /** + * 最大回合数 + */ + public int maxRound = 0; + /** + * 服务器重连 + */ + public boolean serverRload = false; + /** + * 是否开始 + */ + public boolean isplaying = false; + + /** + * 是否禁止解散 + */ + public boolean isBanDismiss = false; + + /** + * 房间解散处理对象 + */ + public RoomDismiss dismissRunable; + /** + * 当前房间对象逻辑锁 + */ + public Object lock = new Object(); + /** + * 房间数据redis映射 + */ + public Map redis_room_map; + /** + * 战绩回放redis key + */ + public String military_key; + /** + * 退还 + */ + public int pay = 0; + /** + * 支付人玩家ID + */ + public int pay_playerid = 0; + /** + * 是否AA支付 + */ + public boolean pay_AA = false; + /** + * 是否是代理房间 + */ + public boolean agent = false; + /** + * 0 未开始 1开始 2删除标记 3已删除 + */ + public int status = 0; + /** + * 圈子ID + */ + public int groupId = 0; + /** + * 圈子玩法ID + */ + public int groupPid = 0; + + /** + * 圈子玩法名称 + */ + public String groupPname = ""; + /** + * 奖励类型 + */ + public int rewardType = 1; + public int rewardValueType = 1; + public int basePump = 0; + public int totalPump = 0; + + public int xipai_rewardType = 1; + public int xipai_rewardValueType = 1; + + /** + * 人头制时,是否需要奖励 + */ + public boolean aHeadReward = true; + + /** + * 精牌 + */ + public boolean jingCard = true; + + /** + * 限制进入房间 limitInRoom 限制抢庄 limitloot 退出游戏体力值限制 limitPlay 抽水设置 limitPump (0 + * --大赢家抽水 ; 1 --全部赢家抽水) 抽水比例 pumpProportion 单人单局抽水上限 UpperLimit 抽水类型 type + * 1.固定抽水 : 2.浮动抽水(百分比) 倍数 times + */ + public ITObject hpData; + /** + * 是否打开托管 + */ + public boolean openEntrust; + /** + * 托管时间 + */ + public int entrustTime = 60000; + /** + * 1 单局结束 大结算 2 局满结算 3 局结算 + */ + public int entrusResultType = 1; + /** + * 默认托管时间 500ms + */ + public int default_entrust_time = 2000; + /** + * 计时器默认时间 + */ + public int def_actionTimer_time = 1000; + /** + * 踢出时间 + */ + public int kickTime = 0; + /** + * 回放数据 + */ + public BasePlayBack playBackData; + /** + * 是否托管玩法。 + */ + public boolean isEntrust = false; + /** + * 游戏结束类型 1-正常结束 2-托管当局大结算 3-体力值不足 4-中途申请解散 5-管理员解散 + */ + public int endType = Constant.END_TYPE_NORMAL; + + public List win, loss; + /** + * 当前局战绩是否已存储 + */ + public boolean roundSave = false; + + /** + * 申请解散用户 + */ + public String applyDismisUserId; + + /** + * 解散类型 0:正常结束 1:中途解散 2:管理员解散 + */ + public int dismisType = 0; + + /** + * 同意解散用户集合 + */ + public List agreeDismisUserId = new ArrayList<>(); + + /** + * 进入玩家 + */ + public Player join_player; + + public boolean while_list = false; + + public double white_value = 20; + + public int xi_pai_score = 0; + + public Room(String roomid, Map redis_room_map) { + this.roomid = roomid; + this.room_key = "room:" + roomid; + if (owner_id == 0) { + String owner_key = redis_room_map.get("owner"); + String ownerid = Redis.use().hget(owner_key, "id"); + owner_id = Integer.parseInt(ownerid); + military_key = "military_" + roomid + redis_room_map.get("create_time"); + } + + this.stateMachine = new StateMachine(this); + this.stateMachine.changeState(Global.getState(RoomInitState.class)); + redis_room_map.remove("cache_ver"); + this.redis_room_map = redis_room_map; + this.win = new ArrayList<>(); + this.loss = new ArrayList<>(); + this.config = TObject.newFromJsonData(redis_room_map.get("options")); + this.maxPlayers = Integer.parseInt(redis_room_map.get("maxPlayers")); + this.maxRound = Integer.parseInt(redis_room_map.get("times")); + this.config.putInt("maxPlayers", this.maxPlayers); + this.config.putInt("times", this.maxRound); + this.pay = Integer.parseInt(redis_room_map.get("pay")); + this.pay_playerid = Integer.parseInt(redis_room_map.get("payer")); + this.pay_AA = Integer.parseInt(redis_room_map.get("AA")) == 1; + this.config.putInt("AA", this.pay_AA ? 1 : 0); + this.agent = Integer.parseInt(redis_room_map.get("agent")) > 0; + this.status = Integer.parseInt(redis_room_map.get("status")); + if (this.config.containsKey("start_num")) { + this.startGameNum = this.config.getInt("start_num"); + } else { + this.startGameNum = this.maxPlayers; + } + + Integer str = config.getInt("isBanDismiss");// 0 / 1 + if (str != null && str == 1) { + this.isBanDismiss = true; + } else { + this.isBanDismiss = false; + } + + this.dismissRunable = new RoomDismiss(this); + this.xi_pai_score = 0; + if (redis_room_map.containsKey("group")) { + groupId = Integer.parseInt(redis_room_map.get("group")); + if (groupId > 0) { + if (redis_room_map.containsKey("dismiss_time")) { + this.dismissRunable.maxTime = Integer.parseInt(redis_room_map.get("dismiss_time")); + } + if (redis_room_map.containsKey("kick_time")) { + this.kickTime = Integer.parseInt(redis_room_map.get("kick_time")); + } + groupPid = Integer.parseInt(redis_room_map.get("gpid")); + + groupPname = redis_room_map.get("gpname"); + + rewardType = Integer.parseInt(redis_room_map.get("rewardType")); + if (redis_room_map.get("rewardValueType") != null) { + rewardValueType = Integer.parseInt(redis_room_map.get("rewardValueType")); + } + + if (redis_room_map.get("xipai_rewardType") != null) { + xipai_rewardType = Integer.parseInt(redis_room_map.get("xipai_rewardType")); + } + + if (redis_room_map.get("xipai_rewardValueType") != null) { + xipai_rewardValueType = Integer.parseInt(redis_room_map.get("xipai_rewardValueType")); + } + + if (this.config.containsKey("hpData")) { + hpData = this.config.getTObject("hpData"); + + if (hpData.containsKey("basePump")) { + basePump = hpData.getInt("basePump"); + } + } + if (this.config.containsKey("tuoguan_active_time")) { + + this.entrustTime = this.config.getInt("tuoguan_active_time") * 1000; + this.openEntrust = this.entrustTime > 0; + this.entrusResultType = this.config.getInt("tuoguan_result_type"); + } + + } + } else { + + if (this.config.containsKey("tuoguan_active_time")) { + this.entrustTime = this.config.getInt("tuoguan_active_time") * 1000; + this.openEntrust = this.entrustTime > 0; + this.entrusResultType = this.config.getInt("tuoguan_result_type"); + } +// Global.logger.info("普通用户创建房间的信息config:" + this.config); + + hpData = this.config.getTObject("hpData"); +// Global.logger.info("普通用户创建房间的信息hpData:" + hpData); + } + } + + /** + * 决定总结算方式 + * + * @return true : 总结算 + */ + protected boolean totalType() { + boolean result = false; + int jieNum = 0; + + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + + // 托管 + Integer jieShan = 0; + if (player.room.hpData != null) { + jieShan = player.room.hpData.getInt("JieShan"); + + } + + if (jieShan == 1) { + jieNum = 0; + } + + if (jieShan == 2) { + jieNum = 1; + } + if (jieShan == 3) { + jieNum = 2; + } + if (jieShan == 4) { + jieNum = 3; + } + if (player.entrust == true) { + this.endType = Constant.END_TYPE_ENTRUST; + } + + if (this.endType == Constant.END_TYPE_ENTRUST) { + result = player.entrust_round == jieNum; + } + + if (this.endType == Constant.END_TYPE_NORMAL) { + result = this.round >= this.maxRound; + + } + if (this.endType == Constant.END_TYPE_ADMIN) { + result = this.round >= this.maxRound; + this.dismisType = 2; + + } + if (this.round >= this.maxRound) { + return true; + } + } + return result; + } + + public void start() { + if (isActive) + return; + last_read_status_time = 0; + roomUpdateThread = new Thread(this, room_key + "_" + round); + roomUpdateThread.start(); + isActive = true; + } + + private void handleTimer(int index) { + if (isDestroy) { + return; + } + if (timerList.size() > index) { + Timer timer = timerList.get(index); + if (timer.isRuning()) { + timer.executeTask(); + handleTimer(index + 1); + } else { + synchronized (timerList) { + timerList.remove(index); + } + handleTimer(index); + } + } + } + + private void handleTask() { + if (isDestroy) { + return; + } + if (updateHandleList.size() > 0) { + Runnable tem = null; + synchronized (updateHandleList) { + tem = updateHandleList.poll(); + } + if (tem == null) + return; + tem.run(); + handleTask(); + } + } + + private long last_read_status_time = 0; + + public void run() { + + while (isActive && !isDestroy) { + try { + synchronized (lock) { + if (System.currentTimeMillis() - last_read_status_time > 1000) { + last_read_status_time = System.currentTimeMillis(); + String status = Redis.use().hget(room_key, "status"); + if (StringUtil.isNotEmpty(status)) { + int tem = Integer.parseInt(status); + + if (tem == Constant.ROOM_STATUS_DEL_FALG || tem == Constant.ROOM_STATUS_DEL_FALG) { + this.endType = Constant.END_TYPE_ADMIN; + this.dismisType = 2; + this.saveMilitaryTotal(true); + this.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + + Global.roomMgr.dismissRoom(roomid, false); + continue; + } + } else { + this.dismisType = 2; + this.endType = Constant.END_TYPE_ADMIN; + this.saveMilitaryTotal(true); + this.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + + Global.roomMgr.dismissRoom(roomid, false); + continue; + } + } + handleTimer(0); + if (isDestroy) + continue; + handleTask(); + if (isDestroy) + continue; + } + Thread.sleep(5); + } catch (InterruptedException e) { + isActive = false; + Global.logger.error("[" + room_key + "] room thread interrupted!"); + } catch (Throwable t) { + Global.logger.error("[" + room_key + "] exception!", t); + } + } + } + + /** + * add queue runnable + * + * @param runnable + */ + public void enqueueRunnable(Runnable runnable) { + if (!isActive) + return; + if (runnable == null) + return; + synchronized (updateHandleList) { + updateHandleList.add(runnable); + } + } + + /** + * 单线程计时器 + * + * @param timer + */ + public void addTimer(Timer timer) { + if (!isActive) + return; + if (timer == null) + return; + synchronized (timerList) { + timerList.add(timer); + timer.start(); + } + } + + /** + * 开始游戏改变状态 + */ + public void startGame() { + this.isActive = true; + this.isDestroy = false; + while_list = false; + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + player.clear(); + if (player.stateMachine.curState instanceof PlayerPopupState) { + continue; + } + // 已玩局数++ + player.already_round++; + player.ready = false; + player.is_white = false; + player.black_white_status = 0; + String gm_key = GroupMemberCache.genKey(this.groupId, player.playerid); + String black_key = Redis.use("group1_db10").hget(gm_key, "group_black_key"); + if (StringUtil.isEmpty(black_key)) { + black_key = gm_key; + } + + String black = Redis.use("group1_db10").hget(black_key, "black"); + String black_rate = Redis.use("group1_db10").hget(black_key, "group_black_rate"); + + if (StringUtil.isNotEmpty(black) && black.equals("0")) { + player.black_white_status = 0; + player.black_white_rate = 0; + } else if (StringUtil.isNotEmpty(black) && black.equals("1")) { + player.black_white_status = 1; + if (StringUtil.isNotEmpty(black_rate)) { + try { + player.black_white_rate = Integer.parseInt(black_rate); + } catch (NumberFormatException e) { + player.black_white_rate = 10; + } + } + } else if (StringUtil.isNotEmpty(black) && black.equals("2")) { + player.black_white_status = 2; + if (StringUtil.isNotEmpty(black_rate)) { + try { + player.black_white_rate = Integer.parseInt(black_rate); + } catch (NumberFormatException e) { + player.black_white_rate = 10; + } + } + } else { + player.black_white_status = 0; + player.black_white_rate = 0; + } + + player.initSeat(); + this.playerMapByPlaying.put(player.playerid, player); + +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// String playingGroupIdKey ="g{"+this.groupId+"}:playings"; +// try { +// jedis10.hset(playingGroupIdKey, player.playerid+"","playing"); +// }catch (Exception e){ +// Global.logger.info("数据没存上", e); +// }finally { +// jedis10.close(); +// } + + } + if (this.round == 0 && this.status == Constant.ROOM_STATUS_NOBEGIN) { + this.status = Constant.ROOM_STATUS_PLAYING; + this.redis_room_map.put("status", this.status + ""); + Redis.use().hset(this.room_key, "status", this.status + ""); + this.redis_room_map.put("open", "0"); + Redis.use().hset(this.room_key, "open", "0"); + + } + + this.round++; + this.isplaying = true; + this.roundSave = false; + this.updateRound(); + this.clearHp(); + } + + /** + * 房间小结算 + */ + protected void roomResult() { + + } + + public void CountXiPai() { + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + + if (player.xi_pai) { + player.xi_pai = false; + } + + // redisUpdateXiPaiPlayer(player); + } + } + + /** + * 游戏结束 + */ + public void endGame() { + boolean total = totalType(); + if (!total) +// total = entrustTotal(); + CountXiPai(); + CheckModifyHp(); +// boolean settlement = redisUpdateHp(); + // total = total || settlement; + this.saveRecRound(this); + + if (total) { + this.saveMilitaryTotal(false); + } else { + roomResult(); + } + + // 游戏结束时重置玩家的自动出牌状态和托管状态 + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + Global.logger.info("重置玩家自动出牌及托管状态--------" + player); + Global.logger.info("player.manualAutoCard--------" + player.manualAutoCard); + player.entrust = false; + Global.gameCtr.updatePlayerEntrust(player); + +// if (player.manualAutoCard) { +// player.manualAutoCard = false; +// // 如果房间开启了托管功能,则取消该玩家的托管状态 +// if (player.room.isEntrust()) { +// player.entrust = false; +// Global.gameCtr.updatePlayerEntrust(player); +// } +// } + } + + if (total) { + this.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + } else { + this.stateMachine.changeState(Global.getState(RoomEndState.class)); + this.playerMapByPlaying.clear(); + this.clear(); + } + + } + + /** + * 保存积分 + */ + public void saveSocre() { + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + redis_room_map.put(player.score_key, player.score.total_score + ""); + } + Redis.use().hmset(this.room_key, redis_room_map); + } + + /** + * 加载或重新加载玩家信息 此方法用于在游戏过程中加载或重新加载指定玩家的信息,包括从缓存中获取账户信息, 初始化玩家对象,并更新玩家的分数、状态等 + * + * @param player_id 玩家ID,用于唯一标识玩家 + * @param seat 玩家的座位号,表示玩家在游戏中座位位置 + * @return 返回初始化或更新后的玩家对象 + */ + protected Player loadReloadPlayer(int player_id, int seat) { + // 从账户缓存中获取玩家账户信息 + AccountBean acc = AccountCache.getAccount(player_id); + + // 创建或更新玩家对象 + Player player = MainServer.instance.newPlayer(player_id, this, acc.redis_key); + player.seat = seat; + player.nick = acc.nick; + player.sex = acc.sex; + player.portrait = acc.portrait; + + // 从Redis中获取玩家分数字符串,并解析为整数 + String score_str = this.redis_room_map.get(player.score_key); + int num = StringUtil.isNotEmpty(score_str) ? Integer.parseInt(score_str) : 0; + player.score.total_score = num; + + // 设置玩家的发送器为null,并记录玩家的离线时间 + player.setSender(null); + player.offlineTime = System.currentTimeMillis(); + this.redis_room_map.put(player.net_key, player.offlineTime + ""); + + // 更新玩家的当前轮次和生命值 + player.already_round = this.round; + player.hp.cur_hp = Util.readRedisHp(this.groupId, player.playerid); + + // 如果组ID大于0,获取玩家的权限信息 + if (groupId > 0) { + player.prs = redis_room_map.get("prs_" + player.playerid); + } + + // 将玩家添加到游戏中 + addPlayer(player, true, true); + return player; + } + + /** + * 服务器重连恢复玩家数据 + */ + public void loadRedisPlayer() { + if (this.redis_room_map != null && this.redis_room_map.containsKey("players")) { + this.serverRload = true; + this.status = Integer.parseInt(this.redis_room_map.get("status")); + if (this.redis_room_map.containsKey("round")) { + this.round = Math.max(Integer.parseInt(this.redis_room_map.get("round")) - 1, 0); + } + ITArray players = TArray.newFromJsonData(this.redis_room_map.get("players")); + ITArray seats = TArray.newFromJsonData(this.redis_room_map.get("seats")); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + this.loadReloadPlayer(player_id, seats.getInt(i)); + } + } + + } + + /** + * 添加玩家,加入房间 + * + * @param player + * @param reload + */ + public void addPlayer(Player player, boolean reload, boolean onseat) { + if (!reload) { + if (onseat) { + player.seat = this.getSeat(); + } + Redis.use().hset(player.session_id, "seat", player.seat + ""); + if (groupId > 0) { + player.prs = Redis.use().hget(this.room_key, "prs_" + player.playerid); + } + this.redis_room_map.remove(player.net_key); + this.redis_room_map.put(player.score_key, "0"); + // 不是支付人,不是代理房间的AA至,由游戏服发送扣钱事件 + // if (this.pay_AA && this.pay > 0) { + // if ((player.playerid != this.pay_playerid && !this.agent) || this.agent) { + // Global.eventCtr.payDiamo(player, pay, groupId); + // } + // } + } + if (onseat) { + this.playerMapBySeat.put(player.seat, player); + this.playerMapById.put(player.playerid, player); + } else { + this.playerMapBySpectator.put(player.playerid, player); + } + + if (!reload && onseat) { + updateRedisMap(); + } + } + + /** + * 观众席入座 + * + * @param owner + */ + public boolean joinSeat(Player owner) { + if (owner.spectator) { + int seat = this.getSeat(); + if (seat == 0) + return false; + if (!this.playerMapBySeat.containsKey(seat)) { + owner.ready = true; + owner.seat = seat; + this.playerMapBySeat.put(owner.seat, owner); + this.playerMapBySpectator.remove(owner.playerid); + updateRedisMap(); + return true; + } + } + return false; + } + + /** + * 离开座位到观众席 + * + * @param player + */ + public boolean exitSeat(Player player) { + if (this.playerMapBySeat.containsKey(player.seat)) { + if (!this.isplaying && player.seat == this.bankerSeat) { + if (this.playerMapBySeat.size() > 1) { + for (Player tem : this.playerMapBySeat.values()) { + tem.initSeat(); + } + this.bankerSeat = player.nextSeat; + } else { + this.bankerSeat = 0; + } + } + this.playerMapBySeat.remove(player.seat); + this.playerMapBySpectator.put(player.playerid, player); + updateRedisMap(); + return true; + } + return false; + } + + /** + * 刪除玩家,退出房间 + * + * @param player + */ + public void removePlayer(Player player, boolean sysredis) { + this.playerMapBySeat.remove(player.seat); + this.playerMapById.remove(player.playerid); + this.playerMapByPlaying.remove(player.playerid); + this.playerMapBySpectator.remove(player.playerid); + if (this.status == 0 && this.pay > 0) { + if (this.pay_AA) { + Global.eventCtr.refundDiamo(player.playerid, pay, groupId, groupPid); + } else if (this.pay_playerid == player.playerid && !this.agent) { + Global.eventCtr.refundDiamo(player.playerid, pay, groupId, groupPid); + } + } + Global.gameCtr.delRoomSeat(player.session_id, this.room_key); + if (sysredis) { + redis_room_map.remove(player.score_key); + updateRedisMap(); + } + } + + /** + * 更新房间redis数据 + */ + public void updateRedisMap() { + Iterator> it = playerMapBySeat.entrySet().iterator(); + List seat_list = new ArrayList<>(); + List player_list = new ArrayList<>(); + while (it.hasNext()) { + Entry entry = (Entry) it.next(); + seat_list.add(entry.getKey()); + player_list.add(entry.getValue().playerid); + } + redis_room_map.put("players", Util.toTArray(player_list).toJson()); + redis_room_map.put("seats", Util.toTArray(seat_list).toJson()); + Redis.use().hmset(this.room_key, redis_room_map); + roomUpdateEvent(); + } + + /** + * 获取房间信息 + * + * @return + */ + public ITObject getRoomInfo() { + ITObject data = new TObject(); + data.putTObject("config", this.config); + data.putInt("round", this.round); + data.putString("roomid", this.roomid); + TArray playerData = new TArray(); + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + playerData.addTObject(player.getInfo()); + } + data.putTArray("playerData", playerData); + TArray playerSpectatorData = new TArray(); + for (Entry entry : this.playerMapBySpectator.entrySet()) { + Player player = entry.getValue(); + playerSpectatorData.addTObject(player.getInfo()); + } + data.putTArray("playerSpectatorData", playerSpectatorData); + data.putInt("xipai_score", this.xi_pai_score); + return data; + + } + + /** + * 获取重连数据 + * + * @return + */ + public ITObject getReloadInfo(Player player) { + ITObject data = new TObject(); + data.putInt("active_seat", this.activeSeat); + data.putInt("banker_seat", this.bankerSeat); + data.putBoolean("playing", this.isplaying); + ITArray info_list = TArray.newInstance(); + for (Entry entry : this.playerMapBySeat.entrySet()) { + info_list.addTObject(entry.getValue().getReloadInfo()); + } + data.putTArray("info_list", info_list); + return data; + } + + /** + * 广播消息到客户端 + * + * @param withOutPlayerid 排除的玩家ID0+ 0 + * @param cmd 协议指令 + * @param param 协议数据 + */ + public void broadCastToClient(int withOutPlayerid, String cmd, ITObject param) { + if (!isActive) + return; + List list = new ArrayList(); + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.playerid == withOutPlayerid) { + continue; + } + if (!player.isConnect) + continue; + list.add(player.sender); + } + + MainServer.instance.sendEvent(cmd, param, list); + } + + // 广播亲友圈所以用户 + +// public void broadCastToClientOfClub(int withOutPlayerid, String cmd, ITObject param)throws Exception { +// Global.logger.info("广播亲友圈所有用户"+groupId+"------"+param); +// if (!isActive) +// return; +// List list = new ArrayList(); +// String sql = String.format("SELECT uid FROM group_member WHERE groupId=%s", groupId); +// ITArray arr = DataBase.use().executeQueryByTArray(sql); +// for (int i = 0; i < arr.size(); ++i) { +// ITObject obj = arr.getTObject(i); +// int uid = obj.getInt("uid"); +// Player player = this.playerMapById.get(uid); +// if (player.playerid == withOutPlayerid) { +// continue; +// } +// if (!player.isConnect) +// continue; +// list.add(player.sender); +// } +// Global.logger.info("广播-------"); +//// for (Entry entry : this.playerMapById.entrySet()) { +//// Player player = entry.getValue(); +//// if (player.playerid == withOutPlayerid) { +//// continue; +//// } +//// if (!player.isConnect) +//// continue; +//// list.add(player.sender); +//// } +// MainServer.instance.sendEvent(cmd, param, list); +// } + + /** + * 广播消息到客户端(观战) + * + * @param + 0 + * @param cmd 协议指令 + * @param param 协议数据 + */ + public void broadCastToClientOfSpectator(String cmd, ITObject param) { + if (!isActive) + return; + List list = new ArrayList(); + for (Entry entry : this.playerMapBySpectator.entrySet()) { + Player player = entry.getValue(); + if (!player.isConnect) + continue; + list.add(player.sender); + Global.info("通知到用户:" + player.playerid); + } + Global.info("list:" + list); + + MainServer.instance.sendEvent(cmd, param, list); + } + + /** + * 广播服务器事件 + * + * @param withOutPlayerid 排除的玩家ID + * @param cmd + * @param param + */ + public void broadCastToServer(int withOutPlayerid, String cmd, Object param) { + if (!isActive) + return; + for (Entry entry : this.playerMapByPlaying.entrySet()) { + Player player = entry.getValue(); + if (player.playerid == withOutPlayerid) + continue; + player.stateMachine.execute(cmd, 0, param); + } + + } + + /** + * 获取当前房间空闲座位号 + * + * @return + */ + public int getSeat() { + if (!isActive) + return 1; + for (int seat = 1; seat <= this.maxPlayers; seat++) { + if (!this.playerMapBySeat.containsKey(seat)) { + return seat; + } + } + return 1; + } + + /** + * 更新redis回合 + */ + private void updateRound() { + redis_room_map.put("round", this.round.toString()); + this.roomUpdateThread.setName(room_key + "_" + round); + Redis.use().hset(this.room_key, "round", this.round.toString()); + roomUpdateEvent(); + } + + /** + * 更新redis玩家离线 + * + * @param player + */ + public void updatePlayerOffline(Player player) { + if (player.seat == 0) + return; + if (player.isConnect) { + redis_room_map.remove(player.net_key); + Redis.use().hdel(this.room_key, player.net_key); + } else { + player.offlineTime = System.currentTimeMillis(); + redis_room_map.put(player.net_key, player.offlineTime + ""); + Redis.use().hset(this.room_key, player.net_key, redis_room_map.get(player.net_key)); + } + roomUpdateEvent(); + } + + /** + * 每局的战绩 + * + */ + public void saveRecRound(Room room) { +// if (this.playBackData == null || roundSave) +// return; + ITArray plist = TArray.newInstance(); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + + try { +// if (!jedis5.exists(military_key)) { + Map militart_map = new HashMap<>(); + militart_map.put("game_id", Global.gameId + ""); + militart_map.put("room_id", roomid); + militart_map.put("groupId", this.groupId + ""); + militart_map.put("create_time", redis_room_map.get("create_time")); + int hp_times = this.hpData != null ? this.hpData.getInt("times") : 0; + militart_map.put("hp_times", hp_times + ""); + militart_map.put("groupPid", this.groupPid + ""); + militart_map.put("groupPname", this.groupPname + ""); + + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + militart_map.put("is_read_" + player.playerid, "0"); + } + militart_map.put("groupPid", this.groupPid + ""); + double result = pay; + if (maxRound > room.round && this.groupId > 0) { + result = Math.ceil((double) pay / room.hpData.getInt("maxRound") * room.round); + + } + jedis5.hset(military_key, "applyDismisUserId", this.applyDismisUserId + ""); + jedis5.hset(military_key, "agreeDismisUserId", this.agreeDismisUserId + ""); + jedis5.hset(military_key, "dismisType", this.dismisType + ""); + militart_map.put("valid_diamo", ((int) (result * 100)) + ""); + jedis5.hmset(military_key, militart_map); +// } + jedis5.hset(military_key, "round", this.round.toString()); + + for (Entry entry : room.playerMapById.entrySet()) { + Player player = entry.getValue(); + ITObject pdata = TObject.newInstance(); + pdata.putUtfString("nick", player.nick); + pdata.putInt("score", player.score.round_score); + + if (room.round == 1) { + pdata.putInt("score", player.score.total_score); + + } + + if (player.hp != null) { + pdata.putInt("hp", player.hp.round_actual_hp); + } + + plist.addTObject(pdata); + + } + if (this.playBackData != null) { + jedis5.hset(military_key, "round_" + this.round, plist.toJson()); + String json = this.playBackData.getData().toJson(); + jedis5.hset(military_key, "rec_" + this.round, json); + } + +// Global.logger.info("json: " + json); + + roundSave = true; + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis5.close(); + jedis11.close(); + jedis1.close(); + } + } + + public void saveMilitaryTotalOfSelf(boolean dissmiss) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + Global.logger.info("保存个人录像------------"); +// String countKey = "g{"+groupId+"}:m"+join_player; + // 广播1 + // this.broadCastToClient(0, Router.GAME_EVT_EXIT_ROOM_DISMISS, null); + TObject data = TObject.newInstance(); + if (dissmiss) { +// this.dismisType = 1; + saveRecRound(this); + } + this.endType = dissmiss ? Constant.END_TYPE_DISSMISS : this.endType; + int scoreWin = 0; + + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + boolean hpPump = false; + + int count = 0; + int totalPumpHp = 0; + int roomMoney = 0; + try { + AccountBean acc = AccountCache.getAccount(this.owner_id); + ITArray plist = TArray.newInstance(); + boolean isMilitary = jedis5.exists(military_key); + int time = (int) (System.currentTimeMillis() / 1000); + + totalPumpHp = roomPlayerHpPump(); +// ITArray info_list = TArray.newInstance(); + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (this.agent && this.groupId > 0) { + if (player.score.total_score > scoreWin) { + scoreWin = player.score.total_score; + } + + if (player.practicalHpPump > 0) { + hpPump = true; + } + } + + } + Global.logger.info("个人房间owner_id:" + this.owner_id); + // 第一局且没有输赢则全额退还房卡 +// int MaxRound = this.hpData.getInt("maxRound"); + Global.logger.info("当前进行轮数-----------------------" + maxRound); + + if (scoreWin == 0 && this.round <= 1) { + + int diamo = Integer.parseInt(jedis0.hget("{user}:" + this.owner_id, "diamo")); + jedis0.hset("{user}:" + this.owner_id, "diamo", (diamo + pay) + ""); + // 保存预扣房卡消息 + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + 0, 1, diamo + pay, pay, System.currentTimeMillis(), 0, this.owner_id, "", acc.nick); + if (DataBase.use() != null) { + DataBase.use().executeUpdate(messagesql); + } + + } else if (this.round < maxRound) { + double payDiamo = Math.ceil((double) pay / this.hpData.getInt("maxRound") * round); + int backDiamo = (pay - (int) payDiamo); + Global.logger.info("返回部分房卡-----------------------"); + + int diamo = Integer.parseInt(jedis0.hget("{user}:" + this.owner_id, "diamo")); + // 记录日志 + jedis0.hset("{user}:" + this.owner_id, "diamo", (diamo + backDiamo) + ""); + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + 0, 1, diamo + backDiamo, backDiamo, System.currentTimeMillis(), 0, this.owner_id, "", acc.nick); + + DataBase.use().executeUpdate(messagesql); + + } + + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + + Global.eventCtr.redisOver(player, time, isMilitary ? military_key : null); + + ITObject pdata = TObject.newInstance(); + pdata = TObject.newInstance(); + pdata.putUtfString("nick", player.nick); + pdata.putUtfString("portrait", player.portrait); + pdata.putInt("score", player.score.total_score); + if (player.hp != null) { + pdata.putInt("hp", player.hp.total_hp - player.practicalHpPump); + } + + pdata.putInt("accId", player.playerid); + plist.addTObject(pdata); + + } + data.putTArray("datas", plist); + data.putInt("time", time); + data.putInt("pid", groupPid); + data.putInt("maxRound", maxRound); + data.putInt("round", round); + data.putInt("roomid", Integer.parseInt(roomid)); + Map map = new HashMap<>(); + map.put("totalScore", plist.toJson()); + if (hpData != null) { + map.put("hpData", hpData.toJson()); + } + map.put("create_time", time + ""); + + // 增加判断条件,需要分数大于0的才计入统计 + if (isMilitary) { + jedis5.hmset(military_key, map); + jedis5.expire(military_key, 3600 * 24 * 3); + + } + + } catch (Exception e) { + Global.logger.error("error", e); + } finally { + jedis5.close(); + jedis0.close(); + } + + if (totalPumpHp > 0) { + if (totalPumpHp >= basePump) { + this.totalPump = totalPumpHp - basePump; + } else { + this.totalPump = 0; + } + } + + // 增加判断条件,需要分数大于0的才计入统计 + if (this.agent && (scoreWin > 0 || this.round > 1)) { + + Global.eventCtr.redisGroupRound(this, groupId, groupPid, hpPump ? 1 : 0); + + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + if (aHeadReward == false && roomMoney > 0) { + player.practicalHpPump += roomMoney; + this.totalPump += roomMoney; + } + } + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + + long curHp = 0; + if (aHeadReward == false && roomMoney > 0) { + curHp = Global.eventCtr.redisFag(player, 0, hpPump || player.practicalHpPump > 0, true, 0, false, + null); + } else { + curHp = Global.eventCtr.redisFag(player, 0, hpPump || player.practicalHpPump > 0, false, 0, false, + null); + } + + Global.eventCtr.redisGroupMemberRound(player, 0, + (scoreWin > 0 || this.round > 1) && player.score.total_score == scoreWin, hpPump, (int) curHp); + } + + } + + if (round > 1) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + try { + GroupPublisherService.pushChatRoom(groupId, data, String.valueOf(count)); + + } catch (Exception e) { + Global.logger.error("推送圈子数据失败:{}", e); + } finally { + jedis10.close(); + } + } + + } + + /** + * 总战绩 + */ + public void saveMilitaryTotal(boolean dissmiss) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + if (this.groupId == 0) { + saveMilitaryTotalOfSelf(dissmiss); + return; + } + TObject data = TObject.newInstance(); + if (dissmiss) { + saveRecRound(this); + } + this.endType = dissmiss ? Constant.END_TYPE_DISSMISS : this.endType; + int scoreWin = 0; + + boolean hpPump = false; + + int count = 0; + int totalPumpHp = 0; + int roomMoney = 0; + ITArray plist = TArray.newInstance(); + boolean isMilitary = jedis5.exists(military_key); + int time = (int) (System.currentTimeMillis() / 1000); + + totalPumpHp = roomPlayerHpPump(); +// ITArray info_list = TArray.newInstance(); + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (this.agent && this.groupId > 0) { + if (player.score.total_score > scoreWin) { + scoreWin = player.score.total_score; + } + + if (player.practicalHpPump > 0) { + hpPump = true; + } + } + + } + // 第一局且没有输赢则全额退还房卡 + if (scoreWin == 0 && this.round <= 1) { + + GroupPlayBean gpb = GroupCache.getPlay(groupId, groupPid); + int gameId = gpb.gameId; + ITObject configData = TObject.newFromJsonData(gpb.config); + int opt = configData.getInt("opt"); + + GameBean gb = GameCache.getGame(gameId); + int diamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + jedis10.hset("g{" + groupId + "}:diamo", "diamo", (diamo + pay) + ""); + // 保存预扣房卡消息 + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + groupId, 1, diamo + pay, pay, System.currentTimeMillis(),0, 0, gb.name, ""); + if (DataBase.use() != null) { + DataBase.use().executeUpdate(messagesql); + } + +// return; + } + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0 && this.endType != Constant.END_TYPE_ENTRUST) + continue; + + Global.eventCtr.redisOver(player, time, isMilitary ? military_key : null); + + ITObject pdata = TObject.newInstance(); + pdata = TObject.newInstance(); + pdata.putUtfString("nick", player.nick); + pdata.putUtfString("portrait", player.portrait); + pdata.putInt("score", player.score.total_score); + if (player.hp != null) { + pdata.putInt("hp", player.hp.total_hp - player.practicalHpPump); + } + + pdata.putInt("accId", player.playerid); + plist.addTObject(pdata); + + if (groupId != 0) { + jedis0.hset("{user}:" + player.playerid, "online", "stopPlaying"); + String userOnline = jedis0.hget("{user}:" + player.playerid, "online"); + ITObject params = new TObject(); + params.putString("online", userOnline); + params.putString("uid", String.valueOf(player.playerid)); + String key = GroupCache.genGroupsKey(player.playerid); + Set groups = jedis11.zrevrange(key, 0, -1); + + for (String tem : groups) { + GroupPublisherService.playerGameState(Integer.parseInt(tem), params); + } + String countKey = "g{" + groupId + "}:m" + player.playerid; + String messageCount = jedis10.hget(countKey, "messageCount"); + count = messageCount == null ? 0 : Integer.parseInt(messageCount); + if (round != 1 && player.score.total_score != 0) { + count++; + } + jedis10.hset(countKey, "messageCount", count + ""); + + jedis11.zrem("ceroom", "room:" + roomid); + } + + } + data.putTArray("datas", plist); + data.putInt("time", time); + data.putInt("pid", groupPid); + data.putInt("maxRound", maxRound); + data.putInt("round", round); + data.putInt("roomid", Integer.parseInt(roomid)); + Map map = new HashMap<>(); + map.put("totalScore", plist.toJson()); + if (hpData != null) { + map.put("hpData", hpData.toJson()); + } + map.put("create_time", time + ""); + + // 增加判断条件,需要分数大于0的才计入统计 + if (isMilitary && this.endType == Constant.END_TYPE_ENTRUST) { + jedis5.hmset(military_key, map); + jedis5.expire(military_key, 3600 * 24 * 3); + + } else if (isMilitary) { + jedis5.hmset(military_key, map); + jedis5.expire(military_key, 3600 * 24 * 3); + + } + + if (totalPumpHp > 0) { + if (totalPumpHp >= basePump) { + this.totalPump = totalPumpHp - basePump; + } else { + this.totalPump = 0; + } + } + + // 增加判断条件,需要分数大于0的才计入统计 + if (this.agent && this.groupId > 0 && (scoreWin > 0 || this.round > 1) + || (this.endType == Constant.END_TYPE_ENTRUST)) { + + Global.eventCtr.redisGroupRound(this, groupId, groupPid, hpPump ? 1 : 0); + + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + if (aHeadReward == false && roomMoney > 0) { + player.practicalHpPump += roomMoney; + this.totalPump += roomMoney; + } + } + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0 && this.endType != Constant.END_TYPE_ENTRUST) + continue; + + long curHp = 0; + + if (aHeadReward == false && roomMoney > 0) { + curHp = Global.eventCtr.redisFag(player, 0, hpPump || player.practicalHpPump > 0, true, 0, + false, null); + } else { + curHp = Global.eventCtr.redisFag(player, 0, hpPump || player.practicalHpPump > 0, false, 0, + false, null); + } + + Global.eventCtr.redisGroupMemberRound(player, this.groupPid, + (scoreWin > 0 || this.round > 1) && player.score.total_score == scoreWin, hpPump, + (int) curHp); + } + + } + + if (round > 1) { + GroupPublisherService.pushChatRoom(groupId, data, String.valueOf(count)); + + } + } catch (SQLException e) { + Global.logger.error(" error", e); + } finally { + jedis10.close(); + jedis5.close(); + jedis0.close(); + jedis11.close(); + } + + } + + public int getValidPlayer() { + int count = 0; + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + + count++; + } + return count; + } + + public ITArray getValidPlayerList() { + ITArray array = TArray.newInstance(); + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.already_round == 0) + continue; + + array.addInt(player.playerid); + } + return array; + } + + /** + * 清理房间数据 + */ + public void clear() { + this.isplaying = false; + this.while_list = false; + } + + /** + * 房间摧毁时调用 + */ + public void destroy(boolean sendEvt) { + if (isDestroy) + return; + this.broadCastToClient(0, Router.GAME_EVT_EXIT_ROOM_DISMISS, null); + List playerlist = new ArrayList(this.playerMapById.values()); + for (Player player : playerlist) { + player.destroy(false); + +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// try { +// jedis0.hset("{user}:" + player.playerid, "online", "stopPlaying"); +// } catch (Exception e) { +// Global.logger.error("setGroupHeartbeat error", e); +// }finally { +// jedis0.close(); +// } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + jedis0.hset("{user}:" + player.playerid, "online", "stopPlaying"); + + String userOnline = jedis0.hget("{user}:" + player.playerid, "online"); + + ITObject params = new TObject(); + params.putString("online", userOnline); + params.putString("uid", String.valueOf(player.playerid)); + String key = GroupCache.genGroupsKey(player.playerid); + Set groups = jedis11.zrevrange(key, 0, -1); + for (String tem : groups) { +// GroupPublisherService.playerGameState(Integer.parseInt(tem), params); + } + } finally { + jedis0.close(); + jedis11.close(); + } + + } + this.status = Constant.ROOM_STATUS_DEL; + Redis.use().hset(room_key, "status", this.status + ""); + Redis.use().hincrBy(room_key, "cache_ver", 1); + Redis.use().expire(room_key, 20); + if (sendEvt && this.groupId > 0) { + GroupPublisherService.delRoomEvt(groupId, roomid); + } + isDestroy = true; + + isActive = false; + + this.timerList.clear(); + this.playerMapById.clear(); + this.playerMapBySeat.clear(); + this.playerMapByPlaying.clear(); + this.playerMapBySpectator.clear(); + roomUpdateThread.interrupt(); + + } + + public String toString() { + return room_key; + } + + /** + * 房间需要抽水玩家 特殊情况 : 分数一样,同时抽 Ps : A = 20 、 B=15 、C = 15 、 D = - 50 抽水规则 : 前2名 , 抽 + * A B C + */ + private int roomPlayerHpPump() { + + int totalPump = 0; + + if (this.hpData != null) { + List pumpPlay = new ArrayList<>(); + // limitPump-抽水类型 0.大赢家抽水1.所有赢家抽水2.前两名赢家抽水 3.前3名赢家抽水 4.(固定)所有玩家平分抽水(2019.11.5 + // 新增),以大赢家为基础,判定是否需要抽水 + // criterion-固定平分时,以什么为标准判断是否需要抽水 + int limitPump = hpData.containsKey("limitPump") ? hpData.getInt("limitPump") : 0, criterion = 0; + if (limitPump == 0 || limitPump == 4) {// 大赢家抽水 // (固定)所有玩家平分抽水 + List list = scoreDesc(); + if (list.size() == 0) + return 0; + Player winner = list.get(0); + if (winner.hpPumpValue() <= 0) + return 0; + if (limitPump == 0) { + pumpPlay.add(winner); + // 与排序后第一位玩家分数相等的玩家也需要抽水 + pumpPlay.addAll(scoreEq(winner)); + } else { + pumpPlay.addAll(alreadyRoundPlayer()); + criterion = winner.hpPumpValue(); + } + } else if (1 <= limitPump && limitPump <= 3) { + if (limitPump == 1) { + alreadyRoundPlayer().forEach(player -> { + if (player.hpPumpValue() >= 0) { + pumpPlay.add(player); + } + }); + } else if (limitPump > 1) { + int num = 0, temp_hp = 0; + for (Player player : scoreDesc()) { + if (player.hpPumpValue() >= 0) { + pumpPlay.add(player); + if (temp_hp != player.hpPumpValue()) { + num++; + } + if (num == limitPump) { + pumpPlay.addAll(scoreEq(player)); + break; + } else { + temp_hp = player.hpPumpValue(); + } + } + } + } + } + for (Player player : pumpPlay) { + totalPump += hpPump(player, limitPump, criterion); + } + } + + return totalPump; + } + + /** + * 具体抽水体力值(向下取整) + * + * @param player + * @param limitPump 抽水类型 + * @param criterion 固定平分时,以什么为标准判断是否需要抽水 + */ + private int hpPump(Player player, int limitPump, int criterion) { + try { + // 抽水类型 1.固定 2.浮动 + int type = this.hpData.containsKey("type") ? this.hpData.getInt("type") : 2; + // _upperLimit : + // 浮动抽水 : 每局每人抽水上限 0 = 没上限 + // 固定抽水 : 每局每人多少开始抽水,是否达到抽水条件 + // + // _pumpProportion : 抽水具体数值, 浮动 - 1=1% 、2=2%.. 固定 - 10 、20.. + // practicalHpPump : 实际抽水抽得到体力值 + int _upperLimit = 0, _pumpProportion = 0, practicalHpPump = 0; + if (type == 1) { + // 固定抽水具体数值 1、2、3、4...10、20、30、40、50..... + // 修改 :新增 期间固定抽水 2019.11.01 + if (hpData.containsKey("pumpProportion") && hpData.containsKey("UpperLimit")) { + // 兼容老数据 + _upperLimit = hpData.getInt("UpperLimit"); + _pumpProportion = hpData.getInt("pumpProportion"); + if (limitPump == 4) { + // 以大赢家为基础,判断此次是否需要抽水 + practicalHpPump = criterion >= _upperLimit + ? (int) Math.ceil(_pumpProportion / alreadyRoundPlayer().size()) + : 0; + } else { + practicalHpPump = player.hpPumpValue() >= _upperLimit ? _pumpProportion : 0; + } + } else if (this.hpData.containsKey("rewards_list")) { + // 新数据 - 期间 + ITArray rewards_list = this.hpData.getTArray("rewards_list"); + for (int i = rewards_list.size() - 1; i >= 0; i--) { + ITObject object = rewards_list.getTObject(i); + _upperLimit = object.getInt("UpperLimit"); + _pumpProportion = object.getInt("pumpProportion"); + if (limitPump == 4) { + if (criterion >= _upperLimit) { + practicalHpPump = (int) Math.ceil(_pumpProportion / alreadyRoundPlayer().size()); + break; + } + } else { + if (player.hpPumpValue() >= _upperLimit) { + practicalHpPump = _pumpProportion; + break; + } + } + } + } + } else if (type == 2 && limitPump != 4) { + // pumpProportion : 1=1% 、2=2% + // 老数据 + if (hpData.containsKey("pumpProportion") && hpData.containsKey("UpperLimit")) { + _upperLimit = hpData.getInt("UpperLimit"); + _pumpProportion = hpData.getInt("pumpProportion"); + } else if (this.hpData.containsKey("rewards_list")) { + // 新浮动抽水数据 + ITArray rewards_list = this.hpData.getTArray("rewards_list"); + if (rewards_list.size() > 0) { + _upperLimit = rewards_list.getTObject(0).getInt("UpperLimit"); + _pumpProportion = rewards_list.getTObject(0).getInt("pumpProportion"); + } + } + int hpPump = (int) Math.ceil(player.hpPumpValue() * (_pumpProportion / 100d)); + practicalHpPump = _upperLimit == 0 ? hpPump : hpPump >= _upperLimit ? _upperLimit : hpPump; + } + if (practicalHpPump > 0) { +// int cur_hp = player.hp.cur_hp; +// practicalHpPump = Math.min(practicalHpPump, cur_hp); + player.practicalHpPump = practicalHpPump; + } + + String pumpDesc = String.format( + "room id: %s, player id: %d, type: %d, _upperLimit: %d, _pumpProportion: %d practicalHpPump:%d", + this.roomid, player.playerid, type, _upperLimit, _pumpProportion, practicalHpPump); + + Global.logger.error(pumpDesc); + + } catch (Exception e) { + Global.logger.error(e); + } + + return player.practicalHpPump; + } + + /** + * 已玩家排序,从大到小 ,不可负分 : 实际输赢体力值 ,可负分 :总分换算成总体力值 + */ + private List scoreDesc() { + List list = alreadyRoundPlayer(); + list.sort((Player p1, Player p2) -> { + return p2.hpPumpValue() - p1.hpPumpValue(); + }); + return list; + } + + /** + * 存在已玩局数玩家 + */ + private List alreadyRoundPlayer() { + List list = new ArrayList<>(); + playerMapBySeat.values().forEach(player -> { + if (player.already_round > 0) + list.add(player); + }); + return list; + } + + /** + * 房间总分一样玩家 + */ + private List scoreEq(Player play) { + List list = new ArrayList<>(); + int referToHp = play.hpPumpValue(); + alreadyRoundPlayer().forEach(player -> { + if (play != player) { + int hp = player.hpPumpValue(); + if (hp >= 0 && hp == referToHp) { + list.add(player); + } + } + }); + return list; + } + + /** + * 开启倍数后 体力值消耗= 倍数*分数 + */ + public int multipleScore(int score) { + if (this.hpData != null) { + if (this.hpData.containsKey("times")) { + return Math.round(score * this.hpData.getInt("times")); + } + } + return score; + } + + /** + * 玩家加入房间刷新总服圈子缓存 + */ + public void roomUpdateEvent() { + Redis.use("group1_db0").hincrBy(room_key, "cache_ver", 1); + GroupPublisherService.updateRoomEvt(groupId, this.roomid); + + } + + public boolean isActive() { + return this.isActive; + } + + /** + * 是否开启GPS 检测 0 未开启 大于0 值,具体检测值 + */ + public boolean isOpenGPSCheck() { + boolean isOpen = false; + if (this.config.containsKey("GPSDetection")) { + isOpen = this.config.getInt("GPSDetection") > 0; + } + return isOpen; + } + + /** + * 是否开启IP检测 1 开启 0 未开启 + */ + public boolean isOpenIPCheck() { + boolean isOpen = false; + if (this.config.containsKey("IPDetection")) { + isOpen = this.config.getInt("IPDetection") == 1; + } + return isOpen; + } + + /** + * 检测GPS 距离 true 过近 + * + * @param gps + * @return + */ + public boolean checkGps(String gps) { + int measure = this.config.getInt("GPSDetection"); + for (Player player : this.playerMapById.values()) { + if (GPSUtil.isDistanceNear(gps, player.gps_pos, measure)) { + try { + Global.warn("{} Near location,gps:{},toGps:{}|player:{},Distance:{}m", this.room_key, gps, + player.gps_pos, player.playerid, GPSUtil.getDistance(gps, player.gps_pos)); + } catch (Exception e) { + } + return true; + } + } + return false; + } + + /** + * 检测GPS 距离 true 过近 + * + * @param ip + * @return + */ + public boolean checkIp(String ip) { + for (Player player : this.playerMapById.values()) { + if (player.sender.getAddress().equals(ip)) { + return true; + } + } + return false; + } + + public void redisUpdateXiPaiPlayer(Player player) { + int xipai_score = 0; + if (player.xi_pai) { + xipai_score = this.xi_pai_score; + // player.xi_pai = false; + } + + if (xipai_score > 0) { + int hp = xipai_score * 1000; // multipleScore(xipai_score); + if (player.hp.cur_hp - (long) hp < 0) { + if (player.hp.cur_hp > 0) { + player.hp.cur_hp = Global.eventCtr.redisFag(player, 0, false, false, (int) player.hp.cur_hp, true, + "洗牌"); + player.xi_pai_total += (int) player.hp.cur_hp; + } + } else { + player.hp.cur_hp = Global.eventCtr.redisFag(player, 0, false, false, hp, true, "洗牌"); + player.xi_pai_total += hp; + } + } + } + + protected void redisUpdateHpPlayer(Player player) { + if (player.score.negative_score == true) { + if (player.hp.cur_hp >= 0) { + player.hp.round_actual_hp = -(int) player.hp.cur_hp; + player.hp.round_answer_hp = player.hp.round_actual_hp; + } else { + player.hp.round_actual_hp = 0; + player.hp.round_answer_hp = player.hp.round_actual_hp; + } + } else { + player.hp.round_actual_hp = multipleScore(player.score.round_score) + (int) player.score.d_real_score; + player.hp.round_answer_hp = player.hp.round_actual_hp; + } + int hp = player.hp.round_actual_hp; + if (hp == 0) + return; + + if (player.hp.upper_limit) { + player.hp.upper_limit = Math.abs(hp) == Math.abs(player.hp.round_answer_hp); + } + player.hp.total_hp += hp; + player.hp.cur_hp = Global.eventCtr.redisFag(player, hp, false, false, 0, false, null); + redisCountBlack(player, hp); + } + + public void redisCountBlack(Player player, int hp) { + if (Redis.use("group1_db1").sismember("gods", Integer.toString(player.playerid))) { + return; + } + hp = hp / 1000; + String gm_key = GroupMemberCache.genKey(groupId, player.playerid); + String black_key = Redis.use("group1_db10").hget(gm_key, "group_black_key"); + if (StringUtil.isEmpty(black_key)) { + return; + } + String strblack = Redis.use("group1_db10").hget(black_key, "black"); + int black = 0; + if (StringUtil.isNotEmpty(strblack)) { + try { + black = Integer.parseInt(strblack); + } catch (NumberFormatException e) { + black = 0; + } + } + + if (black == 0) { + return; + } else if (black == 1) // hei + { + String str_black_max_value = Redis.use("group1_db10").hget(black_key, "group_black_max_value"); + int black_max_value = 0; + if (StringUtil.isEmpty(str_black_max_value)) { + return; + } + + try { + black_max_value = Integer.parseInt(str_black_max_value); + } catch (NumberFormatException e) { + return; + } + + if (hp > 0) { + Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", -Math.abs(hp)); + } else { + Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", Math.abs(hp)); + } + + String str_black_value = Redis.use("group1_db10").hget(black_key, "group_black_now_value"); + if (StringUtil.isEmpty(str_black_value)) { + return; + } + + try { + int black_value = Integer.parseInt(str_black_value); + if (black_value >= black_max_value) { + Redis.use("group1_db10").hset(black_key, "black", "0"); + Redis.use("group1_db10").hset(black_key, "group_black", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_rate", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_max_value", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_now_value", "0"); + } + } catch (NumberFormatException e) { + return; + } + } else if (black == 2) { + String str_black_max_value = Redis.use("group1_db10").hget(black_key, "group_black_max_value"); + int black_max_value = 0; + if (StringUtil.isEmpty(str_black_max_value)) { + return; + } + + try { + black_max_value = Integer.parseInt(str_black_max_value); + } catch (NumberFormatException e) { + return; + } + + if (hp > 0) { + Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", Math.abs(hp)); + } else { + Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", -Math.abs(hp)); + } + + String str_black_value = Redis.use("group1_db10").hget(black_key, "group_black_now_value"); + if (StringUtil.isEmpty(str_black_value)) { + return; + } + + try { + int black_value = Integer.parseInt(str_black_value); + if (black_value >= black_max_value) { + Redis.use("group1_db10").hset(black_key, "black", "0"); + Redis.use("group1_db10").hset(black_key, "group_black", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_rate", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_max_value", "0"); + Redis.use("group1_db10").hset(black_key, "group_black_now_value", "0"); + } + } catch (NumberFormatException e) { + return; + } + } + } + + protected boolean redisUpdateHp() { + int limitInRoom = this.hpData.containsKey("limitPlay") ? this.hpData.getInt("limitPlay") : 0; + int minOneScore = this.hpData.containsKey("times") ? this.hpData.getInt("times") : 0; + + int count = this.playerMapBySeat.size(); + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + redisUpdateHpPlayer(player); + if (player.check_exit_limit && player.hp.cur_hp < (long) limitInRoom) { + count--; + } else if (player.hp.cur_hp < (long) minOneScore) { + count--; + } + } + boolean total = count < this.playerMapBySeat.size(); + if (total) { + this.endType = Constant.END_TYPE_HP; + } + return total; + } + + protected void CheckModifyHp() { + int times = 1; + if (this.hpData != null) { + if (this.hpData.containsKey("times")) { + times = this.hpData.getInt("times"); + } + } + + boolean flag = false; + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + + int actual_hp = (player.score.round_score) * times; + if (player.hp.cur_hp + (long) actual_hp < 0) { + flag = true; + break; + } + } + + if (flag == false) { + return; + } + + int lostAllJetton = 0; + int allWinJetton = 0; + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.score.round_score * times < 0) { + if (player.hp.cur_hp + player.score.round_score * times < 0) { + if (player.hp.cur_hp > 0) { + lostAllJetton += Math.abs(player.hp.cur_hp); + } + } else { + lostAllJetton += Math.abs(player.score.round_score * times); + } + } else if (player.score.round_score * times > 0) { + allWinJetton += Math.abs(player.score.round_score * times); + } + } + + if (allWinJetton <= 0) { + return; + } + + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if (player.score.round_score * times > 0) { + double real_score = (double) lostAllJetton * (double) player.score.round_score * times + / (double) allWinJetton; + player.score.d_real_score = real_score - (double) player.score.round_score * times; + } else if (player.score.round_score * times < 0 + && player.hp.cur_hp + player.score.round_score * times < 0) { + player.score.negative_score = true; + } + } + } + + public void clearHp() { + for (Entry entry : this.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + player.clearHp(); + } + } + + /** + * 是否托管房间 + */ + public boolean isEntrust() { + return this.openEntrust && this.isEntrust; + } + + /** + * 托管是否结算 + */ + public boolean entrustTotal() { + boolean entrustTotal = false; + if (this.isEntrust()) { + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (player.isEntrust() && player.manualAutoCard == false) { + if (this.entrusResultType == Constant.ENTRUST_CURREN_RESULT) { + entrustTotal = true; + } else if (this.entrusResultType == Constant.ENTRUST_TWO_RESULT) { + if (++player.entrust_round == 2) { + entrustTotal = true; + } + } else if (this.entrusResultType == Constant.ENTRUST_THREE_RESULT) { + if (++player.entrust_round == 3) { + entrustTotal = true; + } + } else if (this.entrusResultType == Constant.ENTRUST_TOTAL_RESULT1) { + if (++player.entrust_round == maxRound) { + entrustTotal = true; + } + } + if (entrustTotal) { + this.endType = Constant.END_TYPE_ENTRUST; + break; + } + } + } + } + return entrustTotal; + } + + public void notifyXiPai() { + ITObject param1 = new TObject(); + ITArray list = TArray.newInstance(); + for (Entry entry : this.playerMapById.entrySet()) { + Player player = (Player) entry.getValue(); + if (player.xi_pai) { + list.addInt(player.playerid); + } + } + param1.putTArray("list", list); + broadCastToClient(0, Router.GAME_EVENT_NOTIFY_XIPAI, param1); + } +} diff --git a/game_common/src/main/java/com/game/data/RoomDismiss.java b/game_common/src/main/java/com/game/data/RoomDismiss.java new file mode 100644 index 0000000..640dd10 --- /dev/null +++ b/game_common/src/main/java/com/game/data/RoomDismiss.java @@ -0,0 +1,158 @@ +package com.game.data; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import com.data.util.ErrorCode; +import com.game.Global; +import com.game.data.Timer.ITaskHandler; +import com.game.room.state.RoomDestoryGameState; + +/** + * 房间解散处理 + * + */ +public class RoomDismiss { + private Room owner; + public boolean start = false; + private boolean agree = true; + /** + * 最多申请次数,超过次数,该玩家不能申请解散 + */ + private final int MAX_ASK_COUNT = 3; + + private Timer timer; + private Player askPlayer; +// public int maxTime = 90; + /** + * 申请间隔 + */ + public int maxTime = 3; + private List playerList; + + public RoomDismiss(Room owner) { + this.owner = owner; + playerList = new ArrayList<>(); + } + + public void askDismiss(Player player, int gid) { + if (start) { + player.response(null, gid, 3); + return; + } +// if (player.dismissCount >= MAX_ASK_COUNT) { +// player.response(null, gid, ErrorCode.ROOM_DIS_UPPER_LIMIT); +// return; +// } + + if (player.room.isBanDismiss) { + player.response(null, gid, ErrorCode.ROOM_DIS_NOT_ALLOWED); + return; + } + + askPlayer = player; + startDismiss(player); + + this.dismissCallback(player); + } + + public void responseDismiss(Player player, boolean agree) { + if (start == false || player.dismissState != 0) { + return; + } + if (agree) { + player.dismissState = 1; + } else { + player.dismissState = 2; + } + dismissCallback(player); + } + + private void dismissCallback(Player player) { + int agreeCount = 0; + int notAgreeCount = 0; + for (Player p : playerList) { + if (p.dismissState == 1) { + agreeCount += 1; + } else if (p.dismissState == 2) { + notAgreeCount += 1; + } + } + agree = notAgreeCount == 0 && agreeCount == playerList.size(); + + if (agree) { + + interruptTimer(); + } else { + if (notAgreeCount > 0) { + Global.gameCtr.dismisRoomFail(owner,playerList,askPlayer,getLeftTime()); + interruptTimer(); + } else { + Global.gameCtr.dismissRoom(askPlayer, null, playerList, getLeftTime()); + } + + } + } + + private void interruptTimer() { + if (timer != null) + timer.stop(); + timer = null; + checkDestroy(); + } + + private void startDismiss(Player player) { + playerList.clear(); + for (Entry entry : owner.playerMapBySeat.entrySet()) { + Player p = entry.getValue(); + if (p.already_round > 0) { + playerList.add(p); + p.dismissState = 0; + } + } + timer = new Timer(maxTime * 1000, new ITaskHandler() { + @Override + public void doTask(Timer timer) { + disMissTimeOutCallback(); + Global.logger.error("[" + owner.room_key + "] room dismiss time out destroy!"); + } + }); + owner.addTimer(timer); + start = true; + player.dismissState = 1; + player.dismissCount++; + } + + public void reload(Player owner) { + if (start) { + if (playerList.contains(owner)) { + Global.gameCtr.dismissRoom(askPlayer, owner, playerList, getLeftTime()); + } + + } + } + + public int getLeftTime() { + return Math.abs(timer.getCountdownTime() / 1000); + } + + private void checkDestroy() { + start = false; + + if (agree) { + owner.saveMilitaryTotal(true); + owner.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); + } + agree = true; + } + + private void disMissTimeOutCallback() { + for (Player p : playerList) { + p.dismissState = 1; + } + agree = true; + checkDestroy(); + } + +} diff --git a/game_common/src/main/java/com/game/data/Score.java b/game_common/src/main/java/com/game/data/Score.java new file mode 100644 index 0000000..fe70326 --- /dev/null +++ b/game_common/src/main/java/com/game/data/Score.java @@ -0,0 +1,54 @@ +package com.game.data; + +import java.util.HashMap; +import java.util.Map; + +import com.game.Global; + +/** + * 玩家积分统计 + * + * + * 2017年9月19日 + */ +public class Score { + + public Map round_log; + + /** + * 每局的积分统计 + */ + public int round_score; + /** + * 每局的积分统计 对方积分不够的情况下, 会存在小数点问题 + */ + public double d_real_score; + /** + * 总积分统计 + */ + public int total_score; + + public boolean negative_score; + + protected Player owner; + + public Score(Player owner) { + this.owner = owner; + this.round_log = new HashMap<>(); + this.negative_score = false; + this.d_real_score = 0; + this.initLog(); + } + + protected void initLog() { + } + + public void resetRound() { + this.round_log.clear(); + this.initLog(); + round_score = 0; + this.d_real_score = 0; + negative_score = false; + } + +} diff --git a/game_common/src/main/java/com/game/data/Timer.java b/game_common/src/main/java/com/game/data/Timer.java new file mode 100644 index 0000000..c3d4aa5 --- /dev/null +++ b/game_common/src/main/java/com/game/data/Timer.java @@ -0,0 +1,75 @@ +package com.game.data; + +import java.util.HashMap; +import java.util.Map; + +/** + * Room timer class + * + * + */ +public class Timer { + private volatile boolean _start; + private int _time; + private long _lastTime; + private ITaskHandler _task; + public Map parameters; + + /** + * + * @param time 单位毫秒 + * @param task + */ + public Timer(int time, ITaskHandler task) { + _lastTime = System.currentTimeMillis(); + _time = time; + _task = task; + this.parameters = new HashMap(); + } + + void start() { + if (_start) + return; + _start = true; + } + + public void restart() { + _lastTime = System.currentTimeMillis(); + start(); + } + + void executeTask() { + if (!_start) + return; + if (System.currentTimeMillis() - _lastTime >= _time) { + _start = false; + if (_task != null) { + _task.doTask(this); + } + } + } + + /** + * 获取倒计时,单位毫秒 + * + * @return + */ + public int getCountdownTime() { + return (int) (_time - (System.currentTimeMillis() - _lastTime)); + } + + public void stop() { + if (!_start) + return; + _start = false; + } + + public boolean isRuning() { + return _start; + } + + public interface ITaskHandler { + + public void doTask(Timer timer); + } +} diff --git a/game_common/src/main/java/com/game/manager/RoomManager.java b/game_common/src/main/java/com/game/manager/RoomManager.java new file mode 100644 index 0000000..fc098f1 --- /dev/null +++ b/game_common/src/main/java/com/game/manager/RoomManager.java @@ -0,0 +1,302 @@ +package com.game.manager; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.data.util.ErrorCode; +import com.game.Constant; +import com.game.Global; +import com.game.MainServer; +import com.game.Router; +import com.game.data.JoinRoomData; +import com.game.data.Room; +import com.game.room.state.RoomReloadState; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.StringUtil; +import com.taurus.permanent.data.Session; + +import redis.clients.jedis.Jedis; + +/** + * 房间管理类 + * + * + */ +public class RoomManager { + + public ConcurrentHashMap tableMap; + + public RoomManager() { + this.tableMap = new ConcurrentHashMap(); + } + + /** + * 进入房间 + * + * @param sender + * @param session_key + * @param gid + */ + public void joinRoom(Session sender, String session_key, int gid, String gps_pos) { + Jedis jedis = Redis.use().getJedis(); + try { + if (!jedis.exists(session_key)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + + String room_key = jedis.hget(session_key, "room"); + if (StringUtil.isEmpty(room_key)) { + MainServer.instance.sendResponse(gid, ErrorCode.NO_ROOM_NUM, null, sender); + return; + } + Map room_map = null; + RedisLock lock = new RedisLock(room_key, jedis); + try { + lock.lock(); + room_map = jedis.hgetAll(room_key); + String status = room_map.get("status"); + if (StringUtil.isEmpty(status)) { + Global.gameCtr.delRoomSeat(session_key, room_key); + MainServer.instance.sendResponse(gid, ErrorCode.NO_ROOM_NUM, null, sender); + return; + } + if (status.equals("3") || status.equals("2")) { + Global.gameCtr.delRoomSeat(session_key, room_key); + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_ROOM_DEL, null, sender); + return; + } + + if (Global.gameId != Integer.parseInt(room_map.get("game"))) { + Global.logger.error("joinRoom gameId:" + Global.gameId + " != gameId:" + + Integer.parseInt(room_map.get("game"))); + MainServer.instance.sendResponse(gid, ErrorCode.NO_SERVICE, null, sender); + return; + } + + String room_id = room_map.get("id"); + Room room = null; + if (this.tableMap.containsKey(room_id)) { + room = this.tableMap.get(room_id); + if (room.isDestroy) { + MainServer.instance.sendResponse(gid, ErrorCode._FAILED, null, sender); + return; + } + } else { + room = MainServer.instance.newRoom(room_id, room_map); + room.loadRedisPlayer(); + + this.tableMap.put(room_id, room); + room.start(); + room.stateMachine.changeState(Global.getState(RoomReloadState.class)); + } + if (room.isActive() == false) { + room.start(); + } + + sender.setHashId(session_key); + final JoinRoomData jrd = new JoinRoomData(); + jrd.room = room; + jrd.session_key = session_key; + jrd.sender = sender; + jrd.gps_pos = gps_pos; + room.enqueueRunnable(new Runnable() { + @Override + public void run() { + try { + int result = Global.gameCtr.joinRoom(jrd, gid); + if (result != 0) { + MainServer.instance.sendResponse(gid, result, null, sender); + } + Global.logger.info(session_key + " join [" + jrd.room.room_key + "]!"); + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 500, null, sender); + } + } + }); + } finally { + lock.unlock(false); + } + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 500, null, sender); + } finally { + jedis.close(); + } + } + + /** + * 进入房间(观战) + * + * @param sender + * @param session_key + * @param gid + */ + public void joinRoomOfSpectator(Session sender, String session_key, int gid, String gps_pos) { + Jedis jedis = Redis.use().getJedis(); + try { + if (!jedis.exists(session_key)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + + String room_key = jedis.hget(session_key, "spectator_room"); + + if (StringUtil.isEmpty(room_key)) { + Global.logger.info("找不到观战房间"); + MainServer.instance.sendResponse(gid, ErrorCode.NO_ROOM_NUM, null, sender); + return; + } + Map room_map = null; + RedisLock lock = new RedisLock(room_key, jedis); + try { + lock.lock(); + room_map = jedis.hgetAll(room_key); + String status = room_map.get("status"); +// if (StringUtil.isEmpty(status)) { +// Global.gameCtr.delRoomSeat(session_key, room_key); +// MainServer.instance.sendResponse(gid, ErrorCode.NO_ROOM_NUM, null, sender); +// return; +// } + if (status.equals("3") || status.equals("2")) { + Global.gameCtr.delRoomSeat(session_key, room_key); + MainServer.instance.sendResponse(gid, ErrorCode.GROUP_ROOM_DEL, null, sender); + return; + } + + if (Global.gameId != Integer.parseInt(room_map.get("game"))) { + Global.logger.error("joinRoom gameId:" + Global.gameId + " != gameId:" + + Integer.parseInt(room_map.get("game"))); + MainServer.instance.sendResponse(gid, ErrorCode.NO_SERVICE, null, sender); + return; + } + + String room_id = room_map.get("id"); + Room room = null; + if (this.tableMap.containsKey(room_id)) { + room = this.tableMap.get(room_id); + if (room.isDestroy) { + MainServer.instance.sendResponse(gid, ErrorCode._FAILED, null, sender); + return; + } + } + + sender.setHashId(session_key); + final JoinRoomData jrd = new JoinRoomData(); + jrd.room = room; + jrd.session_key = session_key; + jrd.sender = sender; + jrd.gps_pos = gps_pos; + + room.enqueueRunnable(new Runnable() { + @Override + public void run() { + try { + Global.logger.info(session_key + " join [" + jrd.room.room_key + "] begin!"); + + int result = Global.gameCtr.joinRoomOfSpectator(jrd, gid); + if (result != 0) { + MainServer.instance.sendResponse(gid, result, null, sender); + } + Global.logger.info(session_key + " join [" + jrd.room.room_key + "]! end"); + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 500, null, sender); + } + } + }); + } finally { + lock.unlock(false); + } + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 500, null, sender); + } finally { + jedis.close(); + } + } + + /** + * 退出房间(观战) + * + * @param sender + * @param session_key + * @param gid + */ + public void outRoomOfSpectator(Session sender, String session_key, int gid, int uid) { + Jedis jedis = Redis.use().getJedis(); + try { + if (!jedis.exists(session_key)) { + MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + + String room_key = jedis.hget(session_key, "spectator_room"); + if (StringUtil.isEmpty(room_key)) { + MainServer.instance.sendResponse(gid, ErrorCode.NO_ROOM_NUM, null, sender); + return; + } + Map room_map = null; + RedisLock lock = new RedisLock(room_key, jedis); + try { + lock.lock(); + room_map = jedis.hgetAll(room_key); + + String room_id = room_map.get("id"); + Room room = null; + if (this.tableMap.containsKey(room_id)) { + room = this.tableMap.get(room_id); + if (room.isDestroy) { + MainServer.instance.sendResponse(gid, ErrorCode._FAILED, null, sender); + return; + } + ITObject data = new TObject(); + data.putInt("player", uid); + + room.playerMapBySpectator.remove(uid); + room.broadCastToClient(0, Router.GAME_EVT_OUT_SPECTATOR, data); + room.broadCastToClientOfSpectator(Router.GAME_EVT_OUT_SPECTATOR, data); + + } + + sender.setHashId(session_key); + + } finally { + lock.unlock(false); + } + } catch (Exception e) { + Global.logger.error(e); + MainServer.instance.sendResponse(gid, 500, null, sender); + } finally { + jedis.close(); + } + } + + /** + * 解散房间 + * + * @param roomid 房间ID + */ + public void dismissRoom(String roomid, boolean sendEvt) { + Room room = this.tableMap.get(roomid); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + if (room == null) { + return; + } + RedisLock lock = new RedisLock(room.room_key, jedis0); + try { + lock.lock(); + room.endType = Constant.END_TYPE_ADMIN; + room.dismisType = 2; + room.destroy(sendEvt); + this.tableMap.remove(roomid); + } finally { + lock.unlock(); + } + } + +} diff --git a/game_common/src/main/java/com/game/manager/SessionManager.java b/game_common/src/main/java/com/game/manager/SessionManager.java new file mode 100644 index 0000000..5479945 --- /dev/null +++ b/game_common/src/main/java/com/game/manager/SessionManager.java @@ -0,0 +1,114 @@ +package com.game.manager; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.game.Global; +import com.game.Router; +import com.game.data.Player; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.permanent.data.Session; + +import redis.clients.jedis.Jedis; + +/** + * 当前节点 玩家session管理类 + * + * + */ +public class SessionManager { + + private ConcurrentMap sessionMap = null; + + public SessionManager() { + this.sessionMap = new ConcurrentHashMap(); + } + + /** + * 通过sessionid获取玩家 + * + * @param sessionid + * @return + */ + public Player getPlayer(Session sessionid) { + return this.sessionMap.get(sessionid); + } + + /** + * 增加session + * + * @param sessionid + * @param player + */ + public void putPlayer(Session sessionid, Player player) { + this.sessionMap.put(sessionid, player); + } + + /** + * 删除session + * + * @param sessionid + */ + public Player deleteSession(Session sessionid) { + if (sessionid == null) + return null; + sessionid.setHashId(null); + Player player = this.getPlayer(sessionid); + if (player != null) { + ITObject param = new TObject(); + param.putInt("id", player.playerid); + player.room.broadCastToClientOfSpectator(Router.GAME_OUT_SPECTATOR, param); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + jedis0.hdel("{user}:" + player.playerid, "spectator_room"); + jedis0.close(); + Global.logger.info("player.playerid:" + player.playerid); + } + this.sessionMap.remove(sessionid); + + return player; + } + + /** + * 当前服务器在线人数 + * + * @return + */ + public int size() { + return this.sessionMap.size(); + } + + public List getPlayerList() { + List list = new ArrayList(); + list.addAll(sessionMap.values()); + return list; + } + + /** + * 断线 + * + * @param sender + */ + public synchronized void disconnect(Session sender) { + Player player = this.deleteSession(sender); + if (player == null) { + return; + } + player.room.enqueueRunnable(new Runnable() { + + @Override + public void run() { + if (player.isDestroy) + return; + if (player.sender == sender) { + player.isConnect = false; + Global.gameCtr.playerNetState(player); + } + } + }); + } + +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerEndState.java b/game_common/src/main/java/com/game/player/state/PlayerEndState.java new file mode 100644 index 0000000..e970b67 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerEndState.java @@ -0,0 +1,53 @@ +package com.game.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.Router; +import com.game.data.Player; +import com.game.state.StateBase; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + + +public class PlayerEndState extends StateBase { + + @Override + public void enter(Player owner) { +// owner.clear(); + owner.startActionTimer(); + } + @Override + public void exit(Player owner) { + owner.stopActionTimer(); + } + + @Override + public void execute(Player owner, String cmd, int gid, Object param) { + switch(cmd) { + case ActionEvent.EVENT_READY: + case ActionEvent.EVENT_TIMER_AUTO: + case ActionEvent.EVENT_ENTRUST: + Global.gameCtr.ready(owner); + break; + case ActionEvent.EVENT_READY_AND_XIPAI: + Global.gameCtr.readyAndXipai(owner); + break; + case ActionEvent.EVENT_XIPAI: + if (owner.xi_pai == false) + { + owner.xi_pai = true; + ITObject param1 = new TObject(); + param1.putInt("result", 0); + owner.sendEvent(Router.GAME_EVENT_XIPAI, param1); + + owner.room.redisUpdateXiPaiPlayer(owner); + } + else { + ITObject param1 = new TObject(); + param1.putInt("result", 1); + owner.sendEvent(Router.GAME_EVENT_XIPAI, param1); + } + break; + } + } +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerInitState.java b/game_common/src/main/java/com/game/player/state/PlayerInitState.java new file mode 100644 index 0000000..c5d833a --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerInitState.java @@ -0,0 +1,51 @@ +package com.game.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +/** + * 玩家进房间的初始状态 + * + * + */ +public class PlayerInitState extends StateBase { + + @Override + public void enter(Player owner) { + if(owner.room.round==0&&owner.room.kickTime>0) { + owner.startActionTimer(owner.room.kickTime * 1000); + } + } + + @Override + public void exit(Player owner) { + owner.stopActionTimer(); + } + + @Override + public void execute(Player owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_READY: + Global.gameCtr.ready(owner); + break; + case ActionEvent.EVENT_READY_AND_XIPAI: + Global.gameCtr.readyAndXipai(owner); + break; + case ActionEvent.EVENT_EXIT_ROOM: + if(owner.room.round>0)return; + Global.gameCtr.exitRoom(owner, gid,false); + break; +// case ActionEvent.EVENT_TIMER_AUTO: +// if(owner.room.round>0)return; +// Global.gameCtr.exitRoom(owner, gid,true); +// break; + case ActionEvent.EVENT_SPECTATOR: + if(owner.room.round>0)return; + Global.gameCtr.spectator(owner, gid); + break; + } + } + +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerPauseState.java b/game_common/src/main/java/com/game/player/state/PlayerPauseState.java new file mode 100644 index 0000000..86f7ac6 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerPauseState.java @@ -0,0 +1,21 @@ +package com.game.player.state; + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + + +/** + * 玩家暂停状态 + * + */ +public class PlayerPauseState extends StateBase { + + @SuppressWarnings("unchecked") + @Override + public void toNextState(Player owner) { + owner.stateMachine.lastState.toNextState(owner); + + } + +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerPopupState.java b/game_common/src/main/java/com/game/player/state/PlayerPopupState.java new file mode 100644 index 0000000..c4f0683 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerPopupState.java @@ -0,0 +1,35 @@ +package com.game.player.state; + +import com.game.Router; +import com.game.data.Player; +import com.game.state.StateBase; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +/** + * 玩家缺体力值弹出状态 + * + */ +public class PlayerPopupState extends StateBase{ + /** + * 进入状态时处理 + * + * @param owner + */ + public void enter(Player owner) { + owner.spectator = true; + ITObject msg = TObject.newInstance(); + msg.putInt("seat", owner.seat); + owner.room.broadCastToClient(0, Router.GAME_EVT_STAND_UP, msg); + + } + + /** + * 退出状态时处理 + * + * @param owner + */ + public void exit(Player owner) { + owner.spectator = false; + } +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerReadyState.java b/game_common/src/main/java/com/game/player/state/PlayerReadyState.java new file mode 100644 index 0000000..5108302 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerReadyState.java @@ -0,0 +1,31 @@ +package com.game.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import java.util.Map; + +/** + * 玩家准备状态 + * + * + */ +public class PlayerReadyState extends StateBase { + + @Override + public void enter(Player owner) { + owner.ready = true; + owner.room.stateMachine.execute(ActionEvent.EVENT_READY, 0, null); + } + + @Override + public void execute(Player owner, String cmd, int gid, Object param) { + if(owner.room.round>0)return; + if(cmd.equals(ActionEvent.EVENT_EXIT_ROOM)) { + Global.gameCtr.exitRoom(owner, gid,false); + } + } + +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerReloadState.java b/game_common/src/main/java/com/game/player/state/PlayerReloadState.java new file mode 100644 index 0000000..484bb05 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerReloadState.java @@ -0,0 +1,25 @@ +package com.game.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +/** + * 玩家重连状态 + * + */ +public class PlayerReloadState extends StateBase { + + public void execute(Player owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_READY: + Global.gameCtr.ready(owner); + break; + case ActionEvent.EVENT_READY_AND_XIPAI: + Global.gameCtr.readyAndXipai(owner); + break; + } + } + +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerSpectatorState.java b/game_common/src/main/java/com/game/player/state/PlayerSpectatorState.java new file mode 100644 index 0000000..0e070fe --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerSpectatorState.java @@ -0,0 +1,44 @@ +package com.game.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +/** + * 观看状态 + * + */ +public class PlayerSpectatorState extends StateBase { + /** + * 进入状态时处理 + * + * @param owner + */ + public void enter(Player owner) { + owner.spectator = true; + } + + /** + * 退出状态时处理 + * + * @param owner + */ + public void exit(Player owner) { + owner.spectator = false; + } + + @Override + public void execute(Player owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_EXIT_ROOM: + Global.gameCtr.exitRoom(owner, gid,false); + break; +// case ActionEvent.EVENT_READY: +// if(owner.room.playerMapBySeat.containsKey(owner.seat)) { +// Global.gameCtr.ready(owner); +// } +// break; + } + } +} diff --git a/game_common/src/main/java/com/game/player/state/PlayerWaitState.java b/game_common/src/main/java/com/game/player/state/PlayerWaitState.java new file mode 100644 index 0000000..269bac6 --- /dev/null +++ b/game_common/src/main/java/com/game/player/state/PlayerWaitState.java @@ -0,0 +1,11 @@ +package com.game.player.state; +import com.game.data.Player; +import com.game.state.StateBase; + +/** + * 玩家等待状态 + * + */ +public class PlayerWaitState extends StateBase { + +} diff --git a/game_common/src/main/java/com/game/room/state/RoomDestoryGameState.java b/game_common/src/main/java/com/game/room/state/RoomDestoryGameState.java new file mode 100644 index 0000000..b5d4726 --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomDestoryGameState.java @@ -0,0 +1,17 @@ +package com.game.room.state; +import com.game.Global; +import com.game.data.Room; +import com.game.state.StateBase; + +/** + * 房间结束状态 + * + */ +public class RoomDestoryGameState extends StateBase { + + @Override + public void enter(Room owner) { + Global.roomMgr.dismissRoom(owner.roomid,true); + + } +} diff --git a/game_common/src/main/java/com/game/room/state/RoomEndState.java b/game_common/src/main/java/com/game/room/state/RoomEndState.java new file mode 100644 index 0000000..e9176f4 --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomEndState.java @@ -0,0 +1,42 @@ +package com.game.room.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerEndState; +import com.game.player.state.PlayerPopupState; +import com.game.player.state.PlayerReadyState; +import com.game.state.StateBase; + + +public class RoomEndState extends StateBase{ + @Override + public void enter(Room owner) { + owner.saveSocre(); + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + player.stateMachine.changeState( Global.getState(PlayerEndState.class)); + } + } + + public void execute(Room owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_READY: + for (Entry entry : owner.playerMapBySeat.entrySet()) { + Player player = entry.getValue(); + if(player.stateMachine.curState instanceof PlayerPopupState) { + continue; + } + if (!(player.stateMachine.curState instanceof PlayerReadyState)) { + return; + } + } + owner.stateMachine.changeState(Global.getState(RoomStartGameState.class)); + break; + } + } +} diff --git a/game_common/src/main/java/com/game/room/state/RoomInitState.java b/game_common/src/main/java/com/game/room/state/RoomInitState.java new file mode 100644 index 0000000..46efccf --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomInitState.java @@ -0,0 +1,42 @@ +package com.game.room.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerReadyState; +import com.game.state.StateBase; +import com.taurus.core.plugin.redis.Redis; + +/** + * 房间初始状态 + * + */ +public class RoomInitState extends StateBase { + + + @Override + public void execute(Room owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_READY: + for (Entry entry : owner.playerMapByPlaying.entrySet()) { + if (!(entry.getValue().stateMachine.curState instanceof PlayerReadyState)) { + return; + } + } + if (owner.maxPlayers == owner.playerMapByPlaying.size()) { + owner.redis_room_map.put("open","0"); + Redis.use().hmset(owner.room_key, owner.redis_room_map); + owner.stateMachine.changeState(Global.getState(RoomWaitState.class)); + } + break; + + default: + break; + } + + } + +} diff --git a/game_common/src/main/java/com/game/room/state/RoomReloadState.java b/game_common/src/main/java/com/game/room/state/RoomReloadState.java new file mode 100644 index 0000000..61caf42 --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomReloadState.java @@ -0,0 +1,39 @@ +package com.game.room.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerPopupState; +import com.game.player.state.PlayerReadyState; +import com.game.state.StateBase; + +/** + * 房间重连状态 + * + */ +public class RoomReloadState extends StateBase{ + + public void execute(Room owner, String cmd, int gid, Object param) { + switch (cmd) { + case ActionEvent.EVENT_READY: + for (Entry entry : owner.playerMapBySeat.entrySet()) { + Player p = entry.getValue(); + if (!(p.stateMachine.curState instanceof PlayerReadyState || p.stateMachine.curState instanceof PlayerPopupState)) { + return; + } + } + if(owner.round == 0 &&owner.startGameNum == 0 && owner.playerMapBySeat.size()>1) { + owner.stateMachine.changeState(Global.getState(RoomWaitState.class)); + }else { + int num = owner.startGameNum ==0 ? 2 :owner.startGameNum; + if(owner.playerMapBySeat.size() >= num) { + owner.stateMachine.changeState(Global.getState(RoomStartGameState.class)); + } + } + break; + } + } +} diff --git a/game_common/src/main/java/com/game/room/state/RoomStartGameState.java b/game_common/src/main/java/com/game/room/state/RoomStartGameState.java new file mode 100644 index 0000000..093f008 --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomStartGameState.java @@ -0,0 +1,12 @@ +package com.game.room.state; +import com.game.data.Room; +import com.game.state.StateBase; + +/** + * 房间开始游戏 + * + */ +public class RoomStartGameState extends StateBase{ + + +} diff --git a/game_common/src/main/java/com/game/room/state/RoomWaitState.java b/game_common/src/main/java/com/game/room/state/RoomWaitState.java new file mode 100644 index 0000000..b79fa4f --- /dev/null +++ b/game_common/src/main/java/com/game/room/state/RoomWaitState.java @@ -0,0 +1,31 @@ +package com.game.room.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.state.StateBase; + +/** + * 房间等待状态 + * + */ +public class RoomWaitState extends StateBase { + + @Override + public void execute(Room owner, String cmd, int gid, Object param) { + switch(cmd) { + case ActionEvent.EVENT_START_GAME: + for (Entry entry : owner.playerMapById.entrySet()) { + Player player = entry.getValue(); + player.clear(); + } + owner.stateMachine.changeState(Global.getState(RoomStartGameState.class)); + break; + } + + } + +} diff --git a/game_common/src/main/java/com/game/state/StateBase.java b/game_common/src/main/java/com/game/state/StateBase.java new file mode 100644 index 0000000..3264ed8 --- /dev/null +++ b/game_common/src/main/java/com/game/state/StateBase.java @@ -0,0 +1,51 @@ +package com.game.state; + +/** + * 状态基类 + * + * @param + */ +public abstract class StateBase { + + /** + * 进入状态时处理 + * @param owner + */ + public void enter(T owner) { + + } + + /** + * 退出状态时处理 + * @param owner + */ + public void exit(T owner) { + + } + + /** + * 从该状态转向下一个状态的处理 + * @param owner + */ + public void toNextState(T owner) { + } + + /** + * 执行事件处理 + * @param owner + * @param cmd + * @param gid + * @param param + */ + public void execute(T owner, String cmd, int gid, Object param) { + + } + + /** + * 重连 + * @param owner + */ + public void reload(T owner) { + + } +} diff --git a/game_common/src/main/java/com/game/state/StateMachine.java b/game_common/src/main/java/com/game/state/StateMachine.java new file mode 100644 index 0000000..82842f8 --- /dev/null +++ b/game_common/src/main/java/com/game/state/StateMachine.java @@ -0,0 +1,64 @@ +package com.game.state; + +import com.game.Global; + +/** + * 状态机 + * + */ +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class StateMachine { + + private Object owner = null; + /** + * 当前状态 + */ + public StateBase curState = null; + public StateBase lastState = null; + + public StateMachine(Object owner) { + this.owner = owner; + } + + /** + * 改变状态 + * @param state + */ + public void changeState(StateBase state) { + if (curState != null) { + this.curState.exit(this.owner); + } + if (this.lastState != this.curState) { + this.lastState = this.curState; + } + + if (Global.loggerDebug) { + String old_log = this.curState != null ? curState.getClass().getSimpleName() : "null"; + Global.logger.info(owner + " [" + old_log + "]to[" + state.getClass().getSimpleName() + "]"); + } + this.curState = state; + this.curState.enter(this.owner); + } + + public void toLastState() { + if (lastState == null) { + return; + } + this.changeState(this.lastState); + } + + public void toNextState() { + this.curState.toNextState(this.owner); + } + + /** + * 执行服务器内部事件 + * @param cmd + * @param gid + * @param param + */ + public void execute(String cmd, int gid, Object param) { + this.curState.execute(this.owner, cmd, gid, param); + } + +} diff --git a/game_mj_hongzhong/config/game-config.xml b/game_mj_hongzhong/config/game-config.xml new file mode 100644 index 0000000..9cf969e --- /dev/null +++ b/game_mj_hongzhong/config/game-config.xml @@ -0,0 +1,11 @@ + + + + + 192.168.3.31 + 192.168.3.31 + 8842 + 8840 + 10 + true + \ No newline at end of file diff --git a/game_mj_hongzhong/config/log4j.properties b/game_mj_hongzhong/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/game_mj_hongzhong/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/game_mj_hongzhong/config/taurus-core.xml b/game_mj_hongzhong/config/taurus-core.xml new file mode 100644 index 0000000..bd4d7c9 --- /dev/null +++ b/game_mj_hongzhong/config/taurus-core.xml @@ -0,0 +1,50 @@ + + + log4j.properties + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/game_mj_hongzhong/config/taurus-permanent.xml b/game_mj_hongzhong/config/taurus-permanent.xml new file mode 100644 index 0000000..af0653f --- /dev/null +++ b/game_mj_hongzhong/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 1 + + 512 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 1 + 2 + 1 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 80 +
+ + + + extension - test + extend.mj.EXMainServer + + + + + Sys + 2 + 8 + 60000 + 20000 + + + + + Ext + 2 + 8 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/game_mj_hongzhong/pom.xml b/game_mj_hongzhong/pom.xml new file mode 100644 index 0000000..10fb611 --- /dev/null +++ b/game_mj_hongzhong/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + com.game + game_mj_hongzhong + 1.0.0 + jar + + game_mj_hongzhong + http://maven.apache.org + + + UTF-8 + + + + + + com.game + game_common + 1.0.0 + + + + + game_mj_hongzhong + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + + diff --git a/game_mj_hongzhong/src/main/java/extend/mj/CardNiao.java b/game_mj_hongzhong/src/main/java/extend/mj/CardNiao.java new file mode 100644 index 0000000..a21039b --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/CardNiao.java @@ -0,0 +1,19 @@ +package extend.mj; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +public class CardNiao { + public int card; + + public int playerId=0; + public int score = 0; + + + public ITObject toMP(){ + ITObject obj = TObject.newInstance(); + obj.putInt("card", card); + obj.putInt("score", score); + return obj; + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/Config.java b/game_mj_hongzhong/src/main/java/extend/mj/Config.java new file mode 100644 index 0000000..f20aa60 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/Config.java @@ -0,0 +1,120 @@ +package extend.mj; + +public class Config { + + public static final int HONGZHONG = 412; + public static final int XIPAI_SCORE = 10; + + public static final String ROOM_CONFIG_DIANPAO = "dianpao"; + public static final String ROOM_CONFIG_ZHUANGXIAN = "zhuangxian"; + public static final String ROOM_CONFIG_FENGDING = "fengding"; + public static final String ROOM_CONFIG_FENGDING_SCORE = "fengding_score"; + public static final String ROOM_CONFIG_PIAO_NIAO = "piao_niao"; //0:不嫖 1:自由票 2:固定票 + public static final String ROOM_CONFIG_PIAO_NIAO_AUTO = "auto_piao"; //piao fen + public static final String ROOM_CONFIG_PIAO_NIAO_OPT = "piao_niao_opt"; //piao fen + public static final String ROOM_CONFIG_QIDUI = "qidui"; + public static final String ROOM_CONFIG_NIAO = "niao"; + public static final String ROOM_CONFIG_NIAO_OPT = "niao_opt"; + public static final String ROOM_CONFIG_NIAO_OPT_SCORE = "niao_opt_score"; + public static final String ROOM_CONFIG_HONGZHONG = "laizi"; + public static final String ROOM_CONFIG_WUGUI_JIABEI = "wuguijiabei"; + public static final String ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI = "wuguizhuopaojiabei"; + public static final String ROOM_CONFIG_QIANGKONG = "qiangkong"; + public static final String ROOM_CONFIG_QIANGKONG_NIAO = "qiangkong_niao"; + public static final String ROOM_CONFIG_HONGZHONG8 = "laizi8"; + public static final String ROOM_CONFIG_NONEALL = "none_is_all"; + public static final String ROOM_CONFIG_NIAO_SCORE = "niao_score"; + public static final String ROOM_CONFIG_QG_TYPE = "qianggang_type"; + public static final String ROOM_CONFIG_JIANGMA = "jiangma"; + public static final String ROOM_CONFIG_HZ_HU = "hz_hu"; + public static final String ROOM_CONFIG_XIPAI = "xi_pai"; + public static final String ROOM_CONFIG_XIPAI_SCORE = "xi_pai_score"; + public static final String ROOM_CONFIG_DI_FEN = "di_fen"; //低分 + public static final String ROOM_CONFIG_LAIZI4_HU = "laizi4_hu"; //四鬼胡牌 + + public static final String SETTLE_DIAN_PAO = "dian_pao"; + public static final String SETTLE_JIE_PAO = "jie_pao"; + public static final String SETTLE_ZIMO = "zimo"; + public static final String SETTLE_AN_KONG = "an_kong"; + public static final String SETTLE_MING_KONG = "ming_kong"; + + public static final int NIAO_TYPE_159 =1; + public static final int NIAO_TYPE_ALL =2; + public static final int NIAO_TYPE_WOWO =3; + + /** + * + */ + public static final String GAME_EVT_PLAYER_DEAL = "811"; + + /** + * + */ + public static final String GAME_DIS_CARD = "611"; + + /** + * + */ + public static final String GAME_EVT_DISCARD = "812"; + + /** + * + */ + public static final String GAME_EVT_DISCARD_TIP = "813"; + + /** + * + */ + public static final String GAME_EVT_FZTIPS = "814"; + + /** + * + */ + public static final String GAME_ACTION = "612"; + + /** + * + */ + + public static final String GAME_EVT_ACTION = "815"; + + /** + * + */ + public static final String GAME_EVT_HU = "816"; + + /** + * + */ + public static final String GAME_EVT_RESULT1 = "817"; + + /** + * 大结算 + */ + public static final String GAME_EVT_RESULT2 = "818"; + + /** + * + */ + public static final String GAME_EVT_DRAW = "819"; + + /** + * + */ + public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "820"; + + /** + * + */ + public static final String GAME_EVT_NIAO = "821"; + + /** + * + */ + public static final String GAME_EVT_PIAONIAO_TIP = "833"; + /** + * + */ + public static final String GAME_EVT_PIAONIAO = "834"; + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXActionEvent.java b/game_mj_hongzhong/src/main/java/extend/mj/EXActionEvent.java new file mode 100644 index 0000000..db9bbf0 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXActionEvent.java @@ -0,0 +1,18 @@ +package extend.mj; + +public class EXActionEvent { + + public static final String EVENT_ACTION = "action"; + + public static final String EVENT_DISCARD = "discard"; + + public static final String EVENT_OTHER_DISCARD = "other_discard"; + + public static final String EVENT_START_GAME ="start_game"; + + public static final String EVENT_EXIT_ROOM = "exit_room"; + + public static final String EVENT_KONG_WIN = "kong_win"; + + public static final String EVENT_PIAO_NIAO = "piao_niao"; +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXGameController.java b/game_mj_hongzhong/src/main/java/extend/mj/EXGameController.java new file mode 100644 index 0000000..5c225ff --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXGameController.java @@ -0,0 +1,279 @@ +package extend.mj; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map.Entry; + +import com.game.GameController; +import com.game.Global; +import com.game.Util; +import com.game.data.Player; +import com.game.player.state.PlayerWaitState; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.ActionKey; +import com.taurus.permanent.data.Session; + +import extend.mj.tip.Tip; +import extend.mj.tip.TipManager; + +/** + * + * + * + * EXGameController.java + */ +public class EXGameController extends GameController { + + public EXGameController() { + super(); + } + + @ActionKey(Config.GAME_ACTION) + public void RouterAction(Session sender,ITObject params,int gid,Player owner) { + if(Global.loggerDebug) { + int id = params.getInt("id"); + if(id ==0) { + Global.logger.info(owner + " pass!"); + }else { + TipManager tipMgr =((EXPlayer)owner).tipMgr; + if(tipMgr.tipMap.containsKey(id)) { + Tip tip = tipMgr.tipMap.get(id); + Global.logger.info(owner + " select_action type:"+tip.weight+" card:"+tip.card); + } + } + } + owner.stateMachine.execute(EXActionEvent.EVENT_ACTION, 0, params); + } + + @ActionKey(Config.GAME_DIS_CARD) + public void RouterDisCard(Session sender,ITObject params,int gid,Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_DISCARD, 0, params); + } + + public void changeActiveSeat(EXRoom owner,int activeSeat) { + owner.activeSeat = activeSeat; + TObject param = new TObject(); + param.putInt("seat", activeSeat); + owner.broadCastToClient(0, Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param); + } + + public void getCard(EXPlayer player,int leftCount){ + ITObject otherParam = new TObject(); + otherParam.putInt("card", 0); + otherParam.putInt("seat", player.room.activeSeat); + otherParam.putInt("left_count", leftCount); + + ITObject param = new TObject(); + param.putInt( "card", player.drawCard ); + param.putInt("seat", player.room.activeSeat); + param.putInt("left_count", leftCount); + player.sendEvent(Config.GAME_EVT_DRAW, param); + player.cardInhand.add(player.drawCard); + if(Global.loggerDebug) { + Global.logger.info(player + " drawcard["+player.drawCard+"]"); + } + player.room.broadCastToClient(player.playerid, Config.GAME_EVT_DRAW, otherParam); + ((EXPlayBack)player.getRoom().playBackData).addGetCardCommand(player.room.activeSeat, player.drawCard,leftCount); + } + + public void outCard(EXPlayer player,int discard){ + ITObject response = new TObject(); + response.putInt("seat", player.seat); + response.putInt("card", discard); + player.room.broadCastToClient(0, Config.GAME_EVT_DISCARD, response); + EXRoom room = player.getRoom(); + ((EXPlayBack)room.playBackData).addOutCardCommand(player.seat, discard); + + room.activeCard = discard; + room.lastDiscardSeat = player.seat; + room.currenDiscardSeat = 0; + player.outcardList.add(discard); + Util.removeCard(player.cardInhand, discard, 1); + if(Global.loggerDebug) { + Global.logger.info(player + " outcard["+discard+"]"); + } + room.broadCastToServer(player.playerid, EXActionEvent.EVENT_OTHER_DISCARD, discard); + } + + + + public void actionCard(EXPlayer player,int card,int type,int from_seat,ITArray opcardArray){ + ITObject paramBroadCast = new TObject(); + paramBroadCast.putInt("playerid", player.playerid); + paramBroadCast.putInt("card", card); + paramBroadCast.putInt("type", type); + paramBroadCast.putInt("from_seat", from_seat); + if(opcardArray!=null){ + paramBroadCast.putTArray("opcard", opcardArray); + } + EXRoom room = player.getRoom(); + + if(Global.loggerDebug) { + Global.logger.info(String.format("%s from_seat:%d card:%d type:%d ", player,from_seat,card,type)); + } + room.broadCastToClient(0, Config.GAME_EVT_ACTION, paramBroadCast); + ((EXPlayBack)room.playBackData).addActionCommand(player.seat, type, card, from_seat,opcardArray); + } + + public void dealCard(EXRoom owner) { + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer)entry.getValue(); + //Global.logger.info("playerid:"+player.playerid+" isw: "+player.is_white); + + player.cardInhand = owner.card.deal(player.is_white); + Collections.sort(player.cardInhand); + if(Global.loggerDebug) { + Global.logger.info(player + " cardlist:" + player.cardInhand); + } + ITObject param = new TObject(); + ITArray handCard = Util.toTArray(player.cardInhand); + param.putTArray("card_list", handCard); + param.putInt("bank_seat", player.room.bankerSeat); + param.putInt("round", player.room.round); + player.sendEvent(Config.GAME_EVT_PLAYER_DEAL, param); + player.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + } + + Global.logger.info("dealCard() ===> round = "+owner.round); + } + + public void tipEvent(EXPlayer owner) { + ITObject param = owner.tipMgr.toMP(); + owner.sendEvent(Config.GAME_EVT_FZTIPS, param); + } + + public void discardTipEvent(EXPlayer owner) { + owner.getRoom().currenDiscardSeat = owner.seat; + owner.sendEvent(Config.GAME_EVT_DISCARD_TIP, null); + } + + public void winEvent(EXPlayer owner,int from_seat,int win_card) { + ITArray cardInHand = TArray.newInstance(); + for (int card1 : owner.cardInhand) { + cardInHand.addInt(card1); + } + ITObject param = new TObject(); + param.putTArray("card", cardInHand); + param.putInt("seat", owner.seat); + param.putInt("win_card", win_card); + param.putInt("from_seat", from_seat); + if(Global.loggerDebug) { + Global.logger.info(owner + " hupai!["+(owner.seat == from_seat?"self":"other")+"]"); + } + EXRoom room = owner.getRoom(); + room.broadCastToClient(0, Config.GAME_EVT_HU, param); + ((EXPlayBack)room.playBackData).addWinCardCommand(owner.seat, false); + } + + public void sendNiaoEvt(EXPlayer owner, int seat) { + EXRoom room = owner.getRoom(); + ITObject param = new TObject(); +// param.putInt("playerid", owner.playerid); + ITArray array = new TArray(); + for (int index = 0; index < room.niao.size(); index++) { + array.addTObject(room.niao.get(index).toMP()); + } + param.putTArray("niao", array); + param.putInt("start_seat", seat); + + room.broadCastToClient(0, Config.GAME_EVT_NIAO, param); + ((EXPlayBack)room.playBackData).addNiaoCommand(owner.seat, param); + } + + /** + * Ʊ����ʾ + * @param owner + */ + public void piaoNiaoTipEvent(EXPlayer owner) { + owner.sendEvent(Config.GAME_EVT_PIAONIAO_TIP, null); + } + + /** + * Ʊ���¼� + * @param owner + */ + public void piaoNiaoEvent(EXPlayer owner) { + // if(owner.piaoNiao==0)return; + ITObject param = new TObject(); + param.putInt("seat", owner.seat); + param.putInt("num", owner.piaoNiao); + owner.room.broadCastToClient(0, Config.GAME_EVT_PIAONIAO, param); + } + + private ITObject getRoomResultData(EXRoom owner) { + ITObject mp = TObject.newInstance(); + mp.putBoolean("liuju", owner.liuju); + mp.putInt("xipai_score", owner.xi_pai_score); + mp.putInt("active_player", owner.playerMapBySeat.get(owner.activeSeat).playerid); + long time = System.currentTimeMillis(); + long t = time / 1000; + mp.putLong("time", t); + ITArray niao = new TArray(); + for (int index = 0; index < owner.niao.size(); index++) { + niao.addTObject(owner.niao.get(index).toMP()); + } + mp.putTArray("niao", niao); + ITArray infoList = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject param = new TObject(); + param.putInt("seat", player.seat); + param.putInt("win_card", player.winCard); + param.putBoolean("is_win", player.winer == 1); + param.putInt("hu_score", player.score.round_log.get(EXScore.WIN)); + param.putInt("niao_score", player.score.round_log.get(EXScore.NIAO)); + param.putInt("gang_score", player.score.round_log.get(EXScore.KONG)); + param.putInt("piao_niao_score", player.score.round_log.get(EXScore.PIAO_NIAO)); + player.hp_info(param); + param.putInt("round_score", player.score.round_score); + param.putInt("total_score", player.score.total_score); + ITArray handCard = Util.toTArray(player.cardInhand); + param.putTArray("hand_card", handCard); + infoList.addTObject(param); + } + mp.putTArray("info_list", infoList); + return mp; + } + public void roomResult(EXRoom owner) { + ITObject mp = TObject.newInstance(); + mp.putInt("type", 0); + ITObject result = getRoomResultData(owner); + owner.playBackData.addResult(result); + mp.putTObject("result", result); + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, mp); + } + + + public void roomTotalResult(EXRoom owner,boolean dissmiss) { + ITObject data = TObject.newInstance(); + long t = System.currentTimeMillis() / 1000; + data.putLong("time", t); + ITArray infoList = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject param = new TObject(); + param.putInt("seat", player.seat); + param.putTObject("settle_log", player.settleLog.toTObject()); + param.putInt("total_score", player.score.total_score); + player.hp_info(param); + infoList.addTObject(param); + } + data.putTArray("info_list", infoList); + + ITObject mp = TObject.newInstance(); + mp.putInt("type", dissmiss?2:1); + if(!dissmiss) { + ITObject result = getRoomResultData(owner); + owner.playBackData.addResult(result); + mp.putTObject("result", result); + } + mp.putTObject("total_result", data); + + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, mp); + + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXMainServer.java b/game_mj_hongzhong/src/main/java/extend/mj/EXMainServer.java new file mode 100644 index 0000000..1e98ee6 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXMainServer.java @@ -0,0 +1,98 @@ +package extend.mj; + +import java.util.Map; + +import com.game.GameController; +import com.game.Global; +import com.game.MainServer; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerWaitState; +import com.game.room.state.RoomStartGameState; + +import extend.mj.player.rulestate.PROtherKongState; +import extend.mj.player.rulestate.PROtherWinState; +import extend.mj.player.rulestate.PRPongKongState; +import extend.mj.player.rulestate.PRPongState; +import extend.mj.player.rulestate.PRSelfKongState; +import extend.mj.player.rulestate.PRSelfWinState; +import extend.mj.player.state.EXPlayerDisCardTipState; +import extend.mj.player.state.EXPlayerDiscardState; +import extend.mj.player.state.EXPlayerDrawState; +import extend.mj.player.state.EXPlayerDrawTipState; +import extend.mj.player.state.EXPlayerKongWinState; +import extend.mj.player.state.EXPlayerPiaoNiaoTipState; +import extend.mj.player.state.EXPlayerWaitKongWinState; +import extend.mj.player.state.EXPlayerWaitState; +import extend.mj.room.state.EXRoomDealState; +import extend.mj.room.state.EXRoomSetpState; +import extend.mj.room.state.EXRoomStartGameState; + +/** + * + * + * EXMainServer.java + */ +public class EXMainServer extends MainServer{ + + + public static PlayerRuleManager playerRuleMgr; + + public static EXGameController gameCtr; + + @Override + public void onStart() { + super.onStart(); + gameCtr = (EXGameController)Global.gameCtr; + + registerState(); + + playerRuleMgr = new PlayerRuleManager(); + } + + + private final void registerState() { + Global.registerState(RoomStartGameState.class, new EXRoomStartGameState()); + Global.registerState(EXRoomSetpState.class, new EXRoomSetpState()); + Global.registerState(EXRoomDealState.class, new EXRoomDealState()); + + Global.registerState(PlayerWaitState.class, new EXPlayerWaitState()); + Global.registerState(EXPlayerDrawState.class, new EXPlayerDrawState()); + Global.registerState(EXPlayerDiscardState.class, new EXPlayerDiscardState()); + Global.registerState(EXPlayerDisCardTipState.class, new EXPlayerDisCardTipState()); + Global.registerState(EXPlayerDrawTipState.class, new EXPlayerDrawTipState()); + Global.registerState(EXPlayerWaitKongWinState.class, new EXPlayerWaitKongWinState()); + Global.registerState(EXPlayerKongWinState.class, new EXPlayerKongWinState()); + Global.registerState(EXPlayerPiaoNiaoTipState.class, new EXPlayerPiaoNiaoTipState()); + + Global.registerState(PROtherKongState.class, new PROtherKongState()); + Global.registerState(PROtherWinState.class, new PROtherWinState()); + Global.registerState(PRPongKongState.class, new PRPongKongState()); + Global.registerState(PRPongState.class, new PRPongState()); + Global.registerState(PRSelfKongState.class, new PRSelfKongState()); + Global.registerState(PRSelfWinState.class, new PRSelfWinState()); + + + } + + + @Override + public Room newRoom(String roomid, Map redis_room_map) { + // TODO Auto-generated method stub + return new EXRoom(roomid, redis_room_map); + } + + + @Override + public Player newPlayer(int playerid, Room room, String session_id) { + // TODO Auto-generated method stub + return new EXPlayer(playerid, room, session_id); + } + + + @Override + protected GameController newController() { + // TODO Auto-generated method stub + return new EXGameController(); + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXPlayBack.java b/game_mj_hongzhong/src/main/java/extend/mj/EXPlayBack.java new file mode 100644 index 0000000..d060694 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXPlayBack.java @@ -0,0 +1,68 @@ +package extend.mj; + +import com.game.Util; +import com.game.data.BasePlayBack; +import com.game.data.Player; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +public class EXPlayBack extends BasePlayBack{ + + + public EXPlayBack(EXRoom room){ + super(room); + info.putInt("left_card", room.card.getCount()); + } + + protected ITObject getPlayerInfo(Player player) { + ITObject obj =super.getPlayerInfo(player); + EXPlayer p = (EXPlayer)player; + ITArray cardInhand = Util.toTArray(p.cardInhand); + obj.putTArray("hand_card", cardInhand); + obj.putInt("score", player.score.total_score); + obj.putInt("piao_niao", p.piaoNiao); + return obj; + } + + public void addGetCardCommand(int seat,int card,int left_count){ + ITObject data = TObject.newInstance(); + data.putInt("card", card); + data.putInt("left_count", left_count); + addCommand("GetCard",seat,data); + } + + + public void addOutCardCommand(int seat,int card){ + ITObject data = TObject.newInstance(); + data.putInt("card", card); + addCommand("OutCard",seat,data); + } + + public void addOutCardKongCommand(int seat,ITArray card){ + ITObject data = TObject.newInstance(); + data.putTArray("cardList", card); + addCommand("OutCardKong",seat,data); + } + + public void addActionCommand(int seat,int type,int card,int from_seat,ITArray opcardArray){ + ITObject cmdData = TObject.newInstance(); + cmdData.putInt("card", card); + cmdData.putInt("type", type); + cmdData.putInt("from_seat", from_seat); + if(opcardArray!=null) + cmdData.putTArray("opcard", opcardArray); + addCommand("Action",seat,cmdData); + } + + public void addWinCardCommand(int seat,boolean zimo){ + ITObject cmdData = TObject.newInstance(); + addCommand("Win",seat,cmdData); + } + + public void addNiaoCommand(int seat,ITObject param){ + addCommand("Niao",seat,param); + } + + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXPlayer.java b/game_mj_hongzhong/src/main/java/extend/mj/EXPlayer.java new file mode 100644 index 0000000..ce71187 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXPlayer.java @@ -0,0 +1,142 @@ +package extend.mj; + +import java.util.ArrayList; +import java.util.List; + +import com.game.Util; +import com.game.data.Player; +import com.game.data.Room; +import com.game.data.Score; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; + +import extend.mj.tip.TipManager; + +/** + * + * + * + * 2017��8��30�� + * EXPlayer.java + */ +public class EXPlayer extends Player { + // ���� + public List cardInhand; + + // ������ + public List outcardList; + + public ITArray opCard; + + public List pongGroup; + public List kongGroup; + public List selfKongGroup; + public List opCardList; + + public int drawCard = 0; + public int winCard = 0; + + public TipManager tipMgr; + + public SettleLog settleLog; + + /** + * ©�� + */ + public boolean louhu = false; + + /** + * ǿ�Ƽ����� + */ + public boolean forceCheckWin = false; + /** + * 0 С�� 1 ���ܺ� + */ + public int winType = 0; + public List notPongKongList = new ArrayList<>(); + + public int niaoCount; + public int piaoNiao; + public boolean fengding; + + public EXPlayer(int playerid, Room table, String session_id) { + super(playerid, table, session_id); + + cardInhand = new ArrayList<>(); + outcardList = new ArrayList<>(); + + pongGroup = new ArrayList<>(); + kongGroup = new ArrayList<>(); + selfKongGroup = new ArrayList<>(); + opCardList = new ArrayList<>(); + + opCard = new TArray(); + + tipMgr = new TipManager(this); + + settleLog = new SettleLog(); + settleLog.put(Config.SETTLE_DIAN_PAO, 0); + settleLog.put(Config.SETTLE_JIE_PAO, 0); + settleLog.put(Config.SETTLE_ZIMO, 0); + settleLog.put(Config.SETTLE_AN_KONG, 0); + settleLog.put(Config.SETTLE_MING_KONG, 0); + fengding = false; + } + + protected Score newScore() { + return new EXScore(this); + } + + public void initOpCard(ITArray opcard) { + this.opCard.clear(); + for (int i = 0; i < opcard.size(); ++i) { + this.opCard.addInt(opcard.getInt(i)); + } + } + + public ITObject getReloadInfo() { + ITObject playerData = super.getReloadInfo(); + ITArray disCard = Util.toTArray(this.outcardList); + playerData.putTArray("outcard_list", disCard); + playerData.putInt("card_count", cardInhand.size()); + playerData.putInt("score", score.total_score); + playerData.putInt("piao_niao", this.piaoNiao); + ITArray opcards = TArray.newInstance(); + for (OpCard opcard : opCardList) { + ITObject opcardParam = new TObject(); + opcardParam.putInt("type", opcard.type); + opcardParam.putInt("card", opcard.card); + opcards.addTObject(opcardParam); + } + playerData.putTArray("opcard", opcards); + + return playerData; + } + + public void clear() { + super.clear(); + this.cardInhand.clear(); + this.notPongKongList.clear(); + this.winer = 0; + this.louhu = false; + this.outcardList.clear(); + this.drawCard = 0; + this.kongGroup.clear(); + this.pongGroup.clear(); + this.selfKongGroup.clear(); + this.opCardList.clear(); + this.score.resetRound(); + this.niaoCount = 0; + this.piaoNiao = 0; + this.fengding = false; + } + + + + public EXRoom getRoom() { + return (EXRoom) room; + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXRoom.java b/game_mj_hongzhong/src/main/java/extend/mj/EXRoom.java new file mode 100644 index 0000000..f7a252b --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXRoom.java @@ -0,0 +1,694 @@ +package extend.mj; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Global; +import com.game.Util; +import com.game.data.Player; +import com.game.data.Room; +import com.game.player.state.PlayerWaitState; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.entity.TObject; +import extend.mj.player.state.EXPlayerDisCardTipState; +import extend.mj.tip.Action; +import extend.mj.tip.TipManager; + +public class EXRoom extends Room { + + // + public Map tipMap; + public List actionList; + + public RoomCard card; + + public int activeCard; + public int currenDiscardSeat; + public int lastDiscardSeat; + public int winCount = 0; + public boolean liuju = false; + + public ArrayList niao; + + public int niao_score; + public int piaoNiaoCount; + public int adminSeat = 0; + + public int di_fen = 2; + + public int fengdingScore = 0; + + public EXRoom(String roomid, Map redis_room_map) { + super(roomid, redis_room_map); + card = new RoomCard(this); + + this.tipMap = new HashMap(); + this.actionList = new ArrayList(); + this.niao = new ArrayList(); + this.fengdingScore = 0; + + if (!this.config.containsKey(Config.ROOM_CONFIG_FENGDING)) + { + this.config.putBoolean(Config.ROOM_CONFIG_FENGDING, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_FENGDING_SCORE)) + { + this.config.putInt(Config.ROOM_CONFIG_FENGDING_SCORE, 0); + } + else { + int fengding_score = this.config.getInt(Config.ROOM_CONFIG_FENGDING_SCORE); + if (fengding_score == 0) + { + this.fengdingScore = 0; + } + else if (fengding_score == 1) + { + this.fengdingScore = 35; + } + else if (fengding_score == 2) + { + this.fengdingScore = 40; + } + else if (fengding_score == 3) + { + this.fengdingScore = 45; + } + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_PIAO_NIAO)) + { + this.config.putInt(Config.ROOM_CONFIG_PIAO_NIAO, 0); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_PIAO_NIAO_AUTO)) + { + this.config.putBoolean(Config.ROOM_CONFIG_PIAO_NIAO_AUTO, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_PIAO_NIAO_OPT)) + { + this.config.putInt(Config.ROOM_CONFIG_PIAO_NIAO_OPT, 0); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_WUGUI_JIABEI)) + { + this.config.putBoolean(Config.ROOM_CONFIG_WUGUI_JIABEI, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI)) + { + this.config.putBoolean(Config.ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_LAIZI4_HU)) + { + this.config.putBoolean(Config.ROOM_CONFIG_LAIZI4_HU, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_NIAO_OPT_SCORE)) + { + this.config.putInt(Config.ROOM_CONFIG_NIAO_OPT_SCORE, 1); + } + + if (Global.gameId == 1) { + this.config.putBoolean(Config.ROOM_CONFIG_QIANGKONG, true); + this.config.putBoolean(Config.ROOM_CONFIG_DIANPAO, false); + this.config.putBoolean(Config.ROOM_CONFIG_QIANGKONG_NIAO, true); + this.config.putBoolean(Config.ROOM_CONFIG_HONGZHONG8, false); + this.config.putInt(Config.ROOM_CONFIG_JIANGMA, 0); + if(!this.config.containsKey(Config.ROOM_CONFIG_HZ_HU)) { + this.config.putBoolean(Config.ROOM_CONFIG_HZ_HU,false); + } + this.niao_score = this.config.containsKey(Config.ROOM_CONFIG_NIAO_SCORE)?this.config.getInt(Config.ROOM_CONFIG_NIAO_SCORE):1; + } else { + this.config.putBoolean(Config.ROOM_CONFIG_DIANPAO, false); + this.config.putBoolean(Config.ROOM_CONFIG_HONGZHONG, true); + this.config.putBoolean(Config.ROOM_CONFIG_NONEALL, false); + this.config.putBoolean(Config.ROOM_CONFIG_ZHUANGXIAN, false); + this.config.putInt(Config.ROOM_CONFIG_QG_TYPE, 0); + if(!this.config.containsKey(Config.ROOM_CONFIG_HZ_HU)) { + this.config.putBoolean(Config.ROOM_CONFIG_HZ_HU,false); + } + this.niao_score = 2; + if(this.config.getInt(Config.ROOM_CONFIG_NIAO) > 0) { + int opt = this.config.getInt(Config.ROOM_CONFIG_NIAO_OPT_SCORE); + if(opt==2)this.niao_score = 1; + } + } + + if(!this.config.containsKey(Config.ROOM_CONFIG_HZ_HU)) { + this.config.putBoolean(Config.ROOM_CONFIG_HZ_HU,false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_XIPAI_SCORE)) + { + this.config.putInt(Config.ROOM_CONFIG_XIPAI_SCORE, 0); + this.xi_pai_score = 1; + } + else { + this.xi_pai_score = this.config.getInt(Config.ROOM_CONFIG_XIPAI_SCORE); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_XIPAI)) + { + this.config.putBoolean(Config.ROOM_CONFIG_XIPAI, false); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_DI_FEN)) + { + this.config.putInt(Config.ROOM_CONFIG_DI_FEN, 0); + this.di_fen = 2; + } + else { + int di_index = this.config.getInt(Config.ROOM_CONFIG_DI_FEN); + if (di_index == 0) + { + this.di_fen = 2; + } + else if (di_index == 1) + { + this.di_fen = 3; + } + else if (di_index == 2) + { + this.di_fen = 4; + } + else if (di_index == 3) + { + this.di_fen = 5; + } + } + + // this.entrustTime = this.config.getInt("tuoguan_active_time") * 60000; + // this.openEntrust = this.entrustTime > 0; + // this.entrusResultType = this.config.getInt("tuoguan_result_type"); + this.isEntrust=true; + this.adminSeat = 0; + } + + public void addAction(Action action) { + if (this.actionList.size() == 0) { + this.actionList.add(action); + } else if (action.tip.weight > this.actionList.get(0).tip.weight) { + this.actionList.clear(); + this.actionList.add(action); + } else if (action.tip.weight == this.actionList.get(0).tip.weight) { + this.actionList.add(action); + } + + checkAction(); + } + + public void checkAction() { + boolean isWeightest = this.isWeightestAction(); + if (!isWeightest) { + return; + } + if (this.isAllPass()) { + Player activePlayer = this.playerMapBySeat.get(this.activeSeat); + activePlayer.stateMachine.toNextState(); + } else { + + for (Action action : this.actionList) { + action.run(); + } + this.actionList.clear(); + } + } + + public boolean isAllPass() { + return this.actionList.size() == 0 && this.tipMap.size() == 0; + } + + public boolean isWeightestAction() { + + if (this.isAllPass()) { + return true; + } + if (this.actionList.size() == 0) { + return false; + } + + Action curaction = this.actionList.get(0); + for (Entry entry : this.tipMap.entrySet()) { + TipManager tip = entry.getValue(); + if (curaction.tip.weight <= tip.getWeightest()) { + return false; + } + } + + for (Entry entry : this.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.stateMachine.curState instanceof EXPlayerDisCardTipState) { + player.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + } + } + return true; + + } + + public ITObject getReloadInfo(Player player) { + ITObject data = super.getReloadInfo(player); + EXPlayer p = (EXPlayer) player; + data.putTArray("hand_card", Util.toTArray(p.cardInhand)); + data.putInt("left_card", card.getCount()); + data.putInt("curren_outcard_seat", currenDiscardSeat); + data.putInt("last_outcard_seat", lastDiscardSeat); + return data; + } + + public void addScore(EXPlayer destPlayer, EXPlayer fromPlayer, int score, int type) { + boolean zhuangxian = this.config.getBoolean(Config.ROOM_CONFIG_ZHUANGXIAN); + if(type == EXScore.WIN) { + if (zhuangxian) { + if (destPlayer.seat == this.bankerSeat || fromPlayer.seat == this.bankerSeat) { + score += 1; + } + } + + EXScore exscore = (EXScore) destPlayer.score; + EXScore.HUScore hu_score = exscore.getHuScore(fromPlayer); + if (hu_score == null) { + hu_score = new EXScore.HUScore(); + hu_score.player = fromPlayer; + exscore.hu_score.add(hu_score); + } + + hu_score.score += score; + } + else if (type == EXScore.NIAO) + { + EXScore exscore = (EXScore) destPlayer.score; + EXScore.HUScore hu_score = exscore.getHuScore(fromPlayer); + if (hu_score == null) { + hu_score = new EXScore.HUScore(); + hu_score.player = fromPlayer; + exscore.hu_score.add(hu_score); + } + + hu_score.niao_score += score; + } + + if (type == EXScore.WIN || type == EXScore.NIAO) { + return; + } + + destPlayer.score.round_log.put(type, destPlayer.score.round_log.get(type) + score); + fromPlayer.score.round_log.put(type, fromPlayer.score.round_log.get(type) - score); + + destPlayer.score.round_score += score; + destPlayer.score.total_score += score; + + fromPlayer.score.round_score -= score; + fromPlayer.score.total_score -= score; + } + + public void addAllScore(EXPlayer destPlayer, int socre, int type) { + for (Entry entry : this.playerMapById.entrySet()) { + if (entry.getKey().equals(destPlayer.playerid)) { + continue; + } + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + this.addScore(destPlayer, fromPlayer, socre, type); + } + } + + public void addNiaoScore(EXPlayer destPlayer, EXPlayer fromPlayer, int score) { + this.addScore(destPlayer, fromPlayer, score, EXScore.NIAO); + } + + public void addAllNiaoScore(EXPlayer destPlayer, int score) { + for (Entry entry : this.playerMapById.entrySet()) { + if (entry.getKey().equals(destPlayer.playerid)) { + continue; + } + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + fromPlayer.niaoCount ++; + addNiaoScore(destPlayer, fromPlayer, score); + } + } + + public void addPiaoNiaoScore(EXPlayer destPlayer, EXPlayer fromPlayer) { + int piao_niao = this.config.getInt(Config.ROOM_CONFIG_PIAO_NIAO); + if (piao_niao == 0) return; + + this.addScore(destPlayer, fromPlayer,destPlayer.piaoNiao + fromPlayer.piaoNiao , EXScore.PIAO_NIAO); + } + + public void addAllPiaoNiaoScore(EXPlayer destPlayer) { + int piao_niao = this.config.getInt(Config.ROOM_CONFIG_PIAO_NIAO); + if (piao_niao == 0) return; + + for (Entry entry : this.playerMapById.entrySet()) { + if (entry.getKey().equals(destPlayer.playerid)) { + continue; + } + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + addPiaoNiaoScore(destPlayer,fromPlayer); + } + } + + private int getNiaoNum(int card) { + int niao_num = 0; + int niao = this.config.getInt(Config.ROOM_CONFIG_NIAO); + switch (niao) { + case Config.NIAO_TYPE_159: + int opt = this.config.getInt(Config.ROOM_CONFIG_NIAO_OPT); + niao_num = opt * 2; + break; + case Config.NIAO_TYPE_ALL: + niao_num = 1; + break; + case Config.NIAO_TYPE_WOWO: + int tem = card % 100; + niao_num = (card == Config.HONGZHONG) ? 10 : tem; + break; + } + return niao_num; + } + + public void niao_tongPao(int card) { + EXPlayer dianPaoPlayer = (EXPlayer) this.playerMapBySeat.get(this.activeSeat); + __zhuaNiao(dianPaoPlayer, getNiaoNum(card)); + List winPlayerList = new ArrayList(); + for (Entry entry : this.playerMapById.entrySet()) { + Player player = entry.getValue(); + if (player.winer == 1) { + ((EXPlayer)player).niaoCount = 0; + winPlayerList.add((EXPlayer) player); + } + } + for (CardNiao cn : niao) { + boolean not_niao = true; + if (dianPaoPlayer.playerid == cn.playerId) { + for (EXPlayer winer : winPlayerList) { + int score = cn.score; + if(Global.gameId != 1&&winer.winType == 1) + score = score * (maxPlayers - 1); + winer.niaoCount ++; + this.addNiaoScore(winer, dianPaoPlayer, score); + } + not_niao = false; + } else { + for (EXPlayer winer : winPlayerList) { + if (winer.playerid == cn.playerId) { + boolean jiabei = false; + boolean wuguijiabei = this.config.getBoolean(Config.ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI); + if (wuguijiabei && this.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG)) { + if (Util.cardNum(Config.HONGZHONG, winer.cardInhand) <= 0) { + jiabei = true; + } + } + + int score = 0; + if (jiabei) + { + score = cn.score * 2; + } + else { + score = cn.score; + } + if (Global.gameId != 1&&winer.winType == 1) + score = score * (maxPlayers - 1); + this.addNiaoScore(winer, dianPaoPlayer, score); + not_niao = false; + winer.niaoCount ++; + break; + } + } + } + if (not_niao) + cn.score = 0; + } + boolean none_all = this.config.getBoolean(Config.ROOM_CONFIG_NONEALL); + if(none_all) { + for (EXPlayer winer : winPlayerList) { + if(winer.niaoCount == 6 ||winer.niaoCount == 0) { + this.addNiaoScore(winer, dianPaoPlayer, niao_score*6); + } + } + } + + EXMainServer.gameCtr.sendNiaoEvt(dianPaoPlayer, dianPaoPlayer.seat); + } + + public void niao_dianPao(EXPlayer owner, int card) { + EXPlayer dianPaoPlayer = (EXPlayer) this.playerMapBySeat.get(this.activeSeat); + EXPlayer winer = owner; + int num = getNiaoNum(card); + boolean jiabei = false; + boolean wuguijiabei = this.config.getBoolean(Config.ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI); + if (wuguijiabei && this.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG)) { + if (Util.cardNum(Config.HONGZHONG, owner.cardInhand) <= 0) { + jiabei = true; + int jm_num = config.getInt(Config.ROOM_CONFIG_JIANGMA); + if(jm_num>0) { + num +=jm_num; + } + } + } + + __zhuaNiao(winer, num); + winer.niaoCount = 0; + for (CardNiao cn : niao) { + if (cn.playerId == winer.playerid || dianPaoPlayer.playerid == cn.playerId) { + int score = 0; + if (jiabei) + { + score = cn.score * 2; + } + else { + score = cn.score; + } + if(Global.gameId != 1&&owner.winType == 1) + score = score * (maxPlayers - 1); + winer.niaoCount ++; + this.addNiaoScore(winer, dianPaoPlayer, score); + } else { + cn.score = 0; + } + } + boolean none_all = this.config.getBoolean(Config.ROOM_CONFIG_NONEALL); + if(none_all) { + if(winer.niaoCount == 6 ||winer.niaoCount == 0) { + this.addNiaoScore(winer, dianPaoPlayer, niao_score*6); + } + } + EXMainServer.gameCtr.sendNiaoEvt(winer, winer.seat); + } + + public void niao_selfWin(EXPlayer owner, int card) { + if (this.config.getInt(Config.ROOM_CONFIG_NIAO) == 0) { + return; + } + int num = getNiaoNum(card); + boolean hongzhong = Util.checkCard(Config.HONGZHONG, owner.cardInhand); + int jm_num = config.getInt(Config.ROOM_CONFIG_JIANGMA); + if(card!=Config.HONGZHONG&&!hongzhong&&jm_num>0) { + num +=jm_num; + } + __zhuaNiao(owner, num); + for (Entry entry : owner.room.playerMapById.entrySet()) { + ((EXPlayer)entry.getValue()).niaoCount = 0; + } + boolean jiabei = false; + boolean wuguijiabei = this.config.getBoolean(Config.ROOM_CONFIG_WUGUI_JIABEI); + if (wuguijiabei && this.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG)) { + if (Util.cardNum(Config.HONGZHONG, owner.cardInhand) <= 0 && owner.drawCard != Config.HONGZHONG) { + jiabei = true; + } + } + for (CardNiao cn : niao) { + boolean not_niao = true; + if (cn.playerId == owner.playerid) { + if (jiabei) + { + this.addAllNiaoScore(owner, cn.score * 2); + } + else { + this.addAllNiaoScore(owner, cn.score); + } + not_niao = false; + } else { + for (Entry entry : owner.room.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.playerid == cn.playerId) { + player.niaoCount ++; + if (jiabei) + { + this.addNiaoScore(owner, player, cn.score * 2); + } + else { + this.addNiaoScore(owner, player, cn.score); + } + not_niao = false; + break; + } + } + } + if (not_niao) + cn.score = 0; + } + boolean none_all = this.config.getBoolean(Config.ROOM_CONFIG_NONEALL); + if(none_all) { + for (Entry entry : owner.room.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if(player.niaoCount == 6 ||player.niaoCount == 0) { + if (jiabei) + { + this.addNiaoScore(owner, player, niao_score*6*2); + } + else { + this.addNiaoScore(owner, player, niao_score*6); + } + } + } + } + EXMainServer.gameCtr.sendNiaoEvt(owner, owner.seat); + } + + private final void __zhuaNiao(EXPlayer owner, int niao_num) { + this.niao.clear(); + + boolean niao_all = config.getInt(Config.ROOM_CONFIG_NIAO) == Config.NIAO_TYPE_ALL; + for (int index = 0; index < niao_num; index++) { + if (card.cardList.size() == 0) { + break; + } + + int card = this.card.pop(); + CardNiao cn = new CardNiao(); + cn.card = card; + this.niao.add(cn); + int tem = card % 100; + if (niao_all) { + cn.playerId = owner.playerid; + if (card == Config.HONGZHONG || (Global.gameId == 1 &&tem == 1)) { + cn.score = 10; + } else { + cn.score = tem; + } + } else { + if (card == Config.HONGZHONG || tem == 1 || tem == 5 || tem == 9) { + cn.playerId = owner.playerid; + cn.score = niao_score; + } + } + } + + } + + public void winCallback(EXPlayer owner, int card) { + boolean qiangkong_niao = config.getBoolean(Config.ROOM_CONFIG_QIANGKONG_NIAO); + + if (this.winCount >= this.actionList.size()) { + if (actionList.size() > 1) { + this.bankerSeat = this.activeSeat; + if (owner.winType == 1 && qiangkong_niao) + niao_tongPao(card); + else + niao_tongPao(card); + } else { + if (owner.winType == 1 && qiangkong_niao) { + niao_dianPao(owner, card); + } + else + niao_dianPao(owner, card); + } + + this.endGame(); + } + } + + @Override + public void endGame() { + boolean fengding = this.config.getBoolean(Config.ROOM_CONFIG_FENGDING); + for (Entry entry : this.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.winer == 1) { + List list = ((EXScore) player.score).hu_score; + for (EXScore.HUScore hu_score : list) { + int hu_num = hu_score.score; + int niao_num = hu_score.niao_score; + int sum_score = hu_num + niao_num; + EXPlayer destPlayer = player; + EXPlayer fromPlayer = hu_score.player; + + destPlayer.score.round_log.put(EXScore.WIN, destPlayer.score.round_log.get(EXScore.WIN) + hu_num); + fromPlayer.score.round_log.put(EXScore.WIN, fromPlayer.score.round_log.get(EXScore.WIN) - hu_num); + destPlayer.score.round_log.put(EXScore.NIAO, destPlayer.score.round_log.get(EXScore.NIAO) + niao_num); + fromPlayer.score.round_log.put(EXScore.NIAO, fromPlayer.score.round_log.get(EXScore.NIAO) - niao_num); + //if (fengding) { + // if (sum_score > Config.FENGDING_SCORE) { + // sum_score = Config.FENGDING_SCORE; + // player.fengding = true; + // } + //} + if (fengding && this.fengdingScore > 0) + { + if (sum_score > this.fengdingScore) { + sum_score = this.fengdingScore; + player.fengding = true; + } + } + destPlayer.score.round_score += sum_score; + destPlayer.score.total_score += sum_score; + fromPlayer.score.round_score -= sum_score; + fromPlayer.score.total_score -= sum_score; + } + } + } + super.endGame(); + } + +// public void settleRound() { +// saveMilitaryRound(playBackData.getData()); +// boolean total = this.round >= this.maxRound; +// if(this.entrusResultType ==EXRoom.ENTRUST_CURREN_RESULT) { +// for (Entry entry : this.playerMapById.entrySet()) { +// if(entry.getValue().isEntrust()) { +// total = true; +// break; +// } +// } +// } +// if (!total) +// EXMainServer.gameCtr.roomResult(this); +// else { +// this.saveMilitaryTotal(false); +// } +// this.stateMachine.changeState(Global.getState(EXRoomRoundSettleState.class)); +// this.winCount = 0; +// +// +// if (total) { +// this.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); +// return; +// } +// } + + @Override + public void saveMilitaryTotal(boolean dissmiss) { + super.saveMilitaryTotal(dissmiss); + EXMainServer.gameCtr.roomTotalResult(this, dissmiss); + } + @Override + protected void roomResult() { + EXMainServer.gameCtr.roomResult(this); + } + + @Override + public void clear() { + super.clear(); + this.liuju = false; + this.activeSeat = this.lastDiscardSeat = this.currenDiscardSeat = 0; + this.winCount = this.piaoNiaoCount = 0; + this.niao.clear(); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/EXScore.java b/game_mj_hongzhong/src/main/java/extend/mj/EXScore.java new file mode 100644 index 0000000..fdae96d --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/EXScore.java @@ -0,0 +1,47 @@ +package extend.mj; + +import com.game.data.Score; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EXScore extends Score{ + public static final int WIN = 1; + public static final int KONG = 2; + public static final int NIAO = 3; + public static final int PIAO_NIAO = 4; + + public List hu_score; + + public EXScore(EXPlayer owner){ + super(owner); + this.hu_score = new ArrayList<>(); + } + + protected void initLog() { + this.round_log.put(WIN, 0); + this.round_log.put(KONG, 0); + this.round_log.put(NIAO, 0); + this.round_log.put(PIAO_NIAO, 0); + if(this.hu_score!=null) + this.hu_score.clear(); + } + + public HUScore getHuScore(EXPlayer from){ + for(HUScore hu_score : hu_score){ + if(hu_score.player.playerid == from.playerid){ + return hu_score; + } + } + return null; + } + + + public static final class HUScore{ + public int score; + public EXPlayer player; + public int niao_score; + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/OpCard.java b/game_mj_hongzhong/src/main/java/extend/mj/OpCard.java new file mode 100644 index 0000000..32f8334 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/OpCard.java @@ -0,0 +1,19 @@ +package extend.mj; + +public class OpCard { + public int type; + public int card; + public int seat; + + public OpCard(int type, int card) { + this.type = type; + this.card = card; + this.seat = 0; + } + + public OpCard(int type, int card, int seat) { + this.type = type; + this.card = card; + this.seat = seat; + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/PlayerRuleManager.java b/game_mj_hongzhong/src/main/java/extend/mj/PlayerRuleManager.java new file mode 100644 index 0000000..f935748 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/PlayerRuleManager.java @@ -0,0 +1,103 @@ +package extend.mj; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.game.Global; + +import extend.mj.player.rule.RuleOtherKong; +import extend.mj.player.rule.RuleOtherWin; +import extend.mj.player.rule.RulePong; +import extend.mj.player.rule.RulePongKong; +import extend.mj.player.rule.RuleSelfKong; +import extend.mj.player.rule.RuleSelfWin; +import extend.mj.player.state.EXPlayerDisCardTipState; +import extend.mj.player.state.EXPlayerDrawTipState; +import extend.mj.player.state.EXPlayerKongWinState; +import extend.mj.player.state.EXPlayerTipState; +import extend.mj.tip.IRuleBase; + +/** + * ����������� + * + * + * + * 2017��9��19�� PlayerRuleManager.java + */ +public class PlayerRuleManager { + + /** + * ����ץ�� + */ + public static final int DRAW_RULE = 1; + /** + * ���˳��� + */ + public static final int OTHER_DISCARD_RULE = 2; + /** + * ���ܺ����� + */ + public static final int KONG_HU_RULE = 3; + /** + * �������Ժ���ƹ��� + */ + public static final int CHOW_PONG_DISCARD_RULE = 7; + + public HashMap> ruleMap = null; + public HashMap tipMap = null; + + public PlayerRuleManager() { + ruleMap = new HashMap>(); + + tipMap = new HashMap(); + tipMap.put(PlayerRuleManager.DRAW_RULE, (EXPlayerTipState) Global.getState(EXPlayerDrawTipState.class)); + tipMap.put(PlayerRuleManager.OTHER_DISCARD_RULE, (EXPlayerTipState) Global.getState(EXPlayerDisCardTipState.class)); + tipMap.put(PlayerRuleManager.KONG_HU_RULE, (EXPlayerKongWinState) Global.getState(EXPlayerKongWinState.class)); + tipMap.put(PlayerRuleManager.CHOW_PONG_DISCARD_RULE, (EXPlayerDrawTipState) Global.getState(EXPlayerDrawTipState.class)); + + List drawRuleList = new ArrayList(); + drawRuleList.add(new RuleSelfKong()); + drawRuleList.add(new RulePongKong()); + drawRuleList.add(new RuleSelfWin()); + ruleMap.put(PlayerRuleManager.DRAW_RULE, drawRuleList); + + List otherDiscardList = new ArrayList(); + otherDiscardList.add(new RuleOtherKong()); + otherDiscardList.add(new RulePong()); + otherDiscardList.add(new RuleOtherWin()); + ruleMap.put(PlayerRuleManager.OTHER_DISCARD_RULE, otherDiscardList); + + List konghuList = new ArrayList(); + konghuList.add(new RuleOtherWin()); + ruleMap.put(PlayerRuleManager.KONG_HU_RULE, konghuList); + + List cpDiscardRuleList = new ArrayList(); + cpDiscardRuleList.add(new RuleSelfKong()); + cpDiscardRuleList.add(new RulePongKong()); + ruleMap.put(PlayerRuleManager.CHOW_PONG_DISCARD_RULE, cpDiscardRuleList); + + } + + public boolean condition(int type, EXPlayer player) { + return condition(type, player, true); + } + + public boolean condition(int type, EXPlayer player, boolean tonextState) { + List ruleList = this.ruleMap.get(type); + boolean result = false; + + for (IRuleBase rule : ruleList) { + result = rule.condition(player) || result; + } + + if (result) { + player.stateMachine.changeState(this.tipMap.get(type)); + } else { + if (tonextState) + player.stateMachine.toNextState(); + } + return result; + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/RoomCard.java b/game_mj_hongzhong/src/main/java/extend/mj/RoomCard.java new file mode 100644 index 0000000..384e755 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/RoomCard.java @@ -0,0 +1,190 @@ +package extend.mj; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.game.Global; + +import java.util.Random; +import extend.mj.uitl.WinCard; + + +public class RoomCard { + public List cardList; + EXRoom room; + public ArrayList subCardList; + + public RoomCard(EXRoom table) { + this.cardList = new ArrayList(); + subCardList = new ArrayList<>(); + this.room = table; + } + + public void init() { + this.cardList.clear(); + this.subCardList.clear(); + this.initCard(); + this.shuffle(); + } + + + private void initCard() { + + for (int index = 1; index <= 9; index++) { + for (int index2 = 0; index2 < 4; index2++) { + this.cardList.add(100 + index); + this.cardList.add(200 + index); + this.cardList.add(300 + index); + } + } + + boolean laizi = room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG); + boolean laizi8 = room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG8); + if(laizi) { + int laiziNum = laizi8 ? 8 :4; + WinCard.zhongWinNum = laiziNum; + + } + + } + + private void shuffle() { + for(int i = 0; i < 100; i++) + { + Math.random(); + Collections.shuffle(this.cardList); + } + } + + public void reInitCards(List cards) { + //从底牌移除 + for(Integer card : cards) { + for(int i = cardList.size() - 1;i >= 0;i--) { + if(cardList.get(i).intValue() == card.intValue()) { + if(cardList.remove(i) > 0) { + this.subCardList.add(card); + } + break; + } + } + } + } + +// public int pop() { +// +// if (this.cardList.size() == 0) { +// this.room.bankerSeat = this.room.activeSeat; +//// this.room.roundSettle(); +// } +// +// int card = this.cardList.remove(0); +// +// return card; +// +// } + + public int pop() { + Global.logger.info("pop cardlist size=>"+this.cardList.size()+":sub size==>"+subCardList.size()); + int card = 0; + if (this.cardList.size() == 0) { + if(this.subCardList.size() > 0) { + card = this.subCardList.remove(0); + }else { + this.room.bankerSeat = this.room.activeSeat; + } + }else { + card = this.cardList.remove(0); + } + return card; + + } + + public int popsub() { + Global.logger.info("pop sub cardlist size=>"+this.cardList.size()+":sub size==>"+subCardList.size()); + int card = 0; + if (this.subCardList.size() == 0) { + if (this.cardList.size() == 0) { + this.room.bankerSeat = this.room.activeSeat; + }else { + card = this.cardList.remove(0); + } + }else { + card = this.subCardList.remove(0); + } + return card; +// this.room.roundSettle(); + } + + public int getCount() { + return this.cardList.size() + this.subCardList.size(); + } + + // ���� + public List deal(boolean isw) { + List dealCards = new ArrayList(); + + + if (isw){ + + boolean laizi8 = room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG8); + Random randomno = new Random(); + //boolean value = randomno.nextBoolean(); + if (laizi8){ + for (int ia = 0; ia<3;ia++){ + int indexhh = this.cardList.indexOf(Config.HONGZHONG); + //Global.logger.info("hongzhongid:"+indexhh+"card"+this.cardList); + dealCards.add(Config.HONGZHONG); + this.cardList.remove(indexhh); + Collections.shuffle(this.cardList); + } + + for (int index = 0; index < 10; index++) { + dealCards.add(this.pop()); + } + }else{ + int flag = 1; + //if (value){ + // flag = 2; + //} + for (int ia = 0; ia log; + + public SettleLog() { + log = new HashMap(); + } + + public void put(String key,Integer value) { + log.put(key, value); + } + + public void add(String key) { + if(!log.containsKey(key)) { + return; + } + int value = log.get(key); + value++; + log.put(key, value); + } + + public Integer get(String key) { + if(!log.containsKey(key)) { + return null; + } + return log.get(key); + } + + public ITObject toTObject() { + ITObject obj = TObject.newInstance(); + for (Entry entry : this.log.entrySet()) { + obj.putInt(entry.getKey(), entry.getValue()); + } + return obj; + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherKong.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherKong.java new file mode 100644 index 0000000..fcf6da1 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherKong.java @@ -0,0 +1,50 @@ +package extend.mj.player.rule; + +import com.game.Global; +import com.game.Util; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PROtherKongState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; + +/** + * ���ܼ�� + * + * + * 2017��8��30�� + * RuleOtherKong.java + */ +public class RuleOtherKong implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + EXRoom room = player.getRoom(); + + int eventCard = room.activeCard; + if (eventCard == Config.HONGZHONG || player.isEntrust()) { + return false; + } + + if (Util.checkCard(eventCard, player.cardInhand, 3)) { + ITArray opcard = TArray.newInstance(); + opcard.addInt(eventCard); + Tip tip = new Tip(eventCard, opcard, RuleWeight.KONG, this, RuleWeight.TYPE_KONG); + player.tipMgr.addTip(tip); + return true; + } + return false; + } + + @Override + public void action(EXPlayer player, Tip tip) { + player.stateMachine.changeState(Global.getState(PROtherKongState.class)); + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherWin.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherWin.java new file mode 100644 index 0000000..ebaf0ae --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleOtherWin.java @@ -0,0 +1,61 @@ +package extend.mj.player.rule; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PROtherWinState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; +import extend.mj.uitl.WinCard; + +/** + * ���Ƽ�� + * + * + * 2017��8��30�� + * RuleOtherWin.java + */ +public class RuleOtherWin implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + if(!player.forceCheckWin&&player.louhu)return false; + EXRoom room = player.getRoom(); + ITObject config = room.config; + boolean hz_hu = config.getBoolean(Config.ROOM_CONFIG_HZ_HU); + if (!player.forceCheckWin&&!config.getBoolean(Config.ROOM_CONFIG_DIANPAO)&&!hz_hu) { + return false; + } + boolean qidui = config.getBoolean(Config.ROOM_CONFIG_QIDUI); + + int activieCard = room.activeCard; + boolean laizi = room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG); + WinCard win = new WinCard(player.cardInhand, room.activeCard, Config.HONGZHONG, laizi,qidui); + if(hz_hu&&win.zhong_count >0) { + return false; + } + if (win.checkQidui() || win.tryWin(room)) { + ITArray opcard = TArray.newInstance(); + opcard.addInt(activieCard); + Tip tip = new Tip(room.activeCard,opcard, RuleWeight.WIN,this, RuleWeight.TYPE_WIN); + tip.winType = player.forceCheckWin? 1 :0; + player.tipMgr.addTip(tip); + return true; + } + + return false; + } + + @Override + public void action(EXPlayer player,Tip tip) { + player.winType = tip.winType; + player.stateMachine.changeState(Global.getState(PROtherWinState.class)); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePong.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePong.java new file mode 100644 index 0000000..48cf238 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePong.java @@ -0,0 +1,53 @@ +package extend.mj.player.rule; + +import com.game.Global; +import com.game.Util; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PRPongState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; + +/** + * ����� + * + * + * 2017��8��30�� + * RulePong.java + */ +public class RulePong implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + EXRoom room = player.getRoom(); + int eventCard = room.activeCard; + if (eventCard == Config.HONGZHONG || player.isEntrust()) { + return false; + } + + if (Util.checkCard(eventCard, player.cardInhand, 2)) { + + ITArray opcard = TArray.newInstance(); + opcard.addInt(eventCard); + Tip tip = new Tip(eventCard, opcard, RuleWeight.PONG, this, RuleWeight.TYPE_PONG); + player.tipMgr.addTip(tip); + return true; + } + return false; + } + + @Override + public void action(EXPlayer player, Tip tip) { + if (Util.checkCard(tip.card, player.cardInhand, 3)) { + player.notPongKongList.add(tip.card); + } + player.stateMachine.changeState(Global.getState(PRPongState.class)); + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePongKong.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePongKong.java new file mode 100644 index 0000000..6a36a2e --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RulePongKong.java @@ -0,0 +1,59 @@ +package extend.mj.player.rule; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PRPongKongState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; + +/** + * ���ܼ�� + * + * + * 2017��8��30�� + * RulePongKong.java + */ +public class RulePongKong implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + boolean result = false; + if (player.isEntrust()) { + return false; + } + for (int card : player.cardInhand) { + if(!player.notPongKongList.contains(card)) { + result = conditionCard(player, card) || result; + } + } + return result; + + } + + public boolean conditionCard(EXPlayer player, int card) { + + for (int[] cardGroup : player.pongGroup) { + if (card == cardGroup[0]) { + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + Tip tip = new Tip(card,opcard, RuleWeight.KONG,this, RuleWeight.TYPE_PONG_KONG); + player.tipMgr.addTip(tip); + return true; + } + } + return false; + + } + + @Override + public void action(EXPlayer player,Tip tip) { + // TODO Auto-generated method stub + player.stateMachine.changeState(Global.getState(PRPongKongState.class)); + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfKong.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfKong.java new file mode 100644 index 0000000..ff51846 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfKong.java @@ -0,0 +1,56 @@ +package extend.mj.player.rule; + +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Global; +import com.game.Util; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PRSelfKongState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; + +/** + * ���ܼ�� + * + * + * 2017��8��30�� + * RuleSelfKong.java + */ +public class RuleSelfKong implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + if (player.isEntrust()) { + return false; + } + Map cardMap = Util.getCardNumMap(player.cardInhand); + boolean result = false; + + for (Entry entry : cardMap.entrySet()) { + + int card = entry.getKey(); + if(card == Config.HONGZHONG)continue; + int num = entry.getValue(); + if (num >= 4) { + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + Tip tip = new Tip(card,opcard, RuleWeight.SELFKONG,this, RuleWeight.TYPE_SELF_KONG); + player.tipMgr.addTip(tip); + result = true; + } + } + return result; + } + + @Override + public void action(EXPlayer player,Tip tip) { + player.stateMachine.changeState(Global.getState(PRSelfKongState.class)); + + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfWin.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfWin.java new file mode 100644 index 0000000..93b26b5 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rule/RuleSelfWin.java @@ -0,0 +1,49 @@ +package extend.mj.player.rule; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; +import extend.mj.player.rulestate.PRSelfWinState; +import extend.mj.tip.IRuleBase; +import extend.mj.tip.Tip; +import extend.mj.uitl.WinCard; + +/** + * ������� + * + * + * 2017��8��30�� + * RuleSelfWin.java + */ +public class RuleSelfWin implements IRuleBase { + + @Override + public boolean condition(EXPlayer player) { + // TODO Auto-generated method stub + ITObject config = player.room.config; + boolean qidui = config.getBoolean(Config.ROOM_CONFIG_QIDUI); + boolean laizi = config.getBoolean(Config.ROOM_CONFIG_HONGZHONG); + WinCard win = new WinCard(player.cardInhand, Config.HONGZHONG, laizi,qidui); + if (win.checkQidui() || win.tryWin(player.getRoom())) { + ITArray opcard = TArray.newInstance(); + opcard.addInt(player.drawCard); + Tip tip = new Tip(player.drawCard,opcard, RuleWeight.SELF_WIN,this, RuleWeight.TYPE_WIN); + player.tipMgr.addTip(tip); + return true; + } + return false; + } + + @Override + public void action(EXPlayer player,Tip tip) { + // TODO Auto-generated method stub + player.stateMachine.changeState(Global.getState(PRSelfWinState.class)); + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherKongState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherKongState.java new file mode 100644 index 0000000..ad4facd --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherKongState.java @@ -0,0 +1,89 @@ +package extend.mj.player.rulestate; + +import com.game.Global; +import com.game.Util; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.EXScore; +import extend.mj.OpCard; +import extend.mj.RuleWeight; +import extend.mj.player.state.EXPlayerDrawState; + +/** + * ��Ӧ���ܴ���״̬ + * + * + * 2017��8��30�� + * PROtherKongState.java + */ +public class PROtherKongState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + // TODO Auto-generated method stub + + EXRoom room = owner.getRoom(); + EXPlayer activePlayer = (EXPlayer)room.playerMapBySeat.get(owner.room.activeSeat); + activePlayer.outcardList.remove(activePlayer.outcardList.size()-1); + activePlayer.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + int fromseat = activePlayer.seat; + room.addScore(owner,activePlayer, 3,EXScore.KONG); + + EXMainServer.gameCtr.changeActiveSeat(room,owner.seat); + owner.cardInhand.add(owner.getRoom().activeCard); + + + int [] kongGroup = new int [4]; + int card = room.activeCard; + kongGroup[0] = card; + kongGroup[1] = card; + kongGroup[2] = card; + kongGroup[3] = card; + + owner.kongGroup.add(kongGroup); + owner.opCardList.add( new OpCard(RuleWeight.TYPE_KONG, card, fromseat) ); + Util.removeCard(owner.cardInhand, card, 4); + room.activeCard = 0; + room.lastDiscardSeat = 0; + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + opcard.addInt(card); + opcard.addInt(card); + EXMainServer.gameCtr.actionCard(owner, card, RuleWeight.TYPE_KONG, fromseat,opcard); + owner.settleLog.add(Config.SETTLE_MING_KONG); +// owner.stateMachine.changeState( Global.getState(EXPlayerDrawState.class) ); + +// owner.room.broadCastToServer(owner.playerid, EXActionEvent.EVENT_KONG_WIN, null); +// if(room.tipMap.size() == 0){ + toNextState(owner); +// }else{ +// owner.stateMachine.changeState(Global.getState(EXPlayerWaitKongWinState.class)); +// } + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(EXPlayerDrawState.class)); + + } + + @Override + public void exit(EXPlayer owner) { + // TODO Auto-generated method stub + + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + // TODO Auto-generated method stub + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherWinState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherWinState.java new file mode 100644 index 0000000..f5ba485 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PROtherWinState.java @@ -0,0 +1,73 @@ +package extend.mj.player.rulestate; + +import com.game.Util; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.mj.*; + +import java.util.Map; + +/** + * ��Ӧ���ƴ���״̬ + * + * + * 2017��8��30�� + * PROtherWinState.java + */ +public class PROtherWinState extends StateBase{ + + @Override + public void enter(EXPlayer owner) { + EXRoom room = (EXRoom) owner.room; + + EXPlayer activePlayer = (EXPlayer)room.playerMapBySeat.get(owner.room.activeSeat); + int score = room.di_fen; + int qg_type = room.config.getInt(Config.ROOM_CONFIG_QG_TYPE); + if(qg_type == 0&&owner.winType == 1) { + score = room.di_fen * ( room.maxPlayers - 1); + } + room.addScore(owner,activePlayer, score,EXScore.WIN); + room.addPiaoNiaoScore(owner, activePlayer); + boolean wuguijiabei = room.config.getBoolean(Config.ROOM_CONFIG_WUGUI_ZHUOPAO_JIABEI); + if (wuguijiabei && room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG)) { + if (Util.cardNum(Config.HONGZHONG, owner.cardInhand) <= 0) { + room.addScore(owner,activePlayer, score,EXScore.WIN); + room.addPiaoNiaoScore(owner, activePlayer); + for (Map.Entry entry : room.playerMapById.entrySet()) { + EXPlayer gangPlayer = (EXPlayer) entry.getValue(); + for(int i = 0; i < gangPlayer.opCardList.size(); i++) + { + OpCard op_card = gangPlayer.opCardList.get(i); + if (op_card.type == RuleWeight.TYPE_SELF_KONG) + { + room.addAllScore(gangPlayer, 3, EXScore.KONG); + } + else if (op_card.type == RuleWeight.TYPE_KONG && op_card.seat == 0) + { + room.addAllScore(gangPlayer, 3, EXScore.KONG); + } + else if (op_card.type == RuleWeight.TYPE_KONG && op_card.seat > 0) + { + EXPlayer activePlayer2 = (EXPlayer)room.playerMapBySeat.get(op_card.seat); + room.addScore(gangPlayer,activePlayer2, 3,EXScore.KONG); + } + } + } + } + } + activePlayer.settleLog.add(Config.SETTLE_DIAN_PAO); + activePlayer.winer = 2; + + owner.settleLog.add(Config.SETTLE_JIE_PAO); + EXMainServer.gameCtr.winEvent(owner,activePlayer.seat,room.activeCard); + + room.bankerSeat = owner.seat; + room.winCount += 1; + owner.winer = 1; + owner.winCard = room.activeCard; + + room.winCallback( owner ,owner.winCard); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongKongState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongKongState.java new file mode 100644 index 0000000..070f652 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongKongState.java @@ -0,0 +1,77 @@ +package extend.mj.player.rulestate; + +import com.game.Global; +import com.game.Util; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXActionEvent; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.EXScore; +import extend.mj.OpCard; +import extend.mj.RuleWeight; +import extend.mj.player.state.EXPlayerDrawState; +import extend.mj.player.state.EXPlayerWaitKongWinState; +import extend.mj.uitl.CardUtil; + +/** + * ��Ӧ���ܴ���״̬ + * + * + * 2017��8��30�� + * PRPongKongState.java + */ +public class PRPongKongState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + + EXRoom room = owner.getRoom(); + ITArray opCard = owner.opCard; + int card = opCard.getInt(0); + + Util.removeCard(owner.cardInhand, card, 1); + CardUtil.removeGroup(owner.pongGroup, card); + CardUtil.removeOpcard(owner.opCardList, new OpCard(RuleWeight.TYPE_PONG, card)); + + int[] kong = new int[4]; + kong[0] = card; + kong[1] = card; + kong[2] = card; + kong[3] = card; + owner.kongGroup.add(kong); + owner.opCardList.add(new OpCard(RuleWeight.TYPE_KONG, card)); + + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + + EXMainServer.gameCtr.actionCard(owner, card, RuleWeight.TYPE_PONG_KONG, owner.seat,opcard); + + room.activeCard = card; + boolean qiangkong = room.config.getBoolean(Config.ROOM_CONFIG_QIANGKONG); + if(qiangkong) { + owner.room.broadCastToServer(owner.playerid, EXActionEvent.EVENT_KONG_WIN, null); + if(room.tipMap.size() == 0){ + toNextState(owner); + }else{ + owner.stateMachine.changeState(Global.getState(EXPlayerWaitKongWinState.class)); + } + }else { + toNextState(owner); + } + + } + + @Override + public void toNextState(EXPlayer owner) { + owner.settleLog.add(Config.SETTLE_MING_KONG); + owner.getRoom().addAllScore(owner, 3, EXScore.KONG); + owner.getRoom().activeCard = 0; + owner.stateMachine.changeState(Global.getState(EXPlayerDrawState.class)); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongState.java new file mode 100644 index 0000000..5d82b46 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRPongState.java @@ -0,0 +1,67 @@ +package extend.mj.player.rulestate; + +import com.game.Global; +import com.game.Util; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.OpCard; +import extend.mj.PlayerRuleManager; +import extend.mj.RuleWeight; +import extend.mj.player.state.EXPlayerDiscardState; + +/** + * ��Ӧ���ƴ���״̬ + * + * + * 2017��8��30�� + * PRPongState.java + */ +public class PRPongState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + // TODO Auto-generated method stub + EXRoom room = (EXRoom) owner.room; + EXPlayer activePlayer = (EXPlayer)room.playerMapBySeat.get(owner.room.activeSeat); + activePlayer.outcardList.remove(activePlayer.outcardList.size() - 1); + activePlayer.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + int fromseat = activePlayer.seat; + + EXMainServer.gameCtr.changeActiveSeat(room, owner.seat); + owner.cardInhand.add(room.activeCard); + + int[] pongGroup = new int[3]; + int card = room.activeCard; + pongGroup[0] = card; + pongGroup[1] = card; + pongGroup[2] = card; + owner.pongGroup.add(pongGroup); + Util.removeCard(owner.cardInhand, card, 3); + room.activeCard = 0; + room.lastDiscardSeat = 0; + + owner.opCardList.add(new OpCard(RuleWeight.TYPE_PONG, card)); + + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + opcard.addInt(card); + EXMainServer.gameCtr.actionCard(owner, card, RuleWeight.TYPE_PONG, fromseat,opcard); + + if(!EXMainServer.playerRuleMgr.condition(PlayerRuleManager.CHOW_PONG_DISCARD_RULE, owner,false)){ + toNextState(owner); + } + } + + @Override + public void toNextState(EXPlayer owner) { + owner.drawCard = 0; + owner.stateMachine.changeState(Global.getState(EXPlayerDiscardState.class)); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfKongState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfKongState.java new file mode 100644 index 0000000..f4d8a9f --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfKongState.java @@ -0,0 +1,53 @@ +package extend.mj.player.rulestate; + +import com.game.Global; +import com.game.Util; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; + +import extend.mj.Config; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.EXRoom; +import extend.mj.EXScore; +import extend.mj.OpCard; +import extend.mj.RuleWeight; +import extend.mj.player.state.EXPlayerDrawState; + +/** + * ��Ӧ���ܴ���״̬ + * + * + * 2017��8��30�� + * PRSelfKongState.java + */ +public class PRSelfKongState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + EXRoom room = owner.getRoom(); + + ITArray opCard = owner.opCard; + int card = opCard.getInt(0); + Util.removeCard(owner.cardInhand, card, 4); + int [] kongGroup = new int [4]; + kongGroup[0] = card; + kongGroup[1] = card; + kongGroup[2] = card; + kongGroup[3] = card; + owner.selfKongGroup.add(kongGroup); + owner.opCardList.add(new OpCard(RuleWeight.TYPE_SELF_KONG, card)); + + ITArray opcard = TArray.newInstance(); + opcard.addInt(card); + opcard.addInt(card); + opcard.addInt(card); + opcard.addInt(card); + EXMainServer.gameCtr.actionCard(owner, card, RuleWeight.TYPE_SELF_KONG, owner.seat,opcard); + + room.addAllScore(owner, 3, EXScore.KONG); + owner.stateMachine.changeState(Global.getState(EXPlayerDrawState.class)); + owner.settleLog.add(Config.SETTLE_AN_KONG); + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfWinState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfWinState.java new file mode 100644 index 0000000..3c3d287 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/rulestate/PRSelfWinState.java @@ -0,0 +1,93 @@ +package extend.mj.player.rulestate; + + +import java.util.Map.Entry; + +import com.game.Util; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.mj.*; + +/** + * ��Ӧ��������״̬ + * + * + * 2017��8��30�� + * PRSelfWinState.java + */ +public class PRSelfWinState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + + EXRoom room = owner.getRoom(); + owner.winCard = owner.drawCard; + owner.winer = 1; + Util.removeCard(owner.cardInhand, owner.winCard, 1); + room.addAllScore(owner, room.di_fen,EXScore.WIN); + room.addAllPiaoNiaoScore(owner); + boolean jiabei = true; + boolean wuguijiabei = room.config.getBoolean(Config.ROOM_CONFIG_WUGUI_JIABEI); + if (wuguijiabei && room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG)) + { + if (Util.cardNum(Config.HONGZHONG, owner.cardInhand) <= 0 && owner.drawCard != Config.HONGZHONG) + { + room.addAllScore(owner, room.di_fen,EXScore.WIN); + room.addAllPiaoNiaoScore(owner); + for (Entry entry : room.playerMapById.entrySet()) { + EXPlayer gangPlayer = (EXPlayer) entry.getValue(); + for(int i = 0; i < gangPlayer.opCardList.size(); i++) + { + OpCard op_card = gangPlayer.opCardList.get(i); + if (op_card.type == RuleWeight.TYPE_SELF_KONG) + { + room.addAllScore(gangPlayer, 3, EXScore.KONG); + } + else if (op_card.type == RuleWeight.TYPE_KONG && op_card.seat == 0) + { + room.addAllScore(gangPlayer, 3, EXScore.KONG); + } + else if (op_card.type == RuleWeight.TYPE_KONG && op_card.seat > 0) + { + EXPlayer activePlayer = (EXPlayer)room.playerMapBySeat.get(op_card.seat); + room.addScore(gangPlayer,activePlayer, 3,EXScore.KONG); + } + } + } + } + } + for (Entry entry : room.playerMapById.entrySet()) { + if (entry.getKey().equals(owner.playerid)) { + continue; + } + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + fromPlayer.winer = 2; + } + + EXMainServer.gameCtr.winEvent(owner,owner.seat,owner.winCard); + room.niao_selfWin(owner,owner.winCard ); + owner.room.bankerSeat = owner.seat; + owner.settleLog.add(Config.SETTLE_ZIMO); + room.endGame(); + } + + @Override + public void toNextState(EXPlayer owner) { + // TODO Auto-generated method stub + + } + + @Override + public void exit(EXPlayer owner) { + // TODO Auto-generated method stub + + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + // TODO Auto-generated method stub + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDisCardTipState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDisCardTipState.java new file mode 100644 index 0000000..2e3d968 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDisCardTipState.java @@ -0,0 +1,54 @@ +package extend.mj.player.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.taurus.core.entity.ITObject; + +import extend.mj.EXActionEvent; +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; +import extend.mj.tip.Tip; + +/** + * ��ҳ�����ʾ״̬ + * + * + * 2017��8��30�� + * EXPlayerDisCardTipState.java + */ +public class EXPlayerDisCardTipState extends EXPlayerTipState { + + @Override + public void enter(EXPlayer owner) { + super.enter(owner); + owner.getRoom().tipMap.put(owner.playerid, owner.tipMgr); + } + + @Override + public void exit(EXPlayer owner) { + super.exit(owner); + owner.getRoom().tipMap.remove(owner.playerid); + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + super.execute(owner, cmd, gid, param); + if (cmd.equals(EXActionEvent.EVENT_ACTION)) { + ITObject netParam = (ITObject) param; + int id = netParam.getInt("id"); + owner.tipMgr.choicAction(id); + }else if(cmd.equals(ActionEvent.EVENT_TIMER_AUTO)) { + int id = 0; + for (Entry entry : owner.tipMgr.tipMap.entrySet()) { + Tip tip = entry.getValue(); + if(tip.type == RuleWeight.TYPE_WIN) { + id = tip.id; + break; + } + } + owner.tipMgr.choicAction(id); + } + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDiscardState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDiscardState.java new file mode 100644 index 0000000..c360325 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDiscardState.java @@ -0,0 +1,146 @@ +package extend.mj.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.Router; +import com.game.Util; +import com.game.player.state.PlayerPauseState; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import extend.mj.Config; +import extend.mj.EXActionEvent; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.room.state.EXRoomSetpState; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * �ȴ���ҳ���״̬ + * + */ +public class EXPlayerDiscardState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + EXMainServer.gameCtr.discardTipEvent(owner); + owner.startActionTimer(); + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } + + + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + public void reload(EXPlayer owner) { + owner.startActionTimer(); + } + + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + switch (cmd) { + case EXActionEvent.EVENT_DISCARD: + ITObject netParam = (ITObject) param; + int discard = netParam.getInt("card"); + ITArray card_list = netParam.getTArray("card_list"); + ITArray outcard_list = netParam.getTArray("outcard_list"); + if (card_list == null) { + card_list = TArray.newInstance(); + } + if (outcard_list == null) { + outcard_list = TArray.newInstance(); + } + + ArrayList tmpCardList = new ArrayList(); + for(int i = 0; i < card_list.size(); i++) + { + int card = card_list.getInt(i); + tmpCardList.add(card); + } + + ArrayList out_tmpCardList = new ArrayList(); + for(int i = 0; i < outcard_list.size(); i++) + { + int card = outcard_list.getInt(i); + out_tmpCardList.add(card); + } + + + Collections.sort(tmpCardList); + Collections.sort(out_tmpCardList); + + ArrayList tmpCardList2 = new ArrayList(); + tmpCardList2.addAll(owner.cardInhand); + Collections.sort(tmpCardList2); + + ArrayList out_tmpCardList2 = new ArrayList(); + out_tmpCardList2.addAll(owner.outcardList); + Collections.sort(out_tmpCardList2); + + if (!tmpCardList.equals(tmpCardList2) || !out_tmpCardList.equals(out_tmpCardList2)) + { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + if (!Util.checkCard(discard, owner.cardInhand)) { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + owner.louhu = false; + EXMainServer.gameCtr.outCard(owner, discard); + + if (owner.getRoom().tipMap.size() != 0) { + owner.stateMachine.changeState(Global.getState(PlayerPauseState.class)); + } else { + this.toNextState(owner); + } + break; + case ActionEvent.EVENT_TIMER_AUTO: + owner.louhu = false; + discard = owner.drawCard; + if(owner.drawCard == 0) { + discard = owner.cardInhand.get(owner.cardInhand.size() - 1); + } + if(discard == Config.HONGZHONG) { + for (Integer card : owner.cardInhand) { + if(card !=Config.HONGZHONG) { + discard = card; + break; + } + } + } + EXMainServer.gameCtr.outCard(owner, discard); + + if (owner.getRoom().tipMap.size() != 0) { + owner.stateMachine.changeState(Global.getState(PlayerPauseState.class)); + } else { + this.toNextState(owner); + } + break; + case ActionEvent.EVENT_ENTRUST: + owner.startActionTimer(); + break; + default: + break; + } + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawState.java new file mode 100644 index 0000000..bea12cf --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawState.java @@ -0,0 +1,232 @@ +package extend.mj.player.state; + +import com.data.cache.GroupMemberCache; +import com.game.Global; +import com.game.Util; +import com.game.state.StateBase; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import extend.mj.*; +import extend.mj.tip.Tip; +import extend.mj.uitl.WinCard; + +import java.util.ArrayList; + +/** + * ���ץ��״̬ + * + * + * 2017��8��30�� + * EXPlayerDrawState.java + */ +public class EXPlayerDrawState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + EXRoom room = owner.getRoom(); + if (room.card.cardList.size() == 0) { + room.liuju = true; + room.endGame(); + return; + + } + + ITObject config = room.config; + boolean qidui = config.getBoolean(Config.ROOM_CONFIG_QIDUI); + boolean hz_hu = config.getBoolean(Config.ROOM_CONFIG_HZ_HU); + boolean laizi = room.config.getBoolean(Config.ROOM_CONFIG_HONGZHONG); + + if(owner.seat == room.adminSeat) { + double rand = Math.random() % 100; + if (room.while_list && !owner.is_white && rand > room.white_value) + { + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + int drawCard = owner.drawCard = room.card.popsub(); + + WinCard win = new WinCard(owner.cardInhand, drawCard, Config.HONGZHONG, laizi,qidui); + if(!(hz_hu && win.zhong_count >0)) { + if (win.checkQidui() || win.tryWin(room)) { + if (room.card.cardList.size() != 0 && count++ <= 5) { + tempCardList.add(drawCard); + continue; + } + } + } + + owner.drawCard = drawCard; + break; + } while(true); + + room.card.cardList.addAll(tempCardList); + } + else + { + owner.drawCard = room.card.popsub(); + } + }else { + double rand = Math.random() % 100 * 100; + if (room.while_list && owner.is_white && rand > room.white_value) + { + Global.logger.info("dealcards playerid:"+owner.playerid+ " xingyuhao:"+owner.is_white+" white_value:"+room.white_value); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + int drawCard = room.card.pop(); + + if(!IsGoodCard(owner, drawCard, qidui, hz_hu, laizi)) { + if (room.card.cardList.size() != 0 && count++ <= 5) { + tempCardList.add(drawCard); + Global.logger.info("no white to hu:" + drawCard); + continue; + } + } + + owner.drawCard = drawCard; + break; + } while(true); + room.card.cardList.addAll(tempCardList); + } + else + { + if(owner.black_white_status == 2) { + double rand1 = Math.random() % 100 * 100; + if (rand1 <= owner.black_white_rate) { + Global.logger.info("dealcards playerid:"+owner.playerid+ " white_value:"+owner.black_white_rate); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + int drawCard = room.card.pop(); + + boolean flag = false; + if(IsGoodCard(owner, drawCard, qidui, hz_hu, laizi)) { + flag = true; + } + + if (!flag) { + if (room.card.cardList.size() > 0 && count++ <= 5) { + tempCardList.add(drawCard); + //Global.logger.info("not good card:" + drawCard + " for white player"); + continue; + } + } + + owner.drawCard = drawCard; + break; + } + while (true); + room.card.cardList.addAll(tempCardList); + } else { + owner.drawCard = room.card.pop(); + } + } + else if(owner.black_white_status == 1) { + double rand1 = Math.random() % 100 * 100; + if (rand1 <= owner.black_white_rate) { + Global.logger.info("dealcards playerid:"+owner.playerid+ " black_value:"+owner.black_white_rate); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + int drawCard = room.card.pop(); + + boolean flag = false; + if(IsGoodCard(owner, drawCard, qidui, hz_hu, laizi)) { + flag = true; + } + + if (flag) { + if (room.card.cardList.size() > 0 && count++ <= 5) { + tempCardList.add(drawCard); + //Global.logger.info("not good card:" + drawCard + " for white player"); + continue; + } + } + + owner.drawCard = drawCard; + break; + } + while (true); + room.card.cardList.addAll(tempCardList); + } else { + owner.drawCard = room.card.pop(); + } + } + else { + owner.drawCard = room.card.pop(); + } + } + } + + int leftCount = room.card.getCount(); + ((EXGameController)Global.gameCtr).getCard(owner, leftCount); + + EXMainServer.playerRuleMgr.condition(PlayerRuleManager.DRAW_RULE, owner); + } + + private boolean IsGoodCard(EXPlayer player, int drawCard, boolean qidui, boolean hz_hu, boolean laizi) { + if (drawCard == Config.HONGZHONG) + { + return true; + } + + if (Util.cardNum(drawCard, player.cardInhand) >= 2) + { + return true; + } + + for (int[] cardGroup : player.pongGroup) { + if (drawCard == cardGroup[0]) { + return true; + } + } + + WinCard win = new WinCard(player.cardInhand, drawCard, Config.HONGZHONG, laizi,qidui); + if(!(hz_hu && win.zhong_count >0)) { + if (win.checkQidui() || win.tryWin(player.getRoom())) { + return true; + } + } + + if (drawCard < 400) + { + if (drawCard % 100 <= 7) + { + if (Util.cardNum(drawCard+1, player.cardInhand) >= 1 && Util.cardNum(drawCard+2, player.cardInhand) >= 1) + { + return true; + } + } + + if (drawCard % 100 >= 3) + { + if (Util.cardNum(drawCard-1, player.cardInhand) >= 1 && Util.cardNum(drawCard-2, player.cardInhand) >= 1) + { + return true; + } + } + + if (drawCard % 100 >= 2 && drawCard % 100 <= 8) + { + if (Util.cardNum(drawCard-1, player.cardInhand) >= 1 && Util.cardNum(drawCard+1, player.cardInhand) >= 1) + { + return true; + } + } + } + + return false; + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(EXPlayerDiscardState.class)); + + } + + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawTipState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawTipState.java new file mode 100644 index 0000000..f2b5baf --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerDrawTipState.java @@ -0,0 +1,43 @@ +package extend.mj.player.state; + +import java.util.Map.Entry; + +import com.game.ActionEvent; +import com.game.Global; +import com.taurus.core.entity.ITObject; + +import extend.mj.EXActionEvent; +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; +import extend.mj.tip.Tip; + +/** + * ���ץ����ʾ״̬ + * + */ +public class EXPlayerDrawTipState extends EXPlayerTipState { + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + super.execute(owner, cmd, gid, param); + if (cmd.equals(EXActionEvent.EVENT_ACTION)) { + ITObject netParam = (ITObject) param; + int id = netParam.getInt("id"); + boolean win = (owner.tipMgr.weight &RuleWeight.SELF_WIN)!=0 ; + if(Global.gameId == 1 && win && id == 0)return; + owner.tipMgr.doAction(id); + }else if(cmd.equals(ActionEvent.EVENT_TIMER_AUTO)) { + int id = 0; + for (Entry entry : owner.tipMgr.tipMap.entrySet()) { + Tip tip = entry.getValue(); + if(tip.type == RuleWeight.TYPE_WIN) { + id = tip.id; + break; + } + } + owner.tipMgr.doAction(id); + } + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerKongWinState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerKongWinState.java new file mode 100644 index 0000000..441c172 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerKongWinState.java @@ -0,0 +1,42 @@ +package extend.mj.player.state; + +import com.taurus.core.entity.ITObject; + +import extend.mj.EXActionEvent; +import extend.mj.EXPlayer; + +/** + * ���������ʾ�ȴ� + * + * + * 2017��8��30�� + * EXPlayerKongWinState.java + */ +public class EXPlayerKongWinState extends EXPlayerTipState{ + + @Override + public void enter(EXPlayer owner) { + // TODO Auto-generated method stub + super.enter(owner); + owner.getRoom().tipMap.put(owner.playerid, owner.tipMgr); + + } + + @Override + public void exit(EXPlayer owner) { + // TODO Auto-generated method stub + super.exit(owner); + owner.getRoom().tipMap.remove(owner.playerid); + + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + if (cmd.equals(EXActionEvent.EVENT_ACTION)) { + ITObject netParam = (ITObject) param; + int id = netParam.getInt("id"); + owner.tipMgr.choicAction(id); + } + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerPiaoNiaoTipState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerPiaoNiaoTipState.java new file mode 100644 index 0000000..1263fff --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerPiaoNiaoTipState.java @@ -0,0 +1,54 @@ +package extend.mj.player.state; + + +import com.game.ActionEvent; +import com.game.Global; +import com.game.player.state.PlayerWaitState; +import com.taurus.core.entity.ITObject; + +import extend.mj.EXActionEvent; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; + +/** + * Ʊ����ʾ״̬ + * + */ +public class EXPlayerPiaoNiaoTipState extends EXPlayerTipState { + + @Override + public void enter(EXPlayer owner) { + if(!owner.isEntrust()) { + EXMainServer.gameCtr.piaoNiaoTipEvent(owner); + owner.startActionTimer(); + }else{ + _action(owner, 0, 0); + } + } + @Override + public void exit(EXPlayer owner) { + super.exit(owner); + } + + private void _action(EXPlayer owner,int id,int gid) { + owner.piaoNiao = id; + owner.tipMgr.clean(); + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.getRoom().piaoNiaoCount --; + EXMainServer.gameCtr.piaoNiaoEvent(owner); + owner.getRoom().stateMachine.execute(EXActionEvent.EVENT_PIAO_NIAO, gid, null); + } + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + super.execute(owner, cmd, gid, param); + if (cmd.equals(EXActionEvent.EVENT_ACTION)) { + ITObject netParam = (ITObject) param; + int id = netParam.getInt("id"); + _action(owner,id,gid); + }else if(cmd.equals(ActionEvent.EVENT_TIMER_AUTO)) { + _action(owner,0,gid); + } + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerTipState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerTipState.java new file mode 100644 index 0000000..fad0cea --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerTipState.java @@ -0,0 +1,49 @@ +package extend.mj.player.state; + +import com.game.ActionEvent; +import com.game.state.StateBase; + +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; + +/** + * �����ʾ������� + * + * + * 2017��8��30�� + * EXPlayerTipState.java + */ +public abstract class EXPlayerTipState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + if(!owner.isEntrust()) { + EXMainServer.gameCtr.tipEvent(owner); + } + owner.startActionTimer(); + } + + @SuppressWarnings("unchecked") + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.lastState.toNextState(owner); + } + + @Override + public void exit(EXPlayer owner) { + owner.tipMgr.clean(); + owner.stopActionTimer(); + } + + public void reload(EXPlayer owner) { + super.reload(owner); + this.enter(owner); + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + if(cmd.equals(ActionEvent.EVENT_ENTRUST)) { + owner.startActionTimer(); + } + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitKongWinState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitKongWinState.java new file mode 100644 index 0000000..dff6a34 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitKongWinState.java @@ -0,0 +1,24 @@ +package extend.mj.player.state; + +import com.game.state.StateBase; + +import extend.mj.EXPlayer; + +/** + * ������ҵȴ��������ǹ�ܺ� + * + * + * 2017��8��30�� + * EXPlayerWaitKongWinState.java + */ +public class EXPlayerWaitKongWinState extends StateBase{ + + @SuppressWarnings("unchecked") + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.lastState.toNextState(owner); + + } + + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitState.java b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitState.java new file mode 100644 index 0000000..858aee0 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/player/state/EXPlayerWaitState.java @@ -0,0 +1,39 @@ +package extend.mj.player.state; + + +import com.game.state.StateBase; + +import extend.mj.EXActionEvent; +import extend.mj.EXMainServer; +import extend.mj.EXPlayer; +import extend.mj.PlayerRuleManager; + +/** + * ��ҵȴ�״̬ + * + * + * 2017��8��30�� + * EXPlayerWaitState.java + */ +public class EXPlayerWaitState extends StateBase { + + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + // TODO Auto-generated method stub + switch (cmd) { + case EXActionEvent.EVENT_OTHER_DISCARD: + EXMainServer.playerRuleMgr.condition( PlayerRuleManager.OTHER_DISCARD_RULE , owner); + break; + case EXActionEvent.EVENT_KONG_WIN: + owner.forceCheckWin = true; + EXMainServer.playerRuleMgr.condition( PlayerRuleManager.KONG_HU_RULE , owner); + owner.forceCheckWin = false; + break; + default: + break; + } + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomDealState.java b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomDealState.java new file mode 100644 index 0000000..c422f36 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomDealState.java @@ -0,0 +1,147 @@ +package extend.mj.room.state; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import com.game.Global; +import com.game.data.Player; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import com.taurus.permanent.TPServer; +import extend.mj.*; +import extend.mj.player.state.EXPlayerPiaoNiaoTipState; + +/** + * ���䷢��״̬ + * + * + * 2017��8��30�� + * EXRoomDealState.java + */ +public class EXRoomDealState extends StateBase { + + @Override + public void enter(EXRoom owner) { + owner.card.init(); + if (owner.bankerSeat == 0) { + owner.bankerSeat = 1; + } +// owner.isplaying = true; +// owner.round += 1; + + int piao_niao = owner.config.getInt(Config.ROOM_CONFIG_PIAO_NIAO); + if(piao_niao > 0) { + if(piao_niao == 1) { + owner.piaoNiaoCount = owner.maxPlayers; + for (Entry entry : owner.playerMapById.entrySet()) { + Player player = entry.getValue(); + player.stateMachine.changeState(Global.getState(EXPlayerPiaoNiaoTipState.class)); + } + } + else if (piao_niao == 2) + { + owner.piaoNiaoCount = 0; + int opt = owner.config.getInt(Config.ROOM_CONFIG_PIAO_NIAO_OPT); + int piao_fen = 1; + if (opt == 0) + { + piao_fen = 1; + } + else if (opt == 1) + { + piao_fen = 2; + } + else if (opt == 2) + { + piao_fen = 3; + } + + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + player.piaoNiao = piao_fen; + player.tipMgr.clean(); + player.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + player.getRoom().piaoNiaoCount --; + EXMainServer.gameCtr.piaoNiaoEvent(player); + } + this.toNextState(owner); + } + else { + this.toNextState(owner); + } + } else { + this.toNextState(owner); + } + } + + public static void timer(EXRoom owner) { + + TPServer.me().getTimerPool().schedule(new Runnable() { + + @Override + public void run() { + + if (owner == null) { + Global.logger.error("room is null"); + return; + } + + if (owner.isDestroy) + return; + + owner.enqueueRunnable(new Runnable() { + + @Override + public void run() { + ITObject param = new TObject(); + param.putInt("bank_seat", owner.bankerSeat); + EXMainServer.gameCtr.dealCard(owner); + owner.playBackData = new EXPlayBack(owner); + owner.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } + }); + } + }, 4000, TimeUnit.MILLISECONDS); + } + + @Override + public void toNextState(EXRoom owner) { + boolean donghua = false; + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.xi_pai) + { + donghua = true; + break; + } + } + + if (donghua) + { + owner.notifyXiPai(); + //启动定时器 + timer(owner); + } + else { + ITObject param = new TObject(); + param.putInt("bank_seat", owner.bankerSeat); + EXMainServer.gameCtr.dealCard(owner); + owner.playBackData = new EXPlayBack(owner); + owner.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } + } + + public void execute(EXRoom owner, String cmd, int gid, Object param) { + if(cmd.equals(EXActionEvent.EVENT_PIAO_NIAO)) { + if(owner.piaoNiaoCount==0) { + this.toNextState(owner); + } + } + + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomSetpState.java b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomSetpState.java new file mode 100644 index 0000000..47fbd44 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomSetpState.java @@ -0,0 +1,42 @@ +package extend.mj.room.state; + + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.mj.EXMainServer; +import extend.mj.EXRoom; +import extend.mj.player.state.EXPlayerDrawState; + +/** + * ����ת����λ + * + * + * 2017��8��30�� + * EXRoomSetpState.java + */ +public class EXRoomSetpState extends StateBase { + + @Override + public void enter(EXRoom owner) { + Player player; + // TODO Auto-generated method stub + if (owner.activeSeat == 0) { + player = owner.playerMapBySeat.get(owner.bankerSeat); + + } else { + player = owner.playerMapBySeat.get(owner.activeSeat); + int nextSeat = player.nextSeat; + player = owner.playerMapBySeat.get(nextSeat); + + } + + EXMainServer.gameCtr.changeActiveSeat(owner,player.seat); + + player.stateMachine.changeState(Global.getState(EXPlayerDrawState.class)); + + this.toNextState(owner); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomStartGameState.java b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomStartGameState.java new file mode 100644 index 0000000..1272100 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/room/state/EXRoomStartGameState.java @@ -0,0 +1,33 @@ +package extend.mj.room.state; + +import com.game.Global; +import com.game.state.StateBase; + +import extend.mj.EXRoom; + +/** + * ���俪ʼ״̬ + * + */ +public class EXRoomStartGameState extends StateBase { + + @Override + public void enter(EXRoom owner) { +// owner.readyCount = 0; +// for (Entry entry : owner.playerMapById.entrySet()) { +// Player player = entry.getValue(); +// player.ready = false; +// player.clear(); +// player.initSeat(); +// } + owner.startGame(); + + this.toNextState(owner); + } + + @Override + public void toNextState(EXRoom owner) { + owner.stateMachine.changeState(Global.getState(EXRoomDealState.class)); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/tip/Action.java b/game_mj_hongzhong/src/main/java/extend/mj/tip/Action.java new file mode 100644 index 0000000..454d9ca --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/tip/Action.java @@ -0,0 +1,27 @@ +package extend.mj.tip; + + +import extend.mj.EXPlayer; + +/** + * + * + + */ +public class Action { + + public Tip tip; + public EXPlayer player; + + public Action(Tip tip, EXPlayer player) { + this.tip = tip; + this.player = player; + + } + + public void run() { + this.player.initOpCard(tip.opcard); + this.tip.rule.action(this.player,this.tip); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/tip/IRuleBase.java b/game_mj_hongzhong/src/main/java/extend/mj/tip/IRuleBase.java new file mode 100644 index 0000000..79f1ab8 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/tip/IRuleBase.java @@ -0,0 +1,27 @@ +package extend.mj.tip; + +import extend.mj.EXPlayer; + +/** + * ����������� + * + * + * 2017��8��30�� + * RuleBase.java + */ +public interface IRuleBase { + + /** + * ������� + * @param player + * @return + */ + public abstract boolean condition(EXPlayer player ); + + /** + * ִ�иù��� + * @param player + */ + public abstract void action(EXPlayer player ,Tip tip); + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/tip/Tip.java b/game_mj_hongzhong/src/main/java/extend/mj/tip/Tip.java new file mode 100644 index 0000000..434343a --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/tip/Tip.java @@ -0,0 +1,40 @@ +package extend.mj.tip; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +/** + * tip������ + * + * + * + * 2017��8��30�� Tip.java + */ +public class Tip { + public int id; + public IRuleBase rule; + public int weight; + public int card; + public ITArray opcard; + public int winType; + public int type; + + public Tip(int card, ITArray opcard, int weight, IRuleBase rule, int type) { + this.rule = rule; + this.weight = weight; + this.opcard = opcard; + this.card = card; + this.type = type; + } + + public ITObject toMP() { + ITObject tipMp = new TObject(); + tipMp.putInt("id", id); + tipMp.putInt("weight", weight); + tipMp.putInt("type", type); + tipMp.putInt("card", card); + tipMp.putTArray("opcard", opcard); + return tipMp; + } +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/tip/TipManager.java b/game_mj_hongzhong/src/main/java/extend/mj/tip/TipManager.java new file mode 100644 index 0000000..b8361ec --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/tip/TipManager.java @@ -0,0 +1,125 @@ +package extend.mj.tip; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Global; +import com.game.player.state.PlayerWaitState; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; + +import extend.mj.EXPlayer; +import extend.mj.RuleWeight; + +/** + * + * + * + * 2017��9��18�� TipManager.java + */ +public class TipManager { + + private int id = 0; + + public Map tipMap = null; + public Tip actionTip; + public int weight = 0; + public EXPlayer owner = null; + + public TipManager(EXPlayer owner) { + this.tipMap = new HashMap(); + this.owner = owner; + + } + + public void addTip(Tip tip) { + int id = this.getId(); + this.weight = this.weight | tip.weight; + tip.id = id; + this.tipMap.put(id, tip); + } + + private void checkLouhu() { + for (Entry entry : this.tipMap.entrySet()) { + Tip tip = entry.getValue(); + if(tip.type == RuleWeight.TYPE_WIN) { + this.owner.louhu = true; + break; + } + } + } + + public void choicAction(int id) { + if (id == 0) { + this.checkLouhu(); + this.owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + this.owner.getRoom().checkAction(); + } else if (this.tipMap.containsKey(id)) { + Tip tip = this.tipMap.get(id); + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.getRoom().addAction(new Action(tip, owner)); + } else { + throw new Error("tip map has no id" + id); + } + } + + @SuppressWarnings("unchecked") + public void doAction(int id) { + if (id == 0) { + this.checkLouhu(); + this.owner.stateMachine.lastState.toNextState(owner); + } else if (this.tipMap.containsKey(id)) { + Tip tip = this.tipMap.get(id); + owner.initOpCard(tip.opcard); + tip.rule.action(owner,tip); + + } else { + throw new Error("tip map has no id" + id); + } + + } + + public ITObject toMP() { + ITObject mp = new TObject(); + mp.putInt("weight", this.weight); + ITArray tipList = new TArray(); + for (Entry entry : this.tipMap.entrySet()) { + Tip tip = entry.getValue(); + ITObject tipMp = tip.toMP(); + tipList.addTObject(tipMp); + } + mp.putTArray("tip_list", tipList); + return mp; + + } + + private int getId() { + this.id += 1; + return this.id; + } + + public int getWeightest() { + int result = 0; + for (Entry entry : this.tipMap.entrySet()) { + Tip tip = entry.getValue(); + if (tip.weight > result) { + result = tip.weight; + } + } + return result; + } + + public void cleanTip() { + this.weight = 0; + this.id = 0; + this.tipMap = new HashMap(); + } + + public void clean() { + this.cleanTip(); + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/uitl/CardUtil.java b/game_mj_hongzhong/src/main/java/extend/mj/uitl/CardUtil.java new file mode 100644 index 0000000..6d95053 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/uitl/CardUtil.java @@ -0,0 +1,32 @@ +package extend.mj.uitl; + +import java.util.List; + +import extend.mj.OpCard; + +public class CardUtil { + + + static public void removeGroup(List group, int card) { + for (int i = 0; i < group.size(); i++) { + int[] cardArray = group.get(i); + if (cardArray[0] == card) { + group.remove(cardArray); + return; + } + + } + } + + static public void removeOpcard(List opcards, OpCard param) { + for (int i = 0; i < opcards.size(); i++) { + if (param.card == opcards.get(i).card) { + opcards.remove(i); + return; + } + + } + + } + +} diff --git a/game_mj_hongzhong/src/main/java/extend/mj/uitl/WinCard.java b/game_mj_hongzhong/src/main/java/extend/mj/uitl/WinCard.java new file mode 100644 index 0000000..f51e9c6 --- /dev/null +++ b/game_mj_hongzhong/src/main/java/extend/mj/uitl/WinCard.java @@ -0,0 +1,363 @@ +package extend.mj.uitl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +import com.game.Util; +import extend.mj.Config; +import extend.mj.EXRoom; + +public class WinCard { + + public int pair_count; + public Stack> stack; + public List cardList; + public int zhong_count; + public int zhongid = 0; + public boolean qidui; + public static int zhongWinNum = 4; + + private void push(List cardGroup) { + this.stack.push(cardGroup); + } + + private void rollBack() { + List cardGroup = this.stack.pop(); + for (Integer card : cardGroup) { + if (card == zhongid) { + this.zhong_count += 1; + } else { + this.cardList.add(card); + } + } + Collections.sort(this.cardList); + } + + private boolean tryShunzi(int card) { + if (card < 400 && card % 100 > 7) { + return false; + } + if (Util.checkCard(card + 1, this.cardList) && Util.checkCard(card + 2, this.cardList)) { + Util.removeCard(this.cardList, card, 1); + Util.removeCard(this.cardList, card + 1, 1); + Util.removeCard(this.cardList, card + 2, 1); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(card + 1); + cardGroup.add(card + 2); + this.push(cardGroup); + return true; + } + return false; + } + + private boolean tryKezi(int card) { + + if (Util.checkCardAndRomve(card, this.cardList, 3)) { +// CardUtil.removeCard(this.cardList, card, 3); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(card); + cardGroup.add(card); + this.push(cardGroup); + return true; + } + return false; + + } + + private boolean tryPair(int card) { + if (this.pair_count > 0) { + return false; + } + + if (Util.checkCardAndRomve(card, this.cardList, 2)) { +// CardUtil.removeCard(this.cardList, card, 2); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(card); + this.push(cardGroup); + this.pair_count = 1; + return true; + } + return false; + + } + + private boolean tryKezi1Zhong(int card) { + + if (this.zhong_count >= 1 && Util.checkCardAndRomve(card, this.cardList,2)) { +// CardUtil.removeCard(this.cardList, card, 2); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(card); + cardGroup.add(this.zhongid); + this.zhong_count -= 1; + this.push(cardGroup); + return true; + } + return false; + + } + + private boolean tryKezi2Zhong(int card) { + + if (this.zhong_count >= 2 && Util.checkCardAndRomve(card, this.cardList,1)) { +// CardUtil.removeCard(this.cardList, card, 1); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(this.zhongid); + cardGroup.add(this.zhongid); + this.zhong_count -= 2; + this.push(cardGroup); + return true; + } + return false; + + } + + private boolean tryShunzi1Zhong(int card) { + if (card % 100 > 8) { + return false; + } + + if (this.zhong_count < 1) { + return false; + } + + if (Util.checkCard(card + 1, this.cardList)) { + Util.removeCard(cardList, card, 1); + Util.removeCard(cardList, card + 1, 1); + this.zhong_count -= 1; + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(card + 1); + cardGroup.add(this.zhongid); + this.push(cardGroup); + return true; + } + + if (Util.checkCard(card + 2, this.cardList) && ((card + 1) % 100 != 0)) { + Util.removeCard(cardList, card, 1); + Util.removeCard(cardList, card + 2, 1); + this.zhong_count -= 1; + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(this.zhongid); + cardGroup.add(card + 2); + this.push(cardGroup); + return true; + } + + return false; + + } + + private boolean tryPair1Zhong(int card) { + + if (this.pair_count > 0) { + return false; + } + if (this.zhong_count < 1) { + return false; + } + Util.removeCard(cardList, card, 1); + List cardGroup = new ArrayList(); + cardGroup.add(card); + cardGroup.add(this.zhongid); + this.push(cardGroup); + this.zhong_count -= 1; + this.pair_count = 1; + return true; + + } + + private boolean tryPair2Zhong() { + + if (this.pair_count > 0) { + return false; + } + if (this.zhong_count < 2) { + return false; + } + List cardGroup = new ArrayList(); + cardGroup.add(this.zhongid); + cardGroup.add(this.zhongid); + this.push(cardGroup); + this.pair_count = 1; + this.zhong_count -= 2; + return true; + } + + public boolean tryWin(EXRoom room) { + if (room.config.getBoolean(Config.ROOM_CONFIG_LAIZI4_HU)) + { + if (this.zhong_count == zhongWinNum) { + return true; + } + } + + if (this.cardList.size() == 0 && this.pair_count == 1) { + return true; + } + if (this.cardList.size() == 0 && this.pair_count == 0) { + return tryPair2Zhong(); + } + + if (this.cardList.size() == 0) { + return false; + } + int activeCard = this.cardList.get(0); + + if (tryPair(activeCard)) { + if (tryWin(room)) { + return true; + } + this.pair_count = 0; + this.rollBack(); + + } + + if (tryKezi(activeCard)) { + if (tryWin(room)) { + return true; + } + this.rollBack(); + + } + if (tryShunzi(activeCard)) { + if (tryWin(room)) { + return true; + } + this.rollBack(); + + } + + if (tryKezi1Zhong(activeCard)) { + if (tryWin(room)) { + return true; + } + this.rollBack(); + + } + if (tryKezi2Zhong(activeCard)) { + if (tryWin(room)) { + return true; + } + this.rollBack(); + + } + if (tryShunzi1Zhong(activeCard)) { + if (tryWin(room)) { + return true; + } + this.rollBack(); + + } + if (tryPair1Zhong(activeCard)) { + if (tryWin(room)) { + return true; + } + this.pair_count = 0; + this.rollBack(); + } + return false; + } + + public WinCard(List cardInhand, int addCard, int zhongid, boolean isZhong, boolean qidui) { + this.stack = new Stack>(); + this.cardList = new ArrayList(); + this.cardList.addAll(cardInhand); + this.qidui = qidui; + this.cardList.add(addCard); + if (isZhong) { + this.zhongid = zhongid; + this.zhong_count = Util.cardNum(zhongid, this.cardList); + Util.removeCard(this.cardList, zhongid, this.zhong_count); + } + Collections.sort(this.cardList); + } + + public WinCard(List cardInhand, int zhongid, boolean isZhong, boolean qidui) { + this.stack = new Stack>(); + this.cardList = new ArrayList(); + this.qidui = qidui; + this.cardList.addAll(cardInhand); + if (isZhong) { + this.zhongid = zhongid; + this.zhong_count = Util.cardNum(zhongid, this.cardList); + Util.removeCard(this.cardList, zhongid, this.zhong_count); + } + Collections.sort(this.cardList); + + } + + public boolean checkQidui() { + if (!this.qidui) + return false; + if ((this.cardList.size() + zhong_count) != 14) + return false; + List cardlist = new ArrayList<>(); + cardlist.addAll(this.cardList); + hongzhong_count = this.zhong_count; + return isQdPari(cardlist); + } + + private int hongzhong_count = 0; + private int qidui_pari_count = 0; + boolean isQdPari(List cardlist) { + if(qidui_pari_count == 7)return true; + if (cardlist.size() == 0)return true; + int card = cardlist.get(0); + if (Util.cardNum(card, cardlist) >= 2) { + Util.removeCard(cardlist, card, 2); + qidui_pari_count++; + if (isQdPari(cardlist)) { + return true; + } + } + + if (this.hongzhong_count > 0) { + Util.removeCard(cardlist, card, 1); + this.hongzhong_count--; + qidui_pari_count++; + if (isQdPari(cardlist)) { + return true; + } + } + return false; + + } + + public static void main(String[] args) { + + + long time = System.currentTimeMillis(); +// for(int i=0;i<1000000;++i) { + ArrayList cardInhand = new ArrayList(); + cardInhand.add(101); + cardInhand.add(102); + cardInhand.add(103); + cardInhand.add(104); + cardInhand.add(105); + cardInhand.add(106); + + cardInhand.add(204); + cardInhand.add(205); + cardInhand.add(206); + cardInhand.add(201); + cardInhand.add(202); + cardInhand.add(203); + + cardInhand.add(301); + cardInhand.add(301); + cardInhand.add(301); + cardInhand.add(108); + WinCard win = new WinCard(cardInhand,45,45,true,false); +// } + System.out.println( System.currentTimeMillis() - time); + } + +} diff --git a/game_mj_hongzhong/src/test/java/game_mj_hongzhong/MainHongzhong.java b/game_mj_hongzhong/src/test/java/game_mj_hongzhong/MainHongzhong.java new file mode 100644 index 0000000..23f8235 --- /dev/null +++ b/game_mj_hongzhong/src/test/java/game_mj_hongzhong/MainHongzhong.java @@ -0,0 +1,9 @@ +package game_mj_hongzhong; + +import com.taurus.permanent.TPServer; + +public class MainHongzhong { + public static void main(String[] args) { + TPServer.me().start(); + } +} diff --git a/game_pk_duoduo/.idea/compiler.xml b/game_pk_duoduo/.idea/compiler.xml new file mode 100644 index 0000000..da870f6 --- /dev/null +++ b/game_pk_duoduo/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/game_pk_duoduo/.idea/encodings.xml b/game_pk_duoduo/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/game_pk_duoduo/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/game_pk_duoduo/.idea/jarRepositories.xml b/game_pk_duoduo/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/game_pk_duoduo/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/game_pk_duoduo/.idea/misc.xml b/game_pk_duoduo/.idea/misc.xml new file mode 100644 index 0000000..d5cd614 --- /dev/null +++ b/game_pk_duoduo/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/game_pk_duoduo/.idea/vcs.xml b/game_pk_duoduo/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/game_pk_duoduo/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/game_pk_duoduo/config/game-config.xml b/game_pk_duoduo/config/game-config.xml new file mode 100644 index 0000000..53a7f40 --- /dev/null +++ b/game_pk_duoduo/config/game-config.xml @@ -0,0 +1,10 @@ + + + + 192.168.1.3 + 192.168.1.3 + 6841 + 8830 + 66 + true + diff --git a/game_pk_duoduo/config/log4j.properties b/game_pk_duoduo/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/game_pk_duoduo/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/game_pk_duoduo/config/taurus-core.xml b/game_pk_duoduo/config/taurus-core.xml new file mode 100644 index 0000000..692935b --- /dev/null +++ b/game_pk_duoduo/config/taurus-core.xml @@ -0,0 +1,95 @@ + + + log4j.properties + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://127.0.0.1:8060/wb_game + wb_game + 363b76546c + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 200 + + 8 + + 1 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + diff --git a/game_pk_duoduo/config/taurus-permanent.xml b/game_pk_duoduo/config/taurus-permanent.xml new file mode 100644 index 0000000..e3ae95e --- /dev/null +++ b/game_pk_duoduo/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 2 + + 100 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 2 + 3 + 10 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 8080 +
+ + + + extension - test + extend.pk.EXMainServer + + + + + Sys + 4 + 16 + 60000 + 20000 + + + + + Ext + 4 + 16 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/game_pk_duoduo/pom.xml b/game_pk_duoduo/pom.xml new file mode 100644 index 0000000..d1b1111 --- /dev/null +++ b/game_pk_duoduo/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + com.game + game_pk_duoduo + 1.0.0 + jar + + game_pk_duoduo + http://maven.apache.org + + + UTF-8 + + + + + + com.game + game_common + 1.0.0 + + + + + game_duoduo_puke + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + + diff --git a/game_pk_duoduo/src/main/java/extend/pk/CardGroup.java b/game_pk_duoduo/src/main/java/extend/pk/CardGroup.java new file mode 100644 index 0000000..fc7ee92 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/CardGroup.java @@ -0,0 +1,45 @@ +package extend.pk; + +import java.util.List; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import extend.pk.uitl.CardConfig; + +public class CardGroup { + /** + * 当前type + */ + public CardConfig config; + + public int min_card; + /** + * 长度 + */ + public int len = 1; + + public List card_list; + + public ITArray card_list_mp; + + public ITObject toObject(boolean card_size) { + ITObject obj = TObject.newInstance(); + if (card_size) { + obj.putInt("card_size", card_list.size()); + } else { + obj.putTArray("card_list", card_list_mp); + } + + obj.putInt("type", config.type); + obj.putInt("min_card", min_card); + obj.putInt("len", len); + return obj; + } + + public String toString() { + return "{type:" + config + " min_card:" + min_card + " len:" + len + " list:" + card_list + "}"; + } + +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/CardObj.java b/game_pk_duoduo/src/main/java/extend/pk/CardObj.java new file mode 100644 index 0000000..bc2d762 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/CardObj.java @@ -0,0 +1,21 @@ +package extend.pk; + +public class CardObj implements Comparable{ + public int card; + public int cardMod; + + public CardObj(int card) { + this.card = card; + this.cardMod = card % 100; + } + + @Override + public int compareTo(CardObj paramT) { + return cardMod == paramT.cardMod ? 0 : cardMod < paramT.cardMod ? -1 : 1; + } + + @Override + public String toString() { + return card + ""; + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/Config.java b/game_pk_duoduo/src/main/java/extend/pk/Config.java new file mode 100644 index 0000000..ee87a41 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/Config.java @@ -0,0 +1,140 @@ +package extend.pk; + +public class Config { + + public static final int XIPAI_SCORE = 10; + + /** + * 玩家的初始手牌数 + */ + public static final String ROOM_CONFIG_CARDNUM = "leaf"; + + /** + * 首局出牌规则 + */ + public static final String ROOM_CONFIG_RULE = "rule"; + + /** + * 第一局系统随机选一张先出,随后赢家先出 + */ + public static final int RULE_RANDOM = 2; + + /** + * 可不必出 + */ + public static final String ROOM_CONFIG_WILL_BE_OUT = "willBeOut"; + + /** + * 三张不带 + */ + public static final String ROOM_CONFIG_THREE_NOBELT = "threeNoBelt"; + + /** + * 特殊加分 + */ + public static final String ROOM_CONFIG_SPECIL_ADD = "specilAdd"; + + // -------------------------------牌类型--------------------------------- + /** + * 单牌 + */ + public final static int TYPE_DANPAI = 1; + /** + * 对子 + */ + public final static int TYPE_DUIZI = 2; + + /** + * 3不带 + */ + public final static int TYPE_3 = 10; + + /** + * 炸 + */ + public final static int TYPE_ZHA = 8; + + // -------------------------------协议--------------------------------- + + public static final String GAME_EVT_MING_PAI = "2117"; + /** + * 发牌协议 + */ + public static final String GAME_EVT_PLAYER_DEAL = "2011"; + /** + * 出牌 + */ + public static final String GAME_DIS_CARD = "1013"; + /** + * 不出 + */ + public static final String GAME_DIS_PASS = "1014"; + /** + * + */ + public static final String GAME_PIAO = "1015"; + /** + * 出牌事件 + */ + public static final String GAME_EVT_DISCARD = "2021"; + /** + * 出牌提示事件 + */ + public static final String GAME_EVT_DISCARD_TIP = "2004"; + /** + * 转盘指向事件 + */ + public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "2016"; + /** + * pass事件 + */ + public static final String GAME_EVT_PASS = "2030"; + /** + * 更新炸弹分数 + */ + public static final String GAME_EVT_UPDATE_BOM_SCORE = "2118"; + + /** + * 小结算 + */ + public static final String GAME_EVT_RESULT1 = "2007"; + +// /** +// * 获取下局指定牌型协议 +// */ +// public static final String GAME_EVT_NEEDCARDS = "888"; + +// /** +// * 生成下一幅牌 +// */ +// public static final String GAME_NEXTCARD = "8881"; +// +// /** +// * 发送下一幅牌 +// */ +// public static final String GAME_EVT_NEXTCARD = "8882"; + +// /** +// * 飘鸟提示 +// */ +// public static final String GAME_EVT_PIAO_TIP = "2031"; +// public static final String GAME_EVT_PIAO = "2032"; + + // 炸弹分数 + public static final String GAME_EVT_BOMB_SCORE = "2110"; + + /** + * 出牌错误 + */ + public static final String GAME_EVT_PUT_ERROR = "2111"; + + public static final int PUT_ERROR_MUST_OUT_MIN = 0; + public static final int PUT_ERROR_INVALID_TYPE = 1; + public static final int PUT_ERROR_MUST_OUT_MAX = 2; + public static final int PUT_ERROR_BOMB_CHAI = 3; + + public static final String SETTLE_WIN_COUNT = "winnum"; + public static final String SETTLE_CHUNTIAN_COUNT = "springnum"; + public static final String SETTLE_BOMB_COUNT = "boomnum"; + public static final String SETTLE_MAX_SCORE = "maxscore"; +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXActionEvent.java b/game_pk_duoduo/src/main/java/extend/pk/EXActionEvent.java new file mode 100644 index 0000000..b94a22c --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXActionEvent.java @@ -0,0 +1,10 @@ +package extend.pk; + +import com.game.ActionEvent; + +public class EXActionEvent extends ActionEvent{ + + public static final String EVENT_DISCARD = "1013"; + public static final String EVENT_PASS = "1014"; + public static final String EVENT_PIAO= "1015"; +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXGameController.java b/game_pk_duoduo/src/main/java/extend/pk/EXGameController.java new file mode 100644 index 0000000..4ecf7a0 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXGameController.java @@ -0,0 +1,878 @@ +package extend.pk; + +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import com.game.Constant; +import com.game.GameController; +import com.game.Global; +import com.game.data.Player; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.permanent.data.Session; + +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + +/** + * + * + */ +public class EXGameController extends GameController { + + public EXGameController() { + super(); + } + + @ActionKey(Config.GAME_DIS_CARD) + public void RouterDisCard(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_DISCARD, 0, params); + } + + @ActionKey(Config.GAME_DIS_PASS) + public void RouterDisPass(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_PASS, 0, params); + } + + @ActionKey(Config.GAME_PIAO) + public void RouterPiao(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_PIAO, 0, params); + } + +// @ActionKey(Config.GAME_EVT_NEEDCARDS) +// public void needCards(Session sender, ITObject params, int gid, EXPlayer owner) { +// Jedis jedis1 = Redis.use("group1_db1").getJedis(); +// Boolean is_pk_can_choice = false; +// String key = "pk_can_choice"; +// try { +// if (jedis1.hget("pk_can_choice", Global.gameId + "") == null) { +// return; +// } +// String pk_can_choice = jedis1.hget(key, Global.gameId + ""); +// String[] choices = pk_can_choice.split(","); +// for (String playerId : choices) { +// if (owner.playerid == Integer.parseInt(playerId)) { +// is_pk_can_choice = true; +// } +// } +// if (is_pk_can_choice == false) { +// return; +// } +// } catch (Exception e) { +// Global.logger.error(e); +// } finally { +// jedis1.close(); +// } +// owner.nextCardInhand.clear(); +// String choic = params.getString("choic"); +// +// if (choic.equalsIgnoreCase("first") && owner.isChoice) { +// List list = CardUtil.toList(params.getTArray("first")); +// owner.nextCardInhand = list; +// } +// if (choic.equalsIgnoreCase("second") && owner.isChoice) { +// List list = CardUtil.toList(params.getTArray("second")); +// owner.nextCardInhand = list; +// } +// if (choic.equalsIgnoreCase("three") && owner.isChoice) { +// List list = CardUtil.toList(params.getTArray("three")); +// owner.nextCardInhand = list; +// } +// for (Entry entry : owner.getRoom().playerMapById.entrySet()) { +// EXPlayer player = (EXPlayer) entry.getValue(); +// if (player.playerid == owner.playerid) { +// continue; +// } +// if (player.nextCardInhand.size() == 0) { +// if (choic.equalsIgnoreCase("second")) { +// player.nextCardInhand = CardUtil.toList(params.getTArray("three")); +// } +// if (choic.equalsIgnoreCase("first")) { +// player.nextCardInhand = CardUtil.toList(params.getTArray("second")); +// } +// if (choic.equalsIgnoreCase("three")) { +// player.nextCardInhand = CardUtil.toList(params.getTArray("first")); +// } +// +// } +// } +// +// } +// +// @ActionKey(Config.GAME_NEXTCARD) +// public void checkCard(Session sender, ITObject params, int gid, EXPlayer owner) { +// Jedis jedis1 = Redis.use("group1_db1").getJedis(); +// Boolean is_pk_can_choice = false; +// String key = "pk_can_choice"; +// try { +// if (jedis1.hget("pk_can_choice", Global.gameId + "") == null) { +// return; +// } +// String pk_can_choice = jedis1.hget(key, Global.gameId + ""); +// String[] choices = pk_can_choice.split(","); +// for (String playerId : choices) { +// if (owner.playerid == Integer.parseInt(playerId)) { +// is_pk_can_choice = true; +// } +// } +// if (is_pk_can_choice == false) { +// return; +// } +// } catch (Exception e) { +// Global.logger.error(e); +// return; +// } finally { +// jedis1.close(); +// } +// ITObject param = new TObject(); +// for (Entry entry : owner.getRoom().playerMapById.entrySet()) { +// EXPlayer player = (EXPlayer) entry.getValue(); +// if (player.isChoice) { +// return; +// } +// } +// if (owner.getRoom().card.nextCardList.size() == 0) { +// owner.getRoom().card.initNextCard(); +// owner.isChoice = true; +// for (int i = 0; i < 3; i++) { +// List list = owner.getRoom().card.dealNext(true, true, 100, 0, 0, 0, 0, 4, 3); +// ITArray result = new TArray(); +// for (CardObj card : list) { +// result.addInt(card.card); +// } +// if (i == 0) { +// param.putTArray("first", result); +// +// } else if (i == 1) { +// param.putTArray("second", result); +// +// } else if (i == 2) { +// param.putTArray("three", result); +// +// } +// } +// +// owner.sendEvent(Config.GAME_EVT_NEXTCARD, param); +// } else { +// +// } +// +//// ITArray residuCard = Util.toTArray(owner.getRoom().card.cardList); +//// param.putTArray("residueCard", owner.getRoom().card.cardList); +//// param.putInt("seat", owner.seat); +//// owner.getRoom().broadCastToClient(0, Config.GAME_EVT_CHECKCARD, param); +// } + + // 改变活动玩家 + public void changeActiveSeat(EXRoom owner, int activeSeat) { + owner.activeSeat = activeSeat; + ITObject param = new TObject(); + param.putInt("index", activeSeat); + owner.broadCastToClient(0, Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param); + } + + public void sendPutError(EXPlayer owner, int code) { + ITObject param = new TObject(); + param.putInt("error", code); + owner.sendEvent(Config.GAME_EVT_PUT_ERROR, param); + } + + /** + * pass + * + * @param owner + */ + public void pass(EXPlayer owner) { + EXRoom room = owner.getRoom(); + ITObject response = new TObject(); + response.putInt("seat", owner.seat); + if (Global.loggerDebug) { + Global.logger.info(owner + " pass!"); + } + owner.pass = true; + owner.last_outcard = null; + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addPassCommand(owner.seat); + room.broadCastToClient(0, Config.GAME_EVT_PASS, response); + room.broadCastToClientOfSpectator(Config.GAME_EVT_PASS, response); + } + +// /** +// * 票鸟提示 +// * +// * @param owner +// */ +// public void piaoTipEvent(EXPlayer owner, int reload) { +// +// ITObject response = new TObject(); +// response.putInt("piao", owner.room.config.getInt(Config.ROOM_CONFIG_PIAO)); +// response.putInt("reload", reload); +// owner.sendEvent(Config.GAME_EVT_PIAO_TIP, response); +// } + +// /** +// * 票鸟事件 +// * +// * @param owner +// */ +// public void piaoEvent(EXPlayer owner) { +// if (owner.piao == -1) +// return; +// +// ITObject param = new TObject(); +// param.putInt("seat", owner.seat); +// param.putInt("piao", owner.piao); +// owner.room.broadCastToClient(0, Config.GAME_EVT_PIAO, param); +// } + + public void outCard(EXPlayer owner, CardGroup ct) { + EXRoom room = owner.getRoom(); + ITObject response = new TObject(); + response.putInt("player", owner.seat); + response.putTObject("card_obj", ct.toObject(false)); + + owner.outCards.addAll(ct.card_list); + + room.lastDiscardSeat = owner.seat; + room.discard = ct; + owner.last_outcard = ct; + owner.pass = false; + room.firstCard = 0; + if (Global.loggerDebug) { + Global.logger.info(owner + " out card:" + ct); + } + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addOutCardCommand(owner.seat, ct); + + CardUtil.removeCard(owner.cardInhand, ct.card_list); + + response.putInt("remain", owner.cardInhand.size()); + room.broadCastToClient(0, Config.GAME_EVT_DISCARD, response); + room.broadCastToClientOfSpectator(Config.GAME_EVT_DISCARD, response); + + List cardLists = new ArrayList(); + + // 加分 + TObject addPlayerScoreList = new TObject(); + + TObject param = new TObject(); + TArray addPlayerList = new TArray(); + + int numOne = 0; + int numTwo = 0; + if (room.discard.config == CardConfig.ZHA) { + // 拿ct.card_list第一位数字 + numTwo = ct.card_list.get(0).card % 100; + Jedis jediss = Redis.use("group1_db11").getJedis(); + + String playingGroupIdKeys = "g{" + owner.getRoom().groupId + "}:play:" + owner.getRoom().groupPid; + try { + String score = jediss.hget(playingGroupIdKeys, "hp_times"); + + // 循环除当前用户外的用户手牌最后一位数 + for (Entry entry : room.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + + if (player.playerid != owner.playerid) { + // 扣分 + TObject minusPlayerScoreList = new TObject(); + minusPlayerScoreList.putInt("seat", player.seat); + minusPlayerScoreList.putInt("pomSore", -10 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(minusPlayerScoreList); + pb.addZhaScoreCommand(player.seat, ct, -10 * Integer.parseInt(score) / 1000); + + Map maps = new HashMap(); + maps.put(player.seat, player.cardInhand); + // 循环 + for (Entry entry1 : maps.entrySet()) { + List cardInhand = entry1.getValue(); + for (int i = 0; i < cardInhand.size(); i++) { + CardObj cardObj = CardObj.class.cast(cardInhand.get(i)); // 明确获取 CardObj 对象 + int cardValue = cardObj.card % 100; + cardLists.add(cardValue); + } + + Map> map = cardLists.stream() + .collect(Collectors.groupingBy(Integer::intValue)); + for (Entry> entry2 : map.entrySet()) { + + if (entry2.getValue().size() == 4) { + numOne = entry2.getValue().get(0); + } + } + + if (numTwo > numOne) { + cardLists.clear(); + } + + } + Map> map = cardLists.stream() + .collect(Collectors.groupingBy(Integer::intValue)); + for (Entry> entry2 : map.entrySet()) { + if (entry2.getValue().size() == 4) { + numOne = entry2.getValue().get(0); + } + } + + } + + } + + if (room.maxPlayers == 3) { + // 存储当前用户的座位号和分数 + addPlayerScoreList.putInt("seat", owner.seat); + addPlayerScoreList.putInt("pomSore", 20 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(addPlayerScoreList); + pb.addZhaScoreCommand(owner.seat, ct, 20 * Integer.parseInt(score) / 1000); + + } else { + // 存储当前用户的座位号和分数 + addPlayerScoreList.putInt("seat", owner.seat); + addPlayerScoreList.putInt("pomSore", 10 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(addPlayerScoreList); + pb.addZhaScoreCommand(owner.seat, ct, 10 * Integer.parseInt(score) / 1000); + + } + } catch (Exception e) { + Global.logger.error(e); + } finally { + jediss.close(); + } + param.putTArray("PlayerScoreList", addPlayerList); + + if (numTwo > numOne && room.discard.config == CardConfig.ZHA) { + owner.room.broadCastToClient(0, Config.GAME_EVT_BOMB_SCORE, param); + owner.room.broadCastToClientOfSpectator(Config.GAME_EVT_BOMB_SCORE, param); + + } + + } + + } + + private CardGroup checkFour(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + return cg; + } + + public void dealCard(EXRoom owner) { + if (owner.targetCards.size() == 0) { + owner.card.init(); + } + + int maxDanPai = 0; + int maxDuizi = 0; + int maxSanZhang = 0; + boolean existWhite = false; + boolean existXingyunhao = false; + boolean existGeneral = false; + boolean existBlack = false; + double white_rate = 0; + + ArrayList tmpPlayerList = new ArrayList<>(); + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + tmpPlayerList.add(player); + } + + Collections.shuffle(tmpPlayerList); + Random random2 = new Random(); + int seat = random2.nextInt(2) + 1; + + if (tmpPlayerList.size() == 3) { + seat = random2.nextInt(3) + 1; + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); +// if (player.seat == seat) { +// player.is_white = true; +// +// } + player.is_white = true; + if (player.is_white) { + existXingyunhao = true; + } else { + if (player.black_white_status == 0) { + existGeneral = true; + } else if (player.black_white_status == 1) { + existBlack = true; + } else if (player.black_white_status == 2) { + existWhite = true; + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + if (player.is_white) { + white_rate = 100; + } else { + continue; + } + if (player.nextCardInhand.size() != 0) { + List cardInhand = new ArrayList(); + cardInhand.addAll(player.nextCardInhand); + player.cardInhand = cardInhand; + player.nextCardInhand.clear(); + } else { + player.cardInhand = owner.card.deal(true, true, 100, player.black_white_status, player.black_white_rate, + player.black_white_rate, 0, 4, 3); + + } + + Collections.sort(player.cardInhand); + + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 2) { + white_rate = player.black_white_rate; + Global.logger + .info("dealcards playerid:" + player.playerid + " white player:" + player.black_white_rate); + } else { + continue; + } + } + + if (!existXingyunhao) { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate, player.black_white_rate, 0, 0, 0); + } else { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate, player.black_white_rate, maxDanPai, + maxDuizi, maxSanZhang); + + } + + + Collections.sort(player.cardInhand); + + if (!existXingyunhao && (existGeneral || existBlack)) { + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 0) { + Global.logger.info( + "dealcards playerid:" + player.playerid + " general player:" + player.black_white_rate); + } else { + continue; + } + } + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, white_rate, white_rate, maxDanPai, maxDuizi, maxSanZhang); +// // 指定牌型 +// player.cardInhand = owner.card.deal0(player.seat); + +// if (!existXingyunhao && !existWhite) +// { +// //player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,player.black_white_status, white_rate, white_rate, 0, 0, 0); +// player.cardInhand = owner.card.deal1(player.seat); +// } +// else { +// player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, +// player.black_white_status, white_rate, white_rate, maxDanPai, maxDuizi, maxSanZhang); +// +// } +// + + Collections.sort(player.cardInhand); + + if (!existXingyunhao && !existWhite && existBlack) { + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 1) { + Global.logger.info("dealcards playerid:" + player.playerid + " black player:" + + (player.black_white_rate + white_rate)); + } else { + continue; + } + } + + if (!existXingyunhao && !existWhite && !existGeneral) { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate + white_rate, + player.black_white_rate + white_rate, 1, 6, 3); + } else { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate + white_rate, + player.black_white_rate + white_rate, maxDanPai, maxDuizi, maxSanZhang); + } + + + + Collections.sort(player.cardInhand); + } + + if (owner.targetCards.size() > 0 && owner.adminSeat > 0 && owner.supCards.size() > 0) { + owner.card.cardList = owner.supCards.get(0); + } + + // 如果是首局,需要确定庄家 + if (owner.bankerSeat == 0) { + + int rule = Config.RULE_RANDOM; + if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) { + rule = owner.config.getInt(Config.ROOM_CONFIG_RULE); + } + + owner.bankerSeat = this.getBankerSeat(owner); + + this.sendPlayerDeal(owner); + // 如果是随机确定庄家 + if (rule == Config.RULE_RANDOM) { + + EXPlayer player = (EXPlayer) owner.playerMapBySeat.get(owner.bankerSeat); + if (player != null) { + + int len = player.cardInhand.size(); + if (len > 0) { + Random random1 = new Random(); + int rand_pos = random1.nextInt(len); + + this.sendMingPai(owner, player.cardInhand.get(rand_pos).card); + } + } + } + } else { + this.sendPlayerDeal(owner); + } + + } + + /** + * 发生随机牌 用于指示谁首先出牌 + * + * @param owner + */ + private void sendMingPai(EXRoom owner, int card) { + + ITObject param = new TObject(); + param.putInt("mingpai", card); + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + + EXPlayer exPlayer = (EXPlayer) entry.getValue(); + exPlayer.sendEvent(Config.GAME_EVT_MING_PAI, param); + } + ; + } + + /** + * 发牌 + * + * @param owner + */ + private void sendPlayerDeal(EXRoom owner) { + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer exPlayer = (EXPlayer) entry.getValue(); + ITObject param = new TObject(); + ITArray handCard = CardUtil.toTArray(exPlayer.cardInhand); + param.putTArray("cards", handCard); + param.putInt("bank_seat", exPlayer.room.bankerSeat); + param.putInt("round", owner.round); + if (Global.loggerDebug) { + Global.logger.info(owner + " deal card:" + exPlayer.cardInhand); + } + exPlayer.sendEvent(Config.GAME_EVT_PLAYER_DEAL, param); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_PLAYER_DEAL, param); + } + ; + } + + private int getBankerSeatByCard(EXRoom owner) { + for (int index = 3; index <= 13; index++) { + for (int color = 4; color >= 1; color--) { + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + for (CardObj card : player.cardInhand) { + if (card.card == color * 100 + index) { + owner.firstCard = card.card; + return player.seat; + } + } + } + } + } + return 0; + } + + private int getBankerSeat(EXRoom owner) { + int seat = 0; + + int rule = Config.RULE_RANDOM; + if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) { + rule = owner.config.getInt(Config.ROOM_CONFIG_RULE); + } + + // 如果是兩人的情況 + if (owner.maxPlayers == 2) { + + // 如果是随机确定庄家 + if (rule == Config.RULE_RANDOM) { + Random random = new Random(); + seat = random.nextInt(2) + 1; + } + // 如果是黑桃3先出 + else { + seat = getBankerSeatByCard(owner); + // 如果黑桃3 不在任何一个玩家手里 则随机确定一个庄家 + if (seat == 0) { + Random random = new Random(); + seat = random.nextInt(2) + 1; + } + } + } else { + + // 如果是随机确定庄家 + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + // 循环玩家的手牌 + for (CardObj card : player.cardInhand) { + if (card.card == 403) { + seat = getBankerSeatByCard(owner); + return seat; + } else { + Random random = new Random(); + seat = random.nextInt(3) + 1; + } + } + } + +// // 如果是黑桃3先出 +// else { +// seat = getBankerSeatByCard(owner); +// } + } + return seat; + + } + + public void discardTipEvent(EXPlayer owner) { + ITObject param = new TObject(); + boolean gen = (owner.getRoom().lastDiscardSeat != 0 && owner.getRoom().lastDiscardSeat != owner.seat); + param.putInt("play", gen ? 1 : 0); + if (gen) { + param.putTObject("card_obj", owner.getRoom().discard.toObject(true)); + + } + // 如果可以不出 + + EXRoom room = owner.getRoom(); + owner.sendEvent(Config.GAME_EVT_DISCARD_TIP, param); + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addPromptCommand(owner.seat, param); + } + + private ITObject getRoomResultData(EXRoom owner, boolean total) { + + ITObject mp = TObject.newInstance(); + + EXPlayer win = owner.win; + + ITArray info = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.total_score); + + obj.putInt("winscore", player.score.round_score); + player.hp_info(obj); + obj.putInt("thisboomnum", player.boomnum); + obj.putInt("piao", player.piao); + obj.putTArray("cards", CardUtil.toTArray(player.cardInhand)); + obj.putBoolean("chuntian", player.chuntian); + + obj.putTArray("handCards", CardUtil.toTArray(player.cardInhand)); + obj.putTArray("outCards", CardUtil.toTArray(player.outCards)); + + if (total) { + Jedis jedis = Redis.use("group1_db11").getJedis(); + String playingGroupIdKey = "g{" + owner.groupId + "}:play:" + owner.groupPid; + try { +// int score = player.room.hpData.getInt("times") / 1000; + + obj.putInt("total_score", player.score.total_score); + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis.close(); + } + obj.putInt("daniao", player.daniaoScore); + obj.putInt("award", player.bonusScore); + +// if(owner.endType == Constant.END_TYPE_ENTRUST) { +// obj.putInt("entrust", player.entrust ? 1 : 0); +// } + + int jieShan = owner.hpData.getInt("JieShan"); + if (owner.endType == Constant.END_TYPE_ENTRUST && player.entrust_round < jieShan) { + obj.putInt("entrust", player.entrust ? 1 : 0); + } + + obj.putTObject("settle_log", player.settleLog.toTObject()); +// obj.putInt("total_score", player.score.total_score); + + } + info.addTObject(obj); + } + if (win != null) { + mp.putInt("winseat", win.seat); + } else { + mp.putInt("winseat", 0); + } + mp.putTArray("remaincards", CardUtil.toTArray(owner.card.cardList)); + mp.putTArray("info", info); + mp.putInt("xipai_score", owner.xi_pai_score); + + return mp; + } + + public void roomResult(EXRoom owner) { + ITObject result = getRoomResultData(owner, false); + result.putInt("type", 0); + result.putString("cardList", owner.card.cardList.toString()); + + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_RESULT1, result); + } + + /** + * 房间大结算 + * + * @param owner + * @param dissmiss + */ + public void roomTotalResult(EXRoom owner, boolean dissmiss) { + Jedis jedis = Redis.use("group1_db10").getJedis(); + + ITObject result = getRoomResultData(owner, true); + + long t = System.currentTimeMillis() / 1000; + result.putLong("time", t); + result.putInt("type", dissmiss ? 2 : 1); + result.putString("cardList", owner.card.cardList.toString()); + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_RESULT1, result); + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); +// pb.addResultCommand(player.seat, result); +// +// pb.addNewRoundCommand(); + // 扣除积分 + String playerIdKey = "g{" + owner.groupId + "}:" + "m" + player.playerid; + String lost_mj_score = jedis.hget(playerIdKey, "lost_pk_score"); + jedis.hset(playerIdKey, "lost_pk_score", lost_mj_score == null ? player.score.total_score + "" + : Integer.parseInt(lost_mj_score) + player.score.total_score + ""); + + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.zrem("ceroom", "room:" + owner.roomid); + jedis11.close(); + jedis.close(); + + } + +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXMainServer.java b/game_pk_duoduo/src/main/java/extend/pk/EXMainServer.java new file mode 100644 index 0000000..f0f1caa --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXMainServer.java @@ -0,0 +1,59 @@ +package extend.pk; + +import java.util.Map; + +import com.game.GameController; +import com.game.Global; +import com.game.MainServer; +import com.game.data.Player; +import com.game.data.Room; +import com.game.room.state.RoomStartGameState; + +import extend.pk.player.state.EXPlayerDiscardState; +import extend.pk.player.state.EXPlayerPassState; +import extend.pk.room.state.EXRoomDealState; +import extend.pk.room.state.EXRoomSetpState; +import extend.pk.room.state.EXRoomStartGameState; + +/** + * + * + */ +public class EXMainServer extends MainServer { + public static EXGameController gameCtr; + + @Override + public void onStart() { + super.onStart(); + gameCtr = (EXGameController) Global.gameCtr; + registerState(); + } + + private final void registerState() { + + Global.registerState(RoomStartGameState.class, new EXRoomStartGameState()); + Global.registerState(EXRoomSetpState.class, new EXRoomSetpState()); + Global.registerState(EXRoomDealState.class, new EXRoomDealState()); + + Global.registerState(EXPlayerDiscardState.class, new EXPlayerDiscardState()); + Global.registerState(EXPlayerPassState.class, new EXPlayerPassState()); + } + + @Override + public Room newRoom(String roomid, Map redis_room_map) { + // TODO Auto-generated method stub + return new EXRoom(roomid, redis_room_map); + } + + @Override + public Player newPlayer(int playerid, Room room, String session_id) { + // TODO Auto-generated method stub + return new EXPlayer(playerid, room, session_id); + } + + @Override + protected GameController newController() { + // TODO Auto-generated method stub + return new EXGameController(); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXPlayBack.java b/game_pk_duoduo/src/main/java/extend/pk/EXPlayBack.java new file mode 100644 index 0000000..c9328f3 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXPlayBack.java @@ -0,0 +1,61 @@ +package extend.pk; + + +import com.game.data.BasePlayBack; +import com.game.data.Player; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import extend.pk.uitl.CardUtil; + +public class EXPlayBack extends BasePlayBack{ + + public EXPlayBack(EXRoom room) { + super(room); + info.putInt("left_card", room.card.getCount()); + } + + protected ITObject getPlayerInfo(Player p) { + + EXPlayer player = (EXPlayer)p; + ITObject obj =super.getPlayerInfo(player); + ITArray cardInhand = CardUtil.toTArray(player.cardInhand); + obj.putTArray("hand_card", cardInhand); + obj.putInt("score", player.score.total_score); + obj.putInt("piao", player.piao); + + player.hp_info(obj); + return obj; + } + + public void addOutCardCommand(int seat, CardGroup ct) { + ITObject cmdData = ct.toObject(false); + addCommand("OutCard", seat, cmdData); + } + + public void addZhaScoreCommand(int seat, CardGroup ct,int score) { +// ITObject cmdData = ct.toObject(false); +// cmdData.putInt("score", score); +// addCommand("ZhaScore", seat, cmdData); + } + + + public void addPassCommand(int seat) { + ITObject cmdData = TObject.newInstance(); + addCommand("pass", seat, cmdData); + } + + public void addNewRoundCommand() { + ITObject cmdData = TObject.newInstance(); + addCommand("newindex", 0, cmdData); + } + + public void addPromptCommand(int seat ,ITObject cmdData){ + addCommand("prompt", seat, cmdData); + } + + public void addResultCommand(int seat,ITObject cmdData) { + addCommand("result", seat, cmdData); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXPlayer.java b/game_pk_duoduo/src/main/java/extend/pk/EXPlayer.java new file mode 100644 index 0000000..1660127 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXPlayer.java @@ -0,0 +1,137 @@ +package extend.pk; + +import java.util.ArrayList; +import java.util.List; + +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.data.Score; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.plugin.redis.Redis; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + + +/** + * + * + */ +public class EXPlayer extends Player { + + /**默认action时间 20s*/ + public static final int DEFAULT_ACTION_TIME = 20000; + /**默认托管时间 1s*/ + public static final int DEFAULT_ENTRUST_TIME = 1000; + /** + * 默认准备时间 20s + */ + public static final int DEFAULT_READY_TIME = 20000; + + // 手牌 + public List cardInhand; + + // 手牌 + public List nextCardInhand = new ArrayList(); + + + //打出的牌 + public List outCards; + + public CardGroup last_outcard; + public boolean pass; + + // 放作弊场第一张牌是否关闭 + public int open = 0; + + /**春天 */ + public boolean chuntian; + + /**是否有红桃10*/ + public boolean isHaveRedTen; + + public SettleLog settleLog; + + public int boomnum = 0; + public int piao = -1; + public int daniaoScore = 0; + public int bonusScore = 0; + public int awardScore = 0; + + public boolean isChoice = false; + + + public EXPlayer(int playerid, Room table, String session_id) { + super(playerid, table, session_id); + cardInhand = new ArrayList<>(); + outCards = new ArrayList<>(); + + settleLog = new SettleLog(); + settleLog.put(Config.SETTLE_WIN_COUNT, 0); + settleLog.put(Config.SETTLE_CHUNTIAN_COUNT, 0); + settleLog.put(Config.SETTLE_BOMB_COUNT, 0); + settleLog.put(Config.SETTLE_MAX_SCORE, 0); + } + + protected Score newScore() { + return new EXScore(this); + } + + @Override + public ITObject getReloadInfo() { + ITObject playerData = super.getReloadInfo(); + playerData.putInt("card_size", this.cardInhand.size()); + playerData.putInt("piao", this.piao); + if(last_outcard!=null) { + playerData.putTObject("last_outcard", last_outcard.toObject(false)); + } + + if(this.room.isplaying == false) { + playerData.putTArray("cards", CardUtil.toTArray(this.cardInhand)); + + playerData.putTArray("handCards", CardUtil.toTArray(this.cardInhand)); + playerData.putTArray("outCards", CardUtil.toTArray(this.outCards)); + + playerData.putInt("score", score.total_score); + playerData.putInt("winscore", score.round_score); + playerData.putInt("thisboomnum", boomnum); + playerData.putInt("open", open); + } + return playerData; + } + + @Override + public ITObject getInfo() { + ITObject playerData = super.getInfo(); + playerData.putInt("score", score.total_score); + return playerData; + } + + + public void clear() { + super.clear(); + + } + + public void clearEx() { + + this.score.resetRound(); + this.cardInhand.clear(); + this.outCards.clear(); + this.last_outcard = null; + this.pass = false; + this.chuntian =false; + this.isHaveRedTen=false; + this.open = 0; + this.boomnum = 0; + this.piao = -1; + this.daniaoScore = 0; + this.isChoice=false; + } + + public EXRoom getRoom() { + return (EXRoom) room; + } + +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXRoom.java b/game_pk_duoduo/src/main/java/extend/pk/EXRoom.java new file mode 100644 index 0000000..02615a9 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXRoom.java @@ -0,0 +1,430 @@ +package extend.pk; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Constant; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; + +import com.taurus.core.plugin.redis.Redis; +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + +public class EXRoom extends Room { + public RoomCard card; + + /** 上次打牌的座位 */ + public int lastDiscardSeat; + + /** 打出牌的集合 */ + public CardGroup discard; + + public EXPlayer win; + + public int firstCard = 0; + + public Map card_config_map; + + public int piaoCount = 0; + + public List> supCards; + public List targetCards; + public int adminSeat = 0; + + public int chooseover = 0; + + public EXRoom(String roomid, Map redis_room_map) { + super(roomid, redis_room_map); + + card = new RoomCard(this, this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16, maxPlayers); + card_config_map = new HashMap(); + card_config_map.put(CardConfig.DAN.type, CardConfig.DAN); + card_config_map.put(CardConfig.DUIZI.type, CardConfig.DUIZI); + card_config_map.put(CardConfig.ZHA.type, CardConfig.ZHA); + + + + + this.isEntrust = true; + + this.supCards = new ArrayList<>(); + this.targetCards = new ArrayList<>(); + this.adminSeat = 0; + this.chooseover = 0; + } + + public void clear() { + super.clear(); + + } + + public void clearEx() { + this.activeSeat = 0; + this.discard = null; + this.lastDiscardSeat = 0; + this.win = null; + this.firstCard = 0; + } + + public ITObject getReloadInfo(Player player) { + ITObject data = super.getReloadInfo(player); + EXPlayer p = (EXPlayer) player; + + data.putTArray("hand_card", CardUtil.toTArray(p.cardInhand)); + + data.putTArray("handCards", CardUtil.toTArray(p.cardInhand)); + data.putTArray("outCards", CardUtil.toTArray(p.outCards)); + + data.putInt("open", p.open); + + data.putInt("last_outcard_seat", this.lastDiscardSeat); + + // 游戏结束 + if (this.isplaying == false) { + + if (this.win != null) { + data.putInt("winseat", this.win.seat); + } else { + data.putInt("winseat", 0); + } + if (this.card.getCount() > 0) { + data.putTArray("remaincards", CardUtil.toTArray(this.card.cardList)); + } + } + + return data; + } + + /** + * + * */ + private int reMultipleScore(int score) { + if (this.hpData != null) { + if (this.hpData.containsKey("times")) { + return Math.round(score / this.hpData.getInt("times")); + } + } + return score; + } + + public void addScore(Player destPlayer, Player fromPlayer, int score, int type) { + + //// +// if (multipleScore(score) > fromPlayer.hp.cur_hp) { +// score = reMultipleScore((int) fromPlayer.hp.cur_hp); +// // fromPlayer.hp.cur_hp -= multipleScore(score); //不能在这里扣 +// } + // + + + score = score * this.hpData.getInt("times") / 1000; + + + destPlayer.score.round_log.put(type, destPlayer.score.round_log.get(type) + score); + fromPlayer.score.round_log.put(type, fromPlayer.score.round_log.get(type) - score); + destPlayer.score.round_score += score; + destPlayer.score.total_score += score; + fromPlayer.score.round_score -= score; + fromPlayer.score.total_score -= score; + + + + } + + /** + * 变更炸弹积分 + * + * @param destPlayer + */ + public void addAllBombScore(EXPlayer destPlayer) { + + destPlayer.settleLog.add(Config.SETTLE_BOMB_COUNT); + destPlayer.boomnum++; + + TArray seatData = TArray.newInstance(); + for (Entry entry : this.playerMapByPlaying.entrySet()) { + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + ITObject seatListData = TObject.newInstance(); + if (fromPlayer != destPlayer) { + this.addScore(destPlayer, fromPlayer, 10, EXScore.ZHA); + seatListData.putInt("bom_score", -10); + seatListData.putInt("aid", fromPlayer.playerid); + seatData.addTObject(seatListData); + } else { + seatListData.putInt("bom_score", 20); + seatListData.putInt("aid", destPlayer.playerid); + seatData.addTObject(seatListData); + } + } + TObject allData = TObject.newInstance(); + allData.putTArray("gold_list", seatData); + this.broadCastToClient(0, Config.GAME_EVT_UPDATE_BOM_SCORE, allData); + } + + /** + * 变更游戏积分 + * + * @param destPlayer 目标玩家,将接收其他玩家的分数 + */ +public void addAllScore(Player destPlayer) { + + // 将目标玩家转换为扩展玩家类型 + EXPlayer dp = (EXPlayer) destPlayer; + + // 标记是否有玩家达到春天条件 + boolean bSpring = false; + + // 遍历所有参与游戏的玩家 + for (Entry entry : this.playerMapByPlaying.entrySet()) { + + // 将当前玩家转换为扩展玩家类型 + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + + // 确保当前玩家不是目标玩家 + if (fromPlayer != destPlayer) { + + // 检查当前玩家手中是否有超过一张牌 + if (fromPlayer.cardInhand.size() > 1) { + + // 计算基础分数 + int size = fromPlayer.cardInhand.size(); + int score = size; + + // 计算出牌数量 + int outCard = (this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16) - size; + + // 检查是否达到春天条件 + if (size == (this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16)) { + fromPlayer.chuntian = true; + score = size * 2; + bSpring = true; + + } else if (outCard < 2 && this.config.getInt(Config.ROOM_CONFIG_SPECIL_ADD) == 1 ) { + // 只出一张牌多10分 + score += 10; + } else if (outCard < 4 && this.config.getInt(Config.ROOM_CONFIG_SPECIL_ADD) == 1 ) { + // 出2-3张牌多5分 + score += 5; + } + + + + // 加上目标玩家的飘分 + if (dp.piao > 0) { + score += dp.piao; + } + + // 加上当前玩家的飘分 + if (fromPlayer.piao > 0) { + score += fromPlayer.piao; + } + + // 更新目标玩家和当前玩家的分数 + this.addScore(destPlayer, fromPlayer, score, EXScore.WIN); + } + } + } + + // 设置玩家的当初最大分数 + for (Entry entry : this.playerMapByPlaying.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + + // 为目标玩家增加胜利次数记录 + if (destPlayer == player) { + player.settleLog.add(Config.SETTLE_WIN_COUNT); + } + + // 更新玩家的最高分数记录 + if (player.score.round_score > player.settleLog.get(Config.SETTLE_MAX_SCORE)) { + player.settleLog.put(Config.SETTLE_MAX_SCORE, player.score.round_score); + } + } + +// // 增加玩家春天的个数 +// if (bSpring) { +// dp.settleLog.add(Config.SETTLE_CHUNTIAN_COUNT); +// } + + // 检查是否启用总分模式 +// if (totalType()) { +// // 检查房间配置中是否设置了大鸟分,并获取设置值 +// if (config.containsKey(Config.ROOM_CONFIG_DANIAO) && config.getInt(Config.ROOM_CONFIG_DANIAO) > 0) { +// +// int daniao = this.config.getInt(Config.ROOM_CONFIG_DANIAO); +// if (daniao == 1) +// daniao = 10; +// else if (daniao == 2) +// daniao = 20; +// else if (daniao == 3) +// daniao = 50; +// +// // 初始化最大总分数和最大总分出现次数 +// int maxTotalScore = 0; +// int maxTotalCount = 0; +// +// // 遍历所有玩家,找出最大总分数和出现次数 +// for (Entry entry : this.playerMapBySeat.entrySet()) { +// +// Player player = entry.getValue(); +// +// if (player.score.total_score > maxTotalScore) { +// +// maxTotalScore = player.score.total_score; +// maxTotalCount = 1; +// } else if (player.score.total_score == maxTotalScore && maxTotalScore > 0) { +// +// maxTotalCount++; +// } +// } +// +// // 如果存在大赢家 +// if (maxTotalScore > 0 && maxTotalCount > 0) { +// +// // 根据大赢家和非大赢家更新玩家分数 +// for (Entry entry : this.playerMapBySeat.entrySet()) { +// +// EXPlayer player = (EXPlayer) entry.getValue(); +// +// if (player.score.total_score == maxTotalScore) { +// +// player.score.total_score += daniao; +// player.daniaoScore = daniao; +// } else { +// +// player.score.total_score -= daniao * maxTotalCount; +// player.daniaoScore = -daniao * maxTotalCount; +// } +// } +// } +// } +// } +} + + + @Override + protected void roomResult() { + EXMainServer.gameCtr.roomResult(this); + } + + @Override + public void saveMilitaryTotal(boolean dissmiss) { + super.saveMilitaryTotal(dissmiss); + EXMainServer.gameCtr.roomTotalResult(this, dissmiss); + } + + private ITObject getRoomResultData(EXRoom owner, boolean total) { + + ITObject mp = TObject.newInstance(); + + EXPlayer win = owner.win; + + ITArray info = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.total_score); + + + obj.putInt("winscore", player.score.round_score); + player.hp_info(obj); + obj.putInt("thisboomnum", player.boomnum); + obj.putInt("piao", player.piao); + obj.putTArray("cards", CardUtil.toTArray(player.cardInhand)); + obj.putBoolean("chuntian", player.chuntian); + + obj.putTArray("handCards", CardUtil.toTArray(player.cardInhand)); + obj.putTArray("outCards", CardUtil.toTArray(player.outCards)); + + if (total) { + Jedis jedis = Redis.use("group1_db11").getJedis(); + String playingGroupIdKey = "g{" + owner.groupId + "}:play:" + owner.groupPid; + try { +// int score = player.room.hpData.getInt("times") / 1000; + + obj.putInt("total_score", player.score.total_score); + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis.close(); + } + obj.putInt("daniao", player.daniaoScore); + obj.putInt("award", player.bonusScore); + +// if(owner.endType == Constant.END_TYPE_ENTRUST) { +// obj.putInt("entrust", player.entrust ? 1 : 0); +// } + + int jieShan = owner.hpData.getInt("JieShan"); + if (owner.endType == Constant.END_TYPE_ENTRUST && player.entrust_round < jieShan) { + obj.putInt("entrust", player.entrust ? 1 : 0); + } + + obj.putTObject("settle_log", player.settleLog.toTObject()); +// obj.putInt("total_score", player.score.total_score); + + } + info.addTObject(obj); + } + if (win != null) { + mp.putInt("winseat", win.seat); + } else { + mp.putInt("winseat", 0); + } + mp.putTArray("remaincards", CardUtil.toTArray(owner.card.cardList)); + mp.putTArray("info", info); + mp.putInt("xipai_score", owner.xi_pai_score); + + + + + + return mp; + } + + @Override + public void endGame() { + addAllScore(win); + + this.chooseover = 0; + //拿结算数据 + + ITObject mp = getRoomResultData(this, true); + + EXPlayBack pb = (EXPlayBack) this.playBackData; + + ITObject pbResult = TObject.newInstance(); + + ITArray info = new TArray(); + for (Entry entry : playerMapByPlaying.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.round_score); + obj.putBoolean("entrust", player.entrust); + info.addTObject(obj); + + if (player.entrust == true){ + player.entrust_round++; + } + } +//// + pbResult.putTArray("result", info); + pbResult.putTObject("win", mp); + Global.logger.error("------------------pbResult:" + pbResult); + pb.addResultCommand(win.seat, pbResult); +// + pb.addNewRoundCommand(); + super.endGame(); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/EXScore.java b/game_pk_duoduo/src/main/java/extend/pk/EXScore.java new file mode 100644 index 0000000..fc4343f --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/EXScore.java @@ -0,0 +1,18 @@ +package extend.pk; + +import com.game.data.Score; + +public class EXScore extends Score { + public static final int WIN = 1; + public static final int ZHA = 2; + + + public EXScore(EXPlayer owner) { + super(owner); + } + + protected void initLog() { + this.round_log.put(WIN, 0); + this.round_log.put(ZHA, 0); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/RoomCard.java b/game_pk_duoduo/src/main/java/extend/pk/RoomCard.java new file mode 100644 index 0000000..efc11e9 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/RoomCard.java @@ -0,0 +1,1192 @@ +package extend.pk; + +import com.game.Global; +import extend.pk.uitl.CardUtil; + +import java.util.*; + +public class RoomCard { + + public static final int HEART_TEN = 310; + public static final int CARD_A = 14; + public static final int CARD_2 = 15; + public static final int CARD_3 = 3; + public List cardList; + public List nextCardList = new ArrayList(); + + public List cardListTemp; + EXRoom room; + int num; + int maxPlayer; + Random rand = new Random(); + + int boomNumLimit = rand.nextInt(2) + 2; + int sangzhangNumLimit = rand.nextInt(5) + 10; + + int totalBoomNum = 0; + int totalSanZhangNum = 0; + + public RoomCard(EXRoom table, int num, int maxPlayer) { + this.cardList = new ArrayList(); + this.cardListTemp = new ArrayList(); + this.room = table; + this.num = num; + this.maxPlayer = maxPlayer; + } + + public void init() { + this.boomNumLimit = rand.nextInt(2) + 2; + this.sangzhangNumLimit = rand.nextInt(5) + 10; + + this.totalBoomNum = 0; + this.totalSanZhangNum = 0; + this.cardList.clear(); + this.initCard(); + int currentBoomNum = 0; + int currentSanZhangNum = 0; + Map result = new HashMap(); + do { + currentBoomNum = 0; + currentSanZhangNum = 0; + this.shuffle(); + for (int i = 0; i < this.maxPlayer; i++) { + this.cardListTemp.clear(); + for (int j = 0; j < num; j++) { + this.cardListTemp.add(this.cardList.get(i * num + j)); + CardUtil.getCardNumMap(result, this.cardListTemp); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + currentBoomNum++; + } else if (entry.getValue() == 3) { + currentSanZhangNum++; + } + } + } + } + } while ((currentBoomNum + totalBoomNum > boomNumLimit) + || (currentSanZhangNum + totalSanZhangNum > sangzhangNumLimit)); + } + + private void initCard() { + for (int index = 3; index <= 13; index++) { + + if (!(index == 13 && this.num == 15)) { + // 方片 + this.cardList.add(new CardObj(100 + index)); + } + // 梅花 + this.cardList.add(new CardObj(200 + index)); + // 红桃 + this.cardList.add(new CardObj(300 + index)); + // 黑桃 + this.cardList.add(new CardObj(400 + index)); + } + + if (this.num == 16) { + this.cardList.add(new CardObj(214)); + this.cardList.add(new CardObj(314)); + this.cardList.add(new CardObj(414)); + + this.cardList.add(new CardObj(415)); + } else { + this.cardList.add(new CardObj(214)); + this.cardList.add(new CardObj(415)); + } + + rand.setSeed(System.currentTimeMillis()); + int len = this.cardList.size(); + for (int i = 0; i < len; i++) { + + int randpos = rand.nextInt(1000000000) % len; + CardObj cotemp = this.cardList.get(i); + + this.cardList.set(i, this.cardList.get(randpos)); + this.cardList.set(randpos, cotemp); + } + + } + + public void initNextCard() { + this.nextCardList.clear(); + for (int index = 3; index <= 13; index++) { + + if (!(index == 13 && this.num == 15)) { + // 方片 + this.nextCardList.add(new CardObj(100 + index)); + } + // 梅花 + this.nextCardList.add(new CardObj(200 + index)); + // 红桃 + this.nextCardList.add(new CardObj(300 + index)); + // 黑桃 + this.nextCardList.add(new CardObj(400 + index)); + } + + if (this.num == 16) { + this.nextCardList.add(new CardObj(214)); + this.nextCardList.add(new CardObj(314)); + this.nextCardList.add(new CardObj(414)); + + this.nextCardList.add(new CardObj(415)); + } else { + this.nextCardList.add(new CardObj(214)); + this.nextCardList.add(new CardObj(415)); + } + + rand.setSeed(System.currentTimeMillis()); + int len = this.nextCardList.size(); + for (int i = 0; i < len; i++) { + + int randpos = rand.nextInt(1000000000) % len; + CardObj cotemp = this.nextCardList.get(i); + + this.nextCardList.set(i, this.nextCardList.get(randpos)); + this.nextCardList.set(randpos, cotemp); + } + + } + + private void shuffle() { + for (int i = 0; i < 100; i++) { + Collections.shuffle(this.cardList); + } + Random rand = new Random(); + int len = this.cardList.size(); + + for (int i = 0; i < 10000; i++) { + rand.setSeed(System.currentTimeMillis()); + if(len<=0) { + continue; + } +// System.out.println("len:"+len); + int start = rand.nextInt(len); + int end = rand.nextInt(len); + + CardObj co = this.cardList.get(start); + this.cardList.set(start, this.cardList.get(end)); + this.cardList.set(end, co); + } + } + + private void shuffleNext() { + for (int i = 0; i < 100; i++) { + Collections.shuffle(this.nextCardList); + } + Random rand = new Random(); + int len = this.nextCardList.size(); + + for (int i = 0; i < 10000; i++) { + rand.setSeed(System.currentTimeMillis()); + if(len<=0) { + continue; + } +// System.out.println("len:"+len); + int start = rand.nextInt(len); + int end = rand.nextInt(len); + + CardObj co = this.nextCardList.get(start); + this.nextCardList.set(start, this.nextCardList.get(end)); + this.nextCardList.set(end, co); + } + } + + public CardObj pop() { + CardObj card = this.cardList.remove(0); + return card; + } + + public CardObj nextPop() { + + CardObj card = this.nextCardList.remove(0); + return card; + } + + public int getCount() { + return this.cardList.size(); + } + + public List deal0(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + dealCards.add(new CardObj(406)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(307)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(112)); + + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + } else if (seat == 2) { + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + dealCards.add(new CardObj(308)); + dealCards.add(new CardObj(408)); + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(109)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + dealCards.add(new CardObj(410)); + dealCards.add(new CardObj(211)); + dealCards.add(new CardObj(212)); + + dealCards.add(new CardObj(303)); + dealCards.add(new CardObj(214)); + }else if (seat == 3){ + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + dealCards.add(new CardObj(409)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(307)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(112)); + + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + } + + return dealCards; + } + + public List deal1(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(414)); + dealCards.add(new CardObj(415)); + dealCards.add(new CardObj(413)); + + dealCards.add(new CardObj(404)); + dealCards.add(new CardObj(405)); + dealCards.add(new CardObj(406)); + + dealCards.add(new CardObj(104)); + dealCards.add(new CardObj(304)); + dealCards.add(new CardObj(204)); + + dealCards.add(new CardObj(103)); + dealCards.add(new CardObj(203)); + dealCards.add(new CardObj(303)); + + dealCards.add(new CardObj(115)); + dealCards.add(new CardObj(215)); + dealCards.add(new CardObj(315)); + + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(111)); + + dealCards.add(new CardObj(311)); + dealCards.add(new CardObj(211)); + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + + } + + return dealCards; + } + + public List deal2(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + dealCards.add(new CardObj(105)); + dealCards.add(new CardObj(205)); + dealCards.add(new CardObj(305)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(110)); + + } else if (seat == 2) { + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + + // dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal3(int seat) { + + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(112)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(215)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal4(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + dealCards.add(new CardObj(307)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + dealCards.add(new CardObj(308)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + dealCards.add(new CardObj(410)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal6(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(103)); + dealCards.add(new CardObj(203)); + + dealCards.add(new CardObj(104)); + dealCards.add(new CardObj(204)); + + dealCards.add(new CardObj(105)); + dealCards.add(new CardObj(105)); + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(106)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(109)); + + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(110)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List dealTest(int seat) { + + List dealCards = deal2(seat); + if (dealCards == null || dealCards.size() == 0) { + + dealCards = deal(); + } + + return dealCards; + } + + // 发牌 + public List deal(boolean room_white, boolean is_white, double room_rate, int white_black_status, + double black_white_rate, double black_black_rate, int maxDanPai, int maxDuizi, int maxSanZhang) { + List dealCards = new ArrayList(); + shuffle(); + + double rand1 = Math.random() % 100 * 100; + for (int index = 0; index < this.num; index++) { + if (room_white && is_white) { + if (rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards xingyun card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard3(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard4(tempCard.cardMod, dealCards, false, 0, 6, 6)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.cardList.addAll(tempCardList); + } + } else { + if (white_black_status == 2) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards white card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } else if (white_black_status == 1) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards black card"); + } + } + ; + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, true, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, true, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } else { + if (room_white && rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } + } + } + } + shuffle(); + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + + // 发牌 + public List dealNext(boolean room_white, boolean is_white, double room_rate, int white_black_status, + double black_white_rate, double black_black_rate, int maxDanPai, int maxDuizi, int maxSanZhang) { + List dealCards = new ArrayList(); + shuffleNext(); + + double rand1 = Math.random() % 100 * 100; + for (int index = 0; index < this.num; index++) { + if (room_white && is_white) { + if (rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards xingyun card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard3(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard4(tempCard.cardMod, dealCards, false, 2, 4, 3)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else { + if (white_black_status == 2) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards white card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else if (white_black_status == 1) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards black card"); + } + } + ; + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, true, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, true, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else { + if (room_white && rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } + } + } + } + shuffleNext(); + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + + boolean isGooodCard(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + if (isGooodCard2(card, dealCards, black, maxDanPai, maxDuizi, maxSanZhang)) { + return true; + } + + if (maxDanPai != 0) { + if (card >= maxDanPai) { + return true; + } + } + + if (maxDanPai != 0) { + if (CardUtil.checkGoodCard(card, dealCards, 1)) { + if (card >= maxDuizi) { + return true; + } + } + } + + if (maxDanPai != 0) { + if (CardUtil.checkGoodCard(card, dealCards, 2)) { + if (card >= maxSanZhang) { + return true; + } + } + } + + return false; + } + + boolean isGooodCard2(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + double rand = Math.random() % 100 * 100; + if (black) { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 70) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 70) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 70) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 70) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 70) { + Global.logger.info("remove checkQPai"); + return true; + } + } else { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 50) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 50) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 50) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 50) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 50) { + Global.logger.info("remove checkQPai"); + return true; + } + } + + return false; + } + + boolean isGooodCard3(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + double rand = Math.random() % 100 * 100; + if (black) { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 50) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 50) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 50) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 70) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 50) { + Global.logger.info("remove checkQPai"); + return true; + } + } else { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 40) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 40) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 40) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 40) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 40) { + Global.logger.info("remove checkQPai"); + return true; + } + } + + return false; + } + + boolean isGooodCard4(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { +// double rand = Math.random() % 100 * 100; +// if (black) { +// if (CardUtil.checkKPai(card, dealCards) && rand < 5) { +// Global.logger.info("remove checkQPai"); +// return true; +// } +// if (CardUtil.checkGoodCard(card, dealCards, 5) && rand < 5) { +// Global.logger.info("remove zhadan"); +// return true; +// } +// +// if (CardUtil.checkFenJi(card, dealCards) && rand < 5) { +// Global.logger.info("remove feiji"); +// return true; +// } +// +// if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 5) { +// Global.logger.info("remove sevent shun zi"); +// return true; +// } +// +// if (CardUtil.checkFourDui(card, dealCards) && rand < 5) { +// Global.logger.info("remove four dui"); +// return true; +// } +// +// } else + { + if (CardUtil.checkGoodCard(card, dealCards, 8) ) { + Global.logger.info("remove zhadan"); + return true; + } +// if (CardUtil.checkShunZi(card, dealCards)) { +// Global.logger.info("remove shun zi"); +// return true; +// } + if (CardUtil.checkFenJi(card, dealCards)) { + Global.logger.info("remove feiji"); + return true; + } + +// if (CardUtil.checkSevenShunzi(card, dealCards)) { +// Global.logger.info("remove sevent shun zi"); +// return true; +// } + + +// if (CardUtil.checkSanTiao(card, dealCards)) { +// Global.logger.info("remove sevent san tiao"); +// return true; +// } + + + + if (CardUtil.checkSixDui(card, dealCards)) { + Global.logger.info("remove five dui"); + return true; + } + +// if (CardUtil.checkKPai(card, dealCards)) { +// Global.logger.info("remove checkKPai"); +// return true; +// } + } + + return false; + } + + public List deal() { + List dealCards = new ArrayList(); + + for (int index = 0; index < this.num; index++) { + dealCards.add(this.pop()); + } + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/SettleLog.java b/game_pk_duoduo/src/main/java/extend/pk/SettleLog.java new file mode 100644 index 0000000..eb6b8c6 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/SettleLog.java @@ -0,0 +1,44 @@ +package extend.pk; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +public class SettleLog { + private Map log; + + public SettleLog() { + log = new HashMap(); + } + + public void put(String key,Integer value) { + log.put(key, value); + } + + public void add(String key) { + if(!log.containsKey(key)) { + return; + } + int value = log.get(key); + value++; + log.put(key, value); + } + + public Integer get(String key) { + if(!log.containsKey(key)) { + return null; + } + return log.get(key); + } + + public ITObject toTObject() { + ITObject obj = TObject.newInstance(); + for (Entry entry : this.log.entrySet()) { + obj.putInt(entry.getKey(), entry.getValue()); + } + return obj; + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java b/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java new file mode 100644 index 0000000..d767588 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java @@ -0,0 +1,394 @@ +package extend.pk.player.state; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.game.Global; +import com.game.Router; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import extend.pk.CardGroup; +import extend.pk.CardObj; +import extend.pk.Config; +import extend.pk.EXActionEvent; +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.RoomCard; +import extend.pk.room.state.EXRoomSetpState; +import extend.pk.uitl.CardCheck; +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; + +/** + * 等待玩家出牌状态 + * + * + */ +public class EXPlayerDiscardState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + + // 设置防作弊场开牌的标志 + owner.open = 1; + + EXRoom room = owner.getRoom(); + + // 如果最后一次打牌的座位等于自己 并且牌型是炸弹 + if (room.lastDiscardSeat == owner.seat && room.discard.config == CardConfig.ZHA) { + + room.addAllBombScore(owner);// 炸弹玩家增加积分 + } + + // 如果最后一次的打牌的座位不等于零并且最后一次打牌的座位不等于自己 + if (room.lastDiscardSeat != 0 && room.lastDiscardSeat != owner.seat) { + + boolean bNextBaodan = false; + EXPlayer next = (EXPlayer) owner.room.playerMapBySeat.get(owner.nextSeat); + if (next.cardInhand.size() == 1) { + bNextBaodan = true; + } + CardGroup big_ct = CardCheck.genOutCard(owner.cardInhand, room.discard, room.config, bNextBaodan); + if (big_ct == null) { + + owner.stateMachine.changeState(Global.getState(EXPlayerPassState.class)); + return; + } else { + + if (big_ct.config.type == Config.TYPE_ZHA) { + // 如果能出完,就自动出完 + if (big_ct.card_list.size() == owner.cardInhand.size()) { + + doAction(owner, big_ct, true); + return; + } + } else { + + boolean bContainZha = false; + + Map cardMap = CardUtil.getCardNumMap(owner.cardInhand); + for (Map.Entry entry : cardMap.entrySet()) { + + int handNum = cardMap.get(entry.getKey()); + + // 4张牌 不能出现在处大赞的牌型中 + if (handNum >= 4) { + + bContainZha = true; + } + + } + + if (big_ct.card_list.size() == owner.cardInhand.size() && bContainZha == false) { + doAction(owner, big_ct, true); + return; + } + } + } + } else { + + // 自动出牌 + CardGroup auto_ct = CardCheck.autoOutLastHand2(owner.cardInhand, room.config, false); + if (auto_ct != null) { + doAction(owner, auto_ct, true); + return; + } + } + EXMainServer.gameCtr.discardTipEvent(owner); + + owner.startActionTimer(); + } + + @Override + public void reload(EXPlayer owner) { + EXMainServer.gameCtr.discardTipEvent(owner); + } + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } + + public void over(EXPlayer owner) { + EXRoom room = owner.getRoom(); + room.bankerSeat = owner.seat; + room.win = owner; + room.endGame(); + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + switch (cmd) { + case EXActionEvent.EVENT_DISCARD: + + ITObject netParam = (ITObject) param; + ITArray card_list = netParam.getTArray("card"); + ITArray all_card = netParam.getTArray("all_card"); + + if (all_card != null) { + ArrayList temCardList = new ArrayList(); + for (int i = 0; i < all_card.size(); ++i) { + temCardList.add(all_card.getInt(i)); + } + Collections.sort(temCardList); + + ArrayList temCardList2 = new ArrayList(); + for (int i = 0; i < owner.cardInhand.size(); ++i) { + temCardList2.add(owner.cardInhand.get(i).card); + } + Collections.sort(temCardList2); + + if (!temCardList.equals(temCardList2)) { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + } + + // 如果出的牌的个数为0 或者大于手牌的数目 则是非法的 + if (card_list.size() == 0 || card_list.size() > owner.cardInhand.size()) { + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_INVALID_TYPE); + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + + List list = CardUtil.toList(card_list); + + for (CardObj card : list) { + + boolean bNotExisted = false; + + for (CardObj handc : owner.cardInhand) { + if (card.card == handc.card) { + bNotExisted = true; + break; + } + } + + if (bNotExisted == false) { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + } + +// if(owner.getRoom().firstCard != 0 && CardUtil.getCard1(owner.getRoom().firstCard, list) == null) { +// EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_MUST_OUT_MIN); +// return; +// } + + CardGroup ct = CardCheck.getType(list, owner.room.config); + + if (ct == null) { + +// if (CardCheck.isConfig4_2_and_4_3(owner.room.config)) { +// //四带三摆尾 +// if (list.size() == owner.cardInhand.size()) { //最后一把 +// Map cardMap =CardUtil.getCardNumMap(list); +// +// if (ct == null) { +// if(owner.room.config.containsKey(Config.ROOM_CONFIG_SIDAI_3) && owner.room.config.getBoolean(Config.ROOM_CONFIG_SIDAI_3)) { +//// if (list.size() == 5 || list.size() == 6) { +//// ct = CardCheck.checkSiWithThree(cardMap,owner.room.config); +//// } +// if (list.size() == 5 ) { +// ct = CardCheck.checkSiWithThree(cardMap,owner.room.config); +// } +// +// } +// } +// +// if (ct != null) { +// for(CardObj cardObj : owner.cardInhand) { +// ct.card_list.add(cardObj); +// } +// ct.card_list_mp = CardUtil.toTArray(ct.card_list); +// } +// } +// } + + if (ct == null) { + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_INVALID_TYPE); + return; + } + } + + // 验证客户端发过来的类型 + if (!CardCheck.tryType(ct, owner.cardInhand.size(), owner.room.config)) { + + // tryType 判断3条a判断不出来, 所以 + if (!(ct.config.type == Config.TYPE_ZHA && card_list.size() == 3 && + + CardUtil.checkCard(RoomCard.CARD_A, list, 3))) { + + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_INVALID_TYPE); + return; + } + } + + // 如果炸弹不允许拆分,则检测非炸弹和4带三的牌型,看他们是否拆分了炸弹 + + if (ct.config.type != Config.TYPE_ZHA) { + + Map hangCardMap = CardUtil.getCardNumMap(owner.cardInhand); + Map cardMap = CardUtil.getCardNumMap(list); + for (Map.Entry entry : cardMap.entrySet()) { + + int handNum = hangCardMap.get(entry.getKey()); + + // 4张牌 不能出现在处大赞的牌型中 + if (handNum >= 4) { + + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_BOMB_CHAI); + return; + } + + } + } + + doAction(owner, ct, false); + break; + + case EXActionEvent.EVENT_PASS: + + if (owner.room.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1) { + return; + } + pass(owner); + + break; + case EXActionEvent.EVENT_OFFLINE: + owner.startActionTimer(); + break; + case EXActionEvent.EVENT_TIMER_AUTO: + case EXActionEvent.EVENT_ENTRUST: + + AutoOut(owner); + break; + } + } + + private void AutoOut(EXPlayer owner) { + + EXRoom room = owner.getRoom(); + + if (room.lastDiscardSeat != 0 && room.lastDiscardSeat != owner.seat) { + + CardGroup big_ct = null; + EXPlayer playerNext = (EXPlayer) room.playerMapBySeat.get(owner.nextSeat); + if (playerNext != null && room.discard.config.type == Config.TYPE_DANPAI + && playerNext.cardInhand.size() == 1) { + + Map> cardMap = CardUtil.getCardListMap(owner.cardInhand); + big_ct = CardCheck.selectDanpai(cardMap, room.discard, room.config, true); + } else { + big_ct = CardCheck.tryBig(owner.cardInhand, room.discard); + } + + if (big_ct != null) { + big_ct.card_list_mp = CardUtil.toTArray(big_ct.card_list); + doAction(owner, big_ct, true); + } else { + pass(owner); + } + + } else { + + // 在托管或者自动出牌的时候 系统先出炸弹,如果炸弹没有 再出单张 + // 将来可以把这个函数做的能智能一些,不光可以出炸弹 也可以出顺子飞机等等 + CardGroup out_ct = CardCheck.autoOut(owner.cardInhand, owner.room.config); + if (out_ct == null) { + + out_ct = new CardGroup(); + List out_list = new ArrayList<>(); + out_ct.card_list = out_list; + out_ct.config = CardConfig.DAN; + out_ct.len = 1; + + if (room.firstCard != 0) { + CardObj co = CardUtil.getCard1(room.firstCard, owner.cardInhand); + out_list.add(co); + } else { + EXPlayer next = (EXPlayer) owner.room.playerMapBySeat.get(owner.nextSeat); + if (next.cardInhand.size() == 1) { + out_list.add(owner.cardInhand.get(owner.cardInhand.size() - 1)); + } else { + out_list.add(owner.cardInhand.get(0)); + } + } + } + + out_ct.card_list_mp = CardUtil.toTArray(out_ct.card_list); + out_ct.min_card = out_ct.card_list.get(0).cardMod; + + doAction(owner, out_ct, true); + } + } + + private void pass(EXPlayer owner) { + EXMainServer.gameCtr.pass(owner);// 打不起过 + this.toNextState(owner);// 下一位大哥 + } + + private void doAction(EXPlayer owner, CardGroup ct, boolean skip) { + + EXRoom room = owner.getRoom(); + boolean outcard = true; + if (!skip) { + + if (room.lastDiscardSeat != 0 && room.lastDiscardSeat != owner.seat) { + outcard = CardCheck.tryCompete(room.discard, ct, room.config); + } + + // 如果玩家的下家只有一张牌,玩家出单张必须是最大的 + if (outcard && ct.config.type == Config.TYPE_DANPAI) { + + EXPlayer playerNext = (EXPlayer) room.playerMapBySeat.get(owner.nextSeat); + if (playerNext != null && playerNext.cardInhand.size() == 1) { + + Map cardMap = CardUtil.getCardNumMap(owner.cardInhand); + for (Integer number : cardMap.keySet()) { + + if (ct.min_card < number) { + + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_MUST_OUT_MAX); + return; + } + } + } + } + } + if (!outcard) { + EXMainServer.gameCtr.sendPutError(owner, Config.PUT_ERROR_INVALID_TYPE); + return; + } + + EXMainServer.gameCtr.outCard(owner, ct); + + if (owner.cardInhand.size() == 0) { + // 如果最后一手牌是炸弹 则需要添加炸弹分 + if (ct.config.type == Config.TYPE_ZHA) { + + room.addAllBombScore(owner);// 炸弹玩家增加积分 + } + this.over(owner); + } else { + this.toNextState(owner); + } + } + +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerPassState.java b/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerPassState.java new file mode 100644 index 0000000..97a56be --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/player/state/EXPlayerPassState.java @@ -0,0 +1,52 @@ +package extend.pk.player.state; + +import com.game.Global; +import com.game.data.Timer; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; + +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.room.state.EXRoomSetpState; + +/** + * 等待玩家Pass状态 + * + * + */ +public class EXPlayerPassState extends StateBase { + + private void pass(EXPlayer owner) { + EXMainServer.gameCtr.pass(owner);//打不起过 + this.toNextState(owner);//下一位大哥 + } + + @Override + public void enter(EXPlayer owner) { + EXRoom room = owner.getRoom(); + if(!owner.entrust) { + Timer passTimer = new Timer(10, new Timer.ITaskHandler() { + @Override + public void doTask(Timer timer) { + pass(owner); + } + }); + room.addTimer(passTimer); + }else { + pass(owner); + } + } + + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomDealState.java b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomDealState.java new file mode 100644 index 0000000..67cfa86 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomDealState.java @@ -0,0 +1,112 @@ +package extend.pk.room.state; + + + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import com.taurus.permanent.TPServer; +import extend.pk.Config; +import extend.pk.EXMainServer; +import extend.pk.EXPlayBack; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.uitl.CardCheck; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 房间发牌状态 + * + * + */ +public class EXRoomDealState extends StateBase { + @Override + public void enter(EXRoom owner) { + boolean donghua = false; + for (Map.Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.xi_pai) + { + donghua = true; + break; + } + } + + if (donghua) + { + owner.notifyXiPai(); + //启动定时器 + timer(owner); + } + else { + this.toNextState(owner); + } + + } + + public static void timer(EXRoom owner) { + + TPServer.me().getTimerPool().schedule(new Runnable() { + + @Override + public void run() { + + if (owner == null) { + Global.logger.error("room is null"); + return; + } + + if (owner.isDestroy) + return; + + owner.enqueueRunnable(new Runnable() { + + @Override + public void run() { + owner.stateMachine.toNextState(); + } + }); + } + }, 3000, TimeUnit.MILLISECONDS); + } + + @Override + public void toNextState(EXRoom owner) { + //owner.card.init(); + if(owner.bankerSeat!=0&&!owner.playerMapBySeat.containsKey(owner.bankerSeat)) { + owner.bankerSeat = 0; + } + EXMainServer.gameCtr.dealCard(owner); + + owner.playBackData = new EXPlayBack(owner); + +// if(owner.config.getInt(Config.ROOM_CONFIG_MINBOOM) == 1) { +// +// int startSpringSeat = 0; +// int seat = owner.bankerSeat; +// do { +// +// EXPlayer player = (EXPlayer)owner.playerMapBySeat.get(seat); +// if(CardCheck.checkStartSpring(player.cardInhand)) { +// +// startSpringSeat = seat; +// break; +// } +// }while(seat != owner.bankerSeat); +// +// if(startSpringSeat != 0) { +// owner.bankerSeat = startSpringSeat; +// owner.win = (EXPlayer)owner.playerMapBySeat.get(startSpringSeat); +// owner.endGame(); +// return; +// } +// } + + + + owner.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomSetpState.java b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomSetpState.java new file mode 100644 index 0000000..ce6843c --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomSetpState.java @@ -0,0 +1,35 @@ +package extend.pk.room.state; + +import com.game.Global; +import com.game.state.StateBase; + +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.player.state.EXPlayerDiscardState; + +/** + * 房间转换座位 + * + * + */ +public class EXRoomSetpState extends StateBase { + + @Override + public void enter(EXRoom owner) { + EXPlayer player = null; + if (owner.activeSeat == 0) { + player = (EXPlayer) owner.playerMapBySeat.get(owner.bankerSeat); + } else { + player = (EXPlayer) owner.playerMapBySeat.get(owner.activeSeat); + int nextSeat = player.nextSeat; + player = (EXPlayer) owner.playerMapBySeat.get(nextSeat); + } + + + EXMainServer.gameCtr.changeActiveSeat(owner, player.seat); + + player.stateMachine.changeState(Global.getState(EXPlayerDiscardState.class)); + + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomStartGameState.java b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomStartGameState.java new file mode 100644 index 0000000..af3d56e --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/room/state/EXRoomStartGameState.java @@ -0,0 +1,38 @@ +package extend.pk.room.state; + +import java.util.Map.Entry; + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.pk.Config; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; + +/** + * 房间开始状态 + * + * + */ +public class EXRoomStartGameState extends StateBase { + + @Override + public void enter(EXRoom owner) { + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + player.clearEx(); + } + owner.clearEx(); + owner.startGame(); + + this.toNextState(owner); + } + + @Override + public void toNextState(EXRoom owner) { + + owner.stateMachine.changeState(Global.getState(EXRoomDealState.class)); + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/uitl/CardCheck.java b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardCheck.java new file mode 100644 index 0000000..6a9d618 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardCheck.java @@ -0,0 +1,859 @@ +package extend.pk.uitl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import extend.pk.CardGroup; +import extend.pk.CardObj; +import extend.pk.Config; +import extend.pk.RoomCard; + +/** + * + * + */ +public class CardCheck { + + /** + * 服务器跟牌判定 + * + * @param cardInhand + * @param out + * @param roomConfig + * @param nextBaodan + * @return + */ + public static CardGroup genOutCard(List cardInhand, CardGroup out, ITObject roomConfig, + boolean nextBaodan) { + + CardGroup cg = null; + + Map> cardMap = CardUtil.getCardListMap(cardInhand); + int handCardSize = cardInhand.size(); + // 如果有炸弹 并且玩家手上仅剩下炸弹 就不用找了 直接出牌就可以了 + cg = selectZha(cardMap, out, roomConfig); + if (cg != null && cg.card_list.size() == handCardSize) { + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + return cg; + } + + // 如果别的玩家出的是一张单牌,则寻找一个合适的单牌,如果找不到就用炸弹,炸弹没有则过 + if (out.config.type == Config.TYPE_DANPAI) { + + CardGroup tempCg = selectDanpai(cardMap, out, roomConfig, nextBaodan); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是不能带牌的牌型(对子,顺子,连队)则寻找合适的牌型,如果找不到就用炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_DUIZI) { + + CardGroup tempCg = selectWithoutCardType(handCardSize, cardMap, out, roomConfig); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是带牌的三带牌型 ,则寻找合适的牌型,如果找不到就用炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_3) { + + boolean bLack = false; + + CardGroup tempCg = selectWithCardType(cardInhand, cardMap, out, roomConfig, bLack); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果是四带二或者四带三 就不处理了,如果有炸弹,则玩家自己去选择是炸还是跟,如果没有炸弹 玩家也大不了,所以后面就不用判断了 + if (cg != null) { + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + return cg; + } + + /** + * 选择炸弹 + * + * @param cardMap + * @param out + * @param roomConfig + * @return + */ + private static CardGroup selectZha(Map> cardMap, CardGroup out, ITObject roomConfig) { + + CardGroup cg = null; + + int minValue = 0; + if (out.config.type == Config.TYPE_ZHA) { + minValue = out.min_card; + } + + for (Map.Entry> entry : cardMap.entrySet()) { + + if (entry.getValue().size() == 4 || (entry.getKey() == RoomCard.CARD_A && entry.getValue().size() == 3)) { + + if (entry.getKey() > minValue) { + + cg = new CardGroup(); + + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + + cg.card_list = new ArrayList<>(); + for (CardObj cardObj : entry.getValue()) { + cg.card_list.add(cardObj); + } + break; + } + } + } + + return cg; + } + + /** + * 选择单牌 + * + * @param cardMap + * @param out + * @param roomConfig + * @param nextBaodan + * @return + */ + public static CardGroup selectDanpai(Map> cardMap, CardGroup out, ITObject roomConfig, + boolean nextBaodan) { + CardGroup cg = null; + + int minValue = out.min_card + 1; + + if (!nextBaodan) { + + for (int i = minValue; i <= 15; i++) { + + List listCard = cardMap.get(i); + if (listCard != null && listCard.size() >= 1) { + // 如果是炸弹 并且不能拆分炸弹,则不能用它作为单牌来处理 + if ((listCard.size() == 4 || (i == RoomCard.CARD_A && listCard.size() == 3))) { + + } else { + cg = new CardGroup(); + + cg.config = CardConfig.DAN; + cg.min_card = i; + cg.len = 1; + + cg.card_list = new ArrayList<>(); + cg.card_list.add(listCard.get(0)); + break; + } + } + } + } else { + for (int i = 15; i >= minValue; i--) { + + List listCard = cardMap.get(i); + if (listCard != null && listCard.size() >= 1) { + + // 如果是炸弹 并且不能拆分炸弹,则不能用它作为单牌来处理 + if ((listCard.size() == 4 || (i == RoomCard.CARD_A && listCard.size() == 3))) { + + } else { + + cg = new CardGroup(); + + cg.config = CardConfig.DAN; + cg.min_card = i; + cg.len = 1; + + cg.card_list = new ArrayList<>(); + cg.card_list.add(listCard.get(0)); + break; + } + } + } + } + + return cg; + } + + /** + * 选择不需要带牌的牌型 + * + * @param handCardSize + * @param cardMap + * @param out + * @param roomConfig + * @return + */ + private static CardGroup selectWithoutCardType(int handCardSize, Map> cardMap, CardGroup out, + ITObject roomConfig) { + CardGroup cg = null; + + int len = out.len; + + // 如果手牌数满足要求 + if (handCardSize >= len * out.config.repeat_num) { + + List card_list = new ArrayList(); + + // 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + int min_card = out.min_card + 1; + + // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + int max_card = min_card + len - 1; + + // 长度如果大于一并且最大的牌 + if (!(len > 1 && max_card > 14)) { + + int count = 0; + + for (int i = min_card; i <= 14; ++i) { + + List list = cardMap.get(i); + + // 如果牌值对应的牌为空 或者他是炸弹,则之前找到的牌取消 + if (list == null || ((list.size() == 4 || (i == RoomCard.CARD_A && list.size() == 3)))) { + count = 0; + card_list.clear(); + continue; + } + + // 如果牌值对应的牌的个数满足要求,则将牌放入队列中 + if (list.size() >= out.config.repeat_num) { + + for (int k = 0; k < out.config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + + // 如果已经找到了足够数量的相同牌型 + if (count == len) { + + cg = new CardGroup(); + + cg.config = out.config; + cg.card_list = card_list; + cg.len = len; + cg.min_card = card_list.get(0).cardMod; + + return cg; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + return cg; + } + + private static CardGroup selectWithCardType(List cardInhand, Map> cardMap, + CardGroup out, ITObject roomConfig, boolean bLack) { + + CardGroup cg = null; + + int handCardSize = cardInhand.size(); + + int len = out.len; + + // 如果手牌数满足要求 + if (handCardSize >= len * out.config.repeat_num) { + + List card_list = new ArrayList(); + + // 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + int min_card = out.min_card + 1; + + // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + int max_card = min_card + len - 1; + + // 长度如果大于一并且最大的牌 + if (!(len > 1 && max_card > 14)) { + + int count = 0; + + for (int i = min_card; i <= 14; ++i) { + + List list = cardMap.get(i); + + // 如果牌值对应的牌为空 或者他是炸弹,则之前找到的牌取消 + if (list == null || ((list.size() == 4 || (i == RoomCard.CARD_A && list.size() == 3)))) { + count = 0; + card_list.clear(); + continue; + } + + // 如果牌值对应的牌的个数满足要求,则将牌放入队列中 + if (list.size() >= out.config.repeat_num) { + + for (int k = 0; k < out.config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + + // 如果已经找到了足够数量的相同牌型 + if (count == len) { + + int sd = out.config.repeat_num * len + out.config.with_card_num * len; + + if (bLack == false && handCardSize < sd) { + + return cg; + } + + // 新建一个临时的列表,来保存剩余的牌 + List tem_list = new ArrayList(); + tem_list.addAll(cardInhand); + CardUtil.removeCard(tem_list, card_list); + + // 如果剩余的牌有炸弹,则需要把剩余牌中的炸弹对应的牌从临时列表中剔除,以确定是否有足够的单牌 + // 如果因为剔除的原因,最后牌型不能做成,那就提示他有炸弹出就可以了 + Map> reservedCardMap = CardUtil.getCardListMap(tem_list); + int duiNum = 0; + for (Map.Entry> entry : reservedCardMap.entrySet()) { + + int num = entry.getValue().size(); + if (num == 4 || (entry.getKey() == RoomCard.CARD_A && num == 3)) { + + CardUtil.removeCard(tem_list, entry.getValue()); + } + + if (num >= 2) { + duiNum++; + } + } + + // 如果手牌数多于牌型的基本要求 + if (handCardSize >= sd) { + + if (tem_list.size() < out.config.with_card_num * len) { + return cg; + } + + for (int m = 0; m < out.config.with_card_num * len; m++) { + card_list.add(tem_list.get(m)); + } + } else { + + card_list.addAll(tem_list); + } + + cg = new CardGroup(); + + cg.config = out.config; + cg.card_list = card_list; + cg.len = len; + cg.min_card = card_list.get(0).cardMod; + + return cg; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + return cg; + } + + /** + * 得到所出牌的牌型 + * + * @param cardOut + * @param roomConfig + * @return + */ + public static CardGroup getType(List cardOut, ITObject roomConfig) { + + CardGroup cg = autoOutLastHand(cardOut, roomConfig, true); + + return cg; + } + + /** + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOutLastHand(List cardInhand, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + int len = cardInhand.size(); + if (len == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DAN; + cg.min_card = cardInhand.get(0).cardMod; + cg.len = 1; + } else if (len == 2) { + cg = checkTwo(cardMap); + } else if (len == 3) { + + cg = checkThree(cardMap, roomConfig); + } else if (len == 4) { + + cg = checkFour(cardMap, roomConfig); + } else if (len == 5) { + +// if (isConfig4_2_and_4_3(roomConfig) && getMaxCardNum(cardMap) == 4) {// 四带一 +// return null;// 不能判为三带二 +// } + + cg = checkFive(cardMap, roomConfig, bSpecial); + } else { + if (bSpecial) { + + } + + if (cg == null) { + } + } + + if (cg != null) { + + for (CardObj cardObj : cardInhand) { + cg.card_list.add(cardObj); + } + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + + return cg; + } + + /** + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOutLastHand2(List cardInhand, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + int len = cardInhand.size(); + if (len == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DAN; + cg.min_card = cardInhand.get(0).cardMod; + cg.len = 1; + } else if (len == 2) { + cg = checkTwo(cardMap); + } else if (len == 3) { + + cg = checkThree(cardMap, roomConfig); + } else if (len == 4) { + + cg = checkFour(cardMap, roomConfig); + } else if (len == 5) { + +// if (isConfig4_2_and_4_3(roomConfig) && getMaxCardNum(cardMap) == 4) {// 四带一 +// return null;// 不能判为三带二 +// } + + if (cardInhand.size() == 5 && getMaxCardNum(cardMap) == 4) { + return null; + } + cg = checkFive(cardMap, roomConfig, bSpecial); + } else { + if (bSpecial) { + + } + + if (cg == null) { + + } + } + + if (cg != null) { + + for (CardObj cardObj : cardInhand) { + cg.card_list.add(cardObj); + } + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + + return cg; + } + + private static int getMaxCardNum(Map cardMap) { + int maxNum = 0; + for (Map.Entry entry : cardMap.entrySet()) { + if (entry.getValue() > maxNum) { + maxNum = entry.getValue(); + } + } + + return maxNum; + } + +// public static boolean isConfig4_2_and_4_3(ITObject roomConfig) { +// if ((roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_2) && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_2)) +// || (roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_3) +// && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_3))) { +// return true; +// } else { +// return false; +// } +// } + + private static CardGroup checkTwo(Map cardMap) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + if (entry.getValue() == 2) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DUIZI; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + + return cg; + } + + private static CardGroup checkThree(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 3) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN; + cg.min_card = entry.getKey(); + cg.len = 1; + + } + } + return cg; + } + + private static CardGroup checkFour(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + return cg; + } + + private static CardGroup checkFive(Map cardMap, ITObject roomConfig, boolean bSpecial) { + CardGroup cg = null; + for (Map.Entry entry : cardMap.entrySet()) { + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + + return cg; + } + + /** + * 自动出牌 + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOut(List cardInhand, ITObject roomConfig) { + + CardGroup cg = null; + + // 寻找炸弹 + Map cardMap = CardUtil.getCardNumMap(cardInhand); + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + List out_list = new ArrayList<>(); + + cg.card_list = out_list; + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + + for (CardObj cardObj : cardInhand) { + + if (cardObj.cardMod == entry.getKey()) { + out_list.add(cardObj); + } + } + } + } + + return cg; + } + + /** + * 验证牌型 + * + * @param ct + * @param left_count + * @return + */ + public static boolean tryType(CardGroup ct, int left_count, ITObject roomConfig) { + List cardInhand = ct.card_list; + int size = cardInhand.size(); + CardConfig config = ct.config; + + if (size < config.min_card_num || size > config.max_card_num) { + return false; + } + int len = ct.len; + if (len < config.min_len) { + return false; + } + // 牌型所需要的正常牌数 + int tem_size = len * config.repeat_num + len * config.with_card_num; + + // 如果牌型可以带牌 并且手牌的剩余数等于出牌的数目(全出了) + if (config.with_card_num > 0 && size == left_count) { + // 牌太少了 出牌太多了 + if (size < len * config.repeat_num || size > tem_size) { + return false; + } + + } + // 没有带牌 没有全出 + else { + if (tem_size != size) { + return false; + } + } + + int min_card = ct.min_card; + + int max_card = min_card + len - 1; + + if (len > 1 && max_card > 14) { + return false; + } + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + for (int i = min_card; i <= max_card; ++i) { + if (!cardMap.containsKey(i)) { + return false; + } + if (cardMap.get(i) < config.repeat_num) { + return false; + } + } + return true; + } + + /** + * 比牌大小 + * + * @param banker + * @param other + * @return + */ + public final static boolean tryCompete(CardGroup banker, CardGroup other, ITObject roomConfig) { + int bankerCradType = banker.config.type; + int otherCradType = other.config.type; + + if (bankerCradType != Config.TYPE_ZHA && otherCradType == Config.TYPE_ZHA) { + return true; + } + if (bankerCradType != otherCradType) { + return false; + } + + if (other.min_card > banker.min_card) { + if (otherCradType == Config.TYPE_ZHA) { + + return true; + } else { + + if (other.len == banker.len) { + return true; + } else { + return false; + } + } + } + + return false; + } + + public final static CardGroup tryBig(List cardInhand, CardGroup other) { + + List card_list = new ArrayList(); + int size = cardInhand.size(); + CardConfig config = other.config; + Map> cardMap = null; + int len = other.len; + + if (size >= len * config.repeat_num) { + + int min_card = other.min_card + 1;// 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + + int max_card = min_card + len - 1; // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + + if (!(len > 1 && max_card > 14)) {// 长度如果大于一并且最大的牌 + + int count = 0; + cardMap = CardUtil.getCardListMap(cardInhand); + int max = len > 1 ? 14 : 15; + for (int i = min_card; i <= max; ++i) { + + List list = cardMap.get(i); + + if (cardMap.containsKey(i) && list.size() >= config.repeat_num) { + + // 不出炸牌 + if (other.config.type != Config.TYPE_ZHA && list.size() >= 4) { + count = 0; + card_list.clear(); + continue; + } + + for (int k = 0; k < config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + if (count == len) { + CardGroup ct = new CardGroup(); + ct.config = other.config; + ct.card_list = card_list; + ct.len = len; + ct.min_card = card_list.get(0).cardMod; + if (config.with_card_num > 0) { + List tem_list = new ArrayList(); + tem_list.addAll(cardInhand); + CardUtil.removeCard(tem_list, card_list); + + // 不把炸牌带出去 + int rcard_size = 0; + rcard: for (int k = 0; k < tem_list.size(); ++k) { + int card = tem_list.get(k).cardMod; + List tem_list1 = cardMap.get(card); + if (tem_list1.size() >= 4) { + CardUtil.removeCard(tem_list, tem_list1); + rcard_size += 4; + break rcard; + } + } + int with_card_size = config.with_card_num * len; + if (rcard_size == 0) { + with_card_size = tem_list.size() < with_card_size ? tem_list.size() + : with_card_size; + } + if (tem_list.size() < with_card_size) { + break; + } + for (int k = 0; k < with_card_size; ++k) { + card_list.add(tem_list.get(k)); + } + } + return ct; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + if (other.config.type != Config.TYPE_ZHA && cardInhand.size() >= 4) { + if (cardMap == null) { + cardMap = CardUtil.getCardListMap(cardInhand); + } + + for (Entry> entry : cardMap.entrySet()) { + int card = entry.getKey(); + List list = entry.getValue(); + if (list.size() >= 4) { + CardGroup ct = new CardGroup(); + ct.config = CardConfig.ZHA; + ct.card_list = list; + ct.len = 1; + ct.min_card = card; + return ct; + } + } + } + return null; + } + + public static boolean checkStartSpring(List cardInhand) { + + boolean bRet = false; + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + if (cardMap.getOrDefault(RoomCard.CARD_3, 0) == 4) { + + bRet = true; + } else if (cardMap.getOrDefault(RoomCard.CARD_2, 0) == 1 && cardMap.getOrDefault(RoomCard.CARD_A, 0) == 3) { + + bRet = true; + } + + return bRet; + } + + public static void main(String[] args) { + + ITObject test = new TObject(); + ITArray card_list = new TArray(); + card_list.addInt(215); + card_list.addInt(114); + card_list.addInt(303); + card_list.addInt(204); + card_list.addInt(205); + // card_list.addInt(307); + // card_list.addInt(207); + test.putInt("sidaiyi", 0); + test.putInt("threeA", 1); + test.putInt("threelack", 1); + test.putInt("fourBeltThree", 1); + List tlist = CardUtil.toList(card_list); + System.out.println(tlist); + CardGroup ct = CardCheck.getType(tlist, test); + // Boolean a = CardCheck.tryType(ct,4,test); + System.out.println(ct); + // System.out.println(a); + + } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/uitl/CardConfig.java b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardConfig.java new file mode 100644 index 0000000..f49f09e --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardConfig.java @@ -0,0 +1,39 @@ +package extend.pk.uitl; + +import extend.pk.Config; + +public enum CardConfig { + DAN("单牌", Config.TYPE_DANPAI, 1, 1, 1, 1, 0), + DUIZI("对子", Config.TYPE_DUIZI, 1, 2, 2, 2, 0), + SAN("三不带", Config.TYPE_3, 1, 3, 3, 3, 0), + ZHA("炸弹", Config.TYPE_ZHA, 1, 4, 4, 24, 0); + + public final int type; + public final String name; + public final int min_len; + public final int repeat_num; + public final int min_card_num; + public final int max_card_num; + public final int with_card_num; + + private CardConfig(String name, int type, int min_len, int repeat_num, int min_card_num, int max_card_num, + int with_card_num) { + this.name = name; + this.type = type; + + this.min_len = min_len; + this.repeat_num = repeat_num; + this.min_card_num = min_card_num; + this.max_card_num = max_card_num; + this.with_card_num = with_card_num; + } + + public String toString() { + return this.name; + } +// +// public static void main(String[] args) { +// String string = "0x4e34aab634F52d919E23399ed17c12A688483013".toLowerCase(); +// System.out.println(string); +// } +} diff --git a/game_pk_duoduo/src/main/java/extend/pk/uitl/CardUtil.java b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardUtil.java new file mode 100644 index 0000000..741ff18 --- /dev/null +++ b/game_pk_duoduo/src/main/java/extend/pk/uitl/CardUtil.java @@ -0,0 +1,419 @@ +package extend.pk.uitl; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import extend.pk.CardObj; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CardUtil { + + /** + * list to TArray + * + * @param list + * @return + */ + public static final ITArray toTArray(List list) { + ITArray result = new TArray(); + for (CardObj card : list) { + result.addInt(card.card); + } + return result; + } + + public static final CardObj getCard(int eventCard, List cardList) { + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + return card; + } + } + return null; + } + + public static final CardObj getCard1(int eventCard, List cardList) { + for (CardObj card : cardList) { + if (card.card == eventCard) { + return card; + } + } + return null; + } + + /** + * 检测牌数量 + * + * @param eventCard + * @param cardList + * @param num + * @return + */ + public static final boolean checkCard(int eventCard, List cardList, int num) { + int result = 0; + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + result++; + if (result == num) + return true; + } + } + return false; + } + + public static final boolean checkGoodCard(int eventCard, List cardList, int num) { + int result = 0; + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + result++; + if (result >= num) + return true; + } + } + return false; + } + + public static final boolean checkShunZi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard + 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 1)) { + result++; + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 1)) { + result++; + } + } + } + } + } + + if (result >= 5) { + return true; + } + return false; + } + + public static final boolean checkSevenShunzi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard + 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 6, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 7, cardList, 1)) { + result++; + } + } + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 6, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 7, cardList, 1)) { + result++; + } + } + } + } + } + } + } + + if (result >= 6) { + return true; + } + return false; + } + + public static final boolean checkSanTiao(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 2)) { + + if (checkGoodCard(eventCard, cardList, 3)) { + result++; + + } + } + + if (result >= 2) { + return true; + } + return false; + } + + public static final boolean checkFenJi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 1, cardList, 3)) { + result++; + } + if (checkGoodCard(eventCard - 1, cardList, 3)) { + result++; + } + } + + if (result >= 2) { + return true; + } + return false; + } + + public static final boolean checkFourDui(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 1)) { + result++; + } + + if (checkGoodCard(eventCard + 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 2)) { + result++; + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 2)) { + result++; + } + } + } + } + + if (result >= 4) { + return true; + } + return false; + } + + public static final boolean checkSixDui(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 1)) { + result++; + } + + if (checkGoodCard(eventCard + 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 6, cardList, 2)) { + result++; + } + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 6, cardList, 2)) { + result++; + } + } + } + } + } + } + + if (result >= 6) { + return true; + } + return false; + } + + public static final boolean checkQPai(int eventCard, List cardList) { + int result = 0; + if (eventCard >= 12) { + result++; + for (CardObj card : cardList) { + if (card.cardMod >= 12) { + result++; + } + } + } + + if (result >= 5) { + return true; + } + return false; + } + + public static final boolean checkKPai(int eventCard, List cardList) { + int result = 0; + if (eventCard >= 14) { + result++; + for (CardObj card : cardList) { + if (card.cardMod >= 14) { + + result++; + } + } + } + + if (result >= 1) { + return true; + } + return false; + } + + /** + * TArray to list + * + * @param list + * @return + */ + public static final List toList(ITArray list) { + List tem = new ArrayList(); + for (int i = 0; i < list.size(); ++i) { + tem.add(new CardObj(list.getInt(i))); + } + return tem; + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final Map getCardNumMap(List cardList) { + Map result = new HashMap(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + return result; + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final void getCardNumMap(Map result, List cardList) { + result.clear(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + } + + public static final void getCardNumMap(Map result, List cardList, CardObj tempCard) { + result.clear(); + result.put(tempCard.cardMod, 1); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final Map> getCardListMap(List cardList) { + Map> result = new HashMap>(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + List list = new ArrayList(); + list.add(card); + result.put(card.cardMod, list); + } else { + List list = result.get(card.cardMod); + list.add(card); + } + } + return result; + } + + static public void removeCard(List cardList, List cards) { + for (int i = 0; i < cards.size(); i++) { + for (int j = 0; j < cardList.size(); j++) { + if (cardList.get(j).card == cards.get(i).card) { + cardList.remove(j); + break; + } + } + } + } +} diff --git a/game_pk_duoduo/src/test/java/game_pk_paodekuai/MainPaodekuai.java b/game_pk_duoduo/src/test/java/game_pk_paodekuai/MainPaodekuai.java new file mode 100644 index 0000000..0d30aa1 --- /dev/null +++ b/game_pk_duoduo/src/test/java/game_pk_paodekuai/MainPaodekuai.java @@ -0,0 +1,9 @@ +package game_pk_paodekuai; + +import com.taurus.permanent.TPServer; + +public class MainPaodekuai { + public static void main(String[] args) { + TPServer.me().start(); + } +} diff --git a/game_pk_paodekuai/.idea/compiler.xml b/game_pk_paodekuai/.idea/compiler.xml new file mode 100644 index 0000000..da870f6 --- /dev/null +++ b/game_pk_paodekuai/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/game_pk_paodekuai/.idea/encodings.xml b/game_pk_paodekuai/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/game_pk_paodekuai/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/game_pk_paodekuai/.idea/jarRepositories.xml b/game_pk_paodekuai/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/game_pk_paodekuai/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/game_pk_paodekuai/.idea/misc.xml b/game_pk_paodekuai/.idea/misc.xml new file mode 100644 index 0000000..d5cd614 --- /dev/null +++ b/game_pk_paodekuai/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/game_pk_paodekuai/.idea/vcs.xml b/game_pk_paodekuai/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/game_pk_paodekuai/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/game_pk_paodekuai/config/game-config.xml b/game_pk_paodekuai/config/game-config.xml new file mode 100644 index 0000000..53a7f40 --- /dev/null +++ b/game_pk_paodekuai/config/game-config.xml @@ -0,0 +1,10 @@ + + + + 192.168.1.3 + 192.168.1.3 + 6841 + 8830 + 66 + true + diff --git a/game_pk_paodekuai/config/log4j.properties b/game_pk_paodekuai/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/game_pk_paodekuai/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/game_pk_paodekuai/config/taurus-core.xml b/game_pk_paodekuai/config/taurus-core.xml new file mode 100644 index 0000000..692935b --- /dev/null +++ b/game_pk_paodekuai/config/taurus-core.xml @@ -0,0 +1,95 @@ + + + log4j.properties + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://127.0.0.1:8060/wb_game + wb_game + 363b76546c + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 200 + + 8 + + 1 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + diff --git a/game_pk_paodekuai/config/taurus-permanent.xml b/game_pk_paodekuai/config/taurus-permanent.xml new file mode 100644 index 0000000..e3ae95e --- /dev/null +++ b/game_pk_paodekuai/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 2 + + 100 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 2 + 3 + 10 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 8080 +
+ + + + extension - test + extend.pk.EXMainServer + + + + + Sys + 4 + 16 + 60000 + 20000 + + + + + Ext + 4 + 16 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/game_pk_paodekuai/pom.xml b/game_pk_paodekuai/pom.xml new file mode 100644 index 0000000..641c53a --- /dev/null +++ b/game_pk_paodekuai/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + com.game + game_pk_paodekuai + 1.0.0 + jar + + game_pk_paodekuai + http://maven.apache.org + + + UTF-8 + + + + + + com.game + game_common + 1.0.0 + + + + + game_paodekuai_puke + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + + diff --git a/game_pk_paodekuai/src/main/java/extend/pk/CardGroup.java b/game_pk_paodekuai/src/main/java/extend/pk/CardGroup.java new file mode 100644 index 0000000..fc7ee92 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/CardGroup.java @@ -0,0 +1,45 @@ +package extend.pk; + +import java.util.List; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import extend.pk.uitl.CardConfig; + +public class CardGroup { + /** + * 当前type + */ + public CardConfig config; + + public int min_card; + /** + * 长度 + */ + public int len = 1; + + public List card_list; + + public ITArray card_list_mp; + + public ITObject toObject(boolean card_size) { + ITObject obj = TObject.newInstance(); + if (card_size) { + obj.putInt("card_size", card_list.size()); + } else { + obj.putTArray("card_list", card_list_mp); + } + + obj.putInt("type", config.type); + obj.putInt("min_card", min_card); + obj.putInt("len", len); + return obj; + } + + public String toString() { + return "{type:" + config + " min_card:" + min_card + " len:" + len + " list:" + card_list + "}"; + } + +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/CardObj.java b/game_pk_paodekuai/src/main/java/extend/pk/CardObj.java new file mode 100644 index 0000000..bc2d762 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/CardObj.java @@ -0,0 +1,21 @@ +package extend.pk; + +public class CardObj implements Comparable{ + public int card; + public int cardMod; + + public CardObj(int card) { + this.card = card; + this.cardMod = card % 100; + } + + @Override + public int compareTo(CardObj paramT) { + return cardMod == paramT.cardMod ? 0 : cardMod < paramT.cardMod ? -1 : 1; + } + + @Override + public String toString() { + return card + ""; + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/Config.java b/game_pk_paodekuai/src/main/java/extend/pk/Config.java new file mode 100644 index 0000000..f803e57 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/Config.java @@ -0,0 +1,248 @@ +package extend.pk; + +public class Config { + + public static final int XIPAI_SCORE = 10; + + /** + * 玩家的初始手牌数 + */ + public static final String ROOM_CONFIG_CARDNUM = "leaf"; + + /** + * 炸弹带的规则 + */ + public static final String ROOM_CONFIG_SIDAI = "fourBeltThree"; + + public static final String ROOM_CONFIG_SIDAI_2 = "fourDaiTwo"; + public static final String ROOM_CONFIG_SIDAI_3 = "fourDaiThree"; + + /** + * 首局出牌规则 + */ + public static final String ROOM_CONFIG_RULE = "rule"; + + /** + * 第一局系统随机选一张先出,随后赢家先出 + */ + public static final int RULE_RANDOM = 2; + + /** + * 第一局黑桃3先出,随后赢家先出 + */ + public static final int RULE_HEITAO3 = 1; + + /** + * 炸弹不能拆 + */ + public static final String ROOM_CONFIG_DEMOLITION = "demolition"; + /** + * 可不必出 + */ + public static final String ROOM_CONFIG_WILL_BE_OUT = "willBeOut"; + + /** + * 3条a是否是炸弹 + */ + public static final String ROOM_CONFIG_THREE_A = "threeA"; + + /** + * 红桃10分翻倍 + */ + public static final String ROOM_CONFIG_HEARTTEN = "heartten"; + + /** + * 飞机少带可接完 + */ + public static final String ROOM_CONFIG_PLANE_LACK = "planelack"; + + /** + * 飞机不带 + */ + public static final String ROOM_CONFIG_PLANE_NOBELT = "planeNoBelt"; + + /** + * 三张不带 + */ + public static final String ROOM_CONFIG_THREE_NOBELT = "threeNoBelt"; + + /** + * 三张少带可接完 + */ + public static final String ROOM_CONFIG_THREE_LACK = "threelack"; + + /** + * 4个3333 或者 2 AAA 算春天 + */ + public static final String ROOM_CONFIG_MINBOOM = "minboom"; + + /** + * 自动托管功能 + */ + public static final String ROOM_CONFIG_AUTO_TUOGUAN = "autotuoguan"; + + /** + * 飘分玩法 + */ + public static final String ROOM_CONFIG_PIAO = "piao"; + + /** + * 打鸟 + */ + public static final String ROOM_CONFIG_DANIAO = "daniao"; + + /** + * 三带 飞机带 + */ + public static final String ROOM_CONFIG_SANDAIDAN = "sandaidan"; + + public static final String ROOM_CONFIG_XIPAI = "xi_pai"; + + public static final String ROOM_CONFIG_XIPAI_SCORE = "xi_pai_score"; + + + /** + * 特殊加分 + */ + public static final String ROOM_CONFIG_SPECIL_ADD = "specilAdd"; + + //-------------------------------牌类型--------------------------------- + /** + * 单牌 + */ + public final static int TYPE_DANPAI = 1; + /** + * 对子 + */ + public final static int TYPE_DUIZI = 2; + /** + * 顺子 + */ + public final static int TYPE_SHUNZI = 3; + /** + * 连对 + */ + public final static int TYPE_LIANDUI = 4; + /** + * 3带2 + */ + public final static int TYPE_3_2 = 5; + + + /** + * 飞机 + */ + public final static int TYPE_FEIJI_2 = 6; + /** + * 4带3 + */ + public final static int TYPE_4_3 = 7; + + /** + * 炸 + */ + public final static int TYPE_ZHA = 8; + + /** + * 4带2 + */ + public final static int TYPE_4_2 = 9; + + /** + * 3不带 + */ + public final static int TYPE_3 = 10; + + /** + * 飞机不带 + */ + public final static int TYPE_FEIJI = 11; + + + //-------------------------------协议--------------------------------- + + public static final String GAME_EVT_MING_PAI = "2117"; + /** + * 发牌协议 + */ + public static final String GAME_EVT_PLAYER_DEAL = "2011"; + /** + * 出牌 + */ + public static final String GAME_DIS_CARD = "1013"; + /** + * 不出 + */ + public static final String GAME_DIS_PASS = "1014"; + /** + * + */ + public static final String GAME_PIAO = "1015"; + /** + * 出牌事件 + */ + public static final String GAME_EVT_DISCARD = "2021"; + /** + * 出牌提示事件 + */ + public static final String GAME_EVT_DISCARD_TIP = "2004"; + /** + * 转盘指向事件 + */ + public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "2016"; + /** + * pass事件 + */ + public static final String GAME_EVT_PASS = "2030"; + /** + * 更新炸弹分数 + */ + public static final String GAME_EVT_UPDATE_BOM_SCORE = "2118"; + + /** + * 小结算 + */ + public static final String GAME_EVT_RESULT1 = "2007"; + + + /** + * 获取下局指定牌型协议 + */ + public static final String GAME_EVT_NEEDCARDS = "888"; + + /** + * 生成下一幅牌 + */ + public static final String GAME_NEXTCARD = "8881"; + + /** + * 发送下一幅牌 + */ + public static final String GAME_EVT_NEXTCARD = "8882"; + + + /** + * 飘鸟提示 + */ + public static final String GAME_EVT_PIAO_TIP = "2031"; + public static final String GAME_EVT_PIAO = "2032"; + + + //炸弹分数 + public static final String GAME_EVT_BOMB_SCORE = "2110"; + + /** + * 出牌错误 + */ + public static final String GAME_EVT_PUT_ERROR = "2111"; + + public static final int PUT_ERROR_MUST_OUT_MIN = 0; + public static final int PUT_ERROR_INVALID_TYPE = 1; + public static final int PUT_ERROR_MUST_OUT_MAX = 2; + public static final int PUT_ERROR_BOMB_CHAI =3; + + public static final String SETTLE_WIN_COUNT = "winnum"; + public static final String SETTLE_CHUNTIAN_COUNT = "springnum"; + public static final String SETTLE_BOMB_COUNT = "boomnum"; + public static final String SETTLE_MAX_SCORE = "maxscore"; +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXActionEvent.java b/game_pk_paodekuai/src/main/java/extend/pk/EXActionEvent.java new file mode 100644 index 0000000..b94a22c --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXActionEvent.java @@ -0,0 +1,10 @@ +package extend.pk; + +import com.game.ActionEvent; + +public class EXActionEvent extends ActionEvent{ + + public static final String EVENT_DISCARD = "1013"; + public static final String EVENT_PASS = "1014"; + public static final String EVENT_PIAO= "1015"; +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXGameController.java b/game_pk_paodekuai/src/main/java/extend/pk/EXGameController.java new file mode 100644 index 0000000..208c91f --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXGameController.java @@ -0,0 +1,950 @@ +package extend.pk; + +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import com.game.Constant; +import com.game.GameController; +import com.game.Global; +import com.game.data.Player; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.permanent.data.Session; + +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + +/** + * + * + */ +public class EXGameController extends GameController { + + public EXGameController() { + super(); + } + + @ActionKey(Config.GAME_DIS_CARD) + public void RouterDisCard(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_DISCARD, 0, params); + } + + @ActionKey(Config.GAME_DIS_PASS) + public void RouterDisPass(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_PASS, 0, params); + } + + @ActionKey(Config.GAME_PIAO) + public void RouterPiao(Session sender, ITObject params, int gid, Player owner) { + owner.stateMachine.execute(EXActionEvent.EVENT_PIAO, 0, params); + } + + @ActionKey(Config.GAME_EVT_NEEDCARDS) + public void needCards(Session sender, ITObject params, int gid, EXPlayer owner) { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Boolean is_pk_can_choice = false; + String key = "pk_can_choice"; + try { + if (jedis1.hget("pk_can_choice", Global.gameId + "") == null) { + return; + } + String pk_can_choice = jedis1.hget(key, Global.gameId + ""); + String[] choices = pk_can_choice.split(","); + for (String playerId : choices) { + if (owner.playerid == Integer.parseInt(playerId)) { + is_pk_can_choice = true; + } + } + if (is_pk_can_choice == false) { + return; + } + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis1.close(); + } + owner.nextCardInhand.clear(); + String choic = params.getString("choic"); + + if (choic.equalsIgnoreCase("first") && owner.isChoice) { + List list = CardUtil.toList(params.getTArray("first")); + owner.nextCardInhand = list; + } + if (choic.equalsIgnoreCase("second") && owner.isChoice) { + List list = CardUtil.toList(params.getTArray("second")); + owner.nextCardInhand = list; + } + if (choic.equalsIgnoreCase("three") && owner.isChoice) { + List list = CardUtil.toList(params.getTArray("three")); + owner.nextCardInhand = list; + } + for (Entry entry : owner.getRoom().playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.playerid == owner.playerid) { + continue; + } + if (player.nextCardInhand.size() == 0) { + if (choic.equalsIgnoreCase("second")) { + player.nextCardInhand = CardUtil.toList(params.getTArray("three")); + } + if (choic.equalsIgnoreCase("first")) { + player.nextCardInhand = CardUtil.toList(params.getTArray("second")); + } + if (choic.equalsIgnoreCase("three")) { + player.nextCardInhand = CardUtil.toList(params.getTArray("first")); + } + + } + } + + } + + @ActionKey(Config.GAME_NEXTCARD) + public void checkCard(Session sender, ITObject params, int gid, EXPlayer owner) { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Boolean is_pk_can_choice = false; + String key = "pk_can_choice"; + try { + if (jedis1.hget("pk_can_choice", Global.gameId + "") == null) { + return; + } + String pk_can_choice = jedis1.hget(key, Global.gameId + ""); + String[] choices = pk_can_choice.split(","); + for (String playerId : choices) { + if (owner.playerid == Integer.parseInt(playerId)) { + is_pk_can_choice = true; + } + } + if (is_pk_can_choice == false) { + return; + } + } catch (Exception e) { + Global.logger.error(e); + return; + } finally { + jedis1.close(); + } + ITObject param = new TObject(); + for (Entry entry : owner.getRoom().playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.isChoice) { + return; + } + } + if (owner.getRoom().card.nextCardList.size() == 0) { + owner.getRoom().card.initNextCard(); + owner.isChoice = true; + for (int i = 0; i < 3; i++) { + List list = owner.getRoom().card.dealNext(true, true, 100, 0, 0, 0, 0, 4, 3); + ITArray result = new TArray(); + for (CardObj card : list) { + result.addInt(card.card); + } + if (i == 0) { + param.putTArray("first", result); + + } else if (i == 1) { + param.putTArray("second", result); + + } else if (i == 2) { + param.putTArray("three", result); + + } + } + + owner.sendEvent(Config.GAME_EVT_NEXTCARD, param); + } else { + + } + +// ITArray residuCard = Util.toTArray(owner.getRoom().card.cardList); +// param.putTArray("residueCard", owner.getRoom().card.cardList); +// param.putInt("seat", owner.seat); +// owner.getRoom().broadCastToClient(0, Config.GAME_EVT_CHECKCARD, param); + } + + // 改变活动玩家 + public void changeActiveSeat(EXRoom owner, int activeSeat) { + owner.activeSeat = activeSeat; + ITObject param = new TObject(); + param.putInt("index", activeSeat); + owner.broadCastToClient(0, Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param); + } + + public void sendPutError(EXPlayer owner, int code) { + ITObject param = new TObject(); + param.putInt("error", code); + owner.sendEvent(Config.GAME_EVT_PUT_ERROR, param); + } + + /** + * pass + * + * @param owner + */ + public void pass(EXPlayer owner) { + EXRoom room = owner.getRoom(); + ITObject response = new TObject(); + response.putInt("seat", owner.seat); + if (Global.loggerDebug) { + Global.logger.info(owner + " pass!"); + } + owner.pass = true; + owner.last_outcard = null; + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addPassCommand(owner.seat); + room.broadCastToClient(0, Config.GAME_EVT_PASS, response); + room.broadCastToClientOfSpectator(Config.GAME_EVT_PASS, response); + } + + /** + * 票鸟提示 + * + * @param owner + */ + public void piaoTipEvent(EXPlayer owner, int reload) { + + ITObject response = new TObject(); + response.putInt("piao", owner.room.config.getInt(Config.ROOM_CONFIG_PIAO)); + response.putInt("reload", reload); + owner.sendEvent(Config.GAME_EVT_PIAO_TIP, response); + } + + /** + * 票鸟事件 + * + * @param owner + */ + public void piaoEvent(EXPlayer owner) { + if (owner.piao == -1) + return; + + ITObject param = new TObject(); + param.putInt("seat", owner.seat); + param.putInt("piao", owner.piao); + owner.room.broadCastToClient(0, Config.GAME_EVT_PIAO, param); + } + + public void outCard(EXPlayer owner, CardGroup ct) { + EXRoom room = owner.getRoom(); + ITObject response = new TObject(); + response.putInt("player", owner.seat); + response.putTObject("card_obj", ct.toObject(false)); + + owner.outCards.addAll(ct.card_list); + + room.lastDiscardSeat = owner.seat; + room.discard = ct; + owner.last_outcard = ct; + owner.pass = false; + room.firstCard = 0; + if (Global.loggerDebug) { + Global.logger.info(owner + " out card:" + ct); + } + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addOutCardCommand(owner.seat, ct); + + CardUtil.removeCard(owner.cardInhand, ct.card_list); + + response.putInt("remain", owner.cardInhand.size()); + room.broadCastToClient(0, Config.GAME_EVT_DISCARD, response); + room.broadCastToClientOfSpectator(Config.GAME_EVT_DISCARD, response); + + List cardLists = new ArrayList(); + + // 加分 + TObject addPlayerScoreList = new TObject(); + + TObject param = new TObject(); + TArray addPlayerList = new TArray(); + + int numOne = 0; + int numTwo = 0; + if (room.discard.config == CardConfig.ZHA) { + // 拿ct.card_list第一位数字 + numTwo = ct.card_list.get(0).card % 100; + Jedis jediss = Redis.use("group1_db11").getJedis(); + + String playingGroupIdKeys = "g{" + owner.getRoom().groupId + "}:play:" + owner.getRoom().groupPid; + try { + String score = jediss.hget(playingGroupIdKeys, "hp_times"); + + // 循环除当前用户外的用户手牌最后一位数 + for (Entry entry : room.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + + if (player.playerid != owner.playerid) { + // 扣分 + TObject minusPlayerScoreList = new TObject(); + minusPlayerScoreList.putInt("seat", player.seat); + minusPlayerScoreList.putInt("pomSore", -10 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(minusPlayerScoreList); + pb.addZhaScoreCommand(player.seat, ct, -10 * Integer.parseInt(score) / 1000); + + Map maps = new HashMap(); + maps.put(player.seat, player.cardInhand); + // 循环 + for (Entry entry1 : maps.entrySet()) { + List cardInhand = entry1.getValue(); + for (int i = 0; i < cardInhand.size(); i++) { + CardObj cardObj = CardObj.class.cast(cardInhand.get(i)); // 明确获取 CardObj 对象 + int cardValue = cardObj.card % 100; + cardLists.add(cardValue); + } + + Map> map = cardLists.stream() + .collect(Collectors.groupingBy(Integer::intValue)); + for (Entry> entry2 : map.entrySet()) { + + if (entry2.getValue().size() == 4) { + numOne = entry2.getValue().get(0); + } + } + + if (numTwo > numOne) { + cardLists.clear(); + } + + } + Map> map = cardLists.stream() + .collect(Collectors.groupingBy(Integer::intValue)); + for (Entry> entry2 : map.entrySet()) { + if (entry2.getValue().size() == 4) { + numOne = entry2.getValue().get(0); + } + } + + } + + } + + if (room.maxPlayers == 3) { + // 存储当前用户的座位号和分数 + addPlayerScoreList.putInt("seat", owner.seat); + addPlayerScoreList.putInt("pomSore", 20 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(addPlayerScoreList); + pb.addZhaScoreCommand(owner.seat, ct, 20 * Integer.parseInt(score) / 1000); + + } else { + // 存储当前用户的座位号和分数 + addPlayerScoreList.putInt("seat", owner.seat); + addPlayerScoreList.putInt("pomSore", 10 * Integer.parseInt(score) / 1000); + addPlayerList.addTObject(addPlayerScoreList); + pb.addZhaScoreCommand(owner.seat, ct, 10 * Integer.parseInt(score) / 1000); + + } + } catch (Exception e) { + Global.logger.error(e); + } finally { + jediss.close(); + } + param.putTArray("PlayerScoreList", addPlayerList); + + if (numTwo > numOne && room.discard.config == CardConfig.ZHA) { + owner.room.broadCastToClient(0, Config.GAME_EVT_BOMB_SCORE, param); + owner.room.broadCastToClientOfSpectator(Config.GAME_EVT_BOMB_SCORE, param); + + } + + } + + } + + private CardGroup checkFour(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } else if (entry.getValue() == 3) { + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + if (entry.getKey() == RoomCard.CARD_A && bThreeA) { + return cg; + } + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_LACK) == 1) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN_2; + cg.min_card = entry.getKey(); + cg.len = 1; + } + + } else if (entry.getValue() == 2) { + + if (minCard == 0 || entry.getKey() < minCard) { + minCard = entry.getKey(); + } + + if (maxCard == 0 || entry.getKey() > maxCard) { + maxCard = entry.getKey(); + } + + if (minCard != 0 && maxCard != 0 && minCard + 1 == maxCard) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.LIANDUI; + cg.min_card = minCard; + cg.len = 2; + } + } + } + return cg; + } + + public void dealCard(EXRoom owner) { + if (owner.targetCards.size() == 0) { + owner.card.init(); + } + + int maxDanPai = 0; + int maxDuizi = 0; + int maxSanZhang = 0; + boolean existWhite = false; + boolean existXingyunhao = false; + boolean existGeneral = false; + boolean existBlack = false; + double white_rate = 0; + + ArrayList tmpPlayerList = new ArrayList<>(); + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + tmpPlayerList.add(player); + } + + Collections.shuffle(tmpPlayerList); + Random random2 = new Random(); + int seat = random2.nextInt(2) + 1; + + if (tmpPlayerList.size() == 3) { + seat = random2.nextInt(3) + 1; + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); +// if (player.seat == seat) { +// player.is_white = true; +// +// } + player.is_white = true; + if (player.is_white) { + existXingyunhao = true; + } else { + if (player.black_white_status == 0) { + existGeneral = true; + } else if (player.black_white_status == 1) { + existBlack = true; + } else if (player.black_white_status == 2) { + existWhite = true; + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + if (player.is_white) { + white_rate = 100; + } else { + continue; + } + if (player.nextCardInhand.size() != 0) { + List cardInhand = new ArrayList(); + cardInhand.addAll(player.nextCardInhand); + player.cardInhand = cardInhand; + player.nextCardInhand.clear(); + } else { + player.cardInhand = owner.card.deal(true, true, 100, player.black_white_status, player.black_white_rate, + player.black_white_rate, 0, 4, 3); + + } + + if (owner.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1 + && owner.config.getInt(Config.ROOM_CONFIG_HEARTTEN) == 2) { + if (CardUtil.getCard1(RoomCard.HEART_TEN, player.cardInhand) != null) { + player.isHaveRedTen = true; + } + } + + Collections.sort(player.cardInhand); + + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 2) { + white_rate = player.black_white_rate; + Global.logger + .info("dealcards playerid:" + player.playerid + " white player:" + player.black_white_rate); + } else { + continue; + } + } + + if (!existXingyunhao) { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate, player.black_white_rate, 0, 0, 0); + } else { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate, player.black_white_rate, maxDanPai, + maxDuizi, maxSanZhang); + + } + + if (owner.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1 + && owner.config.getInt(Config.ROOM_CONFIG_HEARTTEN) == 2) { + if (CardUtil.getCard1(RoomCard.HEART_TEN, player.cardInhand) != null) { + player.isHaveRedTen = true; + } + } + + Collections.sort(player.cardInhand); + + if (!existXingyunhao && (existGeneral || existBlack)) { + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 0) { + Global.logger.info( + "dealcards playerid:" + player.playerid + " general player:" + player.black_white_rate); + } else { + continue; + } + } + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, white_rate, white_rate, maxDanPai, maxDuizi, maxSanZhang); +// // 指定牌型 +// player.cardInhand = owner.card.deal0(player.seat); + +// if (!existXingyunhao && !existWhite) +// { +// //player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,player.black_white_status, white_rate, white_rate, 0, 0, 0); +// player.cardInhand = owner.card.deal1(player.seat); +// } +// else { +// player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, +// player.black_white_status, white_rate, white_rate, maxDanPai, maxDuizi, maxSanZhang); +// +// } +// + if (owner.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1 + && owner.config.getInt(Config.ROOM_CONFIG_HEARTTEN) == 2) { + if (CardUtil.getCard1(RoomCard.HEART_TEN, player.cardInhand) != null) { + player.isHaveRedTen = true; + } + } + + Collections.sort(player.cardInhand); + + if (!existXingyunhao && !existWhite && existBlack) { + Map playermap = CardUtil.getCardNumMap(player.cardInhand); + for (Entry card_entry : playermap.entrySet()) { + int card = card_entry.getKey(); + int num = card_entry.getValue(); + if (card > maxDanPai) { + maxDanPai = card; + } + + if (num == 2) { + if (card > maxDuizi) { + maxDuizi = card; + } + } + + if (num == 3) { + if (card > maxSanZhang) { + maxSanZhang = card; + } + } + } + } + } + + for (int i = 0; i < tmpPlayerList.size(); i++) { + EXPlayer player = tmpPlayerList.get(i); + + if (player.is_white) { + continue; + } else { + if (player.black_white_status == 1) { + Global.logger.info("dealcards playerid:" + player.playerid + " black player:" + + (player.black_white_rate + white_rate)); + } else { + continue; + } + } + + if (!existXingyunhao && !existWhite && !existGeneral) { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate + white_rate, + player.black_white_rate + white_rate, 1, 6, 3); + } else { + player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value, + player.black_white_status, player.black_white_rate + white_rate, + player.black_white_rate + white_rate, maxDanPai, maxDuizi, maxSanZhang); + } + + if (owner.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1 + && owner.config.getInt(Config.ROOM_CONFIG_HEARTTEN) == 2) { + if (CardUtil.getCard1(RoomCard.HEART_TEN, player.cardInhand) != null) { + player.isHaveRedTen = true; + } + } + + Collections.sort(player.cardInhand); + } + + if (owner.targetCards.size() > 0 && owner.adminSeat > 0 && owner.supCards.size() > 0) { + owner.card.cardList = owner.supCards.get(0); + } + + // 如果是首局,需要确定庄家 + if (owner.bankerSeat == 0) { + + int rule = Config.RULE_RANDOM; + if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) { + rule = owner.config.getInt(Config.ROOM_CONFIG_RULE); + } + + owner.bankerSeat = this.getBankerSeat(owner); + + + this.sendPlayerDeal(owner); + // 如果是随机确定庄家 + if (rule == Config.RULE_RANDOM) { + + EXPlayer player = (EXPlayer) owner.playerMapBySeat.get(owner.bankerSeat); + if (player != null) { + + int len = player.cardInhand.size(); + if (len > 0) { + Random random1 = new Random(); + int rand_pos = random1.nextInt(len); + + this.sendMingPai(owner, player.cardInhand.get(rand_pos).card); + } + } + } + } else { + this.sendPlayerDeal(owner); + } + + } + + /** + * 发生随机牌 用于指示谁首先出牌 + * + * @param owner + */ + private void sendMingPai(EXRoom owner, int card) { + + ITObject param = new TObject(); + param.putInt("mingpai", card); + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + + EXPlayer exPlayer = (EXPlayer) entry.getValue(); + exPlayer.sendEvent(Config.GAME_EVT_MING_PAI, param); + } + ; + } + + /** + * 发牌 + * + * @param owner + */ + private void sendPlayerDeal(EXRoom owner) { + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer exPlayer = (EXPlayer) entry.getValue(); + ITObject param = new TObject(); + ITArray handCard = CardUtil.toTArray(exPlayer.cardInhand); + param.putTArray("cards", handCard); + param.putInt("bank_seat", exPlayer.room.bankerSeat); + param.putInt("round", owner.round); + if (Global.loggerDebug) { + Global.logger.info(owner + " deal card:" + exPlayer.cardInhand); + } + exPlayer.sendEvent(Config.GAME_EVT_PLAYER_DEAL, param); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_PLAYER_DEAL, param); + } + ; + } + + private int getBankerSeatByCard(EXRoom owner) { + for (int index = 3; index <= 13; index++) { + for (int color = 4; color >= 1; color--) { + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + for (CardObj card : player.cardInhand) { + if (card.card == color * 100 + index) { + owner.firstCard = card.card; + return player.seat; + } + } + } + } + } + return 0; + } + + private int getBankerSeat(EXRoom owner) { + int seat = 0; + + int rule = Config.RULE_RANDOM; + if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) { + rule = owner.config.getInt(Config.ROOM_CONFIG_RULE); + } + + + // 如果是兩人的情況 + if (owner.maxPlayers == 2) { + + // 如果是随机确定庄家 + if (rule == Config.RULE_RANDOM) { + Random random = new Random(); + seat = random.nextInt(2) + 1; + } + // 如果是黑桃3先出 + else { + seat = getBankerSeatByCard(owner); + // 如果黑桃3 不在任何一个玩家手里 则随机确定一个庄家 + if (seat == 0) { + Random random = new Random(); + seat = random.nextInt(2) + 1; + } + } + } else { + + // 如果是随机确定庄家 + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + // 循环玩家的手牌 + for (CardObj card : player.cardInhand) { + if (card.card == 403) { + seat = getBankerSeatByCard(owner); + return seat; + } else { + Random random = new Random(); + seat = random.nextInt(3) + 1; + } + } + } + +// // 如果是黑桃3先出 +// else { +// seat = getBankerSeatByCard(owner); +// } + } + return seat; + + } + + public void discardTipEvent(EXPlayer owner) { + ITObject param = new TObject(); + boolean gen = (owner.getRoom().lastDiscardSeat != 0 && owner.getRoom().lastDiscardSeat != owner.seat); + param.putInt("play", gen ? 1 : 0); + if (gen) { + param.putTObject("card_obj", owner.getRoom().discard.toObject(true)); + + } + // 如果可以不出 + + EXRoom room = owner.getRoom(); + owner.sendEvent(Config.GAME_EVT_DISCARD_TIP, param); + EXPlayBack pb = (EXPlayBack) room.playBackData; + pb.addPromptCommand(owner.seat,param); + } + + private ITObject getRoomResultData(EXRoom owner, boolean total) { + + ITObject mp = TObject.newInstance(); + + EXPlayer win = owner.win; + + ITArray info = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.total_score); + + + obj.putInt("winscore", player.score.round_score); + player.hp_info(obj); + obj.putInt("thisboomnum", player.boomnum); + obj.putInt("piao", player.piao); + obj.putTArray("cards", CardUtil.toTArray(player.cardInhand)); + obj.putBoolean("chuntian", player.chuntian); + + obj.putTArray("handCards", CardUtil.toTArray(player.cardInhand)); + obj.putTArray("outCards", CardUtil.toTArray(player.outCards)); + + if (total) { + Jedis jedis = Redis.use("group1_db11").getJedis(); + String playingGroupIdKey = "g{" + owner.groupId + "}:play:" + owner.groupPid; + try { +// int score = player.room.hpData.getInt("times") / 1000; + + obj.putInt("total_score", player.score.total_score); + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis.close(); + } + obj.putInt("daniao", player.daniaoScore); + obj.putInt("award", player.bonusScore); + +// if(owner.endType == Constant.END_TYPE_ENTRUST) { +// obj.putInt("entrust", player.entrust ? 1 : 0); +// } + + int jieShan = owner.hpData.getInt("JieShan"); + if (owner.endType == Constant.END_TYPE_ENTRUST && player.entrust_round < jieShan) { + obj.putInt("entrust", player.entrust ? 1 : 0); + } + + obj.putTObject("settle_log", player.settleLog.toTObject()); +// obj.putInt("total_score", player.score.total_score); + + } + info.addTObject(obj); + } + if (win != null) { + mp.putInt("winseat", win.seat); + } else { + mp.putInt("winseat", 0); + } + mp.putTArray("remaincards", CardUtil.toTArray(owner.card.cardList)); + mp.putTArray("info", info); + mp.putInt("xipai_score", owner.xi_pai_score); + + + + + + return mp; + } + + public void roomResult(EXRoom owner) { + ITObject result = getRoomResultData(owner, false); + result.putInt("type", 0); + result.putString("cardList", owner.card.cardList.toString()); + + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_RESULT1, result); + } + + /** + * 房间大结算 + * + * @param owner + * @param dissmiss + */ + public void roomTotalResult(EXRoom owner, boolean dissmiss) { + Jedis jedis = Redis.use("group1_db10").getJedis(); + + ITObject result = getRoomResultData(owner, true); + + + long t = System.currentTimeMillis() / 1000; + result.putLong("time", t); + result.putInt("type", dissmiss ? 2 : 1); + result.putString("cardList", owner.card.cardList.toString()); + owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result); + owner.broadCastToClientOfSpectator(Config.GAME_EVT_RESULT1, result); + + + + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); +// pb.addResultCommand(player.seat, result); +// +// pb.addNewRoundCommand(); + // 扣除积分 + String playerIdKey = "g{" + owner.groupId + "}:" + "m" + player.playerid; + String lost_mj_score = jedis.hget(playerIdKey, "lost_pk_score"); + jedis.hset(playerIdKey, "lost_pk_score", + lost_mj_score == null ? player.score.total_score+"" : Integer.parseInt(lost_mj_score) + player.score.total_score + ""); + + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.zrem("ceroom","room:"+owner.roomid); + jedis11.close(); + jedis.close(); + + } + +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXMainServer.java b/game_pk_paodekuai/src/main/java/extend/pk/EXMainServer.java new file mode 100644 index 0000000..44e5e63 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXMainServer.java @@ -0,0 +1,66 @@ +package extend.pk; + +import java.util.Map; + +import com.game.GameController; +import com.game.Global; +import com.game.MainServer; +import com.game.data.Player; +import com.game.data.Room; +import com.game.room.state.RoomStartGameState; + +import extend.pk.player.state.EXPlayerDiscardState; +import extend.pk.player.state.EXPlayerPassState; +import extend.pk.player.state.EXPlayerPiaoNiaoTipState; +import extend.pk.room.state.EXRoomDealState; +import extend.pk.room.state.EXRoomPiaoState; +import extend.pk.room.state.EXRoomSetpState; +import extend.pk.room.state.EXRoomStartGameState; + +/** + * + * + */ +public class EXMainServer extends MainServer { + public static EXGameController gameCtr; + + @Override + public void onStart() { + super.onStart(); + gameCtr = (EXGameController) Global.gameCtr; + registerState(); + } + + private final void registerState() { + + Global.registerState(RoomStartGameState.class, new EXRoomStartGameState()); + Global.registerState(EXRoomSetpState.class, new EXRoomSetpState()); + Global.registerState(EXRoomDealState.class, new EXRoomDealState()); + Global.registerState(EXRoomPiaoState.class, new EXRoomPiaoState()); + + Global.registerState(EXPlayerDiscardState.class, new EXPlayerDiscardState()); + Global.registerState(EXPlayerPassState.class, new EXPlayerPassState()); + Global.registerState(EXPlayerPiaoNiaoTipState.class, new EXPlayerPiaoNiaoTipState()); + } + + + @Override + public Room newRoom(String roomid, Map redis_room_map) { + // TODO Auto-generated method stub + return new EXRoom(roomid, redis_room_map); + } + + + @Override + public Player newPlayer(int playerid, Room room, String session_id) { + // TODO Auto-generated method stub + return new EXPlayer(playerid, room, session_id); + } + + + @Override + protected GameController newController() { + // TODO Auto-generated method stub + return new EXGameController(); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXPlayBack.java b/game_pk_paodekuai/src/main/java/extend/pk/EXPlayBack.java new file mode 100644 index 0000000..c9328f3 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXPlayBack.java @@ -0,0 +1,61 @@ +package extend.pk; + + +import com.game.data.BasePlayBack; +import com.game.data.Player; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import extend.pk.uitl.CardUtil; + +public class EXPlayBack extends BasePlayBack{ + + public EXPlayBack(EXRoom room) { + super(room); + info.putInt("left_card", room.card.getCount()); + } + + protected ITObject getPlayerInfo(Player p) { + + EXPlayer player = (EXPlayer)p; + ITObject obj =super.getPlayerInfo(player); + ITArray cardInhand = CardUtil.toTArray(player.cardInhand); + obj.putTArray("hand_card", cardInhand); + obj.putInt("score", player.score.total_score); + obj.putInt("piao", player.piao); + + player.hp_info(obj); + return obj; + } + + public void addOutCardCommand(int seat, CardGroup ct) { + ITObject cmdData = ct.toObject(false); + addCommand("OutCard", seat, cmdData); + } + + public void addZhaScoreCommand(int seat, CardGroup ct,int score) { +// ITObject cmdData = ct.toObject(false); +// cmdData.putInt("score", score); +// addCommand("ZhaScore", seat, cmdData); + } + + + public void addPassCommand(int seat) { + ITObject cmdData = TObject.newInstance(); + addCommand("pass", seat, cmdData); + } + + public void addNewRoundCommand() { + ITObject cmdData = TObject.newInstance(); + addCommand("newindex", 0, cmdData); + } + + public void addPromptCommand(int seat ,ITObject cmdData){ + addCommand("prompt", seat, cmdData); + } + + public void addResultCommand(int seat,ITObject cmdData) { + addCommand("result", seat, cmdData); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXPlayer.java b/game_pk_paodekuai/src/main/java/extend/pk/EXPlayer.java new file mode 100644 index 0000000..1660127 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXPlayer.java @@ -0,0 +1,137 @@ +package extend.pk; + +import java.util.ArrayList; +import java.util.List; + +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.game.data.Score; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.plugin.redis.Redis; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + + +/** + * + * + */ +public class EXPlayer extends Player { + + /**默认action时间 20s*/ + public static final int DEFAULT_ACTION_TIME = 20000; + /**默认托管时间 1s*/ + public static final int DEFAULT_ENTRUST_TIME = 1000; + /** + * 默认准备时间 20s + */ + public static final int DEFAULT_READY_TIME = 20000; + + // 手牌 + public List cardInhand; + + // 手牌 + public List nextCardInhand = new ArrayList(); + + + //打出的牌 + public List outCards; + + public CardGroup last_outcard; + public boolean pass; + + // 放作弊场第一张牌是否关闭 + public int open = 0; + + /**春天 */ + public boolean chuntian; + + /**是否有红桃10*/ + public boolean isHaveRedTen; + + public SettleLog settleLog; + + public int boomnum = 0; + public int piao = -1; + public int daniaoScore = 0; + public int bonusScore = 0; + public int awardScore = 0; + + public boolean isChoice = false; + + + public EXPlayer(int playerid, Room table, String session_id) { + super(playerid, table, session_id); + cardInhand = new ArrayList<>(); + outCards = new ArrayList<>(); + + settleLog = new SettleLog(); + settleLog.put(Config.SETTLE_WIN_COUNT, 0); + settleLog.put(Config.SETTLE_CHUNTIAN_COUNT, 0); + settleLog.put(Config.SETTLE_BOMB_COUNT, 0); + settleLog.put(Config.SETTLE_MAX_SCORE, 0); + } + + protected Score newScore() { + return new EXScore(this); + } + + @Override + public ITObject getReloadInfo() { + ITObject playerData = super.getReloadInfo(); + playerData.putInt("card_size", this.cardInhand.size()); + playerData.putInt("piao", this.piao); + if(last_outcard!=null) { + playerData.putTObject("last_outcard", last_outcard.toObject(false)); + } + + if(this.room.isplaying == false) { + playerData.putTArray("cards", CardUtil.toTArray(this.cardInhand)); + + playerData.putTArray("handCards", CardUtil.toTArray(this.cardInhand)); + playerData.putTArray("outCards", CardUtil.toTArray(this.outCards)); + + playerData.putInt("score", score.total_score); + playerData.putInt("winscore", score.round_score); + playerData.putInt("thisboomnum", boomnum); + playerData.putInt("open", open); + } + return playerData; + } + + @Override + public ITObject getInfo() { + ITObject playerData = super.getInfo(); + playerData.putInt("score", score.total_score); + return playerData; + } + + + public void clear() { + super.clear(); + + } + + public void clearEx() { + + this.score.resetRound(); + this.cardInhand.clear(); + this.outCards.clear(); + this.last_outcard = null; + this.pass = false; + this.chuntian =false; + this.isHaveRedTen=false; + this.open = 0; + this.boomnum = 0; + this.piao = -1; + this.daniaoScore = 0; + this.isChoice=false; + } + + public EXRoom getRoom() { + return (EXRoom) room; + } + +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXRoom.java b/game_pk_paodekuai/src/main/java/extend/pk/EXRoom.java new file mode 100644 index 0000000..0183243 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXRoom.java @@ -0,0 +1,455 @@ +package extend.pk; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Constant; +import com.game.Global; +import com.game.data.Player; +import com.game.data.Room; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; + +import com.taurus.core.plugin.redis.Redis; +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; +import redis.clients.jedis.Jedis; + +public class EXRoom extends Room { + public RoomCard card; + + /** 上次打牌的座位 */ + public int lastDiscardSeat; + + /** 打出牌的集合 */ + public CardGroup discard; + + public EXPlayer win; + + public int firstCard = 0; + + public Map card_config_map; + + public int piaoCount = 0; + + public List> supCards; + public List targetCards; + public int adminSeat = 0; + + public int chooseover = 0; + + public EXRoom(String roomid, Map redis_room_map) { + super(roomid, redis_room_map); + + card = new RoomCard(this, this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16, maxPlayers); + card_config_map = new HashMap(); + card_config_map.put(CardConfig.DAN.type, CardConfig.DAN); + card_config_map.put(CardConfig.DUIZI.type, CardConfig.DUIZI); + card_config_map.put(CardConfig.LIANDUI.type, CardConfig.LIANDUI); + card_config_map.put(CardConfig.SHUNZI.type, CardConfig.SHUNZI); + card_config_map.put(CardConfig.ZHA.type, CardConfig.ZHA); + card_config_map.put(CardConfig.FEIJI.type, CardConfig.FEIJI); + card_config_map.put(CardConfig.FEIJI_2.type, CardConfig.FEIJI_2); + card_config_map.put(CardConfig.SAN_2.type, CardConfig.SAN_2); + + boolean sidai_2 = this.config.getBoolean(Config.ROOM_CONFIG_SIDAI_2); + boolean sidai_3 = this.config.getBoolean(Config.ROOM_CONFIG_SIDAI_3); + if (sidai_2) { + card_config_map.put(CardConfig.SI_2.type, CardConfig.SI_2); + } + if (sidai_3) { + card_config_map.put(CardConfig.SI_3.type, CardConfig.SI_3); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_XIPAI_SCORE)) { + this.config.putInt(Config.ROOM_CONFIG_XIPAI_SCORE, 0); + this.xi_pai_score = 1; + } else { + this.xi_pai_score = this.config.getInt(Config.ROOM_CONFIG_XIPAI_SCORE); + } + + if (!this.config.containsKey(Config.ROOM_CONFIG_XIPAI)) { + this.config.putBoolean(Config.ROOM_CONFIG_XIPAI, false); + } + + this.isEntrust = true; + + this.supCards = new ArrayList<>(); + this.targetCards = new ArrayList<>(); + this.adminSeat = 0; + this.chooseover = 0; + } + + public void clear() { + super.clear(); + + } + + public void clearEx() { + this.activeSeat = 0; + this.discard = null; + this.lastDiscardSeat = 0; + this.win = null; + this.firstCard = 0; + } + + public ITObject getReloadInfo(Player player) { + ITObject data = super.getReloadInfo(player); + EXPlayer p = (EXPlayer) player; + + data.putTArray("hand_card", CardUtil.toTArray(p.cardInhand)); + + data.putTArray("handCards", CardUtil.toTArray(p.cardInhand)); + data.putTArray("outCards", CardUtil.toTArray(p.outCards)); + + data.putInt("open", p.open); + + data.putInt("last_outcard_seat", this.lastDiscardSeat); + + // 游戏结束 + if (this.isplaying == false) { + + if (this.win != null) { + data.putInt("winseat", this.win.seat); + } else { + data.putInt("winseat", 0); + } + if (this.card.getCount() > 0) { + data.putTArray("remaincards", CardUtil.toTArray(this.card.cardList)); + } + } + + return data; + } + + /** + * + * */ + private int reMultipleScore(int score) { + if (this.hpData != null) { + if (this.hpData.containsKey("times")) { + return Math.round(score / this.hpData.getInt("times")); + } + } + return score; + } + + public void addScore(Player destPlayer, Player fromPlayer, int score, int type) { + + //// +// if (multipleScore(score) > fromPlayer.hp.cur_hp) { +// score = reMultipleScore((int) fromPlayer.hp.cur_hp); +// // fromPlayer.hp.cur_hp -= multipleScore(score); //不能在这里扣 +// } + // + + + score = score * this.hpData.getInt("times") / 1000; + + + destPlayer.score.round_log.put(type, destPlayer.score.round_log.get(type) + score); + fromPlayer.score.round_log.put(type, fromPlayer.score.round_log.get(type) - score); + destPlayer.score.round_score += score; + destPlayer.score.total_score += score; + fromPlayer.score.round_score -= score; + fromPlayer.score.total_score -= score; + + + + } + + /** + * 变更炸弹积分 + * + * @param destPlayer + */ + public void addAllBombScore(EXPlayer destPlayer) { + + destPlayer.settleLog.add(Config.SETTLE_BOMB_COUNT); + destPlayer.boomnum++; + + TArray seatData = TArray.newInstance(); + for (Entry entry : this.playerMapByPlaying.entrySet()) { + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + ITObject seatListData = TObject.newInstance(); + if (fromPlayer != destPlayer) { + this.addScore(destPlayer, fromPlayer, 10, EXScore.ZHA); + seatListData.putInt("bom_score", -10); + seatListData.putInt("aid", fromPlayer.playerid); + seatData.addTObject(seatListData); + } else { + seatListData.putInt("bom_score", 20); + seatListData.putInt("aid", destPlayer.playerid); + seatData.addTObject(seatListData); + } + } + TObject allData = TObject.newInstance(); + allData.putTArray("gold_list", seatData); + this.broadCastToClient(0, Config.GAME_EVT_UPDATE_BOM_SCORE, allData); + } + + /** + * 变更游戏积分 + * + * @param destPlayer 目标玩家,将接收其他玩家的分数 + */ +public void addAllScore(Player destPlayer) { + + // 将目标玩家转换为扩展玩家类型 + EXPlayer dp = (EXPlayer) destPlayer; + + // 标记是否有玩家达到春天条件 + boolean bSpring = false; + + // 遍历所有参与游戏的玩家 + for (Entry entry : this.playerMapByPlaying.entrySet()) { + + // 将当前玩家转换为扩展玩家类型 + EXPlayer fromPlayer = (EXPlayer) entry.getValue(); + + // 确保当前玩家不是目标玩家 + if (fromPlayer != destPlayer) { + + // 检查当前玩家手中是否有超过一张牌 + if (fromPlayer.cardInhand.size() > 1) { + + // 计算基础分数 + int size = fromPlayer.cardInhand.size(); + int score = size; + + // 计算出牌数量 + int outCard = (this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16) - size; + + // 检查是否达到春天条件 + if (size == (this.config.getInt(Config.ROOM_CONFIG_CARDNUM) == 1 ? 15 : 16)) { + fromPlayer.chuntian = true; + score = size * 2; + bSpring = true; + + } else if (outCard < 2 && this.config.getInt(Config.ROOM_CONFIG_SPECIL_ADD) == 1 ) { + // 只出一张牌多10分 + score += 10; + } else if (outCard < 4 && this.config.getInt(Config.ROOM_CONFIG_SPECIL_ADD) == 1 ) { + // 出2-3张牌多5分 + score += 5; + } + + // 检查是否有红桃十,以及房间配置是否启用红桃十加倍 + if ((fromPlayer.isHaveRedTen || dp.isHaveRedTen) && this.config.getInt(Config.ROOM_CONFIG_HEARTTEN) == 2) { + score = score * 2; + } + + // 加上目标玩家的飘分 + if (dp.piao > 0) { + score += dp.piao; + } + + // 加上当前玩家的飘分 + if (fromPlayer.piao > 0) { + score += fromPlayer.piao; + } + + // 更新目标玩家和当前玩家的分数 + this.addScore(destPlayer, fromPlayer, score, EXScore.WIN); + } + } + } + + // 设置玩家的当初最大分数 + for (Entry entry : this.playerMapByPlaying.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + + // 为目标玩家增加胜利次数记录 + if (destPlayer == player) { + player.settleLog.add(Config.SETTLE_WIN_COUNT); + } + + // 更新玩家的最高分数记录 + if (player.score.round_score > player.settleLog.get(Config.SETTLE_MAX_SCORE)) { + player.settleLog.put(Config.SETTLE_MAX_SCORE, player.score.round_score); + } + } + + // 增加玩家春天的个数 + if (bSpring) { + dp.settleLog.add(Config.SETTLE_CHUNTIAN_COUNT); + } + + // 检查是否启用总分模式 + if (totalType()) { + // 检查房间配置中是否设置了大鸟分,并获取设置值 + if (config.containsKey(Config.ROOM_CONFIG_DANIAO) && config.getInt(Config.ROOM_CONFIG_DANIAO) > 0) { + + int daniao = this.config.getInt(Config.ROOM_CONFIG_DANIAO); + if (daniao == 1) + daniao = 10; + else if (daniao == 2) + daniao = 20; + else if (daniao == 3) + daniao = 50; + + // 初始化最大总分数和最大总分出现次数 + int maxTotalScore = 0; + int maxTotalCount = 0; + + // 遍历所有玩家,找出最大总分数和出现次数 + for (Entry entry : this.playerMapBySeat.entrySet()) { + + Player player = entry.getValue(); + + if (player.score.total_score > maxTotalScore) { + + maxTotalScore = player.score.total_score; + maxTotalCount = 1; + } else if (player.score.total_score == maxTotalScore && maxTotalScore > 0) { + + maxTotalCount++; + } + } + + // 如果存在大赢家 + if (maxTotalScore > 0 && maxTotalCount > 0) { + + // 根据大赢家和非大赢家更新玩家分数 + for (Entry entry : this.playerMapBySeat.entrySet()) { + + EXPlayer player = (EXPlayer) entry.getValue(); + + if (player.score.total_score == maxTotalScore) { + + player.score.total_score += daniao; + player.daniaoScore = daniao; + } else { + + player.score.total_score -= daniao * maxTotalCount; + player.daniaoScore = -daniao * maxTotalCount; + } + } + } + } + } +} + + + @Override + protected void roomResult() { + EXMainServer.gameCtr.roomResult(this); + } + + @Override + public void saveMilitaryTotal(boolean dissmiss) { + super.saveMilitaryTotal(dissmiss); + EXMainServer.gameCtr.roomTotalResult(this, dissmiss); + } + + private ITObject getRoomResultData(EXRoom owner, boolean total) { + + ITObject mp = TObject.newInstance(); + + EXPlayer win = owner.win; + + ITArray info = new TArray(); + for (Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.total_score); + + + obj.putInt("winscore", player.score.round_score); + player.hp_info(obj); + obj.putInt("thisboomnum", player.boomnum); + obj.putInt("piao", player.piao); + obj.putTArray("cards", CardUtil.toTArray(player.cardInhand)); + obj.putBoolean("chuntian", player.chuntian); + + obj.putTArray("handCards", CardUtil.toTArray(player.cardInhand)); + obj.putTArray("outCards", CardUtil.toTArray(player.outCards)); + + if (total) { + Jedis jedis = Redis.use("group1_db11").getJedis(); + String playingGroupIdKey = "g{" + owner.groupId + "}:play:" + owner.groupPid; + try { +// int score = player.room.hpData.getInt("times") / 1000; + + obj.putInt("total_score", player.score.total_score); + } catch (Exception e) { + Global.logger.error(e); + } finally { + jedis.close(); + } + obj.putInt("daniao", player.daniaoScore); + obj.putInt("award", player.bonusScore); + +// if(owner.endType == Constant.END_TYPE_ENTRUST) { +// obj.putInt("entrust", player.entrust ? 1 : 0); +// } + + int jieShan = owner.hpData.getInt("JieShan"); + if (owner.endType == Constant.END_TYPE_ENTRUST && player.entrust_round < jieShan) { + obj.putInt("entrust", player.entrust ? 1 : 0); + } + + obj.putTObject("settle_log", player.settleLog.toTObject()); +// obj.putInt("total_score", player.score.total_score); + + } + info.addTObject(obj); + } + if (win != null) { + mp.putInt("winseat", win.seat); + } else { + mp.putInt("winseat", 0); + } + mp.putTArray("remaincards", CardUtil.toTArray(owner.card.cardList)); + mp.putTArray("info", info); + mp.putInt("xipai_score", owner.xi_pai_score); + + + + + + return mp; + } + + @Override + public void endGame() { + addAllScore(win); + + this.chooseover = 0; + //拿结算数据 + + ITObject mp = getRoomResultData(this, true); + + EXPlayBack pb = (EXPlayBack) this.playBackData; + + ITObject pbResult = TObject.newInstance(); + + ITArray info = new TArray(); + for (Entry entry : playerMapByPlaying.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + ITObject obj = TObject.newInstance(); + obj.putInt("seat", player.seat); + obj.putInt("score", player.score.round_score); + obj.putBoolean("entrust", player.entrust); + info.addTObject(obj); + + if (player.entrust == true){ + player.entrust_round++; + } + } +//// + pbResult.putTArray("result", info); + pbResult.putTObject("win", mp); + Global.logger.error("------------------pbResult:" + pbResult); + pb.addResultCommand(win.seat, pbResult); +// + pb.addNewRoundCommand(); + super.endGame(); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/EXScore.java b/game_pk_paodekuai/src/main/java/extend/pk/EXScore.java new file mode 100644 index 0000000..fc4343f --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/EXScore.java @@ -0,0 +1,18 @@ +package extend.pk; + +import com.game.data.Score; + +public class EXScore extends Score { + public static final int WIN = 1; + public static final int ZHA = 2; + + + public EXScore(EXPlayer owner) { + super(owner); + } + + protected void initLog() { + this.round_log.put(WIN, 0); + this.round_log.put(ZHA, 0); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/RoomCard.java b/game_pk_paodekuai/src/main/java/extend/pk/RoomCard.java new file mode 100644 index 0000000..efc11e9 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/RoomCard.java @@ -0,0 +1,1192 @@ +package extend.pk; + +import com.game.Global; +import extend.pk.uitl.CardUtil; + +import java.util.*; + +public class RoomCard { + + public static final int HEART_TEN = 310; + public static final int CARD_A = 14; + public static final int CARD_2 = 15; + public static final int CARD_3 = 3; + public List cardList; + public List nextCardList = new ArrayList(); + + public List cardListTemp; + EXRoom room; + int num; + int maxPlayer; + Random rand = new Random(); + + int boomNumLimit = rand.nextInt(2) + 2; + int sangzhangNumLimit = rand.nextInt(5) + 10; + + int totalBoomNum = 0; + int totalSanZhangNum = 0; + + public RoomCard(EXRoom table, int num, int maxPlayer) { + this.cardList = new ArrayList(); + this.cardListTemp = new ArrayList(); + this.room = table; + this.num = num; + this.maxPlayer = maxPlayer; + } + + public void init() { + this.boomNumLimit = rand.nextInt(2) + 2; + this.sangzhangNumLimit = rand.nextInt(5) + 10; + + this.totalBoomNum = 0; + this.totalSanZhangNum = 0; + this.cardList.clear(); + this.initCard(); + int currentBoomNum = 0; + int currentSanZhangNum = 0; + Map result = new HashMap(); + do { + currentBoomNum = 0; + currentSanZhangNum = 0; + this.shuffle(); + for (int i = 0; i < this.maxPlayer; i++) { + this.cardListTemp.clear(); + for (int j = 0; j < num; j++) { + this.cardListTemp.add(this.cardList.get(i * num + j)); + CardUtil.getCardNumMap(result, this.cardListTemp); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + currentBoomNum++; + } else if (entry.getValue() == 3) { + currentSanZhangNum++; + } + } + } + } + } while ((currentBoomNum + totalBoomNum > boomNumLimit) + || (currentSanZhangNum + totalSanZhangNum > sangzhangNumLimit)); + } + + private void initCard() { + for (int index = 3; index <= 13; index++) { + + if (!(index == 13 && this.num == 15)) { + // 方片 + this.cardList.add(new CardObj(100 + index)); + } + // 梅花 + this.cardList.add(new CardObj(200 + index)); + // 红桃 + this.cardList.add(new CardObj(300 + index)); + // 黑桃 + this.cardList.add(new CardObj(400 + index)); + } + + if (this.num == 16) { + this.cardList.add(new CardObj(214)); + this.cardList.add(new CardObj(314)); + this.cardList.add(new CardObj(414)); + + this.cardList.add(new CardObj(415)); + } else { + this.cardList.add(new CardObj(214)); + this.cardList.add(new CardObj(415)); + } + + rand.setSeed(System.currentTimeMillis()); + int len = this.cardList.size(); + for (int i = 0; i < len; i++) { + + int randpos = rand.nextInt(1000000000) % len; + CardObj cotemp = this.cardList.get(i); + + this.cardList.set(i, this.cardList.get(randpos)); + this.cardList.set(randpos, cotemp); + } + + } + + public void initNextCard() { + this.nextCardList.clear(); + for (int index = 3; index <= 13; index++) { + + if (!(index == 13 && this.num == 15)) { + // 方片 + this.nextCardList.add(new CardObj(100 + index)); + } + // 梅花 + this.nextCardList.add(new CardObj(200 + index)); + // 红桃 + this.nextCardList.add(new CardObj(300 + index)); + // 黑桃 + this.nextCardList.add(new CardObj(400 + index)); + } + + if (this.num == 16) { + this.nextCardList.add(new CardObj(214)); + this.nextCardList.add(new CardObj(314)); + this.nextCardList.add(new CardObj(414)); + + this.nextCardList.add(new CardObj(415)); + } else { + this.nextCardList.add(new CardObj(214)); + this.nextCardList.add(new CardObj(415)); + } + + rand.setSeed(System.currentTimeMillis()); + int len = this.nextCardList.size(); + for (int i = 0; i < len; i++) { + + int randpos = rand.nextInt(1000000000) % len; + CardObj cotemp = this.nextCardList.get(i); + + this.nextCardList.set(i, this.nextCardList.get(randpos)); + this.nextCardList.set(randpos, cotemp); + } + + } + + private void shuffle() { + for (int i = 0; i < 100; i++) { + Collections.shuffle(this.cardList); + } + Random rand = new Random(); + int len = this.cardList.size(); + + for (int i = 0; i < 10000; i++) { + rand.setSeed(System.currentTimeMillis()); + if(len<=0) { + continue; + } +// System.out.println("len:"+len); + int start = rand.nextInt(len); + int end = rand.nextInt(len); + + CardObj co = this.cardList.get(start); + this.cardList.set(start, this.cardList.get(end)); + this.cardList.set(end, co); + } + } + + private void shuffleNext() { + for (int i = 0; i < 100; i++) { + Collections.shuffle(this.nextCardList); + } + Random rand = new Random(); + int len = this.nextCardList.size(); + + for (int i = 0; i < 10000; i++) { + rand.setSeed(System.currentTimeMillis()); + if(len<=0) { + continue; + } +// System.out.println("len:"+len); + int start = rand.nextInt(len); + int end = rand.nextInt(len); + + CardObj co = this.nextCardList.get(start); + this.nextCardList.set(start, this.nextCardList.get(end)); + this.nextCardList.set(end, co); + } + } + + public CardObj pop() { + CardObj card = this.cardList.remove(0); + return card; + } + + public CardObj nextPop() { + + CardObj card = this.nextCardList.remove(0); + return card; + } + + public int getCount() { + return this.cardList.size(); + } + + public List deal0(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + dealCards.add(new CardObj(406)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(307)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(112)); + + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + } else if (seat == 2) { + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + dealCards.add(new CardObj(308)); + dealCards.add(new CardObj(408)); + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(109)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + dealCards.add(new CardObj(410)); + dealCards.add(new CardObj(211)); + dealCards.add(new CardObj(212)); + + dealCards.add(new CardObj(303)); + dealCards.add(new CardObj(214)); + }else if (seat == 3){ + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + dealCards.add(new CardObj(409)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(307)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(112)); + + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + } + + return dealCards; + } + + public List deal1(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(414)); + dealCards.add(new CardObj(415)); + dealCards.add(new CardObj(413)); + + dealCards.add(new CardObj(404)); + dealCards.add(new CardObj(405)); + dealCards.add(new CardObj(406)); + + dealCards.add(new CardObj(104)); + dealCards.add(new CardObj(304)); + dealCards.add(new CardObj(204)); + + dealCards.add(new CardObj(103)); + dealCards.add(new CardObj(203)); + dealCards.add(new CardObj(303)); + + dealCards.add(new CardObj(115)); + dealCards.add(new CardObj(215)); + dealCards.add(new CardObj(315)); + + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + + dealCards.add(new CardObj(314)); + dealCards.add(new CardObj(214)); + dealCards.add(new CardObj(111)); + + dealCards.add(new CardObj(311)); + dealCards.add(new CardObj(211)); + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(110)); + + } + + return dealCards; + } + + public List deal2(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + dealCards.add(new CardObj(105)); + dealCards.add(new CardObj(205)); + dealCards.add(new CardObj(305)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(110)); + + } else if (seat == 2) { + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + + // dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal3(int seat) { + + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(111)); + dealCards.add(new CardObj(112)); + dealCards.add(new CardObj(113)); + dealCards.add(new CardObj(114)); + dealCards.add(new CardObj(215)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal4(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(207)); + dealCards.add(new CardObj(307)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(208)); + dealCards.add(new CardObj(308)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(209)); + dealCards.add(new CardObj(309)); + + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(210)); + dealCards.add(new CardObj(310)); + dealCards.add(new CardObj(410)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List deal6(int seat) { + List dealCards = new ArrayList(); + + if (seat == 1) { + dealCards.add(new CardObj(103)); + dealCards.add(new CardObj(203)); + + dealCards.add(new CardObj(104)); + dealCards.add(new CardObj(204)); + + dealCards.add(new CardObj(105)); + dealCards.add(new CardObj(105)); + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(106)); + + dealCards.add(new CardObj(107)); + dealCards.add(new CardObj(107)); + + dealCards.add(new CardObj(108)); + dealCards.add(new CardObj(108)); + + dealCards.add(new CardObj(109)); + dealCards.add(new CardObj(109)); + + dealCards.add(new CardObj(110)); + dealCards.add(new CardObj(110)); + } else if (seat == 2) { + + dealCards.add(new CardObj(106)); + dealCards.add(new CardObj(206)); + dealCards.add(new CardObj(306)); + + dealCards.add(new CardObj(107)); + } + + return dealCards; + } + + public List dealTest(int seat) { + + List dealCards = deal2(seat); + if (dealCards == null || dealCards.size() == 0) { + + dealCards = deal(); + } + + return dealCards; + } + + // 发牌 + public List deal(boolean room_white, boolean is_white, double room_rate, int white_black_status, + double black_white_rate, double black_black_rate, int maxDanPai, int maxDuizi, int maxSanZhang) { + List dealCards = new ArrayList(); + shuffle(); + + double rand1 = Math.random() % 100 * 100; + for (int index = 0; index < this.num; index++) { + if (room_white && is_white) { + if (rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards xingyun card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard3(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard4(tempCard.cardMod, dealCards, false, 0, 6, 6)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.cardList.addAll(tempCardList); + } + } else { + if (white_black_status == 2) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards white card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } else if (white_black_status == 1) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards black card"); + } + } + ; + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, true, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, true, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } else { + if (room_white && rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.pop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.cardList.size() > 0 && count++ <= this.cardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + + this.cardList.addAll(tempCardList); + } + } + } + } + } + shuffle(); + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + + // 发牌 + public List dealNext(boolean room_white, boolean is_white, double room_rate, int white_black_status, + double black_white_rate, double black_black_rate, int maxDanPai, int maxDuizi, int maxSanZhang) { + List dealCards = new ArrayList(); + shuffleNext(); + + double rand1 = Math.random() % 100 * 100; + for (int index = 0; index < this.num; index++) { + if (room_white && is_white) { + if (rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards xingyun card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard3(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard4(tempCard.cardMod, dealCards, false, 2, 4, 3)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else { + if (white_black_status == 2) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards white card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else if (white_black_status == 1) { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards black card"); + } + } + ; + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, true, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, true, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } else { + if (room_white && rand1 > room_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (rand1 < black_white_rate) { + if (index == 0) { + if (maxDanPai == 0) { + Global.logger.info("dealcards rand card"); + } else { + Global.logger.info("dealcards general cha card"); + } + } + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard(tempCard.cardMod, dealCards, false, maxDanPai, maxDuizi, maxSanZhang)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } else { + if (index == 0) + Global.logger.info("dealcards rand card"); + ArrayList tempCardList = new ArrayList(); + int count = 0; + do { + CardObj tempCard = this.nextPop(); + + if (isGooodCard2(tempCard.cardMod, dealCards, false, 0, 0, 0)) { + if (this.nextCardList.size() > 0 && count++ <= this.nextCardList.size()) { + tempCardList.add(tempCard); + continue; + } + } + + dealCards.add(tempCard); + break; + } while (true); + this.nextCardList.addAll(tempCardList); + } + } + } + } + } + shuffleNext(); + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + + boolean isGooodCard(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + if (isGooodCard2(card, dealCards, black, maxDanPai, maxDuizi, maxSanZhang)) { + return true; + } + + if (maxDanPai != 0) { + if (card >= maxDanPai) { + return true; + } + } + + if (maxDanPai != 0) { + if (CardUtil.checkGoodCard(card, dealCards, 1)) { + if (card >= maxDuizi) { + return true; + } + } + } + + if (maxDanPai != 0) { + if (CardUtil.checkGoodCard(card, dealCards, 2)) { + if (card >= maxSanZhang) { + return true; + } + } + } + + return false; + } + + boolean isGooodCard2(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + double rand = Math.random() % 100 * 100; + if (black) { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 70) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 70) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 70) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 70) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 70) { + Global.logger.info("remove checkQPai"); + return true; + } + } else { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 50) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 50) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 50) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 50) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 50) { + Global.logger.info("remove checkQPai"); + return true; + } + } + + return false; + } + + boolean isGooodCard3(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { + double rand = Math.random() % 100 * 100; + if (black) { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 50) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 50) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 50) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 70) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 50) { + Global.logger.info("remove checkQPai"); + return true; + } + } else { + if (CardUtil.checkGoodCard(card, dealCards, 3) && rand < 40) { + Global.logger.info("remove zhadan"); + return true; + } + + if (CardUtil.checkFenJi(card, dealCards) && rand < 40) { + Global.logger.info("remove feiji"); + return true; + } + + if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 40) { + Global.logger.info("remove sevent shun zi"); + return true; + } + + if (CardUtil.checkFourDui(card, dealCards) && rand < 40) { + Global.logger.info("remove four dui"); + return true; + } + + if (CardUtil.checkQPai(card, dealCards) && rand < 40) { + Global.logger.info("remove checkQPai"); + return true; + } + } + + return false; + } + + boolean isGooodCard4(int card, List dealCards, boolean black, int maxDanPai, int maxDuizi, + int maxSanZhang) { +// double rand = Math.random() % 100 * 100; +// if (black) { +// if (CardUtil.checkKPai(card, dealCards) && rand < 5) { +// Global.logger.info("remove checkQPai"); +// return true; +// } +// if (CardUtil.checkGoodCard(card, dealCards, 5) && rand < 5) { +// Global.logger.info("remove zhadan"); +// return true; +// } +// +// if (CardUtil.checkFenJi(card, dealCards) && rand < 5) { +// Global.logger.info("remove feiji"); +// return true; +// } +// +// if (CardUtil.checkSevenShunzi(card, dealCards) && rand < 5) { +// Global.logger.info("remove sevent shun zi"); +// return true; +// } +// +// if (CardUtil.checkFourDui(card, dealCards) && rand < 5) { +// Global.logger.info("remove four dui"); +// return true; +// } +// +// } else + { + if (CardUtil.checkGoodCard(card, dealCards, 8) ) { + Global.logger.info("remove zhadan"); + return true; + } +// if (CardUtil.checkShunZi(card, dealCards)) { +// Global.logger.info("remove shun zi"); +// return true; +// } + if (CardUtil.checkFenJi(card, dealCards)) { + Global.logger.info("remove feiji"); + return true; + } + +// if (CardUtil.checkSevenShunzi(card, dealCards)) { +// Global.logger.info("remove sevent shun zi"); +// return true; +// } + + +// if (CardUtil.checkSanTiao(card, dealCards)) { +// Global.logger.info("remove sevent san tiao"); +// return true; +// } + + + + if (CardUtil.checkSixDui(card, dealCards)) { + Global.logger.info("remove five dui"); + return true; + } + +// if (CardUtil.checkKPai(card, dealCards)) { +// Global.logger.info("remove checkKPai"); +// return true; +// } + } + + return false; + } + + public List deal() { + List dealCards = new ArrayList(); + + for (int index = 0; index < this.num; index++) { + dealCards.add(this.pop()); + } + + Map result = new HashMap(); + CardUtil.getCardNumMap(result, dealCards); + for (Map.Entry entry : result.entrySet()) { + if (entry.getValue() >= 4) { + this.totalBoomNum++; + } else if (entry.getValue() == 3) { + this.totalSanZhangNum++; + } + } + + return dealCards; + } + +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/SettleLog.java b/game_pk_paodekuai/src/main/java/extend/pk/SettleLog.java new file mode 100644 index 0000000..eb6b8c6 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/SettleLog.java @@ -0,0 +1,44 @@ +package extend.pk; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +public class SettleLog { + private Map log; + + public SettleLog() { + log = new HashMap(); + } + + public void put(String key,Integer value) { + log.put(key, value); + } + + public void add(String key) { + if(!log.containsKey(key)) { + return; + } + int value = log.get(key); + value++; + log.put(key, value); + } + + public Integer get(String key) { + if(!log.containsKey(key)) { + return null; + } + return log.get(key); + } + + public ITObject toTObject() { + ITObject obj = TObject.newInstance(); + for (Entry entry : this.log.entrySet()) { + obj.putInt(entry.getKey(), entry.getValue()); + } + return obj; + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java new file mode 100644 index 0000000..ad99028 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerDiscardState.java @@ -0,0 +1,427 @@ +package extend.pk.player.state; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.game.Global; +import com.game.Router; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.entity.TObject; +import extend.pk.CardGroup; +import extend.pk.CardObj; +import extend.pk.Config; +import extend.pk.EXActionEvent; +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.RoomCard; +import extend.pk.room.state.EXRoomSetpState; +import extend.pk.uitl.CardCheck; +import extend.pk.uitl.CardConfig; +import extend.pk.uitl.CardUtil; + +/** + * 等待玩家出牌状态 + * + * + */ +public class EXPlayerDiscardState extends StateBase { + + @Override + public void enter(EXPlayer owner) { + + // 设置防作弊场开牌的标志 + owner.open = 1; + + EXRoom room = owner.getRoom(); + + //如果最后一次打牌的座位等于自己 并且牌型是炸弹 + if(room.lastDiscardSeat == owner.seat&& room.discard.config == CardConfig.ZHA) { + + room.addAllBombScore(owner);//炸弹玩家增加积分 + } + + //如果最后一次的打牌的座位不等于零并且最后一次打牌的座位不等于自己 + if(room.lastDiscardSeat != 0 &&room.lastDiscardSeat != owner.seat) { + + boolean bNextBaodan = false; + EXPlayer next = (EXPlayer) owner.room.playerMapBySeat.get(owner.nextSeat); + if(next.cardInhand.size() == 1) { + bNextBaodan = true; + } + CardGroup big_ct = CardCheck.genOutCard(owner.cardInhand, room.discard,room.config,bNextBaodan); + if(big_ct==null) { + + owner.stateMachine.changeState(Global.getState(EXPlayerPassState.class)); + return; + } + else { + + if(big_ct.config.type == Config.TYPE_ZHA ) { + // 如果能出完,就自动出完 + if(big_ct.card_list.size() == owner.cardInhand.size()) { + + doAction(owner,big_ct,true); + return; + } + } + else { + + boolean bContainZha = false; + + boolean bThreeA = false; + if(owner.room.config.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + Map cardMap =CardUtil.getCardNumMap(owner.cardInhand); + for(Map.Entry entry : cardMap.entrySet()) { + + int handNum = cardMap.get(entry.getKey()); + + // 4张牌 不能出现在处大赞的牌型中 + if(handNum >= 4) { + + bContainZha = true; + } + + // 三条A 不能拆 + if(entry.getKey() == RoomCard.CARD_A && bThreeA && handNum >= 3) { + + bContainZha = true; + } + } + + if(big_ct.card_list.size() == owner.cardInhand.size() && bContainZha == false) { + doAction(owner,big_ct,true); + return; + } + } + } + } + else { + + // 自动出牌 + CardGroup auto_ct = CardCheck.autoOutLastHand2(owner.cardInhand, room.config,false); + if(auto_ct != null) { + doAction(owner,auto_ct,true); + return; + } + } + EXMainServer.gameCtr.discardTipEvent(owner); + + owner.startActionTimer(); + } + + @Override + public void reload(EXPlayer owner) { + EXMainServer.gameCtr.discardTipEvent(owner); + } + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } + + public void over(EXPlayer owner) { + EXRoom room = owner.getRoom(); + room.bankerSeat = owner.seat; + room.win = owner; + room.endGame(); + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + switch (cmd) { + case EXActionEvent.EVENT_DISCARD: + + ITObject netParam = (ITObject) param; + ITArray card_list = netParam.getTArray("card"); + ITArray all_card = netParam.getTArray("all_card"); + + if (all_card != null) + { + ArrayList temCardList = new ArrayList(); + for(int i=0;i< all_card.size();++i) { + temCardList.add(all_card.getInt(i)); + } + Collections.sort(temCardList); + + ArrayList temCardList2 = new ArrayList(); + for(int i=0;i< owner.cardInhand.size();++i) { + temCardList2.add(owner.cardInhand.get(i).card); + } + Collections.sort(temCardList2); + + if (!temCardList.equals(temCardList2)) + { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + } + + // 如果出的牌的个数为0 或者大于手牌的数目 则是非法的 + if (card_list.size() == 0 || card_list.size() > owner.cardInhand.size()) { + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_INVALID_TYPE); + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + + List list = CardUtil.toList(card_list); + + + for(CardObj card : list) { + + boolean bNotExisted = false; + + for(CardObj handc : owner.cardInhand) { + if(card.card == handc.card) { + bNotExisted = true; + break; + } + } + + if(bNotExisted == false) { + ITObject reconParam = new TObject(); + owner.sendEvent(Router.GAME_EVT__UPDATE_RECONECT, reconParam); + return; + } + } + +// if(owner.getRoom().firstCard != 0 && CardUtil.getCard1(owner.getRoom().firstCard, list) == null) { +// EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_MUST_OUT_MIN); +// return; +// } + + CardGroup ct = CardCheck.getType(list, owner.room.config); + + if(ct == null) { + +// if (CardCheck.isConfig4_2_and_4_3(owner.room.config)) { +// //四带三摆尾 +// if (list.size() == owner.cardInhand.size()) { //最后一把 +// Map cardMap =CardUtil.getCardNumMap(list); +// +// if (ct == null) { +// if(owner.room.config.containsKey(Config.ROOM_CONFIG_SIDAI_3) && owner.room.config.getBoolean(Config.ROOM_CONFIG_SIDAI_3)) { +//// if (list.size() == 5 || list.size() == 6) { +//// ct = CardCheck.checkSiWithThree(cardMap,owner.room.config); +//// } +// if (list.size() == 5 ) { +// ct = CardCheck.checkSiWithThree(cardMap,owner.room.config); +// } +// +// } +// } +// +// if (ct != null) { +// for(CardObj cardObj : owner.cardInhand) { +// ct.card_list.add(cardObj); +// } +// ct.card_list_mp = CardUtil.toTArray(ct.card_list); +// } +// } +// } + + + if (ct == null) { + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_INVALID_TYPE); + return; + } + } + + boolean bThreeA = false; + if(owner.room.config.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + //验证客户端发过来的类型 + if(!CardCheck.tryType(ct,owner.cardInhand.size(),owner.room.config)) { + + // tryType 判断3条a判断不出来, 所以 + if(!(ct.config.type == Config.TYPE_ZHA && + card_list.size() == 3 && + bThreeA && + CardUtil.checkCard(RoomCard.CARD_A, list, 3))) { + + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_INVALID_TYPE); + return; + } + } + + // 如果炸弹不允许拆分,则检测非炸弹和4带三的牌型,看他们是否拆分了炸弹 + if(owner.room.config.getInt(Config.ROOM_CONFIG_DEMOLITION) == 1) { + + if(ct.config.type != Config.TYPE_ZHA ) { + + Map hangCardMap =CardUtil.getCardNumMap(owner.cardInhand); + Map cardMap =CardUtil.getCardNumMap(list); + for(Map.Entry entry : cardMap.entrySet()) { + + int handNum = hangCardMap.get(entry.getKey()); + + // 4张牌 不能出现在处大赞的牌型中 + if(handNum >= 4) { + + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_BOMB_CHAI); + return; + } + + // 三条A 不能拆 + if(entry.getKey() == RoomCard.CARD_A && bThreeA && handNum == 3) { + + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_BOMB_CHAI); + return; + } + } + } + } + + doAction(owner,ct,false); + break; + + case EXActionEvent.EVENT_PASS: + + if(owner.room.config.getInt(Config.ROOM_CONFIG_WILL_BE_OUT) == 1) { + return; + } + pass(owner); + + break; + case EXActionEvent.EVENT_OFFLINE: + owner.startActionTimer(); + break; + case EXActionEvent.EVENT_TIMER_AUTO: + case EXActionEvent.EVENT_ENTRUST: + + AutoOut(owner); + break; + } + } + + private void AutoOut(EXPlayer owner) { + + EXRoom room = owner.getRoom(); + + if(room.lastDiscardSeat != 0 &&room.lastDiscardSeat != owner.seat) { + + CardGroup big_ct = null; + EXPlayer playerNext = (EXPlayer)room.playerMapBySeat.get(owner.nextSeat); + if(playerNext != null && room.discard.config.type ==Config.TYPE_DANPAI && playerNext.cardInhand.size() == 1) { + + Map> cardMap =CardUtil.getCardListMap(owner.cardInhand); + big_ct = CardCheck.selectDanpai(cardMap,room.discard,room.config,true); + }else { + big_ct = CardCheck.tryBig(owner.cardInhand, room.discard); + } + + if (big_ct != null) { + big_ct.card_list_mp = CardUtil.toTArray(big_ct.card_list); + doAction(owner,big_ct,true); + } else { + pass(owner); + } + + }else { + + // 在托管或者自动出牌的时候 系统先出炸弹,如果炸弹没有 再出单张 + // 将来可以把这个函数做的能智能一些,不光可以出炸弹 也可以出顺子飞机等等 + CardGroup out_ct = CardCheck.autoOut(owner.cardInhand, owner.room.config); + if(out_ct == null) { + + out_ct = new CardGroup(); + List out_list = new ArrayList<>(); + out_ct.card_list = out_list; + out_ct.config = CardConfig.DAN; + out_ct.len = 1; + + if(room.firstCard != 0) { + CardObj co = CardUtil.getCard1(room.firstCard, owner.cardInhand); + out_list.add(co); + } + else + { + EXPlayer next = (EXPlayer) owner.room.playerMapBySeat.get(owner.nextSeat); + if(next.cardInhand.size() == 1) { + out_list.add(owner.cardInhand.get(owner.cardInhand.size() -1)); + }else { + out_list.add(owner.cardInhand.get(0)); + } + } + } + + out_ct.card_list_mp = CardUtil.toTArray(out_ct.card_list); + out_ct.min_card = out_ct.card_list.get(0).cardMod; + + doAction(owner,out_ct,true); + } + } + + private void pass(EXPlayer owner) { + EXMainServer.gameCtr.pass(owner);//打不起过 + this.toNextState(owner);//下一位大哥 + } + + private void doAction(EXPlayer owner,CardGroup ct,boolean skip) { + + EXRoom room = owner.getRoom(); + boolean outcard = true; + if(!skip) { + + if(room.lastDiscardSeat != 0 &&room.lastDiscardSeat != owner.seat) { + outcard = CardCheck.tryCompete(room.discard, ct,room.config); + } + + // 如果玩家的下家只有一张牌,玩家出单张必须是最大的 + if(outcard && ct.config.type == Config.TYPE_DANPAI) { + + EXPlayer playerNext = (EXPlayer)room.playerMapBySeat.get(owner.nextSeat); + if(playerNext != null && playerNext.cardInhand.size() == 1) { + + Map cardMap =CardUtil.getCardNumMap(owner.cardInhand); + for(Integer number : cardMap.keySet()) { + + if(ct.min_card < number) { + + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_MUST_OUT_MAX); + return; + } + } + } + } + } + if(!outcard) { + EXMainServer.gameCtr.sendPutError(owner,Config.PUT_ERROR_INVALID_TYPE); + return; + } + + EXMainServer.gameCtr.outCard(owner,ct); + + if (owner.cardInhand.size() == 0) { + // 如果最后一手牌是炸弹 则需要添加炸弹分 + if(ct.config.type == Config.TYPE_ZHA) { + + room.addAllBombScore(owner);//炸弹玩家增加积分 + } + this.over(owner); + } else { + this.toNextState(owner); + } + } + + +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPassState.java b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPassState.java new file mode 100644 index 0000000..97a56be --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPassState.java @@ -0,0 +1,52 @@ +package extend.pk.player.state; + +import com.game.Global; +import com.game.data.Timer; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; + +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.room.state.EXRoomSetpState; + +/** + * 等待玩家Pass状态 + * + * + */ +public class EXPlayerPassState extends StateBase { + + private void pass(EXPlayer owner) { + EXMainServer.gameCtr.pass(owner);//打不起过 + this.toNextState(owner);//下一位大哥 + } + + @Override + public void enter(EXPlayer owner) { + EXRoom room = owner.getRoom(); + if(!owner.entrust) { + Timer passTimer = new Timer(10, new Timer.ITaskHandler() { + @Override + public void doTask(Timer timer) { + pass(owner); + } + }); + room.addTimer(passTimer); + }else { + pass(owner); + } + } + + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + @Override + public void toNextState(EXPlayer owner) { + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPiaoNiaoTipState.java b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPiaoNiaoTipState.java new file mode 100644 index 0000000..d2ecadb --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/player/state/EXPlayerPiaoNiaoTipState.java @@ -0,0 +1,64 @@ +package extend.pk.player.state; + +import com.game.ActionEvent; +import com.game.Global; +import com.game.player.state.PlayerWaitState; +import com.game.state.StateBase; +import com.taurus.core.entity.ITObject; + +import extend.pk.EXActionEvent; +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; + + + +public class EXPlayerPiaoNiaoTipState extends StateBase{ + + @Override + public void enter(EXPlayer owner) { + if(!owner.isEntrust()) { + EXMainServer.gameCtr.piaoTipEvent(owner,0); + } + owner.startActionTimer(); + } + + /** + * 重连 + * @param owner + */ + @Override + public void reload(EXPlayer owner) { + EXMainServer.gameCtr.piaoTipEvent(owner,1); + owner.startActionTimer(); + } + + + @Override + public void exit(EXPlayer owner) { + owner.stopActionTimer(); + } + + private void _action(EXPlayer owner,int id,int gid) { + owner.piao = id; + + owner.stateMachine.changeState(Global.getState(PlayerWaitState.class)); + owner.getRoom().piaoCount --; + EXMainServer.gameCtr.piaoEvent(owner); + owner.getRoom().stateMachine.execute(EXActionEvent.EVENT_PIAO, gid, null); + } + + @Override + public void execute(EXPlayer owner, String cmd, int gid, Object param) { + super.execute(owner, cmd, gid, param); + if (cmd.equals(EXActionEvent.EVENT_PIAO)) { + ITObject netParam = (ITObject) param; + int id = netParam.getInt("id"); + _action(owner, id, gid); + }else if(cmd.equals(ActionEvent.EVENT_TIMER_AUTO) || cmd.equals(ActionEvent.EVENT_ENTRUST)) { + _action(owner,0,gid); + } + else if(cmd.equals(ActionEvent.EVENT_OFFLINE)) { + owner.startActionTimer(); + } + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomDealState.java b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomDealState.java new file mode 100644 index 0000000..c2e34a9 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomDealState.java @@ -0,0 +1,112 @@ +package extend.pk.room.state; + + + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import com.taurus.permanent.TPServer; +import extend.pk.Config; +import extend.pk.EXMainServer; +import extend.pk.EXPlayBack; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.uitl.CardCheck; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 房间发牌状态 + * + * + */ +public class EXRoomDealState extends StateBase { + @Override + public void enter(EXRoom owner) { + boolean donghua = false; + for (Map.Entry entry : owner.playerMapById.entrySet()) { + EXPlayer player = (EXPlayer) entry.getValue(); + if (player.xi_pai) + { + donghua = true; + break; + } + } + + if (donghua) + { + owner.notifyXiPai(); + //启动定时器 + timer(owner); + } + else { + this.toNextState(owner); + } + + } + + public static void timer(EXRoom owner) { + + TPServer.me().getTimerPool().schedule(new Runnable() { + + @Override + public void run() { + + if (owner == null) { + Global.logger.error("room is null"); + return; + } + + if (owner.isDestroy) + return; + + owner.enqueueRunnable(new Runnable() { + + @Override + public void run() { + owner.stateMachine.toNextState(); + } + }); + } + }, 3000, TimeUnit.MILLISECONDS); + } + + @Override + public void toNextState(EXRoom owner) { + //owner.card.init(); + if(owner.bankerSeat!=0&&!owner.playerMapBySeat.containsKey(owner.bankerSeat)) { + owner.bankerSeat = 0; + } + EXMainServer.gameCtr.dealCard(owner); + + owner.playBackData = new EXPlayBack(owner); + + if(owner.config.getInt(Config.ROOM_CONFIG_MINBOOM) == 1) { + + int startSpringSeat = 0; + int seat = owner.bankerSeat; + do { + + EXPlayer player = (EXPlayer)owner.playerMapBySeat.get(seat); + if(CardCheck.checkStartSpring(player.cardInhand)) { + + startSpringSeat = seat; + break; + } + }while(seat != owner.bankerSeat); + + if(startSpringSeat != 0) { + owner.bankerSeat = startSpringSeat; + owner.win = (EXPlayer)owner.playerMapBySeat.get(startSpringSeat); + owner.endGame(); + return; + } + } + + + + owner.stateMachine.changeState(Global.getState(EXRoomSetpState.class)); + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomPiaoState.java b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomPiaoState.java new file mode 100644 index 0000000..dbb1ce8 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomPiaoState.java @@ -0,0 +1,31 @@ +package extend.pk.room.state; + +import java.util.Map.Entry; + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.pk.EXActionEvent; +import extend.pk.EXRoom; +import extend.pk.player.state.EXPlayerPiaoNiaoTipState; + +public class EXRoomPiaoState extends StateBase{ + + @Override + public void enter(EXRoom owner) { + owner.piaoCount = owner.maxPlayers; + for (Entry entry : owner.playerMapById.entrySet()) { + Player player = entry.getValue(); + player.stateMachine.changeState(Global.getState(EXPlayerPiaoNiaoTipState.class)); + } + } + + public void execute(EXRoom owner, String cmd, int gid, Object param) { + if(cmd.equals(EXActionEvent.EVENT_PIAO)) { + if(owner.piaoCount==0) { + owner.stateMachine.changeState(Global.getState(EXRoomDealState.class)); + } + } + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomSetpState.java b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomSetpState.java new file mode 100644 index 0000000..ce6843c --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomSetpState.java @@ -0,0 +1,35 @@ +package extend.pk.room.state; + +import com.game.Global; +import com.game.state.StateBase; + +import extend.pk.EXMainServer; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; +import extend.pk.player.state.EXPlayerDiscardState; + +/** + * 房间转换座位 + * + * + */ +public class EXRoomSetpState extends StateBase { + + @Override + public void enter(EXRoom owner) { + EXPlayer player = null; + if (owner.activeSeat == 0) { + player = (EXPlayer) owner.playerMapBySeat.get(owner.bankerSeat); + } else { + player = (EXPlayer) owner.playerMapBySeat.get(owner.activeSeat); + int nextSeat = player.nextSeat; + player = (EXPlayer) owner.playerMapBySeat.get(nextSeat); + } + + + EXMainServer.gameCtr.changeActiveSeat(owner, player.seat); + + player.stateMachine.changeState(Global.getState(EXPlayerDiscardState.class)); + + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomStartGameState.java b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomStartGameState.java new file mode 100644 index 0000000..665018e --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/room/state/EXRoomStartGameState.java @@ -0,0 +1,43 @@ +package extend.pk.room.state; + +import java.util.Map.Entry; + +import com.game.Global; +import com.game.data.Player; +import com.game.state.StateBase; + +import extend.pk.Config; +import extend.pk.EXPlayer; +import extend.pk.EXRoom; + +/** + * 房间开始状态 + * + * + */ +public class EXRoomStartGameState extends StateBase { + + @Override + public void enter(EXRoom owner) { + + for (Entry entry : owner.playerMapBySeat.entrySet()) { + EXPlayer player = (EXPlayer)entry.getValue(); + player.clearEx(); + } + owner.clearEx(); + owner.startGame(); + + this.toNextState(owner); + } + + @Override + public void toNextState(EXRoom owner) { + + if(owner.config.containsKey(Config.ROOM_CONFIG_PIAO) && owner.config.getInt(Config.ROOM_CONFIG_PIAO) != 0) { + owner.stateMachine.changeState(Global.getState(EXRoomPiaoState.class)); + } + else{ + owner.stateMachine.changeState(Global.getState(EXRoomDealState.class)); + } + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardCheck.java b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardCheck.java new file mode 100644 index 0000000..9d3826b --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardCheck.java @@ -0,0 +1,1429 @@ +package extend.pk.uitl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; + +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import extend.pk.CardGroup; +import extend.pk.CardObj; +import extend.pk.Config; +import extend.pk.RoomCard; + +/** + * + * + */ +public class CardCheck { + + /** + * 服务器跟牌判定 + * + * @param cardInhand + * @param out + * @param roomConfig + * @param nextBaodan + * @return + */ + public static CardGroup genOutCard(List cardInhand, CardGroup out, ITObject roomConfig, + boolean nextBaodan) { + + CardGroup cg = null; + + Map> cardMap = CardUtil.getCardListMap(cardInhand); + int handCardSize = cardInhand.size(); + // 如果有炸弹 并且玩家手上仅剩下炸弹 就不用找了 直接出牌就可以了 + cg = selectZha(cardMap, out, roomConfig); + if (cg != null && cg.card_list.size() == handCardSize) { + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + return cg; + } + + // 如果别的玩家出的是一张单牌,则寻找一个合适的单牌,如果找不到就用炸弹,炸弹没有则过 + if (out.config.type == Config.TYPE_DANPAI) { + + CardGroup tempCg = selectDanpai(cardMap, out, roomConfig, nextBaodan); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是不能带牌的牌型(对子,顺子,连队)则寻找合适的牌型,如果找不到就用炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_DUIZI || out.config.type == Config.TYPE_SHUNZI + || out.config.type == Config.TYPE_LIANDUI) { + + CardGroup tempCg = selectWithoutCardType(handCardSize, cardMap, out, roomConfig); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是带牌的三带牌型 ,则寻找合适的牌型,如果找不到就用炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_3) { + + boolean bLack = false; + + CardGroup tempCg = selectWithCardType(cardInhand, cardMap, out, roomConfig, bLack); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是带牌的三带牌型 ,则寻找合适的牌型,如果找不到就用炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_3_2) { + + boolean bLack = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_LACK) == 1) { + bLack = true; + } + + CardGroup tempCg = selectWithCardType(cardInhand, cardMap, out, roomConfig, bLack); + if (tempCg != null) { + cg = tempCg; + } + } + + // 如果别的玩家出的是带牌的飞机牌型,则寻找合适的牌型,如果找不到用则炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_FEIJI) { + boolean bLack = false; + CardGroup tempCg = selectWithCardType(cardInhand, cardMap, out, roomConfig, bLack); + if (tempCg != null) { + cg = tempCg; + } + } + // 如果别的玩家出的是带牌的飞机牌型,则寻找合适的牌型,如果找不到用则炸弹,炸弹没有则过 + else if (out.config.type == Config.TYPE_FEIJI_2) { + + boolean bLack = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_PLANE_LACK) == 1) { + bLack = true; + } + + CardGroup tempCg = selectWithCardType(cardInhand, cardMap, out, roomConfig, bLack); + if (tempCg != null) { + cg = tempCg; + } + } + // 如果是四带二或者四带三 就不处理了,如果有炸弹,则玩家自己去选择是炸还是跟,如果没有炸弹 玩家也大不了,所以后面就不用判断了 + if (cg != null) { + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + return cg; + } + + /** + * 选择炸弹 + * + * @param cardMap + * @param out + * @param roomConfig + * @return + */ + private static CardGroup selectZha(Map> cardMap, CardGroup out, ITObject roomConfig) { + + CardGroup cg = null; + + boolean bThreeA = false; + if (roomConfig != null && roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + int minValue = 0; + if (out.config.type == Config.TYPE_ZHA) { + minValue = out.min_card; + } + + for (Map.Entry> entry : cardMap.entrySet()) { + + if (entry.getValue().size() == 4 + || (entry.getKey() == RoomCard.CARD_A && bThreeA && entry.getValue().size() == 3)) { + + if (entry.getKey() > minValue) { + + cg = new CardGroup(); + + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + + cg.card_list = new ArrayList<>(); + for (CardObj cardObj : entry.getValue()) { + cg.card_list.add(cardObj); + } + break; + } + } + } + + return cg; + } + + /** + * 选择单牌 + * + * @param cardMap + * @param out + * @param roomConfig + * @param nextBaodan + * @return + */ + public static CardGroup selectDanpai(Map> cardMap, CardGroup out, ITObject roomConfig, + boolean nextBaodan) { + CardGroup cg = null; + + int minValue = out.min_card + 1; + + boolean bDemolition = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_DEMOLITION) == 1) { + bDemolition = true; + } + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + if (!nextBaodan) { + + for (int i = minValue; i <= 15; i++) { + + List listCard = cardMap.get(i); + if (listCard != null && listCard.size() >= 1) { + // 如果是炸弹 并且不能拆分炸弹,则不能用它作为单牌来处理 + if (bDemolition + && (listCard.size() == 4 || (i == RoomCard.CARD_A && bThreeA && listCard.size() == 3))) { + + } else { + cg = new CardGroup(); + + cg.config = CardConfig.DAN; + cg.min_card = i; + cg.len = 1; + + cg.card_list = new ArrayList<>(); + cg.card_list.add(listCard.get(0)); + break; + } + } + } + } else { + for (int i = 15; i >= minValue; i--) { + + List listCard = cardMap.get(i); + if (listCard != null && listCard.size() >= 1) { + + // 如果是炸弹 并且不能拆分炸弹,则不能用它作为单牌来处理 + if (bDemolition + && (listCard.size() == 4 || (i == RoomCard.CARD_A && bThreeA && listCard.size() == 3))) { + + } else { + + cg = new CardGroup(); + + cg.config = CardConfig.DAN; + cg.min_card = i; + cg.len = 1; + + cg.card_list = new ArrayList<>(); + cg.card_list.add(listCard.get(0)); + break; + } + } + } + } + + return cg; + } + + /** + * 选择不需要带牌的牌型 + * + * @param handCardSize + * @param cardMap + * @param out + * @param roomConfig + * @return + */ + private static CardGroup selectWithoutCardType(int handCardSize, Map> cardMap, CardGroup out, + ITObject roomConfig) { + CardGroup cg = null; + + boolean bDemolition = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_DEMOLITION) == 1) { + bDemolition = true; + } + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + int len = out.len; + + // 如果手牌数满足要求 + if (handCardSize >= len * out.config.repeat_num) { + + List card_list = new ArrayList(); + + // 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + int min_card = out.min_card + 1; + + // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + int max_card = min_card + len - 1; + + // 长度如果大于一并且最大的牌 + if (!(len > 1 && max_card > 14)) { + + int count = 0; + + for (int i = min_card; i <= 14; ++i) { + + List list = cardMap.get(i); + + // 如果牌值对应的牌为空 或者他是炸弹,则之前找到的牌取消 + if (list == null || (bDemolition + && (list.size() == 4 || (i == RoomCard.CARD_A && bThreeA && list.size() == 3)))) { + count = 0; + card_list.clear(); + continue; + } + + // 如果牌值对应的牌的个数满足要求,则将牌放入队列中 + if (list.size() >= out.config.repeat_num) { + + for (int k = 0; k < out.config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + + // 如果已经找到了足够数量的相同牌型 + if (count == len) { + + cg = new CardGroup(); + + cg.config = out.config; + cg.card_list = card_list; + cg.len = len; + cg.min_card = card_list.get(0).cardMod; + + return cg; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + return cg; + } + + private static CardGroup selectWithCardType(List cardInhand, Map> cardMap, + CardGroup out, ITObject roomConfig, boolean bLack) { + + CardGroup cg = null; + + int handCardSize = cardInhand.size(); + + boolean bDemolition = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_DEMOLITION) == 1) { + bDemolition = true; + } + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + int len = out.len; + + // 如果手牌数满足要求 + if (handCardSize >= len * out.config.repeat_num) { + + List card_list = new ArrayList(); + + // 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + int min_card = out.min_card + 1; + + // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + int max_card = min_card + len - 1; + + // 长度如果大于一并且最大的牌 + if (!(len > 1 && max_card > 14)) { + + int count = 0; + + for (int i = min_card; i <= 14; ++i) { + + List list = cardMap.get(i); + + // 如果牌值对应的牌为空 或者他是炸弹,则之前找到的牌取消 + if (list == null || (bDemolition + && (list.size() == 4 || (i == RoomCard.CARD_A && bThreeA && list.size() == 3)))) { + count = 0; + card_list.clear(); + continue; + } + + // 如果牌值对应的牌的个数满足要求,则将牌放入队列中 + if (list.size() >= out.config.repeat_num) { + + for (int k = 0; k < out.config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + + // 如果已经找到了足够数量的相同牌型 + if (count == len) { + + int sd = out.config.repeat_num * len + out.config.with_card_num * len; + + boolean sandaidan = roomConfig.containsKey(Config.ROOM_CONFIG_SANDAIDAN) + && roomConfig.getInt(Config.ROOM_CONFIG_SANDAIDAN) == 1; + if (sandaidan) { + + if (handCardSize < out.card_list.size()) { + return cg; + } + } else { + + if (bLack == false && handCardSize < sd) { + + return cg; + } + } + + // 新建一个临时的列表,来保存剩余的牌 + List tem_list = new ArrayList(); + tem_list.addAll(cardInhand); + CardUtil.removeCard(tem_list, card_list); + + // 如果剩余的牌有炸弹,则需要把剩余牌中的炸弹对应的牌从临时列表中剔除,以确定是否有足够的单牌 + // 如果因为剔除的原因,最后牌型不能做成,那就提示他有炸弹出就可以了 + Map> reservedCardMap = CardUtil.getCardListMap(tem_list); + int duiNum = 0; + for (Map.Entry> entry : reservedCardMap.entrySet()) { + + int num = entry.getValue().size(); + if (num == 4 || (entry.getKey() == RoomCard.CARD_A && bThreeA && num == 3)) { + + CardUtil.removeCard(tem_list, entry.getValue()); + } + + if (num >= 2) { + duiNum++; + } + } + + if (sandaidan) { + + boolean isDui = sd == out.card_list.size(); + if (isDui) { + + if (duiNum < len) { + return cg; + } + + for (Map.Entry> entry : reservedCardMap.entrySet()) { + + int num = entry.getValue().size(); + if (num >= 2 && num < 4) { + card_list.add(entry.getValue().get(0)); + card_list.add(entry.getValue().get(1)); + } + } + + } else { + + for (int m = 0; m < len; m++) { + card_list.add(tem_list.get(m)); + } + } + } else { + + // 如果手牌数多于牌型的基本要求 + if (handCardSize >= sd) { + + if (tem_list.size() < out.config.with_card_num * len) { + return cg; + } + + for (int m = 0; m < out.config.with_card_num * len; m++) { + card_list.add(tem_list.get(m)); + } + } else { + + card_list.addAll(tem_list); + } + } + + cg = new CardGroup(); + + cg.config = out.config; + cg.card_list = card_list; + cg.len = len; + cg.min_card = card_list.get(0).cardMod; + + return cg; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + return cg; + } + + /** + * 得到所出牌的牌型 + * + * @param cardOut + * @param roomConfig + * @return + */ + public static CardGroup getType(List cardOut, ITObject roomConfig) { + + CardGroup cg = autoOutLastHand(cardOut, roomConfig, true); + + if (cg == null) { + + int len = cardOut.size(); + int sidai = roomConfig.getInt(Config.ROOM_CONFIG_SIDAI); + // 看看所处的牌是否 4带2 或者4带3 + if ((len == 6 && sidai == 2) || (len == 7 && sidai == 3)) { + + Map cardMap = CardUtil.getCardNumMap(cardOut); + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + if (len == 6) { + cg.config = CardConfig.SI_2; + } else { + cg.config = CardConfig.SI_3; + } + + cg.min_card = entry.getKey(); + cg.len = 1; + + for (CardObj cardObj : cardOut) { + cg.card_list.add(cardObj); + } + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + } + } + } + + return cg; + } + + /** + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOutLastHand(List cardInhand, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + int len = cardInhand.size(); + if (len == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DAN; + cg.min_card = cardInhand.get(0).cardMod; + cg.len = 1; + } else if (len == 2) { + cg = checkTwo(cardMap); + } else if (len == 3) { + + cg = checkThree(cardMap, roomConfig); + } else if (len == 4) { + + cg = checkFour(cardMap, roomConfig); + } else if (len == 5) { + +// if (isConfig4_2_and_4_3(roomConfig) && getMaxCardNum(cardMap) == 4) {// 四带一 +// return null;// 不能判为三带二 +// } + + cg = checkFive(cardMap, roomConfig, bSpecial); + } else { + if (bSpecial) { + if (len == 6) { +// cg = checkSiWithTwo(cardMap, roomConfig); + if (cg == null) { + cg = checkFeijiNoBelt(cardMap, roomConfig); + } + } + + if (len == 7) { + cg = checkSiWithThree(cardMap, roomConfig); + } + } + + if (cg == null) { + cg = checkShunzi(len, cardMap, roomConfig); + if (cg == null) { + cg = checkLiandui(len, cardMap, roomConfig); + if (cg == null) { + cg = checkFeiji(len, cardMap, roomConfig, bSpecial); + } + } + } + } + + if (cg != null) { + + for (CardObj cardObj : cardInhand) { + cg.card_list.add(cardObj); + } + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + + return cg; + } + + /** + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOutLastHand2(List cardInhand, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + int len = cardInhand.size(); + if (len == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DAN; + cg.min_card = cardInhand.get(0).cardMod; + cg.len = 1; + } else if (len == 2) { + cg = checkTwo(cardMap); + } else if (len == 3) { + + cg = checkThree(cardMap, roomConfig); + } else if (len == 4) { + + cg = checkFour(cardMap, roomConfig); + } else if (len == 5) { + +// if (isConfig4_2_and_4_3(roomConfig) && getMaxCardNum(cardMap) == 4) {// 四带一 +// return null;// 不能判为三带二 +// } + + if(cardInhand.size()==5 && getMaxCardNum(cardMap) == 4) { + return null; + } + cg = checkFive(cardMap, roomConfig, bSpecial); + } else { + if (bSpecial) { + if (len == 6) { +// cg = checkSiWithTwo(cardMap, roomConfig); + if (cg == null) { + cg = checkFeijiNoBelt(cardMap, roomConfig); + } + } + + if (len == 7) { + cg = checkSiWithThree(cardMap, roomConfig); + } + } + + if (cg == null) { + cg = checkShunzi(len, cardMap, roomConfig); + if (cg == null) { + cg = checkLiandui(len, cardMap, roomConfig); + if (cg == null) { + cg = checkFeiji(len, cardMap, roomConfig, bSpecial); + } + } + } + } + + if (cg != null) { + + for (CardObj cardObj : cardInhand) { + cg.card_list.add(cardObj); + } + cg.card_list_mp = CardUtil.toTArray(cg.card_list); + } + + return cg; + } + + private static int getMaxCardNum(Map cardMap) { + int maxNum = 0; + for (Map.Entry entry : cardMap.entrySet()) { + if (entry.getValue() > maxNum) { + maxNum = entry.getValue(); + } + } + + return maxNum; + } + + public static boolean isConfig4_2_and_4_3(ITObject roomConfig) { + if ((roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_2) && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_2)) + || (roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_3) + && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_3))) { + return true; + } else { + return false; + } + } + + private static CardGroup checkTwo(Map cardMap) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + if (entry.getValue() == 2) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.DUIZI; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + + return cg; + } + + private static CardGroup checkThree(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 3) { + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + if (entry.getKey() == RoomCard.CARD_A && bThreeA == true) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } else if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_NOBELT) == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN; + cg.min_card = entry.getKey(); + cg.len = 1; + } else { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN_2; + cg.min_card = entry.getKey(); + cg.len = 1; + } + } + } + return cg; + } + + private static CardGroup checkFour(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + } else if (entry.getValue() == 3) { + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + if (entry.getKey() == RoomCard.CARD_A && bThreeA) { + return cg; + } + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_LACK) == 1) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN_2; + cg.min_card = entry.getKey(); + cg.len = 1; + } + + } else if (entry.getValue() == 2) { + + if (minCard == 0 || entry.getKey() < minCard) { + minCard = entry.getKey(); + } + + if (maxCard == 0 || entry.getKey() > maxCard) { + maxCard = entry.getKey(); + } + + if (minCard != 0 && maxCard != 0 && minCard + 1 == maxCard) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.LIANDUI; + cg.min_card = minCard; + cg.len = 2; + } + } + } + return cg; + } + + private static CardGroup checkFive(Map cardMap, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + int count = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 3 || (entry.getValue() == 4)) { + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + if (entry.getKey() == RoomCard.CARD_A && bThreeA) { + return cg; + } + + if (!roomConfig.containsKey(Config.ROOM_CONFIG_SANDAIDAN) + || roomConfig.getInt(Config.ROOM_CONFIG_SANDAIDAN) == 0) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN_2; + cg.min_card = entry.getKey(); + cg.len = 1; + } else { + +// if (entry.getValue() != 4 && cardMap.size() == 2) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SAN_2; + cg.min_card = entry.getKey(); + cg.len = 1; +// } + } + + break; + } else if (entry.getValue() == 1 && entry.getKey() != RoomCard.CARD_2) { + + if (minCard == 0 || entry.getKey() < minCard) { + minCard = entry.getKey(); + } + + if (maxCard == 0 || entry.getKey() > maxCard) { + maxCard = entry.getKey(); + } + count++; + + if (count == 5 && minCard != 0 && maxCard != 0 && minCard + 4 == maxCard) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SHUNZI; + cg.min_card = minCard; + cg.len = 5; + } + } + } + + return cg; + } + + public static CardGroup checkSiWithTwo(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + int count = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + if (roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_2) + && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_2)) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SI_2; + cg.min_card = entry.getKey(); + cg.len = 1; + } + + break; + } + } + + return cg; + } + + public static CardGroup checkFeijiNoBelt(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 3) { + if (roomConfig.getInt(Config.ROOM_CONFIG_PLANE_NOBELT) == 1) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.FEIJI; + cg.min_card = entry.getKey(); + cg.len = cardMap.size(); + } + + break; + } + } + + return cg; + } + + public static CardGroup checkSiWithThree(Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + int count = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4) { + if (roomConfig.containsKey(Config.ROOM_CONFIG_SIDAI_3) + && roomConfig.getBoolean(Config.ROOM_CONFIG_SIDAI_3)) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SI_3; + cg.min_card = entry.getKey(); + cg.len = 1; + } + + break; + } + } + + return cg; + } + + private static CardGroup checkShunzi(int len, Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + + int minCard = 0; + int maxCard = 0; + int count = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 1 && entry.getKey() != RoomCard.CARD_2) { + if (minCard == 0 || entry.getKey() < minCard) { + minCard = entry.getKey(); + } + + if (maxCard == 0 || entry.getKey() > maxCard) { + maxCard = entry.getKey(); + } + count++; + + if (count == len && minCard != 0 && maxCard != 0 && minCard + len - 1 == maxCard) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.SHUNZI; + cg.min_card = minCard; + cg.len = count; + } + } else { + break; + } + } + + return cg; + } + + private static CardGroup checkLiandui(int len, Map cardMap, ITObject roomConfig) { + + CardGroup cg = null; + int minCard = 0; + int maxCard = 0; + int count = 0; + + if (len % 2 != 0) { + return cg; + } + + len = len / 2; + + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 2) { + if (minCard == 0 || entry.getKey() < minCard) { + minCard = entry.getKey(); + } + + if (maxCard == 0 || entry.getKey() > maxCard) { + maxCard = entry.getKey(); + } + count++; + + if (count == len && minCard != 0 && maxCard != 0 && minCard + len - 1 == maxCard) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.LIANDUI; + cg.min_card = minCard; + cg.len = count; + } + } else { + break; + } + } + return cg; + } + + private static CardGroup checkFeiji(int len, Map cardMap, ITObject roomConfig, boolean bSpecial) { + + CardGroup cg = null; + + int[] cardThreeCount = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + int num2 = 0; + for (Map.Entry entry : cardMap.entrySet()) { + + // 如果有炸弹 则不允许自动出牌 + if (bSpecial == false && (entry.getValue() == 4 + || (entry.getKey() == RoomCard.CARD_A && entry.getValue() == 3 && bThreeA == true))) { + return cg; + } + + if (entry.getValue() >= 3) { + cardThreeCount[entry.getKey()] = 1; + } else if (entry.getValue() == 2) { + num2++; + } + } + + int left = 0; + int right = 0; + + for (int i = 4; i < cardThreeCount.length; i++) { + + if (left == 0) { + + if (cardThreeCount[i] == 1 && cardThreeCount[i - 1] == 1) { + left = i - 1; + right = i; + } + } else { + // 如果有连续的继续寻找 + if (cardThreeCount[i] == 1 && right + 1 == i) { + + right = i; + } else { + left = 0; + right = 0; + } + } + // 判断出来一个顺子,就判定一下是否可以全部出 + if (left != 0 && right != 0) { + + int threeCount = right - left + 1; + int sl = threeCount * 5; + + if (!roomConfig.containsKey(Config.ROOM_CONFIG_SANDAIDAN) + || roomConfig.getInt(Config.ROOM_CONFIG_SANDAIDAN) == 0) { + + if (len <= sl) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.FEIJI_2; + cg.min_card = left; + cg.len = threeCount; + + return cg; + } + } else if (roomConfig.getInt(Config.ROOM_CONFIG_PLANE_NOBELT) == 0) { + + if (len <= sl) { + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.FEIJI; + cg.min_card = left; + cg.len = threeCount; + + return cg; + } + } else { + + int withMin = threeCount * 4; + if (len == withMin || num2 == threeCount || len == threeCount * 3) { + + cg = new CardGroup(); + cg.card_list = new ArrayList<>(); + cg.config = CardConfig.FEIJI_2; + cg.min_card = left; + cg.len = threeCount; + + return cg; + } + } + + } + } + + return cg; + } + + /** + * 自动出牌 + * + * @param cardInhand + * @param roomConfig + * @return + */ + public static CardGroup autoOut(List cardInhand, ITObject roomConfig) { + + CardGroup cg = null; + + // 支持3A炸弹 + boolean bThreeA = false; + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_A) == 1) { + bThreeA = true; + } + + // 寻找炸弹 + Map cardMap = CardUtil.getCardNumMap(cardInhand); + for (Map.Entry entry : cardMap.entrySet()) { + + if (entry.getValue() == 4 + || (entry.getKey() == RoomCard.CARD_A && bThreeA == true && entry.getValue() == 3)) { + + cg = new CardGroup(); + List out_list = new ArrayList<>(); + + cg.card_list = out_list; + cg.config = CardConfig.ZHA; + cg.min_card = entry.getKey(); + cg.len = 1; + + for (CardObj cardObj : cardInhand) { + + if (cardObj.cardMod == entry.getKey()) { + out_list.add(cardObj); + } + } + } + } + + return cg; + } + + /** + * 验证牌型 + * + * @param ct + * @param left_count + * @return + */ + public static boolean tryType(CardGroup ct, int left_count, ITObject roomConfig) { + List cardInhand = ct.card_list; + int size = cardInhand.size(); + CardConfig config = ct.config; + + if (size < config.min_card_num || size > config.max_card_num) { + return false; + } + int len = ct.len; + if (len < config.min_len) { + return false; + } + // 牌型所需要的正常牌数 + int tem_size = len * config.repeat_num + len * config.with_card_num; + if (!roomConfig.containsKey(Config.ROOM_CONFIG_SANDAIDAN) + || roomConfig.getInt(Config.ROOM_CONFIG_SANDAIDAN) == 0 + || (ct.config.type != Config.TYPE_3_2 && ct.config.type != Config.TYPE_FEIJI_2)) { + + // 如果牌型可以带牌 并且手牌的剩余数等于出牌的数目(全出了) + if (config.with_card_num > 0 && size == left_count) { + // 牌太少了 出牌太多了 + if (size < len * config.repeat_num || size > tem_size) { + return false; + } + // 如果带的牌不够 + if (size < tem_size) { + // 如果是三张 或者三带 + if (ct.config.type == Config.TYPE_3_2) { + if (roomConfig.getInt(Config.ROOM_CONFIG_THREE_LACK) == 0) { + return false; + } + } + // 如果是飞机 + else if (ct.config.type == Config.TYPE_FEIJI) { + if (roomConfig.getInt(Config.ROOM_CONFIG_PLANE_NOBELT) == 0) { + return false; + } + } else if (ct.config.type == Config.TYPE_FEIJI_2) { + if (roomConfig.getInt(Config.ROOM_CONFIG_PLANE_LACK) == 0) { + return false; + } + } + } + } + // 没有带牌 没有全出 + else { + if (tem_size != size) { + return false; + } + } + } + + int min_card = ct.min_card; + + int max_card = min_card + len - 1; + + if (len > 1 && max_card > 14) { + return false; + } + + Map cardMap = CardUtil.getCardNumMap(cardInhand); + for (int i = min_card; i <= max_card; ++i) { + if (!cardMap.containsKey(i)) { + return false; + } + if (cardMap.get(i) < config.repeat_num) { + return false; + } + } + return true; + } + + /** + * 比牌大小 + * + * @param banker + * @param other + * @return + */ + public final static boolean tryCompete(CardGroup banker, CardGroup other, ITObject roomConfig) { + int bankerCradType = banker.config.type; + int otherCradType = other.config.type; + + if (bankerCradType != Config.TYPE_ZHA && otherCradType == Config.TYPE_ZHA) { + return true; + } + if (bankerCradType != otherCradType) { + return false; + } + + if (other.min_card > banker.min_card) { + if (otherCradType == Config.TYPE_ZHA) { + + return true; + } else { + + if (other.len == banker.len) { + + if (otherCradType == Config.TYPE_3_2 || otherCradType == Config.TYPE_FEIJI_2) { + + boolean sandaidan = roomConfig.containsKey(Config.ROOM_CONFIG_SANDAIDAN) + && roomConfig.getInt(Config.ROOM_CONFIG_SANDAIDAN) == 1; + if (sandaidan) { + if (other.card_list.size() != banker.card_list.size()) { + return false; + } + } + } + + return true; + } else { + return false; + } + } + } + + return false; + } + + public final static CardGroup tryBig(List cardInhand, CardGroup other) { + + List card_list = new ArrayList(); + int size = cardInhand.size(); + CardConfig config = other.config; + Map> cardMap = null; + int len = other.len; + + if (size >= len * config.repeat_num) { + + int min_card = other.min_card + 1;// 最小的数字是9 加一,下一位玩家需要出的牌时从10开始 + + int max_card = min_card + len - 1; // 最小的数字加上上家玩家牌的长度。就是下家玩家需要出牌的张数 + + if (!(len > 1 && max_card > 14)) {// 长度如果大于一并且最大的牌 + + int count = 0; + cardMap = CardUtil.getCardListMap(cardInhand); + int max = len > 1 ? 14 : 15; + for (int i = min_card; i <= max; ++i) { + + List list = cardMap.get(i); + + if (cardMap.containsKey(i) && list.size() >= config.repeat_num) { + + // 不出炸牌 + if (other.config.type != Config.TYPE_ZHA && list.size() >= 4) { + count = 0; + card_list.clear(); + continue; + } + + for (int k = 0; k < config.repeat_num; ++k) { + card_list.add(list.get(k)); + } + count++; + if (count == len) { + CardGroup ct = new CardGroup(); + ct.config = other.config; + ct.card_list = card_list; + ct.len = len; + ct.min_card = card_list.get(0).cardMod; + if (config.with_card_num > 0) { + List tem_list = new ArrayList(); + tem_list.addAll(cardInhand); + CardUtil.removeCard(tem_list, card_list); + + // 不把炸牌带出去 + int rcard_size = 0; + rcard: for (int k = 0; k < tem_list.size(); ++k) { + int card = tem_list.get(k).cardMod; + List tem_list1 = cardMap.get(card); + if (tem_list1.size() >= 4) { + CardUtil.removeCard(tem_list, tem_list1); + rcard_size += 4; + break rcard; + } + } + int with_card_size = config.with_card_num * len; + if (rcard_size == 0) { + with_card_size = tem_list.size() < with_card_size ? tem_list.size() + : with_card_size; + } + if (tem_list.size() < with_card_size) { + break; + } + for (int k = 0; k < with_card_size; ++k) { + card_list.add(tem_list.get(k)); + } + } + return ct; + } + } else { + count = 0; + card_list.clear(); + } + } + } + } + + if (other.config.type != Config.TYPE_ZHA && cardInhand.size() >= 4) { + if (cardMap == null) { + cardMap = CardUtil.getCardListMap(cardInhand); + } + + for (Entry> entry : cardMap.entrySet()) { + int card = entry.getKey(); + List list = entry.getValue(); + if (list.size() >= 4) { + CardGroup ct = new CardGroup(); + ct.config = CardConfig.ZHA; + ct.card_list = list; + ct.len = 1; + ct.min_card = card; + return ct; + } + } + } + return null; + } + + public static boolean checkStartSpring(List cardInhand) { + + boolean bRet = false; + Map cardMap = CardUtil.getCardNumMap(cardInhand); + + if (cardMap.getOrDefault(RoomCard.CARD_3, 0) == 4) { + + bRet = true; + } else if (cardMap.getOrDefault(RoomCard.CARD_2, 0) == 1 && cardMap.getOrDefault(RoomCard.CARD_A, 0) == 3) { + + bRet = true; + } + + return bRet; + } + + public static void main(String[] args) { + + ITObject test = new TObject(); + ITArray card_list = new TArray(); + card_list.addInt(215); + card_list.addInt(114); + card_list.addInt(303); + card_list.addInt(204); + card_list.addInt(205); + // card_list.addInt(307); + // card_list.addInt(207); + test.putInt("sidaiyi", 0); + test.putInt("threeA", 1); + test.putInt("threelack", 1); + test.putInt("fourBeltThree", 1); + List tlist = CardUtil.toList(card_list); + System.out.println(tlist); + CardGroup ct = CardCheck.getType(tlist, test); + // Boolean a = CardCheck.tryType(ct,4,test); + System.out.println(ct); + // System.out.println(a); + + } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardConfig.java b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardConfig.java new file mode 100644 index 0000000..c8ad106 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardConfig.java @@ -0,0 +1,46 @@ +package extend.pk.uitl; + +import extend.pk.Config; + +public enum CardConfig { + DAN( "单牌", Config.TYPE_DANPAI, 1, 1, 1, 1, 0), + DUIZI( "对子", Config.TYPE_DUIZI, 1, 2, 2, 2, 0), + SHUNZI( "顺子", Config.TYPE_SHUNZI, 5, 1, 5, 12, 0), + LIANDUI( "连对", Config.TYPE_LIANDUI, 2, 2, 4, 16, 0), + SAN_2( "三带二", Config.TYPE_3_2, 1, 3, 3, 5, 2), + SAN( "三不带", Config.TYPE_3, 1, 3, 3, 5, 0), + FEIJI_2( "飞机", Config.TYPE_FEIJI_2, 2, 3, 6, 16, 2), + FEIJI( "飞机不带", Config.TYPE_FEIJI, 2, 3, 6, 16, 0), + SI_3( "四带三", Config.TYPE_4_3, 1, 4, 5, 7, 3), + SI_2( "四带二", Config.TYPE_4_2, 1, 4, 5, 6, 2), + ZHA( "炸弹", Config.TYPE_ZHA, 1, 4, 4, 4, 0); + + public final int type; + public final String name; + public final int min_len; + public final int repeat_num; + public final int min_card_num; + public final int max_card_num; + public final int with_card_num; + + + private CardConfig(String name,int type,int min_len,int repeat_num,int min_card_num,int max_card_num,int with_card_num) { + this.name = name; + this.type = type; + + this.min_len = min_len; + this.repeat_num = repeat_num; + this.min_card_num = min_card_num; + this.max_card_num = max_card_num; + this.with_card_num = with_card_num; + } + + public String toString() { + return this.name; + } +// +// public static void main(String[] args) { +// String string = "0x4e34aab634F52d919E23399ed17c12A688483013".toLowerCase(); +// System.out.println(string); +// } +} diff --git a/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardUtil.java b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardUtil.java new file mode 100644 index 0000000..741ff18 --- /dev/null +++ b/game_pk_paodekuai/src/main/java/extend/pk/uitl/CardUtil.java @@ -0,0 +1,419 @@ +package extend.pk.uitl; + +import com.game.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import extend.pk.CardObj; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CardUtil { + + /** + * list to TArray + * + * @param list + * @return + */ + public static final ITArray toTArray(List list) { + ITArray result = new TArray(); + for (CardObj card : list) { + result.addInt(card.card); + } + return result; + } + + public static final CardObj getCard(int eventCard, List cardList) { + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + return card; + } + } + return null; + } + + public static final CardObj getCard1(int eventCard, List cardList) { + for (CardObj card : cardList) { + if (card.card == eventCard) { + return card; + } + } + return null; + } + + /** + * 检测牌数量 + * + * @param eventCard + * @param cardList + * @param num + * @return + */ + public static final boolean checkCard(int eventCard, List cardList, int num) { + int result = 0; + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + result++; + if (result == num) + return true; + } + } + return false; + } + + public static final boolean checkGoodCard(int eventCard, List cardList, int num) { + int result = 0; + for (CardObj card : cardList) { + if (card.cardMod == eventCard) { + result++; + if (result >= num) + return true; + } + } + return false; + } + + public static final boolean checkShunZi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard + 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 1)) { + result++; + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 1)) { + result++; + } + } + } + } + } + + if (result >= 5) { + return true; + } + return false; + } + + public static final boolean checkSevenShunzi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard + 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 6, cardList, 1)) { + result++; + if (checkGoodCard(eventCard + 7, cardList, 1)) { + result++; + } + } + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 6, cardList, 1)) { + result++; + if (checkGoodCard(eventCard - 7, cardList, 1)) { + result++; + } + } + } + } + } + } + } + + if (result >= 6) { + return true; + } + return false; + } + + public static final boolean checkSanTiao(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 2)) { + + if (checkGoodCard(eventCard, cardList, 3)) { + result++; + + } + } + + if (result >= 2) { + return true; + } + return false; + } + + public static final boolean checkFenJi(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 1, cardList, 3)) { + result++; + } + if (checkGoodCard(eventCard - 1, cardList, 3)) { + result++; + } + } + + if (result >= 2) { + return true; + } + return false; + } + + public static final boolean checkFourDui(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 1)) { + result++; + } + + if (checkGoodCard(eventCard + 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 2)) { + result++; + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 2)) { + result++; + } + } + } + } + + if (result >= 4) { + return true; + } + return false; + } + + public static final boolean checkSixDui(int eventCard, List cardList) { + int result = 0; + if (checkGoodCard(eventCard, cardList, 1)) { + result++; + } + + if (checkGoodCard(eventCard + 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 4, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 5, cardList, 2)) { + result++; + if (checkGoodCard(eventCard + 6, cardList, 2)) { + result++; + } + } + } + } + } + } + if (checkGoodCard(eventCard - 1, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 2, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 3, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 4, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 5, cardList, 2)) { + result++; + if (checkGoodCard(eventCard - 6, cardList, 2)) { + result++; + } + } + } + } + } + } + + if (result >= 6) { + return true; + } + return false; + } + + public static final boolean checkQPai(int eventCard, List cardList) { + int result = 0; + if (eventCard >= 12) { + result++; + for (CardObj card : cardList) { + if (card.cardMod >= 12) { + result++; + } + } + } + + if (result >= 5) { + return true; + } + return false; + } + + public static final boolean checkKPai(int eventCard, List cardList) { + int result = 0; + if (eventCard >= 14) { + result++; + for (CardObj card : cardList) { + if (card.cardMod >= 14) { + + result++; + } + } + } + + if (result >= 1) { + return true; + } + return false; + } + + /** + * TArray to list + * + * @param list + * @return + */ + public static final List toList(ITArray list) { + List tem = new ArrayList(); + for (int i = 0; i < list.size(); ++i) { + tem.add(new CardObj(list.getInt(i))); + } + return tem; + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final Map getCardNumMap(List cardList) { + Map result = new HashMap(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + return result; + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final void getCardNumMap(Map result, List cardList) { + result.clear(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + } + + public static final void getCardNumMap(Map result, List cardList, CardObj tempCard) { + result.clear(); + result.put(tempCard.cardMod, 1); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + result.put(card.cardMod, 1); + } else { + int num = result.get(card.cardMod); + result.put(card.cardMod, (num + 1)); + } + } + } + + /** + * 获取每张牌的数量MAP + * + * @param cardList + * @return + */ + public static final Map> getCardListMap(List cardList) { + Map> result = new HashMap>(); + for (CardObj card : cardList) { + if (!result.containsKey(card.cardMod)) { + List list = new ArrayList(); + list.add(card); + result.put(card.cardMod, list); + } else { + List list = result.get(card.cardMod); + list.add(card); + } + } + return result; + } + + static public void removeCard(List cardList, List cards) { + for (int i = 0; i < cards.size(); i++) { + for (int j = 0; j < cardList.size(); j++) { + if (cardList.get(j).card == cards.get(i).card) { + cardList.remove(j); + break; + } + } + } + } +} diff --git a/game_pk_paodekuai/src/test/java/game_pk_paodekuai/MainPaodekuai.java b/game_pk_paodekuai/src/test/java/game_pk_paodekuai/MainPaodekuai.java new file mode 100644 index 0000000..0d30aa1 --- /dev/null +++ b/game_pk_paodekuai/src/test/java/game_pk_paodekuai/MainPaodekuai.java @@ -0,0 +1,9 @@ +package game_pk_paodekuai; + +import com.taurus.permanent.TPServer; + +public class MainPaodekuai { + public static void main(String[] args) { + TPServer.me().start(); + } +} diff --git a/group_mgr/build/local/log4j.properties b/group_mgr/build/local/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/group_mgr/build/local/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/group_mgr/build/local/mgr-config.xml b/group_mgr/build/local/mgr-config.xml new file mode 100644 index 0000000..13542a6 --- /dev/null +++ b/group_mgr/build/local/mgr-config.xml @@ -0,0 +1,6 @@ + + + 123.207.203.115:4013 + 1000 + true + \ No newline at end of file diff --git a/group_mgr/build/local/taurus-core.xml b/group_mgr/build/local/taurus-core.xml new file mode 100644 index 0000000..0dd8a01 --- /dev/null +++ b/group_mgr/build/local/taurus-core.xml @@ -0,0 +1,99 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/group_mgr/build/local/taurus-permanent.xml b/group_mgr/build/local/taurus-permanent.xml new file mode 100644 index 0000000..e72685d --- /dev/null +++ b/group_mgr/build/local/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 1 + + 128 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 1 + 3 + 3 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 8080 +
+ + + + extension - group_mgr + com.mgr.group.MainServer + + + + + Sys + 2 + 8 + 60000 + 20000 + + + + + Ext + 2 + 8 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/group_mgr/build/pro/log4j.properties b/group_mgr/build/pro/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/group_mgr/build/pro/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/group_mgr/build/pro/mgr-config.xml b/group_mgr/build/pro/mgr-config.xml new file mode 100644 index 0000000..0d5a539 --- /dev/null +++ b/group_mgr/build/pro/mgr-config.xml @@ -0,0 +1,6 @@ + + + wegame.hlkj123.cn:11050 + 1000 + true + \ No newline at end of file diff --git a/group_mgr/build/pro/taurus-core.xml b/group_mgr/build/pro/taurus-core.xml new file mode 100644 index 0000000..4b22cf1 --- /dev/null +++ b/group_mgr/build/pro/taurus-core.xml @@ -0,0 +1,98 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/group_mgr/build/pro/taurus-permanent.xml b/group_mgr/build/pro/taurus-permanent.xml new file mode 100644 index 0000000..108342f --- /dev/null +++ b/group_mgr/build/pro/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 1 + + 128 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 1 + 3 + 20 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 8080 +
+ + + + extension - group_mgr + com.mgr.group.MainServer + + + + + Sys + 4 + 16 + 60000 + 20000 + + + + + Ext + 4 + 16 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/group_mgr/build/test/log4j.properties b/group_mgr/build/test/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/group_mgr/build/test/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/group_mgr/build/test/mgr-config.xml b/group_mgr/build/test/mgr-config.xml new file mode 100644 index 0000000..20c748d --- /dev/null +++ b/group_mgr/build/test/mgr-config.xml @@ -0,0 +1,6 @@ + + + 192.168.1.8:4013 + 1000 + true + \ No newline at end of file diff --git a/group_mgr/build/test/taurus-core.xml b/group_mgr/build/test/taurus-core.xml new file mode 100644 index 0000000..9be8e5a --- /dev/null +++ b/group_mgr/build/test/taurus-core.xml @@ -0,0 +1,98 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/group_mgr/build/test/taurus-permanent.xml b/group_mgr/build/test/taurus-permanent.xml new file mode 100644 index 0000000..a2aadfc --- /dev/null +++ b/group_mgr/build/test/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 1 + + 128 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 1 + 3 + 3 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 8080 +
+ + + + extension - group_mgr + com.mgr.group.MainServer + + + + + Sys + 2 + 8 + 60000 + 20000 + + + + + Ext + 2 + 8 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/group_mgr/pom.xml b/group_mgr/pom.xml new file mode 100644 index 0000000..f7083e8 --- /dev/null +++ b/group_mgr/pom.xml @@ -0,0 +1,126 @@ + + 4.0.0 + com.mgr.group + group_mgr + war + 1.0.0 + + UTF-8 + 1.8 + 1.8 + pro + + + + + junit + junit + 3.8.1 + test + + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + com.taurus + taurus-permanent + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + org.quartz-scheduler + quartz + 2.2.3 + + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + + + ROOT + + + org.apache.maven.plugins + maven-war-plugin + + 1.8 + 1.8 + UTF-8 + logs/**,config/** + + + config/ + ${project.basedir}/build/${build.type}/ + + + + + + + + diff --git a/group_mgr/src/main/java/com/mgr/group/Config.java b/group_mgr/src/main/java/com/mgr/group/Config.java new file mode 100644 index 0000000..81d0b9d --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/Config.java @@ -0,0 +1,9 @@ +package com.mgr.group; + +public class Config { + public int mgrId; + public String host; + public String webHost; + public int webPort; + public boolean loggerDebug; +} diff --git a/group_mgr/src/main/java/com/mgr/group/Global.java b/group_mgr/src/main/java/com/mgr/group/Global.java new file mode 100644 index 0000000..2d23c52 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/Global.java @@ -0,0 +1,28 @@ +package com.mgr.group; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.mgr.group.data.Group; +import com.taurus.core.util.Logger; + +public class Global { + /** + * debug模式 + */ + public static boolean loggerDebug = false; + // 日志 + public static Logger logger; + + public static SessionManager sessionMgr; + public static GroupController groupCtr; + public static ConcurrentMap groupMap; + + public static void init() { + groupMap = new ConcurrentHashMap<>(); + sessionMgr = new SessionManager(); + groupCtr = new GroupController(); + } + + +} diff --git a/group_mgr/src/main/java/com/mgr/group/GroupController.java b/group_mgr/src/main/java/com/mgr/group/GroupController.java new file mode 100644 index 0000000..7d1f9d8 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/GroupController.java @@ -0,0 +1,1805 @@ +package com.mgr.group; + +import java.sql.Array; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.data.bean.AccountBean; +import com.data.bean.GroupMemberBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.mgr.group.data.CommandData; +import com.mgr.group.data.Group; +import com.mgr.group.data.Room; +import com.mgr.group.data.User; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.Utils; +import com.taurus.core.util.task.ITaskHandler; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +import com.taurus.web.WebException; +import redis.clients.jedis.Jedis; + +/** + * 基本游戏控制器 + * + */ +public class GroupController implements IController { + + /** + * 请求进入圈子 + */ + @ActionKey(Router.FGMGR_ENTER_GROUP) + public void RouterJoinGroup(Session sender, ITObject params, int gid) { + String session_id = params.getUtfString("session"); + String token = null; + if (StringUtil.isEmpty(session_id)) { + session_id = ""; + } else { + String[] sourceStrArray = session_id.split(","); + if (sourceStrArray.length == 2) { + session_id = sourceStrArray[0]; + token = sourceStrArray[1]; + } + + if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session_id)) { + String token_session = Redis.use("group1_db0").hget(token, "user"); + if (StringUtil.isEmpty(token_session)) { + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } else { + if (!token_session.equals(session_id)) { + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + } else { + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + } + sender.setHashId(session_id); + int groupId = params.getInt("groupId"); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try{ + jedis0.hset(session_id, "enter_group", groupId+""); + }finally { + jedis0.close(); + } + Global.groupCtr.joinGroup(sender, groupId, gid); + + } + + private static AtomicInteger invi_id = new AtomicInteger(0); + + public void joinGroup(Session sender, int groupId, int gid) { + + Group group = null; + synchronized (Global.groupMap) { + if (Global.groupMap.containsKey(groupId)) { + group = Global.groupMap.get(groupId); + } else { + group = new Group(groupId); + Global.groupMap.put(groupId, group); + } + group.lastTime = System.currentTimeMillis(); + } + + group.start(); + if (group.isDestroy) { + TPServer.me().getController().sendResponse(gid, ErrorCode._FAILED, null, sender); + return; + } + + group.enqueueRunnable(new Runnable() { + + @Override + public void run() { + Group group = Global.groupMap.get(groupId); + User user = null; + AccountBean acc = null; + if (sender != null && StringUtil.isNotEmpty(sender.getHashId())) { + acc = AccountCache.getAccount(sender.getHashId()); + } else { + if (sender != null) { + if (StringUtil.isNotEmpty(sender.getHashId())) { + Global.logger.info("---------------session.id:" + sender.getId() + " hashId null"); + } + } else { + Global.logger.info("---------------session为null,"); + } + } + System.out.println(sender.getHashId()); + if (acc == null) { + Global.logger.info("---------------session不存在:" + groupId); + + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + int uid = acc.id; + if (!group.userMap.containsKey(uid)) { + user = new User(); + user.uid = uid; + user.session_key = AccountCache.genKey(uid); + user.group = group; + user.setSender(sender); + group.userMap.put(uid, user); + } else { + user = group.userMap.get(uid); + user.setSender(sender); + } + if (user.gm_key == null) { + user.gm_key = GroupMemberCache.genKey(groupId, uid); + } + String gm_key = user.gm_key; + sender.setHashId(gm_key); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + user.response(null, gid, ErrorCode._FAILED); + return; + } + int partnerLev = gmb.partnerLev; + int lev = gmb.lev; + long hp = 0; + int permission = gmb.permission; + int ban = gmb.ban; + int mail_tip = 0; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + hp = Long.parseLong(jedis10.hget(gm_key, "hp")); + long last_time = System.currentTimeMillis() / 1000; + jedis10.hset(gm_key, "last_time", last_time + ""); + jedis10.hset(gm_key, "on_line", 1 + ""); + String mail_tip_key = GroupCache.genMailTipKey(groupId); + Double tem = jedis10.zscore(mail_tip_key, uid + ""); + if (tem != null && tem > 0) { + mail_tip = 1; + } + + String fp = Redis.use("group1_db1").hget("alllook", uid + ""); + user.partnerLev = partnerLev; + if (fp != null) { + user.lev = 1; + } else { + user.lev = lev; + } + + user.hp = hp; + user.ban = ban; + ITObject info = group.getInfo(lev); + + if (fp != null) { + info.putInt("lev", 1); + } else { + info.putInt("lev", lev); + } + + // info.putInt("lev", lev); + String key = "g{" + groupId + "}:isShowBeginRoom"; + + info.putInt("isShowBeginRoom", jedis11.hget(key, "isShowBeginRoom") == null ? 0 + : Integer.parseInt(jedis11.hget(key, "isShowBeginRoom"))); + + info.putInt("partnerLev", partnerLev); + info.putInt("permission", permission); + String countKey = "g{" + groupId + "}:m" + uid; + if (jedis10.hget(countKey, "messageCount") == null) { + info.putInt("messageCount", 0); + } else { + String messageCount = jedis10.hget(countKey, "messageCount"); + info.putInt("messageCount", Integer.parseInt(messageCount)); + } + + info.putLong("hp", hp); + info.putInt("mail_tip", mail_tip); + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo") == null ? "0" + : jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + + info.putInt("group_diamo", groupDiamo); + + user.response(info, gid, 0); + } finally { + jedis10.close(); + jedis11.close(); + } + // Global.logger.info("joinGroup / playlist --> info: "+info); + } + }); + + } + + public void addRoom(Group group, String roomid) { + Room room = group.addRoom(roomid); + if (room == null) + return; + ITObject param = room.data; + group.addRoomCommand(roomid, CommandData.ADD_ROOM, param); + } + + public void delRoom(Group group, String roomid) { + group.delRoom(roomid); + ITObject param = TObject.newInstance(); + param.putUtfString("roomid", roomid); + group.addRoomCommand(roomid, CommandData.DEL_ROOM, param); + } + + public void publishNotice(int groupId, String notice) { + String key = "g{" + groupId + "}:m*"; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Group group = Global.groupMap.get(groupId); + ITObject param = TObject.newInstance(); + param.putUtfString("notice", notice); + param.putInt("groupId", groupId); + try { + Set keys = jedis10.keys(key); + for (String uids : keys) { + String uid = uids.split("m")[1]; + int uidLength = uid.length(); + if (uidLength < 7) { + User user = group.userMap.get(Integer.parseInt(uid)); + if (user != null) { + TPServer.me().getController().sendEvent(Router.PUSH_NOTICE, param, user.sender); + } + } + + } + } catch (Exception e) { + Global.logger.error("redis error" + e); + } finally { + jedis10.close(); + } + } + + public void updateRoom(Group group, String roomid) { + Room room = group.updateRoom(roomid); + if (room == null) + return; + if (room.priorityValue == 0) { + ITObject param = TObject.newInstance(); + param.putUtfString("roomid", roomid); + group.addRoomCommand(roomid, CommandData.DEL_ROOM, param); + } else { + ITObject param = room.data; + group.addRoomCommand(roomid, CommandData.UPDATE_ROOM, param); + } + + } + +// public void roomButton(Group group, int groupId,String isWatch) { +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// try { +// Set userSet = new HashSet(); +// String groupIdKey = "g{" + groupId+ "}:onlines"; +// String groupIdKeys = "g{" + groupId+ "}:offlines"; +// Map onlines = jedis10.hgetAll(groupIdKey); +// Map offlines = jedis10.hgetAll(groupIdKeys); +// Set onlineskeys = onlines.keySet(); +// Set offlineskey = offlines.keySet(); +// +// for (String key : onlineskeys){ +// int uids = Integer.parseInt(key); +// userSet.add(uids); +// } +// for (String key : offlineskey){ +// int uids = Integer.parseInt(key); +// userSet.add(uids); +// } +// +// for (int uids : userSet){ +// group = Global.groupMap.get(groupId); +// if (group==null){ +// continue; +// } +// if (group.userMap==null){ +// continue; +// } +// User user = group.userMap.get(uids); +// +// if (user != null) { +// ITObject param = TObject.newInstance(); +// GroupMemberBean gmb = GroupCache.getMember(groupId, uids); +// if (gmb != null){ +// if (gmb.lev<3){ +// param.putInt("groupId", groupId); +// param.putString("isWatch", isWatch); +// +// TPServer.me().getController().sendEvent(Router.CHATROOM_BUTTON, param, user.sender); +// } +// } +// +// } +// } +// +// +// +// }catch (Exception e){ +// Global.logger.info("banPlay error"+e); +// }finally { +// jedis10.close(); +// } +// } + + public void delPlay(Group group, int pid) { + group.delPlay(pid); + ITObject param = TObject.newInstance(); + param.putInt("pid", pid); + group.broadCastToClient(Router.FGMGR_EVT_DEL_PLAY, param); + } + + public void addPlay(Group group, int pid) { + GroupPlayBean gp = group.addPlay(pid); + if (gp != null) { + // + group.broadCastToClient(Router.FGMGR_EVT_ADD_PLAY, gp.data); + + Global.logger.info("addPlay: -------------> " + gp.data); + } + +// GroupPlayBean gp = group.addPlay(pid); +// if (gp != null) { +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// String groupIdKey = "g{" + group.id + "}:onlines"; +// String groupIdKeys = "g{" + group.id + "}:offlines"; +// Map onlines = jedis10.hgetAll(groupIdKey); +// Map offlines = jedis10.hgetAll(groupIdKeys); +// Set onlineskeys = onlines.keySet(); +// Set offlineskey = offlines.keySet(); +// try { +// Set userSet = new HashSet(); +// +// for (String key : onlineskeys) { +// int uids = Integer.parseInt(key); +// userSet.add(uids); +// } +// for (String key : offlineskey) { +// int uids = Integer.parseInt(key); +// userSet.add(uids); +// } +// +// for (Integer uid : userSet) { +// if (group.userMap == null) { +// continue; +// } +// User user = group.userMap.get(uid); +// if (user != null) { +// TPServer.me().getController().sendEvent(Router.FGMGR_EVT_ADD_PLAY, gp.data, user.sender); +// } +// +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// jedis10.close(); +// } +// } + } + + public void updatePlay(Group group, int pid) { + GroupPlayBean gp = group.addPlay(pid); + if (gp != null) { + group.broadCastToClient(Router.FGMGR_EVT_UPDATE_PLAY, gp.data); + + Global.logger.info("updatePlay: -------------> " + gp.data); + } + } + + public void updateGroup(Group group, String name, int ban, String notice, int option, int showNum) { + ITObject param = TObject.newInstance(); + param.putUtfString("name", name); + param.putInt("ban", ban); + param.putUtfString("notice", notice); + param.putInt("option", option); + param.putInt("show_num", showNum); + group.broadCastToClient(Router.FGMGR_EVT_UPDATE_GROUP, param); + } + + public void updateJoins(Group group, int joins, String remark, int readStatus, String nick, String portrait, + String reg_time, String id) { + if (joins <= 0) + return; + List list = group.getSessionListByMgr(); + + if (list.size() == 0) + return; + ITObject param = TObject.newInstance(); + param.putInt("joins", joins); + param.putUtfString("remark", remark); + param.putInt("read_status", readStatus); + param.putUtfString("nick", nick); + param.putUtfString("portrait", portrait); + param.putUtfString("reg_time", reg_time); + param.putInt("uid", Integer.parseInt(id)); + TPServer.me().getController().sendEvent(Router.FGMGR_EVT_UPDATE_JOINS, param, list); + } + +//允许加入亲友圈 + public void familyReflash(int groupId, int joins, String remark, int readStatus, int tagId, boolean allow) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String key : onlineskeys) { + int uid = Integer.parseInt(key); + String groupKey = "groups:" + uid; + Set groupIdSet = jedis11.zrange(groupKey, 0, -1); + + for (String gid : groupIdSet) { + + Group group = Global.groupMap.get(Integer.parseInt(gid)); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + ITObject param = TObject.newInstance(); + GroupMemberBean gmb = GroupCache.getMember(Integer.parseInt(gid), uid); + if (gmb != null) { + if (gmb.lev < 3) { + param.putInt("joins", joins); + } else { + param.putInt("joins", 0); + } + } + param.putUtfString("reflashType", "changeJoins"); + param.putInt("uid", tagId); + param.putBoolean("allow", allow); + // "11111"允许加入亲友圈 + TPServer.me().getController().sendEvent(Router.FGMGR_ALLOW, param, user.sender); + } + } + } + + for (String key : offlineskey) { + int uid = Integer.parseInt(key); + String groupKey = "groups:" + uid; + Set groupIdSets = jedis11.zrange(groupKey, 0, -1); + + for (String gid : groupIdSets) { + + Group group = Global.groupMap.get(Integer.parseInt(gid)); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + ITObject param = TObject.newInstance(); + GroupMemberBean gmb = GroupCache.getMember(Integer.parseInt(gid), uid); + if (gmb != null) { + if (gmb.lev < 3) { + param.putInt("joins", joins); + } else { + param.putInt("joins", 0); + } + } + param.putUtfString("reflashType", "changeJoins"); + param.putInt("uid", tagId); + param.putBoolean("allow", allow); + // "11111"允许加入亲友圈 + TPServer.me().getController().sendEvent(Router.FGMGR_ALLOW, param, user.sender); + } + } + + } + +// String sql = String.format("select groupId from group_member where uid = %s ",tagId); +// ITArray list = DataBase.use().executeQueryByTArray(sql); +// +// Set groupIdSetss = new HashSet(); +// for (int i = 0; i < list.size(); ++i) { +// ITObject tem = list.getTObject(i); +// int gid = tem.getInt("groupId"); +// groupIdSetss.add(gid); +// } +// +// for (int gid : groupIdSetss) { +// +// Group group = Global.groupMap.get(gid); +// if (group==null){ +// continue; +// } +// if (group.userMap==null){ +// continue; +// } +// User user = group.userMap.get(tagId); +// +// if(user!=null) { +// ITObject param = TObject.newInstance(); +// GroupMemberBean gmb = GroupCache.getMember(gid, tagId); +// +// String gm_key = GroupMemberCache.genKey(gid, tagId); +// user.sender.setHashId(gm_key); +// +// if (gmb != null){ +// if (gmb.lev<3){ +// param.putInt("joins", joins); +// }else { +// param.putInt("joins", 0); +// } +// } +// param.putUtfString("reflashType", "changeJoins"); +// param.putInt("uid", tagId); +// param.putBoolean("allow",allow); +// //"11111"允许加入亲友圈 +// TPServer.me().getController().sendEvent(Router.FGMGR_ALLOW, param, user.sender); +// } +// } + + } catch (Exception e) { + Global.logger.error("异常", e); + } finally { + jedis10.close(); + jedis11.close(); + } + + } + + public void joinFamily(int groupId, int joins, String remark, int readStatus, int tagId, boolean allow, + ITObject users, String name) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String key : onlineskeys) { + int uid = Integer.parseInt(key); + String groupKey = "groups:" + uid; + Set groupIdSet = jedis11.zrange(groupKey, 0, -1); + for (String gid : groupIdSet) { + Group group = Global.groupMap.get(Integer.parseInt(gid)); + + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + ITObject param = TObject.newInstance(); + param.putInt("groupId", groupId); + param.putInt("joins", joins); + param.putUtfString("reflashType", "joinFamily"); + param.putInt("uid", tagId); + param.putString("name", name); + param.putBoolean("allow", allow); + param.putTObject("usersDetail", users); + + String gm_key = GroupMemberCache.genKey(Integer.parseInt(gid), uid); + user.sender.setHashId(gm_key); + // "11111"允许加入亲友圈 + TPServer.me().getController().sendEvent(Router.FGMGR_ALLOW, param, user.sender); + } + } + } + + for (String key : offlineskey) { + int uid = Integer.parseInt(key); + String groupKey = "groups:" + uid; + Set groupIdSets = jedis11.zrange(groupKey, 0, -1); + for (String gid : groupIdSets) { + Group group = Global.groupMap.get(Integer.parseInt(gid)); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + ITObject param = TObject.newInstance(); + param.putInt("groupId", groupId); + param.putInt("joins", joins); + param.putUtfString("reflashType", "joinFamily"); + param.putInt("uid", tagId); + param.putBoolean("allow", allow); + param.putString("name", name); + param.putTObject("usersDetail", users); + + String gm_key = GroupMemberCache.genKey(Integer.parseInt(gid), uid); + user.sender.setHashId(gm_key); + // "11111"允许加入亲友圈 + TPServer.me().getController().sendEvent(Router.FGMGR_ALLOW, param, user.sender); + } + } + + } + } catch (Exception e) { + Global.logger.error("异常", e); + } finally { + jedis10.close(); + jedis11.close(); + } + } + + public void updateMember(Group group, int uid, int type, int value) { +// User user = group.userMap.get(uid); +// if(user!=null) { +// ITObject param = TObject.newInstance(); +// param.putInt("type", type); +// param.putInt("value", value); +// MainServer.instance.sendEvent(Router.FGMGR_EVT_UPDATE_MEMBER, param, user.sender); +// } + } + + public void updateMailTip(Group group, int uid) { + User user = group.userMap.get(uid); + if (user != null) { + ITObject param = TObject.newInstance(); + TPServer.me().getController().sendEvent(Router.FGMGR_EVT_UPDATE_MAILTIP, param, user.sender); + } + } + + // 禁止娱乐 + public void banPlay(int groupId, int uid, int ban) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + Set userSet = new HashSet(); + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String key : onlineskeys) { + int uids = Integer.parseInt(key); + userSet.add(uids); + } + for (String key : offlineskey) { + int uids = Integer.parseInt(key); + userSet.add(uids); + } + + for (int uids : userSet) { + Group group = Global.groupMap.get(groupId); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uids); + + if (user != null) { + ITObject param = TObject.newInstance(); + GroupMemberBean gmb = GroupCache.getMember(groupId, uids); + if (gmb != null) { + if (gmb.lev < 3) { + param.putInt("tagId", uid); + param.putInt("ban", ban); + // "11111"允许加入亲友圈 + TPServer.me().getController().sendEvent(Router.BAN_PLAY, param, user.sender); + } + } + + } + } + + } catch (Exception e) { + Global.logger.info("banPlay error" + e); + } finally { + jedis10.close(); + } + } + + // 打完一局游戏进行战绩推送 关联到game_common + public void pushChatRooms(int groupId, ITObject param) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Group group = Global.groupMap.get(groupId); + + try { + String groupIdKey = "g{" + groupId + "}:onlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Set keys = onlines.keySet(); + for (String key : keys) { + int uid = Integer.parseInt(key); + User user = group.userMap.get(uid); + if (user != null) { + TPServer.me().getController().sendEvent(Router.FGMGR_CHATROOM_REALTIME, param, user.sender); + } + } + + } catch (Exception e) { + Global.logger.error("数据没存上", e); + } finally { + jedis10.close(); + } + } + + public void familyRefuse(int groupId, int uid) { + Group group = Global.groupMap.get(groupId); + User user = new User(); + // 根据用户id拿用户信息 +// user = Global.sessionMgr.getUser(uid); + + if (user != null) { + ITObject param = TObject.newInstance(); + param.putUtfString("reflashType", "rejectFamily"); + param.putInt("uid", uid); + // 拒绝加入亲友圈,”fgmgr_refuse“ + TPServer.me().getController().sendEvent(Router.FGMGR_REFUSE, param, user.sender); + } + } + + // 退出亲友圈 + public void quitGroup(int groupId, int tagId, String outs, String name) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { +// String groupIdKey = "g{" + groupId+ "}:onlines"; +// String groupIdKeys = "g{" + groupId+ "}:offlines"; +// Map onlines = jedis10.hgetAll(groupIdKey); +// Map offlines = jedis10.hgetAll(groupIdKeys); +// Set onlineskeys = onlines.keySet(); +// Set offlineskey = offlines.keySet(); + +// for (String key : onlineskeys) { +// int uid = Integer.parseInt(key); + String groupKey = "groups:" + tagId; + Set groupIdSet = jedis11.zrange(groupKey, 0, -1); + + + for (String gid : groupIdSet) { + Group group = Global.groupMap.get(Integer.parseInt(gid)); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(tagId); + if (user != null) { + TObject param = TObject.newInstance(); + param.putUtfString("reflashType", outs); + param.putInt("uid", tagId); + param.putInt("groupId", Integer.parseInt(gid)); + param.putString("name", name); + + String gm_key = GroupMemberCache.genKey(Integer.parseInt(gid), tagId); + user.sender.setHashId(gm_key); + + TPServer.me().getController().sendEvent(Router.FGMGR_QUIT_GROUP, param, user.sender); + } + } +// } + +// for (String key : offlineskey) { +// +// int uid = Integer.parseInt(key); +// String groupKey = "groups:"+uid; +// Set groupIdSet = jedis11.zrange(groupKey, 0, -1); +// +// +// +// for (String gid : groupIdSet) { +// Group group = Global.groupMap.get(Integer.parseInt(gid)); +// +// if (group==null){ +// continue; +// } +// if (group.userMap==null){ +// continue; +// } +// User user = group.userMap.get(uid); +// +// if(user!=null) { +// TObject param = TObject.newInstance(); +// param.putUtfString("reflashType", outs); +// param.putInt("uid", tagId); +// param.putInt("groupId", Integer.parseInt(gid)); +// param.putString("name", name); +// +// String gm_key = GroupMemberCache.genKey(Integer.parseInt(gid), uid); +// user.sender.setHashId(gm_key); +// +// +// TPServer.me().getController().sendEvent(Router.FGMGR_QUIT_GROUP, param, user.sender); +// } +// } +// +// } + +// String groupKey = "groups:"+tagId; +// Set groupIdSet = jedis11.zrange(groupKey, 0, -1); +// +// +// +// for (String gid : groupIdSet) { +// Group group = Global.groupMap.get(Integer.parseInt(gid)); +// +// +// +// if (group == null) { +// continue; +// } +// if (group.userMap == null) { +// continue; +// } +// User user = group.userMap.get(tagId); +// +// if (user != null) { +// TObject param = TObject.newInstance(); +// param.putUtfString("reflashType", outs); +// param.putInt("uid", tagId); +// param.putInt("groupId", Integer.parseInt(gid)); +// param.putString("name", name); +// +// String gm_key = GroupMemberCache.genKey(Integer.parseInt(gid), tagId); +// user.sender.setHashId(gm_key); +// +// +// user.sender.setConnected(true); +// TPServer.me().getController().sendEvent(Router.FGMGR_QUIT_GROUP, param, user.sender); +// } +// } + + } catch (Exception e) { + Global.logger.error("异常", e); + } finally { + jedis10.close(); + jedis11.close(); + } + + } + + public void updateOnlineUsers(int groupId, int uid) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + String key = "groups:" + uid; + try { + Set groupsId = jedis11.zrange(key, 0, -1); + Set userId = new HashSet(); + List groupIdLists = new ArrayList(); + for (String tem : groupsId) { + int gid = Integer.parseInt(tem); + groupIdLists.add(gid); + String groupIdKey = "g{" + gid + "}:onlines"; + String groupIdKeys = "g{" + gid + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String onlinekey : onlineskeys) { + userId.add(onlinekey); + } + + for (String offlinekey : offlineskey) { + userId.add(offlinekey); + } + + } + for (int j = 0; j < groupIdLists.size(); j++) { + int gid = (int) groupIdLists.get(j); + Group group = Global.groupMap.get(gid); + if (group == null) { + continue; + } + + TArray userIds = TArray.newInstance(); + for (String uids : userId) { + + String userKey = "{user}:" + uids + "_online"; + String online = jedis0.hget(userKey, "online"); + if (online != null && !online.isEmpty()) { + try { + if (online.equals("1")) { + userIds.addInt(Integer.parseInt(uids)); + } + } catch (NumberFormatException e) { + Global.logger.error("Failed to parse online status for user: "); + } + } + + } + + for (String uids : userId) { + + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(Integer.parseInt(uids)); + if (user != null) { + TObject param = TObject.newInstance(); + param.putTArray("onlineUserId", userIds); + TPServer.me().getController().sendEvent(Router.PUSH_ONLINE, param, user.sender); + } + } + + } + + } catch (Exception e) { + Global.logger.error("异常" + e); + } finally { + jedis11.close(); + jedis0.close(); + jedis10.close(); + } + } + + // 定时推送在线数据 + public void pushOnlineData(int groupId) { + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + Set userId = new HashSet(); + for (String onlinekey : onlineskeys) { + userId.add(onlinekey); + } + + for (String offlinekey : offlineskey) { + userId.add(offlinekey); + } + + for (String uids : userId) { + int uid = Integer.parseInt(uids); + // 获取当前时间 + long now = System.currentTimeMillis(); + String time = jedis0.hget("{user}:" + uid + "_online", "time"); + String gameSate = jedis0.hget("{user}:" + uid, "online"); + String userKey = "{user}:" + uids + "_online"; + String online = jedis0.hget(userKey, "online"); + + if (now - 15000 > Long.parseLong(time) && online.equals("1") && gameSate.equals("stopPlaying")) { + jedis0.hset("{user}:" + uid + "_online", "online", "0"); + jedis0.expire("{user}:" + uid + "_online", 30); + + updateOnlineUsers(groupId, uid); + } + } + } catch (Exception e) { + Global.logger.info("异常" + e); + } finally { + jedis10.close(); + jedis0.close(); + } + } + + // 游戏中推送 + public void playerGameState(int groupId, ITObject param) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + + for (String key : onlineskeys) { + int uid = Integer.parseInt(key); +// String keys = "groups:"+uid; +// Set groupIdSet = jedis11.zrange(keys, 0, -1); +// for (String gid : groupIdSet) { +// Group group = Global.groupMap.get(Integer.parseInt(gid)); + Group group = Global.groupMap.get(groupId); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + String gm_key = GroupMemberCache.genKey(groupId, uid); + user.sender.setHashId(gm_key); + + TPServer.me().getController().sendEvent(Router.PUSH_GAME_STATE, param, user.sender); + } +// } + } + + for (String key : offlineskey) { + int uid = Integer.parseInt(key); +// String keys = "groups:"+uid; +// Set groupIdSet = jedis11.zrange(keys, 0, -1); + +// for (String gid : groupIdSet) { +// Group group = Global.groupMap.get(Integer.parseInt(gid)); + Group group = Global.groupMap.get(groupId); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uid); + + if (user != null) { + String gm_key = GroupMemberCache.genKey(groupId, uid); + user.sender.setHashId(gm_key); + TPServer.me().getController().sendEvent(Router.PUSH_GAME_STATE, param, user.sender); + } +// } + + } + + } catch (Exception e) { + Global.logger.error("异常", e); + } finally { + jedis10.close(); + jedis11.close(); + } + + } + + /** + * 打开/隐藏已开始房间 + */ + public void isOpenBeginRoomPush(int uid, ITObject param) { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int gid = param.getInt("groupId"); + + try { + + Set userSet = new HashSet(); + String groupIdKey = "g{" + gid + "}:onlines"; + String groupIdKeys = "g{" + gid + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String key : onlineskeys) { + userSet.add(key); + } + for (String key : offlineskey) { + userSet.add(key); + } + + for (String uids : userSet) { + int uidss = Integer.parseInt(uids); + Group group = Global.groupMap.get(gid); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uidss); + + if (user != null) { + String key = "g{" + gid + "}:isShowBeginRoom"; + param.putInt("isShowBeginRoom", Integer.parseInt(jedis11.hget(key, "isShowBeginRoom"))); + TPServer.me().getController().sendEvent(Router.PUSH_ROOM_SHOW, param, user.sender); + } + } + + } catch (Exception e) { + Global.logger.error("push数据没存上", e); + } finally { + jedis11.close(); + jedis10.close(); + } + } + + @ActionKey(value = Router.HIDE_AND_SHOW_ROOM) + public final void hideRoom(Session sender, ITObject params, int gid) throws Exception { + int groupId = params.getInt("groupId"); + int uids = params.getInt("uid"); + int isOpen = params.getInt("isOpen"); + + Group group = Global.groupMap.get(groupId); + User user = null; + AccountBean acc = null; + if (sender != null && StringUtil.isNotEmpty(sender.getHashId())) { + acc = AccountCache.getAccount("{user}:" + uids); + } else { + if (sender != null) { + if (StringUtil.isNotEmpty(sender.getHashId())) { + Global.logger.info("---------------session.id:" + sender.getId() + " hashId null"); + } + } else { + Global.logger.info("---------------session为null,"); + } + } + if (acc == null) { + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + int uid = acc.id; + if (!group.userMap.containsKey(uid)) { + user = new User(); + user.uid = uid; + user.session_key = AccountCache.genKey(uid); + user.group = group; + user.setSender(sender); + group.userMap.put(uid, user); + } else { + user = group.userMap.get(uid); + user.setSender(sender); + } + if (user.gm_key == null) { + user.gm_key = GroupMemberCache.genKey(groupId, uid); + } + String gm_key = user.gm_key; + sender.setHashId(gm_key); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + user.response(null, gid, ErrorCode._FAILED); + return; + } + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String key = "g{" + groupId + "}:isShowBeginRoom"; + jedis11.hset(key, "isShowBeginRoom", isOpen + ""); + ITObject info = params; + user.response(info, gid, 0); + params.putInt("groupId", groupId); + isOpenBeginRoomPush(uid, params); + } finally { + jedis11.close(); + } + + } + + @ActionKey(value = Router.OPEN_CHATROOM) + public final void openChatRoom(Session sender, ITObject params, int gid) throws Exception { + int groupId = params.getInt("groupId"); + int uids = params.getInt("uid"); + int openGroupId = 1; + + Group group = Global.groupMap.get(groupId); + User user = null; + AccountBean acc = null; + if (sender != null && StringUtil.isNotEmpty(sender.getHashId())) { + acc = AccountCache.getAccount("{user}:" + uids); + } else { + if (sender != null) { + if (StringUtil.isNotEmpty(sender.getHashId())) { + Global.logger.info("---------------session.id:" + sender.getId() + " hashId null"); + } + } else { + Global.logger.info("---------------session为null,"); + } + } + if (acc == null) { + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + int uid = acc.id; + if (!group.userMap.containsKey(uid)) { + user = new User(); + user.uid = uid; + user.session_key = AccountCache.genKey(uid); + user.group = group; + user.setSender(sender); + group.userMap.put(uid, user); + } else { + user = group.userMap.get(uid); + user.setSender(sender); + } + if (user.gm_key == null) { + user.gm_key = GroupMemberCache.genKey(groupId, uid); + } + String gm_key = user.gm_key; + sender.setHashId(gm_key); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + user.response(null, gid, ErrorCode._FAILED); + return; + } + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String key = "g{" + groupId + "}:chats"; + String keys = "group:" + groupId; + jedis11.hset(key, String.valueOf(uid), openGroupId + ""); + jedis11.hset(keys, "isOpenChatRoom", openGroupId + ""); + jedis11.expire(key + ":" + uid, 600); + ITObject info = params; + info.putInt("group_diamo", 10); + user.response(info, gid, 0); + params.putInt("groupId", groupId); + + String res = jedis10.hget("g{" + groupId + "}:m" + uid, "online"); +// if (res.equals("online")) { + push(uid, params); +// } + } finally { + jedis10.close(); + jedis11.close(); + } + + } + + @ActionKey(value = Router.BREAK_CHATROOM) + public final void breakChatRoom(Session sender, ITObject params, int gid) throws Exception { + int groupId = params.getInt("groupId"); + int uids = params.getInt("uid"); + int openGroupId = 0; + + Group group = Global.groupMap.get(groupId); + User user = null; + AccountBean acc = null; + if (sender != null && StringUtil.isNotEmpty(sender.getHashId())) { + acc = AccountCache.getAccount("{user}:" + uids); + } else { + if (sender != null) { + if (StringUtil.isNotEmpty(sender.getHashId())) { + } + } else { + Global.logger.info("---------------session为null,"); + } + } + System.out.println(acc); + if (acc == null) { + Global.logger.info("---------------session不存在:" + groupId); + + TPServer.me().getController().sendResponse(gid, ErrorCode._NO_SESSION, null, sender); + return; + } + int uid = acc.id; + if (!group.userMap.containsKey(uid)) { + user = new User(); + user.uid = uid; + user.session_key = AccountCache.genKey(uid); + user.group = group; + user.setSender(sender); + group.userMap.put(uid, user); + } else { + user = group.userMap.get(uid); + user.setSender(sender); + } + if (user.gm_key == null) { + user.gm_key = GroupMemberCache.genKey(groupId, uid); + } + String gm_key = user.gm_key; + sender.setHashId(gm_key); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + user.response(null, gid, ErrorCode._FAILED); + return; + } + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String key = "g{" + groupId + "}:chats"; + String keys = "group:" + groupId; + jedis11.hset(key, String.valueOf(uid), openGroupId + ""); + // 清除 +// jedis11.hdel(keys, "isOpenChatRoom"); + jedis11.expire(key + ":" + uid, 600); + +// String res = jedis10.hget("g{" + groupId + "}:m" + uid, "online"); +// if (res.equals("online")) { + +// } + } finally { + jedis10.close(); + jedis11.close(); + } + + ITObject info = params; + + params.putInt("groupId", groupId); + push(uid, params); + } + + /** + * 聊天室状态实时推送 + */ + public void push(int uid, ITObject param) { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int gid = param.getInt("groupId"); + + try { + + Set userSet = new HashSet(); + String groupIdKey = "g{" + gid + "}:onlines"; + String groupIdKeys = "g{" + gid + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String key : onlineskeys) { + userSet.add(key); + } + for (String key : offlineskey) { + userSet.add(key); + } + + for (String uids : userSet) { + int uidss = Integer.parseInt(uids); + Group group = Global.groupMap.get(gid); + if (group == null) { + continue; + } + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(uidss); + + if (user != null) { + Map result = jedis11.hgetAll("g{" + gid + "}:chats"); + for (String element : result.values()) { + param.putInt("chat_id", Integer.parseInt(element)); + TPServer.me().getController().sendEvent(Router.LISTEN_CHATROOM_STATUS, param, user.sender); + } + } + } + + } catch (Exception e) { + Global.logger.error("push数据没存上", e); + } finally { + jedis11.close(); + jedis10.close(); + } + } + + // 聊天室实时推送 + public int pushChatRoom(int uid, ITObject param, int gids) { + int gid = param.getInt("groupId"); + Group group = Global.groupMap.get(gid); + User user = group.userMap.get(uid); + String sql = String.format( + "select rec_key from room_rec_log_new where gid=%s and tagId=%s ORDER BY time desc limit 0,20", gid, + uid); + try { + ITArray list = DataBase.use().executeQueryByTArray(sql); + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); +// ArrayList lists = new ArrayList(); + ITArray lists = TArray.newInstance(); + + try { + for (int i = 0; i < list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, ""); + if (obj == null) { + continue; + } + lists.addTObject(obj); + } + + param.putTArray("records", lists); + + TPServer.me().getController().sendEvent(Router.FGMGR_CHATROOM_REALTIME_PUSH, param, user.sender); + } finally { + jedis5.close(); + } + } else { + return 0; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return 1; + } + + @ActionKey(value = Router.FGMGR_ENTER_CHATROOM) + public final void enterChatRoom(Session sender, ITObject params, int gid) throws Exception { + int groupId = params.getInt("groupId"); + int uids = params.getInt("uid"); + int getData = params.getInt("getData"); + + String countKey = "g{" + groupId + "}:m" + uids; + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + jedis10.hset(countKey, "messageCount", 0 + ""); + } catch (Exception e) { + Global.logger.error("enterChatRoom进入: -------------> " + e); + } finally { + jedis10.close(); + } + + pushChatRoom(uids, params, gid); +// if (i == 0){ +// user.response(null, gid, 0); +// } + } + + @ActionKey(value = Router.GET_ONLINE_MEMBER) + public final void getOnlineMember(Session sender, ITObject params, int gid) throws Exception { + User users = null; + int uids = params.getInt("uid"); + int groupId = params.getInt("id"); + Group group = Global.groupMap.get(groupId); + users = group.userMap.get(uids); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String onlineGroupIdKey = "g{" + groupId + "}:onlines"; + String offlineGroupIdKey = "g{" + groupId + "}:offlines"; + String playingGroupIdKey = "g{" + groupId + "}:playings"; + TObject online = TObject.newInstance(); + User user = null; + List onlineUser = new ArrayList(); + TArray onlineUserId = TArray.newInstance(); + TArray offlineUserId = TArray.newInstance(); + TArray playingUserId = TArray.newInstance(); + try { + jedis10.hset(onlineGroupIdKey, uids + "", "online"); + jedis10.hdel(offlineGroupIdKey, uids + "", "offline"); + Map onlineStringStringMap = jedis10.hgetAll(onlineGroupIdKey); + Map offlineStringStringMap1 = jedis10.hgetAll(offlineGroupIdKey); + Map playingStringStringMap = jedis10.hgetAll(playingGroupIdKey); + if (!onlineStringStringMap.isEmpty()) { + Set hkeys = jedis10.hgetAll(onlineGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + user = group.userMap.get(UserId); + onlineUser.add(user); + onlineUserId.addInt(UserId); + } + } + + if (!playingStringStringMap.isEmpty()) { + Set hkeys = jedis10.hgetAll(playingGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + playingUserId.addInt(UserId); + } + } + + if (!offlineStringStringMap1.isEmpty()) { + Set hkeys = jedis10.hgetAll(offlineGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + offlineUserId.addInt(UserId); + } + } + + online.putTArray("onlineUserId", onlineUserId); + online.putTArray("offlineUserId", offlineUserId); + online.putTArray("playingUserId", playingUserId); + if (onlineUser.size() > 0) { + for (User users1 : onlineUser) { + TPServer.me().getController().sendEvent(Router.PUSH_ONLINE_MEMBER, online, users1.sender); + } + } else { + users.response(online, gid, 0); + } + + } catch (Exception e) { + Global.logger.info("数据没存上" + e); + } finally { + jedis10.close(); + } + } + + @ActionKey(value = Router.GET_OFFLINE_MEMBER) + public final void setOnlineMember(Session sender, ITObject params, int gid) throws Exception { + User users = null; + int uids = params.getInt("uid"); + int groupId = params.getInt("id"); + Group group = Global.groupMap.get(groupId); + users = group.userMap.get(uids); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String onlineGroupIdKey = "g{" + groupId + "}:onlines"; + String offlineGroupIdKey = "g{" + groupId + "}:offlines"; + String playingGroupIdKey = "g{" + groupId + "}:playings"; + TObject online = TObject.newInstance(); + User user = null; + List onlineUser = new ArrayList(); + TArray onlineUserId = TArray.newInstance(); + TArray offlineUserId = TArray.newInstance(); + TArray playingUserId = TArray.newInstance(); + try { + jedis10.hset(offlineGroupIdKey, uids + "", "offline"); + jedis10.hdel(onlineGroupIdKey, uids + "", "online"); + Map onlineStringStringMap = jedis10.hgetAll(onlineGroupIdKey); + Map offlineStringStringMap1 = jedis10.hgetAll(offlineGroupIdKey); + Map playingStringStringMap = jedis10.hgetAll(playingGroupIdKey); + if (!onlineStringStringMap.isEmpty()) { + Set hkeys = jedis10.hgetAll(onlineGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + user = group.userMap.get(UserId); + onlineUser.add(user); + onlineUserId.addInt(UserId); + } + } + + if (!playingStringStringMap.isEmpty()) { + Set hkeys = jedis10.hgetAll(playingGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + playingUserId.addInt(UserId); + } + } + + if (!offlineStringStringMap1.isEmpty()) { + Set hkeys = jedis10.hgetAll(offlineGroupIdKey).keySet(); + for (String key : hkeys) { + int UserId = Integer.parseInt(key); + offlineUserId.addInt(UserId); + } + } + + online.putTArray("onlineUserId", onlineUserId); + online.putTArray("offlineUserId", offlineUserId); + online.putTArray("playingUserId", playingUserId); + + if (onlineUser.size() > 0) { + for (User users1 : onlineUser) { + TPServer.me().getController().sendEvent(Router.PUSH_ONLINE_MEMBER, online, users1.sender); + } + } else { + users.response(online, gid, 0); + } + } catch (Exception e) { + Global.logger.info("数据没存上" + e); + } finally { + jedis10.close(); + } + } + + // 切出游戏推送,set_home + @ActionKey(value = Router.GET_HOME_MEMBER) + public final void getHomeMember(Session session, ITObject params, int gid) throws Exception { + int uids = params.getInt("uid"); + String gameStatus = params.getString("gameStatus"); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + if (gameStatus.equals("enter")) { + jedis0.hset("{user}:" + uids, "setHome", gameStatus); + jedis0.hset("{user}:" + uids + "_online", "online", "1"); + jedis0.expire("{user}:" + uids + "_online", 30); + + } else { + jedis0.hset("{user}:" + uids, "setHome", gameStatus); + jedis0.hset("{user}:" + uids + "_online", "online", "0"); + jedis0.expire("{user}:" + uids + "_online", 30); + + } + + String setHome = jedis0.hget("{user}:" + uids, "setHome"); + params.putString("setHome", setHome); + params.putInt("uid", uids); + params.putInt("online", 0); + + String key = "groups:" + uids; + Set groupsId = jedis11.zrange(key, 0, -1); + Set userId = new HashSet(); + List groupIdLists = new ArrayList(); + for (String tem : groupsId) { + int gids = Integer.parseInt(tem); + groupIdLists.add(gids); + String groupIdKey = "g{" + gids + "}:onlines"; + String groupIdKeys = "g{" + gids + "}:offlines"; + Map onlines = jedis10.hgetAll(groupIdKey); + Map offlines = jedis10.hgetAll(groupIdKeys); + Set onlineskeys = onlines.keySet(); + Set offlineskey = offlines.keySet(); + + for (String onlinekey : onlineskeys) { + userId.add(onlinekey); + } + + for (String offlinekey : offlineskey) { + userId.add(offlinekey); + } + + } + + for (int j = 0; j < groupIdLists.size(); j++) { + int gids = (int) groupIdLists.get(j); + Group group = Global.groupMap.get(gids); + if (group == null) { + continue; + } + TArray userIds = TArray.newInstance(); + for (String uidss : userId) { + + String userKey = "{user}:" + uidss + "_online"; + String online = jedis0.hget(userKey, "online"); + if (online.equals("1")) { + userIds.addInt(Integer.parseInt(uidss)); + } + } + for (String uidss : userId) { + if (group.userMap == null) { + continue; + } + User user = group.userMap.get(Integer.parseInt(uidss)); + if (user != null) { + TObject param = TObject.newInstance(); + + param.putTArray("onlineUserId", userIds); + TPServer.me().getController().sendEvent(Router.PUSH_ONLINE, param, user.sender); + } + } + } + + } catch (Exception e) { + Global.logger.error("setGroupHeartbeat error", e); + } finally { + jedis0.close(); + jedis11.close(); + jedis10.close(); + + } + } + + // 邀请数据 + @ActionKey(value = Router.FGMGR_INVITATION) + public final void fgmgrInvitation(Session sender, ITObject params, int gid) throws Exception { + Global.logger.info("邀请好友 begin--------"); + int groupId = params.getInt("groupId"); + + int tagId = params.getInt("tagId"); + int player_id = params.getInt("player_id"); + String g_name = params.getString("g_name"); + String roomid = params.getString("roomid"); + int pid = params.getInt("pid"); +// GroupMemberBean gmb = GroupCache.getMember(groupId, player_id); + User user = null; + Group group = Global.groupMap.get(groupId); + user = group.userMap.get(player_id); + +// User tagUser = null; +// tagUser = group.userMap.get(tagId); +// Global.logger.info("邀请好友 tagUser--------"+tagUser); + + TObject invitation = TObject.newInstance(); + invitation.putInt("invite_id", player_id); + invitation.putString("g_name", g_name); + invitation.putString("roomid", roomid); + invitation.putInt("groupId", groupId); + invitation.putInt("pid", pid); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + User tagUser = null; + try { + String enterGroupId = jedis0.hget("{user}:"+tagId, "enter_group"); + Group enterGroup = Global.groupMap.get(Integer.parseInt(enterGroupId)); + GroupPlayBean gp = group.playCache.getBean(pid); + + invitation.putTObject("pinfo", gp.data); + + tagUser = enterGroup.userMap.get(tagId); + + invitation.putInt("onlineGroupId", Integer.parseInt(enterGroupId)); + + + + String key = "{user}:" + player_id; + + String nick = jedis0.hget(key, "nick"); + invitation.putString("nik", nick); + } catch (Exception e) { + Global.logger.info("数据没找到" + e); + } finally { + jedis0.close(); + } +// Global.logger.info("邀请好友 sender--------"+tagUser.sender); +// +// Global.logger.info("邀请好友 invitation--------"+invitation); +// + TPServer.me().getController().sendEvent(Router.FGMGR_INVITATION_RESPONSE, invitation, tagUser.sender); + user.response(invitation, groupId, 0); + + } + + // 更新助手推送 + @ActionKey(value = Router.UPDATE_ASSISTANT) + public final void pushAssistant(Session sender, ITObject params, int gid) throws Exception { + int groupId = params.getInt("id"); + int tagId = params.getInt("tagId"); + User users = null; + Group group = Global.groupMap.get(groupId); + users = group.userMap.get(tagId); + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + try { + String lev = jedis10.hget(gm_key, "lev"); + params.putInt("lev", Integer.parseInt(lev)); + TPServer.me().getController().sendEvent(Router.PUSH_ASSISTANT, params, users.sender); + } catch (Exception e) { + Global.logger.info("数据没存上" + e); + } finally { + jedis10.close(); + } + + users.response(params, gid, 0); + } + +// @ActionKey(value = Router.SET_HOME_MEMBER_COUNT) +// public final void setHomeMemberCount(Session sender, ITObject params,int gid) throws Exception { +// User user =null; +// int uids = params.getInt("uid"); +// String gameStatus = params.getString("gameStatus"); +// Group group = Global.groupMap.get(groupId); +// user = group.userMap.get(uids); +// +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// String groupIdKey ="g{"+groupId+"}:setHomes"; +// try { +// jedis10.hset(groupIdKey ,"homes", gameStatus); +// TArray aar= TArray.newInstance(); +// List onlineUser = new ArrayList(); +// MaphomesStringStringMap = jedis10.hgetAll(groupIdKey); +// if (!homesStringStringMap.isEmpty()){ +// Set hkeys = jedis10.hgetAll(groupIdKey).keySet(); +// for (String key : hkeys){ +// int UserId = Integer.parseInt(key); +// user=group.userMap.get(UserId); +// onlineUser.add(user); +// aar.addString(String.valueOf(UserId)); +// } +// } +// +// if (onlineUser.size() > 0){ +// for (User users1 : onlineUser){ +// TPServer.me().getController().sendEvent(Router.PUSH_GAME_OFFLINE , online, users1.sender); +// } +// }else { +// user.response(online, gid, 0); +// } +// +// } catch (Exception e) { +// Global.logger.error("setGroupHeartbeat error", e); +// }finally { +// jedis10.close(); +// } +// +// user.response(params, groupId, 0); +// } +} diff --git a/group_mgr/src/main/java/com/mgr/group/GroupSubscriber.java b/group_mgr/src/main/java/com/mgr/group/GroupSubscriber.java new file mode 100644 index 0000000..5dc4700 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/GroupSubscriber.java @@ -0,0 +1,314 @@ +package com.mgr.group; + +import com.mgr.group.data.Group; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; + +import redis.clients.jedis.JedisPubSub; + +public class GroupSubscriber extends JedisPubSub { + + public static final String CHANNEL_NAME = "mgr_group"; + + private static final String CMD_UPDATE_ROOM="update_room"; + private static final String CMD_DEL_ROOM="del_room"; + private static final String CMD_ADD_ROOM="add_room"; + private static final String CMD_DEL_PLAY="del_play"; + private static final String CMD_ADD_PLAY="add_play"; + private static final String CMD_UPDATE_PLAY="update_play"; + private static final String CMD_DEL_GROUP="del_group"; + private static final String CMD_UPDATE_GROUP="update_group"; + + + public static final String CMD_PUSH_CHAT_ROOM="push_chat_room"; + + + private static final String CMD_UPDATE_JOINS="update_joins"; + private static final String CMD_UPDATE_MEMBER="update_member"; + private static final String CMD_UPDATE_MAIL_TIP = "update_mail_tip"; + + //申请进入亲友圈允许 + public static final String CMD_ALLOW_ENTER_GROUP = "family_reflash"; + + //玩家游戏状态推送 + public static final String CMD_PLAYER_GAME_STATE = "player_game_state"; + + //拒接申请推送 + public static final String CMD_REFUSE_ENTER_GROUP = "family_refuse"; + + //退出亲友圈推送 + public static final String CMD_QUIT_GROUP = "quit_group"; + + //在线用户推送 + public static final String CMD_ONLINE_USERS = "online_users"; + + //聊天室按钮 + public static final String CMD_ROOM_BUTTON = "room_button"; + + + //申请成功加入亲友全友圈推送 + public static final String CMD_APPLY_SUCCESS = "apply_success"; + + //禁止娱乐 + public static final String CMD_BAN_PLAY = "ban_play"; + + + //修改公告 + public static final String CMD_UPDATE_NOTICE = "update_notice"; + + + private Logger log; + + public GroupSubscriber() { + log = Logger.getLogger(this.getClass()); + } + + private void updateRoomEvt(Group group,ITObject param) { + String roomid = param.getUtfString("roomid"); + Global.groupCtr.updateRoom(group,roomid); + } + + private void addRoomEvt(Group group,ITObject param) { + String roomid = param.getUtfString("roomid"); + Global.groupCtr.addRoom(group, roomid); + } + + private void delRoomEvt(Group group,ITObject param) { + String roomid = param.getUtfString("roomid"); + Global.groupCtr.delRoom(group, roomid); + } + +// private void roomButton(Group group,ITObject param) { +// int pid = param.getInt("pid"); +// String isWatch = param.getString("isWatch"); +// Global.groupCtr.roomButton(group, pid, isWatch); +// } + + private void publishNotice(Group group,ITObject param) { + Integer gid = param.getInt("gid"); + String notice = param.getUtfString("notice"); + Global.groupCtr.publishNotice(gid, notice); + } + + private void addPlay(Group group,ITObject param) { + int pid = param.getInt("pid"); + Global.groupCtr.addPlay(group, pid); + } + + private void updatePlay(Group group,ITObject param) { + int pid = param.getInt("pid"); + Global.groupCtr.updatePlay(group, pid); + } + + private void delPlay(Group group,ITObject param) { + int pid = param.getInt("pid"); + Global.groupCtr.delPlay(group, pid); + } + + private void updateGroup(Group group,ITObject param) { + String name = param.getUtfString("name"); + int ban = param.getBoolean("ban")?1:0; + String notice = param.getUtfString("notice"); + int option = param.getInt("option"); + int showNum = param.getInt("show_num"); + Global.groupCtr.updateGroup(group, name, ban,notice,option,showNum); + } + + private void updateJoins(Group group,ITObject param) { + int joins = param.getInt("joins"); + String remark = param.getString("remark"); + String nick = param.getString("nick"); + String portrait = param.getString("portrait"); + String reg_time = param.getString("reg_time"); + String uid=param.getString("uid"); + Integer read_status = param.getInt("read_status"); + Global.groupCtr.updateJoins(group, joins,remark,read_status,nick,portrait,reg_time,uid); + } + + private void familyReflash(int groupId,ITObject param) { + int joins = param.getInt("joins"); + String remark = param.getString("remark"); + Integer read_status = param.getInt("read_status"); + int tagId = param.getInt("tag_id"); + boolean allow = param.getBoolean("allow"); + Global.groupCtr.familyReflash(groupId, joins,remark,read_status,tagId, allow); + } + + private void joinFamily(int groupId,ITObject param) { + int joins = param.getInt("joins"); + String remark = param.getString("remark"); + Integer read_status = param.getInt("read_status"); + int tagId = param.getInt("tag_id"); + boolean allow = param.getBoolean("allow"); + ITObject user = param.getTObject("users"); + String name = param.getString("name"); + Global.groupCtr.joinFamily(groupId, joins,remark,read_status,tagId, allow,user,name); + } + + private void updateMailTip(Group group,ITObject param) { + int uid = param.getInt("uid"); + Global.groupCtr.updateMailTip(group, uid); + } +// private void updateMember(Group group,ITObject param) { +// int uid = param.getInt("uid"); +// int type = param.getInt("type"); +// int value = param.getInt("value"); +// Global.groupCtr.updateMember(group, uid, type, value); +// } + + //禁止娱乐 + private void banPlay(int groupId,ITObject param) { + groupId = param.getInt("gid"); + int tagId = param.getInt("uid"); + int ban = param.getInt("ban"); + Global.groupCtr.banPlay(groupId, tagId, ban); + } + + + private void pushChatRooms(int groupId,ITObject param) { + Global.groupCtr.pushChatRooms (groupId, param); + } + + + + + +// private void isInGame(int groupId,ITObject param) { +// Global.logger.info("进入isInGame: -------------> " + param); +// Global.groupCtr.isInGame(groupId,param); +// } + + + //游戏中状态推送 + public static void playerGameState(int groupId, ITObject data) { + Global.groupCtr.playerGameState(groupId, data); + + } + + public void familyRefuse(int groupId, ITObject data) { + int uid = data.getInt("uid"); + Global.groupCtr.familyRefuse(groupId,uid); + } + + public void quitGroup(int groupId,ITObject users) { + try { + int tagId = users.getInt("tagId"); + String outs = users.getUtfString("outs"); + String name = users.getUtfString("name"); + Global.groupCtr.quitGroup(groupId, tagId,outs, name); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void updateOnlineUsers(int groupId,ITObject users) { + int uid = users.getInt("uid"); + Global.groupCtr.updateOnlineUsers(groupId, uid); + + + } + +// public void onPMessage(String pattern, String channel, String message) { +// Global.logger.info("reids过期-----------------------------------"); +// } + + public void onMessage(String channel, String message) { + if(channel.equals(CHANNEL_NAME)) { +// if(Global.loggerDebug) { +// log.info(message); +// } + try { + ITObject data = TObject.newFromJsonData(message); + final int groupId = data.getInt("gid"); + Group group = Global.groupMap.get(groupId); + if(group!=null) { + group.enqueueRunnable(new Runnable() { + @Override + public void run() { + String cmd = data.getUtfString("cmd"); + Group group = Global.groupMap.get(groupId); + switch(cmd) { + case CMD_UPDATE_ROOM: + updateRoomEvt(group,data); + break; + case CMD_DEL_ROOM: + delRoomEvt(group,data); + break; + case CMD_ADD_ROOM: + addRoomEvt(group,data); + break; + case CMD_DEL_GROUP: + group.destroy(); + break; + case CMD_UPDATE_GROUP: + updateGroup(group,data); + break; + case CMD_ADD_PLAY: + addPlay(group,data); + break; + case CMD_UPDATE_PLAY: + updatePlay(group, data); + break; + case CMD_DEL_PLAY: + delPlay(group,data); + break; + case CMD_PUSH_CHAT_ROOM: + pushChatRooms(groupId,data); + break; + case CMD_UPDATE_JOINS: + updateJoins(group,data); + break; + case CMD_UPDATE_MEMBER: +// updateMember(group,data); + break; + case CMD_UPDATE_MAIL_TIP: + updateMailTip(group,data); + break; + case CMD_ALLOW_ENTER_GROUP: + familyReflash(groupId,data); + break; + case CMD_PLAYER_GAME_STATE: + playerGameState(groupId,data); + break; + case CMD_REFUSE_ENTER_GROUP: + familyRefuse(groupId,data); + break; + case CMD_QUIT_GROUP: + quitGroup(groupId,data); + break; + case CMD_ONLINE_USERS: + updateOnlineUsers(groupId,data); + break; + case CMD_APPLY_SUCCESS: + joinFamily(groupId,data); + break; + + case CMD_UPDATE_NOTICE: + publishNotice(group,data); + break; + case CMD_BAN_PLAY: + banPlay(groupId,data); + break; + } + } + }); + } + }catch (Exception e) { + log.error(e); + } + } + } + + public void onSubscribe(String channel, int subscribedChannels) { + System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d", + channel, subscribedChannels)); + } + + public void onUnsubscribe(String channel, int subscribedChannels) { + System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d", + channel, subscribedChannels)); + + } +} diff --git a/group_mgr/src/main/java/com/mgr/group/MainServer.java b/group_mgr/src/main/java/com/mgr/group/MainServer.java new file mode 100644 index 0000000..3d85f49 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/MainServer.java @@ -0,0 +1,184 @@ +package com.mgr.group; + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import com.mgr.group.data.Group; +import com.taurus.core.events.Event; +import com.taurus.core.events.IEventListener; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.TPEvents; +import com.taurus.permanent.data.Session; +import com.taurus.web.TWebServer; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisConnectionException; + +/** + * + * + */ +public class MainServer extends Extension implements IEventListener { + + public static MainServer instance; + + private GroupSubscriber subscriber; + public Config config; + + @Override + public void onStart() { + try { + instance = this; + + Global.logger = Logger.getLogger(MainServer.class); + Global.init(); + + try { + loadConfig(); + } catch (Exception e1) { + Global.logger.error(e1); + } + +// final String svr_key = "svr_mgr_test_" + config.mgrId; + final String svr_key = "svr_mgr_" + config.mgrId; + + Global.loggerDebug = config.loggerDebug; + TPServer.me().getEventManager().addEventListener(TPEvents.EVENT_SESSION_DISCONNECT, this); + + TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + int size = Global.sessionMgr.size(); + final Map svr_info = new HashMap<>(); + svr_info.put("host", config.host); + svr_info.put("conns", size + ""); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + jedis11.hmset(svr_key, svr_info); + jedis11.expire(svr_key, 15); + jedis11.zadd(GroupSubscriber.CHANNEL_NAME, size, svr_key); + } finally { + jedis11.close(); + } + } catch (Exception e) { + Global.logger.error(e); + } + } + }, 0, 5, TimeUnit.SECONDS); + + TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + List list = new ArrayList(Global.groupMap.values()); + + for (Group group : list) { + if ((System.currentTimeMillis() - group.lastTime) >= 360000000) { + group.enqueueRunnable(new Runnable() { + + @Override + public void run() { + group.destroy(); + } + }); + } + } + } + }, 10, 10, TimeUnit.SECONDS); + + TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + List list = new ArrayList(Global.groupMap.values()); + + for (Group group : list) { + GroupController gc = new GroupController(); + gc.pushOnlineData(group.id); + + } + } + }, 10, 10, TimeUnit.SECONDS); + subscriber = new GroupSubscriber(); + Thread subscribeThread = new Thread(new Runnable() { + + @Override + public void run() { + try { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.subscribe(subscriber, GroupSubscriber.CHANNEL_NAME); + jedis11.close(); + } catch (JedisConnectionException e) { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.subscribe(subscriber, GroupSubscriber.CHANNEL_NAME); + jedis11.close(); + + } + } + }); + subscribeThread.start(); + + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + + @Override + public void run() { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + Redis.use("group1_db11").unsubscribe(subscriber); + jedis11.zrem(GroupSubscriber.CHANNEL_NAME, svr_key); + jedis11.close(); + } + })); + } catch (Exception e) { + Global.logger.error(e); + } + } + + protected void loadConfig() throws Exception { + FileInputStream is = new FileInputStream(TWebServer.me().getContextRealPath() + "/config/mgr-config.xml"); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + Config config = new Config(); + config.host = root.getChildTextTrim("host"); + config.mgrId = Integer.parseInt(root.getChildTextTrim("mgrId")); + config.loggerDebug = Boolean.parseBoolean(root.getChildTextTrim("loggerDebug")); + this.config = config; + } + + public void onStop() { + super.onStop(); + } + + @Override + public void handleEvent(Event evt) { + String evtName = evt.getName(); + switch (evtName) { + case TPEvents.EVENT_SESSION_DISCONNECT: + Session session = (Session) evt.getParameter(TPEvents.PARAM_SESSION); + Global.sessionMgr.disconnect(session); + break; + } + } + + @Override + public void configRoute(Routes me) { + Global.groupCtr = new GroupController(); + me.add("", Global.groupCtr); + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/Router.java b/group_mgr/src/main/java/com/mgr/group/Router.java new file mode 100644 index 0000000..f6f45bf --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/Router.java @@ -0,0 +1,155 @@ +package com.mgr.group; + +import com.taurus.core.entity.ITObject; +import com.taurus.permanent.data.Session; + +/** + * 网络路由处理 + * + */ +public abstract class Router { + /** + * 进入圈子 + */ + public static final String FGMGR_ENTER_GROUP = "11001"; + /** + * 获取在线邀请玩家 + */ + public static final String FGMGR_GET_ONLINE_LIST = "11002"; + /** + * 邀请玩家 + */ + public static final String FGMGR_INVITATION = "11003"; + /** + * 邀请玩家响应 + */ + public static final String FGMGR_INVITATION_RESPONSE = "11004"; + /** + * 更新房间 + */ + public static final String FGMGR_EVT_UPDATE_ROOM = "12001"; + +// /** +// * 删除房间 +// */ +// public static final String FGMGR_EVT_DEL_ROOM = "12002"; +// +// /** +// * 添加房间 +// */ +// public static final String FGMGR_EVT_ADD_ROOM = "12003"; + + /** + * 删除玩法 + */ + public static final String FGMGR_EVT_DEL_PLAY = "12004"; + + /** + * 添加玩法 + */ + public static final String FGMGR_EVT_ADD_PLAY = "12005"; + /** + * 更新玩法 + */ + public static final String FGMGR_EVT_UPDATE_PLAY = "12006"; + /** + * 更新申请 + */ + public static final String FGMGR_EVT_UPDATE_JOINS = "12007"; + + // 允许、拒绝 + public static final String FGMGR_ALLOW = "11111"; + + /** + * 更新圈子 + */ + public static final String FGMGR_EVT_UPDATE_GROUP = "12008"; + /** + * 更新成员 + */ + public static final String FGMGR_EVT_UPDATE_MEMBER = "12009"; + + /** + * 邀请事件 + */ + public static final String FGMGR_EVT_INVITATION = "12010"; + + // 聊天室状态实时推送 + public static final String FGMGR_CHATROOM_REALTIME = "12011"; + + /** + * 更新玩家网络 + */ + public static final String FGMGR_EVT_UPDATE_NET = "update_net"; + /** + * 更新邮件提示 + */ + public static final String FGMGR_EVT_UPDATE_MAILTIP = "update_mail_tip"; + + // 打开聊天室 !! + public static final String OPEN_CHATROOM = "13001"; + + // 关闭聊天室 !! + public static final String BREAK_CHATROOM = "13002"; + + // 聊天室实时推送 + public static final String FGMGR_CHATROOM_REALTIME_PUSH = "13003"; + + // 进入聊天室 + public static final String FGMGR_ENTER_CHATROOM = "13004"; + + // 在线 + public static final String GET_ONLINE_MEMBER = "13005"; + + // 推送在线、离线数据 + public static final String PUSH_ONLINE_MEMBER = "13007"; + + // 离线 + public static final String GET_OFFLINE_MEMBER = "13006"; + + + + // 切出游戏做的离线处理 + public static final String GET_HOME_MEMBER = "3009"; + + // 推送游戏中 + public static final String PUSH_GAME_STATE = "push_game_state"; + + // 修改助理 + public static final String UPDATE_ASSISTANT = "update_assistant"; + // 推送助理 + public static final String PUSH_ASSISTANT = "push_assistant"; + + // 退出亲友圈 + public static final String FGMGR_QUIT_GROUP = "13008"; + + // 拒绝申请推送 + public static final String FGMGR_REFUSE = "fgmgr_refuse"; + + // 监听聊天室状态 + public static final String LISTEN_CHATROOM_STATUS = "12012"; + + // 推送在线 + public static final String PUSH_ONLINE = "13009"; + + // 禁止娱乐 + public static final String BAN_PLAY = "13010"; + + // 聊天室按钮 + public static final String CHATROOM_BUTTON = "13011"; + + // 隐藏已开始房间 + public static final String HIDE_AND_SHOW_ROOM = "13012"; + + // 隐藏已开始房间 + public static final String PUSH_ROOM_SHOW = "13013"; + + //公告推送 + public static final String PUSH_NOTICE = "13014"; + + + public void handel(Session sender, ITObject params, int gid) { + + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/SessionManager.java b/group_mgr/src/main/java/com/mgr/group/SessionManager.java new file mode 100644 index 0000000..5572783 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/SessionManager.java @@ -0,0 +1,80 @@ +package com.mgr.group; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.mgr.group.data.User; +import com.taurus.core.util.json.JSONUtils; +import com.taurus.permanent.data.Session; + +/** + * 当前节点 玩家session管理类 + * + * + */ +public class SessionManager { + + private ConcurrentMap sessionMap = null; + + public SessionManager() { + this.sessionMap = new ConcurrentHashMap(); + } + + /** + * 通过sessionid获取User + * @param sessionid + * @return + */ + public User getUser(Session sessionid) { + return this.sessionMap.get(sessionid); + } + + /** + * 增加session + * @param session + * @param player + */ + public void putUser(Session session, User user) { + this.sessionMap.put(session, user); + } + + /** + * 删除session + * @param session + */ + public User delSession(Session session) { + Global.logger.info("delSession----------------清理session:"+session.toString()); + if(session == null)return null; + session.setHashId(null); + User user =this.sessionMap.remove(session); + return user; + } + + /** + * 当前圈子在线人数 + * @return + */ + public int size() { + return this.sessionMap.size(); + } + + /** + * 断线 + * @param sender + */ + public void disconnect(Session sender) { + User user = this.delSession(sender); + if (user == null) { + return; + } + user.group.enqueueRunnable(new Runnable() { + + @Override + public void run() { + if (user.sender == sender) { + user.isConnect = false; + } + } + }); + } +} diff --git a/group_mgr/src/main/java/com/mgr/group/WebMain.java b/group_mgr/src/main/java/com/mgr/group/WebMain.java new file mode 100644 index 0000000..689df49 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/WebMain.java @@ -0,0 +1,34 @@ +package com.mgr.group; + +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.web.TWebServer; + +public class WebMain extends Extension { + + public void onStart() { + DefaultConstants.SERVER_CFG_FILE = TWebServer.me().getContextRealPath()+"/" + DefaultConstants.SERVER_CFG_FILE; + TPServer.me().start(); + } + + @Override + public void onStop() { + TPServer.me().shutdown(); + } + + + + + @Override + public void configRoute(Routes me) { + // TODO Auto-generated method stub + + } + + public int getConcurrentSize() { + return Global.sessionMgr.size(); + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/CommandData.java b/group_mgr/src/main/java/com/mgr/group/data/CommandData.java new file mode 100644 index 0000000..0d0c846 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/CommandData.java @@ -0,0 +1,36 @@ +package com.mgr.group.data; + +import com.taurus.core.entity.ITObject; + +public class CommandData { + public static final int ADD_ROOM = 1; + public static final int UPDATE_ROOM = 2; + public static final int DEL_ROOM = 3; + + private static final String TYPE_KEY = "$ct"; + public ITObject param; + /**1添加 2更新 3删除*/ + public int type = ADD_ROOM; + + public void setData(int type,ITObject param) { + if(type>=this.type) { + this.type = type; + this.param = param; + this.param.putInt(TYPE_KEY, type); + } + } + +// public void send(Group group,List list) { +// this.param.putInt(TYPE_KEY, type); +// if(type==1) { +// MainServer.instance.sendEvent(Router.FGMGR_EVT_UPDATE_ROOM, param, list); +// }else { +// MainServer.instance.sendEvent(Router.FGMGR_EVT_DEL_ROOM, param, list); +// } +// } + + + + + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/Group.java b/group_mgr/src/main/java/com/mgr/group/data/Group.java new file mode 100644 index 0000000..25e5957 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/Group.java @@ -0,0 +1,386 @@ +package com.mgr.group.data; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.data.bean.GroupBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupPlayCache; +import com.mgr.group.Global; +import com.mgr.group.Router; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; + +public class Group implements Runnable { + public int id; + public String group_key = ""; + /** + * 圈主 + */ + public int owner; + /** + * 圈主session + */ + public String owner_session; + /** + * 圈主钻石 + */ + public int owner_diamo; + /** + * 是否被激活 + */ + public volatile boolean isActive = false; + /** + * 是否被销毁 + */ + public volatile boolean isDestroy = false; + private Thread updateThread; + public volatile long lastTime; + final Queue updateHandleList = new LinkedList(); + public ConcurrentMap userMap; + public GroupPlayCache playCache; + public RoomCache roomCache; + public Map cmdMap = new HashMap<>(); + private long lastSendTime; +// private long lastUpdateOnline; + + public Group(int id) { + this.userMap = new ConcurrentHashMap<>(); + this.id = id; + this.group_key = GroupCache.genKey(id); + String pay_type = Redis.use("group1_db11").hget(group_key, "pay_type"); + this.playCache = new GroupPlayCache(id, Integer.parseInt(pay_type)); + this.roomCache = new RoomCache(id); + } + + public synchronized void start() { + if (isActive || isDestroy) + return; + isActive = true; + GroupBean gb = GroupCache.getGroup(id); + this.owner = gb.owner; + this.owner_session = AccountCache.genKey(owner); + String _diamo = Redis.use("group1_db0").hget(owner_session, "diamo"); + if(StringUtil.isNotEmpty(_diamo)) { + owner_diamo = Integer.parseInt(_diamo); + } + updateThread = new Thread(this, this.group_key); + updateThread.start(); + lastTime = System.currentTimeMillis(); + } + + private void handleTask(Runnable tem) { + if (isDestroy) { + return; + } + + try { + tem.run(); + } catch (Throwable t) { + Global.logger.error("[" + id + "] exception!", t); + } + + handleBroadcast(); + } + + public void handleBroadcast() + { + + long curTime = System.currentTimeMillis(); + if(curTime - lastSendTime >=2000) { + try { + if (cmdMap.size()>0) { + List list = this.getSessionList(); + if(list.size()>0) { + ITArray arr = TArray.newInstance(); + ITObject param = TObject.newInstance(); + + param.putTArray("cmds", arr); + for (Entry entry : cmdMap.entrySet()) { + CommandData cmd = entry.getValue(); + arr.addTObject(cmd.param); + } + TPServer.me().getController().sendEvent(Router.FGMGR_EVT_UPDATE_ROOM, 0, param, list); + } + } + List u_list = null; + synchronized (userMap) { + u_list = new ArrayList(userMap.values()); + } + List r_list = null; + Jedis jedis = Redis.use("group1_db10").getJedis(); + try { + Pipeline pip = jedis.pipelined(); + for (User user : u_list) { + pip.hget(user.gm_key, "hp"); + } + r_list = pip.syncAndReturnAll(); + + }finally { + jedis.close(); + } + + for(int i=0;i 0) { + this.lastTime = System.currentTimeMillis(); + Runnable tem = null; + synchronized (updateHandleList) { + tem = updateHandleList.poll(); + } + if (tem != null){ + try { + handleTask(tem); + } catch (Throwable t) { + Global.logger.error("[" + id + "] exception!", t); + } + } + } + + handleBroadcast(); + + if (isDestroy) + continue; + Thread.sleep(5); + } catch (InterruptedException e) { + isActive = false; + Global.logger.error("[" + id + "] thread interrupted!"); + } catch (Throwable t) { + //isActive = false; + Global.logger.error("[" + id + "] exception!", t); + } + } + } + + public void enqueueRunnable(Runnable runnable) { + if (runnable == null) + return; + synchronized (updateHandleList) { + updateHandleList.add(runnable); + } + } + + public void addRoomCommand(String roomid,int type,ITObject param) { + CommandData cmd = cmdMap.get(roomid); + if(cmd==null) { + cmd = new CommandData(); + cmdMap.put(roomid, cmd); + } + cmd.setData(type, param); + } + + public ITObject getInfo(int lev) { + ITObject info = TObject.newInstance(); + + GroupBean gb = GroupCache.getGroup(this.group_key); + info.putBoolean("ban", gb.ban == 1 ? true : false); + String joins_key = GroupCache.genJoinsKey(id); + String key = "group:" + id; + + int joins = Redis.use("group1_db11").scard(joins_key).intValue(); + String isShow = Redis.use("group1_db11").hget(key, "isShow"); + if (lev<3){ + info.putInt("joins", joins); + }else { + info.putInt("joins", 0); + } + + ITArray rooms = this.roomCache.getRoomList(); + info.putInt("diamo", owner_diamo); + info.putInt("dissolve_opt", gb.dissolve_opt); + info.putInt("kick_opt", gb.kick_opt); + info.putBoolean("ban_chat1", gb.ban_chat1); + info.putBoolean("ban_chat2", gb.ban_chat2); + info.putInt("ban_apply", gb.ban_apply); + info.putInt("exit_opt", gb.exit_opt); + info.putInt("option", gb.option); + + + info.putInt("isShow",Integer.parseInt(isShow)); + info.putInt("isOpenChatRoom", gb.isOpenChatRoom); + info.putInt("isShowBeginRoom", gb.isShowBeginRoom); + + info.putInt("isWatch", gb.isWatch); + + info.putTArray("rooms", rooms); + ITArray arrPlayList = TArray.newInstance(); + Utils.arrayCopy(this.playCache.getPlayList(lev), arrPlayList); + info.putTArray("play_list", arrPlayList); + return info; + } + + public boolean delRoom(String roomid) { + String key = "room:" + roomid; + boolean result =false; + + if (this.roomCache.delBean(key)) { + this.roomCache.updateRoom(); + result = true; + } + String grooms_key = GroupCache.genRoomsKey(id); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.zrem(grooms_key, key); + }finally { + jedis.close(); + } + + return result; + } + + public Room updateRoom(String roomid) { + String key = "room:" + roomid; + String grooms_key = GroupCache.genRoomsKey(id); + Room room = this.roomCache.getBean(key); + this.roomCache.updateRoom(); + if (room == null) { + Redis.use("group1_db11").zrem(grooms_key, key); + } else { + Redis.use("group1_db11").zadd(grooms_key, room.priorityValue, key); + } + + return room; + } + + public Room addRoom(String roomid) { + String key = "room:" + roomid; + String grooms_key = GroupCache.genRoomsKey(id); + Room room = this.roomCache.getBean(key); + + this.roomCache.updateRoom(); + if (room == null) { + Redis.use("group1_db11").zrem(grooms_key, key); + } else { + Redis.use("group1_db11").zadd(grooms_key, room.priorityValue, key); + } + return room; + } + + public GroupPlayBean addPlay(int pid) { + GroupPlayBean gp = this.playCache.getBean(pid); + this.playCache.updatePlay(); + return gp; + } + + public boolean delPlay(int pid) { + boolean del = this.playCache.delBean(pid); + this.playCache.updatePlay(); + return del; + } + + /** + * 广播消息到客户端 + * + * @param cmd 协议指令 + * @param param 协议数据 + */ + public void broadCastToClient(String cmd, ITObject param) { + if (!isActive) + return; + List list = getSessionList(); + if (list == null || list.size() == 0) + return; + TPServer.me().getController().sendEvent(cmd, param, list); + } + + public List getSessionList() { + List list = new ArrayList(); + List tem = null; + synchronized (userMap) { + tem = new ArrayList(userMap.values()); + } + + for (User user : tem) { + if (user.isConnect) { + list.add(user.sender); + } + } + return list; + } + + public List getSessionListByMgr() { + List list = new ArrayList(); + List tem = null; + synchronized (userMap) { + tem = new ArrayList(userMap.values()); + } + + for (User user : tem) { + if (user.isConnect && user.lev < 3) { + list.add(user.sender); + } + } + return list; + } + + public void destroy() { + if (this.isDestroy) + return; + this.isDestroy = true; + Global.groupMap.remove(id); + Collection tem = userMap.values(); + for (User user : tem) { + if (user.isConnect) { + TPServer.me().getController().disconnect(user.sender); + } + } + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/Player.java b/group_mgr/src/main/java/com/mgr/group/data/Player.java new file mode 100644 index 0000000..8c57b06 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/Player.java @@ -0,0 +1,38 @@ +package com.mgr.group.data; + +import com.data.bean.AccountBean; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +/** + * 基本玩家对象 + * + * + */ +public class Player extends AccountBean{ + /** + * 座位 + */ + public int seat = 0; + public int off_time = 0; + public long hp =0; + private ITObject playerData = new TObject(); + + /** + * 获取玩家信息 + * @return + */ + public ITObject getInfo() { + playerData.putInt("aid", this.id); + playerData.putUtfString("nick", this.nick); + playerData.putUtfString("portrait", this.portrait); + playerData.putInt("seat", this.seat); + playerData.putInt("off_time", off_time); + playerData.putLong("hp", hp); + return playerData; + } + + public String toString() { + return redis_key; + } +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/PlayerCache.java b/group_mgr/src/main/java/com/mgr/group/data/PlayerCache.java new file mode 100644 index 0000000..0020d2c --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/PlayerCache.java @@ -0,0 +1,25 @@ +package com.mgr.group.data; + +import com.data.bean.BaseBean; +import com.data.cache.AccountCache; + +public class PlayerCache extends AccountCache{ + + protected BaseBean newBean() { + return new Player(); + } + + static PlayerCache inst; + + + public static Player getPlayer(int id) { + if(inst==null)inst = new PlayerCache(); + return inst.getBean(id); + } + + public static Player getPlayer(String session) { + if(inst==null)inst = new PlayerCache(); + return inst.getBean(session); + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/Room.java b/group_mgr/src/main/java/com/mgr/group/data/Room.java new file mode 100644 index 0000000..f21613b --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/Room.java @@ -0,0 +1,175 @@ +package com.mgr.group.data; + +import java.util.Map; + +import com.data.bean.BaseBean; +import com.data.cache.GroupMemberCache; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.Utils; + +/** + * 基本房间对象 + * + * + */ +public class Room extends BaseBean { + /** + * 房间ID + */ + public String roomid = ""; + /** + * 玩家列表ID映射 + */ + public final ITArray players = TArray.newInstance(); + /** + * 房间最大人数 + */ + public int maxPlayers; + + public int limitInRoom; + + /** + * 圈子玩法ID + */ + public int groupPlayId; + /** + * 局數 + */ + public int round = 0; + /** + * 最大回合数 + */ + public int maxRound = 0; + /** + * 0 未开始 1开始 2标记需要删除 3删除 + */ + public int status = 0; + /** + * 0 关闭 1打开 + */ + public int open = 1; + + /** + * 房间匹配权重 + * pid open status 剩余空位 + * 11 1 1 00 + */ + public int priorityValue = 1; + + /* + 假房间 + */ + public boolean fake = false; + /** + * 最后操作时间 + */ + public long lastTime = 0; + + public ITObject data = TObject.newInstance(); + + private void setInfo() { + data.putUtfString("id", roomid); + data.putInt("round", round); + data.putInt("times", maxRound); + data.putInt("status", status); + data.putInt("maxPlayers", maxPlayers); + data.putInt("pid", groupPlayId); + ITArray arr = TArray.newInstance(); + Utils.arrayCopy(players, arr); + data.putTArray("plist", arr); + data.putInt("limitInRoom", limitInRoom); + + } + + public void fillData(Map redis_map) { + String _id = redis_map.get("id"); + String _status = redis_map.get("status"); + if (StringUtil.isEmpty(_id)) { + this.del = true; + return; + } + if(StringUtil.isNotEmpty(_status)) { + this.status = Integer.parseInt(_status); + } + + if (this.status == 2 || this.status == 3) { + this.del = true; + return; + } + this.roomid = _id; + this.id = Integer.parseInt(_id); + this.groupPlayId = Integer.parseInt(redis_map.get("gpid")); + this.round = Integer.parseInt(redis_map.get("round")); + this.maxRound = Integer.parseInt(redis_map.get("times")); + this.maxPlayers = Integer.parseInt(redis_map.get("maxPlayers")); + this.limitInRoom = Integer.parseInt(redis_map.get("limitInRoom")); + this.open = Integer.parseInt(redis_map.get("open")); + if (StringUtil.isEmpty(redis_map.get("fake"))) + { + this.fake = false; + } + else { + this.fake = true; + } + + this.loadRedisPlayer(redis_map.get("players"), redis_map.get("seats"),redis_map); + setInfo(); + updatePriority(); + } + + + + /** + * 重新加载玩家 + */ + private void loadRedisPlayer(String players_json, String seats_json,Map redis_map) { + players.clear(); + if (StringUtil.isEmpty(players_json)) + return; + ITArray players = TArray.newFromJsonData(players_json); + + ITArray seats = TArray.newFromJsonData(seats_json); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + Player player = PlayerCache.getPlayer(player_id); + player.seat = seats.getInt(i); + Object tem = redis_map.get("net_"+player_id); + player.off_time =tem ==null?0:(int)(Long.parseLong((String)tem)/1000); + + String strGroup = redis_map.get("group"); + int groupId = strGroup ==null?0:(Integer.parseInt((String)strGroup)); + String gm_key1 = GroupMemberCache.genKey(groupId, player.id); + if (this.fake) + { + String strHp = Redis.use("group1_db10").hget("fake_"+player.id, "fake_hp"); + player.hp = strHp ==null?0:(Long.parseLong((String)strHp)); + } + else { + String strHp = Redis.use("group1_db10").hget(gm_key1, "hp"); + player.hp = strHp ==null?0:(Long.parseLong((String)strHp)); + } + + this.players.addTObject(player.getInfo()); + } + } + + /** + * 房间匹配权重 + */ + public void updatePriority() { + if (this.status == 2 || this.status == 3) { + this.priorityValue = 0; + return; + } + int t_status = this.status == 0 ? 1 : 0; + int t_mc = this.players.size() + 1; + t_mc = this.players.size() == this.maxPlayers ? 0 : t_mc; + this.priorityValue = this.groupPlayId * 10000 + this.open * 1000 + t_status * 100 + t_mc; + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/RoomCache.java b/group_mgr/src/main/java/com/mgr/group/data/RoomCache.java new file mode 100644 index 0000000..a43b9d7 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/RoomCache.java @@ -0,0 +1,87 @@ +package com.mgr.group.data; + +import java.util.Map.Entry; +import java.util.Set; + +import com.data.bean.BaseBean; +import com.data.cache.BaseCache; +import com.data.cache.GroupCache; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Utils; + +import redis.clients.jedis.Jedis; + +public class RoomCache extends BaseCache{ + private int groupId; + private long last_time; + private ITArray rooms; + + protected RoomCache(int groupId) { + super("room:","group1_db0"); + this.groupId = groupId; + this.fillSize = 6; + this.readTime = 1; + rooms = TArray.newInstance(); + } + + @Override + protected BaseBean newBean() { + return new Room(); + } + + public final void updateRoom() { + rooms.clear(); + Set> set = this.mapById.entrySet(); + for(Entry entry : set) { + Room gp =(Room)entry.getValue(); + if(!gp.del) { + rooms.addTObject(gp.data); + }else { + this.mapById.remove(gp.id); + this.mapByKey.remove(gp.redis_key); + } + } + } + + /** + * 获取房间列表 + * @return + */ + public final ITArray getRoomList(){ + if(System.currentTimeMillis() - last_time < 10000) { + ITArray arr = TArray.newInstance(); + Utils.arrayCopy(rooms, arr); + return arr; + } + + rooms.clear(); + last_time = System.currentTimeMillis(); + String grooms_key = GroupCache.genRoomsKey(groupId); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Set rooms = jedis11.zrangeByScore(grooms_key, 100000, 2000000); + try { + for (String tem : rooms) { + Room room = this.getBean(tem); + if(room==null) { + jedis11.zrem(grooms_key, tem); + continue; + } + room.del = false; + jedis11.zadd(grooms_key, room.priorityValue, tem); + this.rooms.addTObject(room.data); + } + jedis11.zremrangeByScore(grooms_key, 0, 0); + }finally { + jedis11.close(); + } + + ITArray arr = TArray.newInstance(); + Utils.arrayCopy(this.rooms, arr); + return arr; + } + +} diff --git a/group_mgr/src/main/java/com/mgr/group/data/User.java b/group_mgr/src/main/java/com/mgr/group/data/User.java new file mode 100644 index 0000000..6146764 --- /dev/null +++ b/group_mgr/src/main/java/com/mgr/group/data/User.java @@ -0,0 +1,131 @@ +package com.mgr.group.data; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.data.bean.AccountBean; +import com.data.cache.AccountCache; +import com.mgr.group.Global; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +/** + * 长连接用户 + * + */ +public class User { + public int uid; + public String session_key; + /** + * 合伙人等级 + */ + public int partnerLev; + /** + * 职位等级 + */ + public int lev; + + public volatile Group group = null; + /** + * 是否正在链接 + */ + public volatile boolean isConnect = false; + /** + * mpnet session + */ + public volatile Session sender = null; + + public long hp =0; + public int mail_tip = 0; + public int ban =0; + public String gm_key; + + /**最后邀请时间*/ + public long last_invitation_time; + /**拒绝邀请时间*/ + public long invitation_refuse_time; + public int last_invitation_id; + + /**最后刷新时间*/ + public long last_refresh_time; + + public boolean updateOffline; + + private List onlineList = new ArrayList<>(); + + public ITArray getOnlineList(){ + if((System.currentTimeMillis() - last_refresh_time)>=2000) { + last_refresh_time = System.currentTimeMillis(); + onlineList.clear(); + Collection tem = group.userMap.values(); + for (User user : tem) { + if (user!=this&&user.isConnect&&user.ban==0) { + String room = Redis.use("group1_db0").hget(user.session_key, "room"); + if(StringUtil.isEmpty(room)) { + onlineList.add(user); + } + } + } + } + Collections.shuffle(onlineList); + int size = Math.min(onlineList.size(), 9); + ITArray arr = TArray.newInstance(); + for(int i=0;i + + + + taurus-web + com.taurus.web.WebFilter + + main + com.mgr.group.WebMain + + + + + taurus-web + /* + + diff --git a/group_mgr/src/main/webapp/config/log4j.properties b/group_mgr/src/main/webapp/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/group_mgr/src/main/webapp/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/group_mgr/src/main/webapp/config/mgr-config.xml b/group_mgr/src/main/webapp/config/mgr-config.xml new file mode 100644 index 0000000..20c748d --- /dev/null +++ b/group_mgr/src/main/webapp/config/mgr-config.xml @@ -0,0 +1,6 @@ + + + 192.168.1.8:4013 + 1000 + true + \ No newline at end of file diff --git a/group_mgr/src/main/webapp/config/taurus-core.xml b/group_mgr/src/main/webapp/config/taurus-core.xml new file mode 100644 index 0000000..a70b3ec --- /dev/null +++ b/group_mgr/src/main/webapp/config/taurus-core.xml @@ -0,0 +1,98 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/group_mgr/src/main/webapp/config/taurus-permanent.xml b/group_mgr/src/main/webapp/config/taurus-permanent.xml new file mode 100644 index 0000000..826132e --- /dev/null +++ b/group_mgr/src/main/webapp/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 1 + + 512 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 10 + 3 + 3 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + false +
0.0.0.0
+ 80 +
+ + + + extension - group_mgr + com.mgr.group.MainServer + + + + + Sys + 2 + 8 + 60000 + 20000 + + + + + Ext + 2 + 8 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/group_mgr/src/test/java/group_room_mgr/MainGroupMgr.java b/group_mgr/src/test/java/group_room_mgr/MainGroupMgr.java new file mode 100644 index 0000000..d89b9a0 --- /dev/null +++ b/group_mgr/src/test/java/group_room_mgr/MainGroupMgr.java @@ -0,0 +1,12 @@ +package group_room_mgr; + +import com.taurus.web.JettyServer; + +public class MainGroupMgr { + + public static void main(String[] args) { + new JettyServer("src/main/webapp",4018,"/").start(); + + } + +} diff --git a/pack_tools/pom.xml b/pack_tools/pom.xml new file mode 100644 index 0000000..81968eb --- /dev/null +++ b/pack_tools/pom.xml @@ -0,0 +1,119 @@ + + 4.0.0 + com.pack + pack_tools + war + 1.0.0 + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 3.8.1 + test + + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + + com.aliyun.oss + aliyun-sdk-oss + 3.8.0 + + + + + com.alibaba + fastjson + 1.2.62 + + + + + pack_tools + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + + diff --git a/pack_tools/src/main/java/com/pack/MainServer.java b/pack_tools/src/main/java/com/pack/MainServer.java new file mode 100644 index 0000000..0b6fba7 --- /dev/null +++ b/pack_tools/src/main/java/com/pack/MainServer.java @@ -0,0 +1,63 @@ +package com.pack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import com.pack.service.CommandService; +import com.pack.service.PackUtilService; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; + +public class MainServer extends Extension { + + public static Element packConfig; + public static Element ossListConfig; + public static String probjectName; + public MainServer() { + super(); + String path = System.getProperty("WORKDIR"); + File file = new File(path+"/config/pack-config.xml"); + if(file.exists()) { + try { + InputStream is = new FileInputStream(file); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + packConfig = document.getRootElement(); + ossListConfig = packConfig.getChild("oss-list"); + probjectName = packConfig.getChildTextTrim("project-name"); + }catch (Exception e) { + e.printStackTrace(); + } + } + + } + + + + + @Override + public void configRoute(Routes me) { + + me.add("cmd", CommandService.class); + me.add("pack", PackUtilService.class); + } + + @Override + public void onStart() { + + + } + + @Override + public void onStop() { + // TODO Auto-generated method stub + + + } + +} diff --git a/pack_tools/src/main/java/com/pack/Utils.java b/pack_tools/src/main/java/com/pack/Utils.java new file mode 100644 index 0000000..045b08b --- /dev/null +++ b/pack_tools/src/main/java/com/pack/Utils.java @@ -0,0 +1,98 @@ +package com.pack; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +import org.jdom.Element; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.CannedAccessControlList; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; + +import redis.clients.jedis.Jedis; + +public class Utils { + + public static final String[] svr_list= {"local","test","pro"}; + + public static ITObject getGameData(Jedis jedis1,int game_id,boolean version_add) { + List list = jedis1.hmget("game:"+game_id,"id","name","bundle","version"); + ITObject obj = TObject.newInstance(); + obj.putInt("game_id", Integer.parseInt(list.get(0))); + obj.putUtfString("name", list.get(1)); + obj.putUtfString("bundle", list.get(2)); + String version = list.get(3); + if(version_add) { + String tem[] = version.split("\\."); + version = tem[0]+"."+tem[1]+"."+(Integer.parseInt(tem[2])+1); + } + obj.putUtfString("version", version); + return obj; + } + + public static byte[] httpGet(String url) { + try { + URL realUrl = new URL(url); + // 打开和URL之间的连接 + HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); + if(conn.getResponseCode() == 200) { + InputStream is = conn.getInputStream(); + ByteArrayOutputStream o = new ByteArrayOutputStream(1024); + int i = 1024; + byte[] buf = new byte[i]; + + while ((i = is.read(buf, 0, i)) > 0) { + o.write(buf, 0, i); + } + return o.toByteArray(); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + + public static void uploadOssPack(String objectName,String path) throws Exception{ + List list = MainServer.ossListConfig.getChildren(); + for (Object o : list) { + Element ossConfig = (Element)o; + String endpoint = ossConfig.getChildTextTrim("endpoint"); + String accessKeyId = ossConfig.getChildTextTrim("accessKeyId"); + String accessKeySecret = ossConfig.getChildTextTrim("accessKeySecret"); + String bucketName = ossConfig.getChildTextTrim("bucketName"); + // 创建OSSClient实例。 + OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); + FileInputStream is = new FileInputStream(path+"/"+objectName); + String temName = MainServer.probjectName+"/" + objectName; + ossClient.putObject(bucketName, temName, is); + is.close(); + ossClient.setObjectAcl(bucketName, temName, CannedAccessControlList.PublicRead); + // 关闭OSSClient。 + ossClient.shutdown(); + } + + } + + + public static void uploadOss(Element ossConfig,String objectName,byte[] bytes) throws Exception{ + String endpoint = ossConfig.getChildTextTrim("endpoint"); + String accessKeyId = ossConfig.getChildTextTrim("accessKeyId"); + String accessKeySecret = ossConfig.getChildTextTrim("accessKeySecret"); + String bucketName = ossConfig.getChildTextTrim("bucketName"); + // 创建OSSClient实例。 + OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); + ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes)); + ossClient.setObjectAcl(bucketName, objectName, CannedAccessControlList.PublicRead); + // 关闭OSSClient。 + ossClient.shutdown(); + } +} diff --git a/pack_tools/src/main/java/com/pack/service/CommandService.java b/pack_tools/src/main/java/com/pack/service/CommandService.java new file mode 100644 index 0000000..80e0879 --- /dev/null +++ b/pack_tools/src/main/java/com/pack/service/CommandService.java @@ -0,0 +1,69 @@ +package com.pack.service; + +import com.data.util.ErrorCode; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; + +public class CommandService extends Controller { + + + @ActionKey(value = "get_user") + public final void getUser() throws Exception { + ITObject params = this.getParams(); + String key = params.getUtfString("key"); + int uid = params.getInt("uid"); + ITObject resData = TObject.newInstance(); + String res_v = null; + switch(key) { + case "acc": + res_v = Redis.use("group1_db0").hget("{user}:"+uid,"acc"); + break; + } + res_v = StringUtil.isEmpty(res_v)?StringUtil.Empty:res_v; + resData.putUtfString("value", res_v); + this.sendResponse(ErrorCode._SUCC, resData); + } + + + @ActionKey(value = "set_user") + public final void setUser() throws Exception { + ITObject params = this.getParams(); + String key = params.getUtfString("key"); + int uid = params.getInt("uid"); + int value = params.getInt("value"); + String sql = null; + switch(key) { + case "diamo": + sql = String.format("update account set diamo=%s where id=%s", value,uid); + if(DataBase.use().executeUpdate(sql)==0) { + this.sendResponse(ErrorCode._FAILED, null); + return; + } + Redis.use("group1_db0").hset("{user}:"+uid, "diamo", value+""); + + break; + case "type": + sql = String.format("update account set type=%s where id=%s", value,uid); + if(DataBase.use().executeUpdate(sql)==0) { + this.sendResponse(ErrorCode._FAILED, null); + return; + } + Redis.use("group1_db0").hset("{user}:"+uid, "type", value+""); + break; + case "mng": + sql = String.format("update account set mng=%s where id=%s", value,uid); + if(DataBase.use().executeUpdate(sql)==0) { + this.sendResponse(ErrorCode._FAILED, null); + return; + } + Redis.use("group1_db0").hset("{user}:"+uid, "mng", value+""); + break; + } + this.sendResponse(ErrorCode._SUCC, null); + } +} diff --git a/pack_tools/src/main/java/com/pack/service/PackServerProject.java b/pack_tools/src/main/java/com/pack/service/PackServerProject.java new file mode 100644 index 0000000..48eac89 --- /dev/null +++ b/pack_tools/src/main/java/com/pack/service/PackServerProject.java @@ -0,0 +1,103 @@ +package com.pack.service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.util.Logger; + +public class PackServerProject extends HttpServlet{ + /** + * + */ + private static final long serialVersionUID = 990146541904048926L; + + + private static final Object lock = new Object(); + + private static final String[] project_path = {"E:/elipse_work/leying/game_java/","E:/elipse_work/leying/server_web/"}; + private static final String[] upload_path = {"E:/upload/leying/update_game_java/","E:/upload/leying/"}; + + private static void findall(HttpServletResponse resp) throws Exception{ + ITArray arr = DataBase.use("db2").executeQueryByTArray("select * from leying"); + String t = ""; + for (int i = 0; i < arr.size(); i++) { + ITObject obj = arr.getTObject(i); + int id = obj.getInt("id"); + String name = obj.getUtfString("name"); + String file_name = obj.getUtfString("file_name"); + String upload_path = obj.getUtfString("upload_path"); + String pro_path = obj.getUtfString("pro_path"); + t +=String.format("", name,pro_path,upload_path,file_name,id); + } + t+="
项目名称项目路径上传路径包文件名操作
%s%s%s%s打包
"; + resp.getOutputStream().write(t.getBytes("GBK")); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + if(req.getParameterMap().containsKey("id")){ + try { + int id = Integer.parseInt(req.getParameter("id")); + synchronized (lock) { + ITArray arr = DataBase.use("db2").executeQueryByTArray("select * from leying where id="+id); + if(arr.size()>0){ + ITObject obj = arr.getTObject(0); + int type = obj.getInt("type"); + String name = obj.getUtfString("name"); + Logger log = Logger.getLogger(name); + String path = project_path[type-1]; + String file_name = obj.getUtfString("file_name"); + String upload = upload_path[type-1] + obj.getUtfString("upload_path")+"/"+file_name; + PackUtilService.exeCmd(path+"build.bat " +obj.getUtfString("pro_path")+" "+file_name+" " +upload ,log); + PackUtilService.exeCmd("svn update "+upload_path[1], log); + String tem_path = path + obj.getUtfString("pro_path")+"/target/"+file_name; + Files.copy(new File(tem_path).toPath(), new File(upload).toPath(),StandardCopyOption.REPLACE_EXISTING); + PackUtilService.exeCmd(upload_path[type-1]+"svn_add.bat \""+getIpAddr(req)+"["+name+"]\"",log); + String t="

打包成功!

返回"; + resp.getOutputStream().write(t.getBytes("GBK")); + } + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }else { + try { + findall(resp); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + private static String getIpAddr(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } +} diff --git a/pack_tools/src/main/java/com/pack/service/PackUtilService.java b/pack_tools/src/main/java/com/pack/service/PackUtilService.java new file mode 100644 index 0000000..c0dfcdf --- /dev/null +++ b/pack_tools/src/main/java/com/pack/service/PackUtilService.java @@ -0,0 +1,289 @@ +package com.pack.service; + +import java.io.BufferedReader; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.jdom.Element; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.pack.MainServer; +import com.pack.Utils; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; + +import redis.clients.jedis.Jedis; + +public class PackUtilService extends Controller{ + private static final Object lock = new Object(); + + static void exeCmd(String cmdCode,Logger log) { + BufferedReader br = null; + try { + Process p = Runtime.getRuntime().exec(cmdCode); + br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GBK")); + String line; + while ((line = br.readLine()) != null) { + log.info(line); + } + p.waitFor(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + private void asynBuild(String threadName,String cmd,String os,ITArray arr) { + Thread thread = new Thread(new Runnable() { + + @Override + public void run() { + logger.info("building "+os+"..."); + exeCmd(cmd,logger); + for (int i = 0; i < arr.size(); i++) { + ITObject obj = arr.getTObject(i); + String tem_ver = obj.getUtfString("version"); + String bundle = obj.getUtfString("bundle"); + bundle = bundle.replaceAll("\\.", "/"); + String obj_name = "/"+bundle+"/asset_pack"+tem_ver+".bytes"; + logger.info(obj.getUtfString("name")+"["+tem_ver + "] pack to oss..."); + try { + String path = MainServer.packConfig.getChildTextTrim("temp-pack-path"); + Utils.uploadOssPack(os+obj_name, path); + } catch (Exception e) { + logger.error(e); + buildCount ++; + throw new RuntimeException(e); + } + logger.info(obj.getUtfString("name")+"["+tem_ver + "] upload oss ok!"); + } + + buildCount ++; + } + }); + thread.setName(threadName + "-" + os); + thread.start(); + + } + private volatile int buildCount; + @ActionKey(value = "pack_extend") + public final void packExtend() throws Exception { + ITObject params = this.getParams(); + ITArray list = params.getTArray("list"); + if(list.size()==0) { + this.sendResponse(0, null); + return; + } + String threadName = this.getRemoteAddr()+"(extend)"; + Thread.currentThread().setName(threadName); + synchronized(lock) { + buildCount = 0; + int svr_type = params.getInt("svr_type"); + List> redis_list = new ArrayList<>(); + for(int i=0;i()); + } + logger.info("start build pack ..."); + + String svr = Utils.svr_list[svr_type]; + Jedis jedis1 = Redis.use(svr+"_db1").getJedis(); + try { + ITArray arr = TArray.newInstance(); + for(int i=0;i redis_map = redis_list.get(i); + String ver = gameObj.getUtfString("version"); + redis_map.put("version", ver); + arr.addTObject(gameObj); + } + String temp_path = MainServer.packConfig.getChildTextTrim("temp-pack-path"); + ITObject tem = TObject.newInstance(); + tem.putTArray("data", arr); + tem.putUtfString("hotpath", temp_path); + String data_path = MainServer.packConfig.getChildTextTrim("data-path"); + FileOutputStream fos = new FileOutputStream(data_path); + fos.write(StringUtil.getBytes(tem.toJson())); + fos.close(); + String cmd_params = " \""+data_path+"\""; + String bat_path = MainServer.packConfig.getChildTextTrim("android-path")+"build-extend.bat"; + String cmd = bat_path + cmd_params + " \"android\""; + asynBuild(threadName,cmd,"Android",arr); + bat_path = MainServer.packConfig.getChildTextTrim("ios-path")+"build-extend.bat"; + cmd = bat_path + cmd_params + " \"ios\""; + asynBuild(threadName,cmd,"iOS",arr); + bat_path = MainServer.packConfig.getChildTextTrim("win-path")+"build-extend.bat"; + cmd = bat_path + cmd_params + " \"win\""; + asynBuild(threadName,cmd,"Win",arr); + + while(buildCount < 3) { + Thread.sleep(100); + } + + for (int i = 0; i < redis_list.size(); i++) { + Map map = redis_list.get(i); + int game_id = list.getInt(i); + String key = "game:"+game_id; + jedis1.hmset(key, map); + jedis1.hincrBy(key, "cache_ver", 1); + } + }finally { + jedis1.close(); + } + } + + + } + + + @SuppressWarnings("unchecked") + @ActionKey(value = "pack_base") + public final void packBase() throws Exception { + ITObject params = this.getParams(); + ITArray list = params.getTArray("list"); + if(list.size()==0) { + this.sendResponse(0, null); + return; + } + String threadName = this.getRemoteAddr()+"(base)"; + Thread.currentThread().setName(threadName); + synchronized (lock) { + buildCount = 0; + logger.info("start build pack ..."); + List config_list = new ArrayList<>(); + Element init_json_list = MainServer.packConfig.getChild("init-json-list"); + @SuppressWarnings("rawtypes") + List base_config = init_json_list.getChildren(); + for (int i = 0; i < base_config.size(); i++) { + Element elem = (Element)base_config.get(i); + String url = elem.getChildTextTrim("url"); + String oss_key = elem.getChildTextTrim("oss_key"); + String init_json = elem.getChildTextTrim("init_json"); + BaseConfigData bcd = new BaseConfigData(); + byte[] bytes = Utils.httpGet(url); + if(bytes==null)continue; + String str = StringUtil.getString(bytes); + bcd.init_config_map = JSON.parseObject(str,LinkedHashMap.class, Feature.OrderedField); + Map obj = (Map) bcd.init_config_map.get("Android"); + bcd.old_ver = (String) obj.get("version"); + String v_tem[] = bcd.old_ver.split("\\."); + bcd.new_ver = v_tem[0]+"."+v_tem[1]+"."+(Integer.parseInt(v_tem[2])+1); + bcd.oss_key = oss_key; + bcd.init_json = init_json; + config_list.add(bcd); + } + String ver = config_list.get(0).old_ver; + String config_url = MainServer.packConfig.getChildTextTrim("config-url"); + byte[] bytes = Utils.httpGet(config_url+"asset_config"+ver+".json"); + if(bytes==null)return; + String str = StringUtil.getString(bytes); + ITArray config_arr = TArray.newFromJsonData(str); + ITArray arr = TArray.newInstance(); + for(int i=0;i init_config_map; + + public String old_ver; + + public String new_ver; + + public ITArray config_arr; + public String init_json; + + public String oss_key; + + @SuppressWarnings("unchecked") + public void writeNewVer() throws Exception { + List object= JSON.parseObject(config_arr.toJson(),ArrayList.class,Feature.OrderedField); + String json_str = JSON.toJSONString(object, SerializerFeature.PrettyFormat); + String config_path = "/config/asset_config"+new_ver+".json"; + byte[] config_bytes = StringUtil.getBytes(json_str); + List list = MainServer.ossListConfig.getChildren(); + for (Object o : list) { + Element ossConfig = (Element)o; + Utils.uploadOss(ossConfig,MainServer.probjectName+config_path,config_bytes); + } + + Map obj = (Map) init_config_map.get("Android"); + obj.put("version", new_ver); + obj = (Map) init_config_map.get("iOS"); + obj.put("version", new_ver); + obj = (Map) init_config_map.get("Win"); + obj.put("version", new_ver); + json_str = JSON.toJSONString(init_config_map, SerializerFeature.PrettyFormat); + + Element ossConfig = MainServer.ossListConfig.getChild(oss_key); + Utils.uploadOss(ossConfig,"configure/test1/"+init_json,StringUtil.getBytes(json_str)); + } + } +} diff --git a/pack_tools/src/main/java/com/pack/service/ServletAllGame.java b/pack_tools/src/main/java/com/pack/service/ServletAllGame.java new file mode 100644 index 0000000..8674e34 --- /dev/null +++ b/pack_tools/src/main/java/com/pack/service/ServletAllGame.java @@ -0,0 +1,56 @@ +package com.pack.service; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.pack.Utils; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; + +public class ServletAllGame extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String _svr_type = request.getParameter("svr_type"); + int svr_type = 1; + if(StringUtil.isNotEmpty(_svr_type)) { + svr_type = Integer.parseInt(_svr_type); + } + String svr = Utils.svr_list[svr_type]; + ITArray gameArray = TArray.newInstance(); + Jedis jedis1 = Redis.use(svr+"_db1").getJedis(); + try { + Set all = jedis1.keys("game:[0-9]*"); + for(String key : all) { + key = key.replaceAll("game:", ""); + ITObject gameObj = Utils.getGameData(jedis1, Integer.parseInt(key),false); + gameArray.addTObject(gameObj); + } + }finally { + jedis1.close(); + } + + OutputStream os =response.getOutputStream(); + os.write(StringUtil.getBytes(gameArray.toJson())); + os.flush(); + os.close(); + } +} diff --git a/pack_tools/src/main/webapp/WEB-INF/web.xml b/pack_tools/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..4f12630 --- /dev/null +++ b/pack_tools/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,38 @@ + + + + taurus-web + com.taurus.web.WebFilter + + main + com.pack.MainServer + + + + + taurus-web + /* + + + + allGame + com.pack.service.ServletAllGame + + + + allGame + /allGame + + + + pack_server + com.pack.service.PackServerProject + + + + pack_server + /pack_server + + + + \ No newline at end of file diff --git a/pack_tools/src/main/webapp/config/log4j.properties b/pack_tools/src/main/webapp/config/log4j.properties new file mode 100644 index 0000000..e10e427 --- /dev/null +++ b/pack_tools/src/main/webapp/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/pack_tools.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/pack_tools/src/main/webapp/config/mpnet-tools.xml b/pack_tools/src/main/webapp/config/mpnet-tools.xml new file mode 100644 index 0000000..d50acec --- /dev/null +++ b/pack_tools/src/main/webapp/config/mpnet-tools.xml @@ -0,0 +1,97 @@ + + + + + + 80 + + 2 + + 10 + + -1 + + true + + true + + true + + select 1 + + 180000 + + 60000 + + 30000 + + false + + 300000 + + false + + -1 + + + + + db1 + com.mysql.jdbc.Driver + jdbc:mysql://rm-uf6k4q27s99k5w1p1co.mysql.rds.aliyuncs.com/lygame_test + ly002 + ly2019!@#$ + + + db2 + com.mysql.jdbc.Driver + jdbc:mysql://192.168.0.11:6060/pack_config + proto_ff + 37du_game + + + + + + + + 80 + + 8 + + 2 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + \ No newline at end of file diff --git a/pack_tools/src/main/webapp/config/pack-config.xml b/pack_tools/src/main/webapp/config/pack-config.xml new file mode 100644 index 0000000..4086759 --- /dev/null +++ b/pack_tools/src/main/webapp/config/pack-config.xml @@ -0,0 +1,28 @@ + + + + + http://oss-cn-zhangjiakou.aliyuncs.com + LTAI4Fr18Esz5FBT9fPvSr6Y + 5oGollnfotRsnXwsWZIW7aNlNCMYVa + jingduliansai + + + + + jdls_pack + E:/wb_pro/pack_data.bin + E:/wb_pro/wb_win/ + E:/wb_pro/wb_ios/ + E:/wb_pro/wb_android/ + E:/wb_pack_temp + https://jingduliansai.oss-cn-zhangjiakou.aliyuncs.com/jdls_pack/config/ + + + + init1_0.json + https://jingduliansai.oss-cn-zhangjiakou.aliyuncs.com/configure/test1/init1_0.json + test + + + \ No newline at end of file diff --git a/pack_tools/src/main/webapp/config/taurus-core.xml b/pack_tools/src/main/webapp/config/taurus-core.xml new file mode 100644 index 0000000..2892976 --- /dev/null +++ b/pack_tools/src/main/webapp/config/taurus-core.xml @@ -0,0 +1,94 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://192.168.0.11:6060/wb_game + proto_ff + 37du_game + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + \ No newline at end of file diff --git a/pack_tools/src/test/java/pack_tools/Main.java b/pack_tools/src/test/java/pack_tools/Main.java new file mode 100644 index 0000000..1f53045 --- /dev/null +++ b/pack_tools/src/test/java/pack_tools/Main.java @@ -0,0 +1,9 @@ +package pack_tools; + +import com.taurus.web.JettyServer; + +public class Main { + public static void main(String[] args) { + new JettyServer("src/main/webapp",9091,"/").start(); + } +} diff --git a/pack_tools/src/test/java/pack_tools/TT.java b/pack_tools/src/test/java/pack_tools/TT.java new file mode 100644 index 0000000..c098de5 --- /dev/null +++ b/pack_tools/src/test/java/pack_tools/TT.java @@ -0,0 +1,9 @@ +package pack_tools; + +import com.taurus.web.JettyServer; + +public class TT { + public static void main(String[] args) { + new JettyServer("src/main/webapp",9091,"/").start(); + } +} diff --git a/taurus-permanent/config/log4j.properties b/taurus-permanent/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/taurus-permanent/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/taurus-permanent/config/taurus-core.xml b/taurus-permanent/config/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/taurus-permanent/config/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/taurus-permanent/config/taurus-permanent.xml b/taurus-permanent/config/taurus-permanent.xml new file mode 100644 index 0000000..6c629f3 --- /dev/null +++ b/taurus-permanent/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 4 + + 100 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 2 + 3 + 3 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + true +
0.0.0.0
+ 8080 +
+ + + + extension - test + com.taurus.TestExtension + + + + + Sys + 4 + 16 + 60000 + 20000 + + + + + Ext + 4 + 16 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/taurus-permanent/pom.xml b/taurus-permanent/pom.xml new file mode 100644 index 0000000..7fa00c5 --- /dev/null +++ b/taurus-permanent/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + com.taurus + taurus-server + 1.0.1 + + jar + taurus-permanent + 1.0.1 + + + + + junit + junit + + + + + com.taurus + taurus-core + + + + + io.undertow + undertow-core + 2.0.16.Final + + + diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/Main.java b/taurus-permanent/src/main/java/com/taurus/permanent/Main.java new file mode 100644 index 0000000..9156073 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/Main.java @@ -0,0 +1,9 @@ +package com.taurus.permanent; + +public class Main { + + public static void main(String[] args) { + TPServer taurus = TPServer.me(); + taurus.start(); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java b/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java new file mode 100644 index 0000000..b7b2c9f --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java @@ -0,0 +1,319 @@ +package com.taurus.permanent; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.events.Event; +import com.taurus.core.events.EventManager; +import com.taurus.core.events.IEventListener; +import com.taurus.core.plugin.PluginService; +import com.taurus.core.routes.Extension; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.task.TaskScheduler; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.core.ServerConfig.ExecutorConfig; +import com.taurus.permanent.core.ServerState; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.core.SystemController; +import com.taurus.permanent.core.TPEvents; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.util.GhostUserHunter; + +/** + * The server main class. + * + * + * + */ +public final class TPServer { + /** + * The server version. + */ + private final String version = "1.0.1"; + /** + * The server class instance. + */ + private static TPServer _instance = null; + private final BitSwarmEngine bitSwarmEngine; + private final Logger log; + private volatile ServerState state = ServerState.STARTING; + private volatile boolean initialized = false; + private volatile long serverStartTime; + private ServerConfig config; + private IEventListener networkEvtListener; + private ScheduledThreadPoolExecutor timerPool; + private TaskScheduler taskScheduler; + private EventManager eventManager; + private GhostUserHunter ghostUserHunter; + private SystemController controller; + private Extension extension; + private ThreadPoolExecutor systemExecutor; + private ThreadPoolExecutor extensionExecutor; + + /** + * get main instance + */ + public static TPServer me() { + if (_instance == null) { + _instance = new TPServer(); + } + return _instance; + } + + private TPServer() { + bitSwarmEngine = BitSwarmEngine.getInstance(); + + networkEvtListener = new NetworkEvtListener(); + timerPool = new ScheduledThreadPoolExecutor(1); + log = Logger.getLogger(getClass()); + + } + + public String getVersion() { + return version; + } + + private static final ServerConfig loadServerSettings() throws Exception { + FileInputStream is = new FileInputStream(DefaultConstants.SERVER_CFG_FILE); + ServerConfig config = new ServerConfig(); + config.load(is); + return config; + } + + public void start() { + System.out.println("\n==============================================================================\n" + + ">>Begin start taurus-permanent server....\n" + + "============================================================================== \n"); + if (!initialized) { + initialize(); + } + + try { + + PluginService.me().loadConfig(); + log.info("Load taurus-core config finish"); + + this.config = loadServerSettings(); + initExecutors(); + + this.taskScheduler = new TaskScheduler(); + this.taskScheduler.init(null); + + this.eventManager = new EventManager(systemExecutor); + eventManager.init(null); + + timerPool.setCorePoolSize(config.timerThreadPoolSize); + bitSwarmEngine.init(null); + + log.info("\n\n==============================================================================\n" + + ">>Init Extension...\n"+ + "============================================================================== \n"); + controller = new SystemController(); + ghostUserHunter = new GhostUserHunter(); + extension = instanceExtension(); + controller.init(null); + extension.onStart(); + + state = ServerState.STARTED; + log.info("\n\n==============================================================================\n" + + ">>Server(" + version + ") ready!\n" + + "============================================================================== \n"); + + serverStartTime = System.currentTimeMillis(); + } catch (FileNotFoundException e) { + log.error("Not find taurus-core.xml and taurus-permanent.xml", e); + } catch (Exception e) { + log.error("Server start exception!", e); + } + } + + private void initExecutors() { + final ExecutorConfig sys_cfg = this.config.systemThreadPoolConfig; + this.systemExecutor = new ThreadPoolExecutor(sys_cfg.corePoolSize, sys_cfg.maxPoolSize, sys_cfg.keepAliveTime, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(sys_cfg.maxQueueSize), new TPThreadFactory(sys_cfg.name)); + + final ExecutorConfig ext_cfg = this.config.extensionThreadPoolConfig; + this.extensionExecutor = new ThreadPoolExecutor(ext_cfg.corePoolSize, ext_cfg.maxPoolSize, ext_cfg.keepAliveTime, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(ext_cfg.maxQueueSize), new TPThreadFactory(ext_cfg.name)); + } + + /** + * shut down server. + */ + public void shutdown() { + try { + log.info("Server shutdown!"); + List awaitingExecution = timerPool.shutdownNow(); + log.info("stopping timer pool: " + awaitingExecution.size()); + + bitSwarmEngine.destroy(null); + eventManager.destroy(null); + this.controller.destroy(null); + extension.onStop(); + } catch (Exception e) { + log.error("shut down exception!", e); + } + } + + public ScheduledThreadPoolExecutor getTimerPool() { + return timerPool; + } + + public TaskScheduler getTaskScheduler() { + return taskScheduler; + } + + public ThreadPoolExecutor getSystemExecutor() { + return systemExecutor; + } + + public ThreadPoolExecutor getExtensionExecutor() { + return extensionExecutor; + } + + public EventManager getEventManager() { + return eventManager; + } + + public SessionManager getSessionManager() { + return bitSwarmEngine.getSessionManager(); + } + + public SystemController getController() { + return controller; + } + + public Extension getExtension() { + return extension; + } + + public ServerState getState() { + return state; + } + + public ServerConfig getConfig() { + return config; + } + + /** + * 获取服务器启动时间 + * + * @return + */ + public long getUptime() { + if (serverStartTime == 0L) { + throw new IllegalStateException("Server not ready yet, cannot provide uptime!"); + } + return System.currentTimeMillis() - serverStartTime; + } + + private void initialize() { + if (initialized) { + throw new IllegalStateException("SmartFoxServer engine already initialized!"); + } + bitSwarmEngine.addEventListener(TPEvents.SESSION_LOST, networkEvtListener); + bitSwarmEngine.addEventListener(TPEvents.SESSION_IDLE, networkEvtListener); + bitSwarmEngine.addEventListener(TPEvents.SESSION_IDLE_CHECK_COMPLETE, networkEvtListener); + + initialized = true; + } + + private Extension instanceExtension() { + ServerConfig.ExtensionConfig extensionConfig = config.extensionConfig; + if (StringUtil.isEmpty(extensionConfig.className)) { + throw new RuntimeException("Extension className parameter is missing!"); + } + if (StringUtil.isEmpty(extensionConfig.name)) { + throw new RuntimeException("Extension name parameter is missing!"); + } + Extension extension = null; + try { + Class extensionClass = Class.forName(extensionConfig.className); + if (!Extension.class.isAssignableFrom(extensionClass)) { + throw new RuntimeException("Extension does not extends Extension: " + extensionConfig.name); + } + extension = (Extension) extensionClass.newInstance(); + extension.setName(extensionConfig.name); + } catch (IllegalAccessException e) { + throw new RuntimeException("Illegal access while instantiating class: " + extensionConfig.className); + } catch (InstantiationException e) { + throw new RuntimeException("Cannot instantiate class: " + extensionConfig.className); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Class not found: " + extensionConfig.className); + } + return extension; + } + + private void onSessionClosed(Session session) { + controller.disconnect(session); + } + + private void onSessionIdle(Session idleSession) { + controller.disconnect(idleSession); + } + + /** + * session 网络事件监听 + */ + private class NetworkEvtListener implements IEventListener { + private NetworkEvtListener() { + } + + public void handleEvent(Event event) { + String evtName = event.getName(); + + if (evtName.equals(TPEvents.SESSION_LOST)) { + Session session = (Session) event.getParameter(TPEvents.PARAM_SESSION); + + if (session == null) { + throw new RuntimeException("session is null!"); + } + onSessionClosed(session); + } else if ((evtName.equals(TPEvents.SESSION_IDLE_CHECK_COMPLETE))) { + ghostUserHunter.hunt(); + } else if (evtName.equals(TPEvents.SESSION_IDLE)) { + onSessionIdle((Session) event.getParameter(TPEvents.PARAM_SESSION)); + } + } + } + + private static final class TPThreadFactory implements ThreadFactory { + private static final AtomicInteger POOL_ID; + private static final String THREAD_BASE_NAME = "%s:%s"; + private final AtomicInteger threadId; + private final String poolName; + + static { + POOL_ID = new AtomicInteger(0); + } + + public TPThreadFactory(final String poolName) { + this.threadId = new AtomicInteger(1); + this.poolName = poolName; + TPThreadFactory.POOL_ID.incrementAndGet(); + } + + @Override + public Thread newThread(final Runnable r) { + final Thread t = new Thread(r, + String.format(THREAD_BASE_NAME, (this.poolName != null) ? this.poolName : TPThreadFactory.POOL_ID.get(), this.threadId.getAndIncrement())); + if (t.isDaemon()) { + t.setDaemon(false); + } + if (t.getPriority() != 5) { + t.setPriority(5); + } + return t; + } + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java new file mode 100644 index 0000000..c750488 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java @@ -0,0 +1,46 @@ +package com.taurus.permanent.core; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.events.EventDispatcher; +import com.taurus.core.service.IService; + +/** + * BaseCoreService + * + */ +public abstract class BaseCoreService extends EventDispatcher implements IService { + private static final AtomicInteger serviceId = new AtomicInteger(0); + private static final String DEFAULT_NAME = "Service-"; + protected String name; + protected volatile boolean active = false; + + public void init(Object o) { + name = getServiceId(); + active = true; + } + + public void destroy(Object o) { + active = false; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isActive() { + return active; + } + + public String toString() { + return "[Core Service]: " + name + ", State: " + (isActive() ? "active" : "not active"); + } + + protected static String getServiceId() { + return DEFAULT_NAME + serviceId.getAndIncrement(); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java new file mode 100644 index 0000000..e733060 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java @@ -0,0 +1,337 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.taurus.core.events.Event; +import com.taurus.core.events.IEventListener; +import com.taurus.core.service.IService; +import com.taurus.core.util.FixedIndexThreadPool; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.ServerConfig.SocketAddress; +import com.taurus.permanent.data.BindableSocket; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; +import com.taurus.permanent.io.IOHandler; +import com.taurus.permanent.io.ProtocolHandler; +import com.taurus.permanent.normal.SocketAcceptor; +import com.taurus.permanent.normal.SocketReader; +import com.taurus.permanent.normal.SocketWriter; +import com.taurus.permanent.websocket.WebSocketService; + +/** + * 核心网络字节群处理类 + * + */ +public final class BitSwarmEngine extends BaseCoreService { + private static BitSwarmEngine __engine__; + private SocketAcceptor socketAcceptor; + private SocketReader socketReader; + private SocketWriter socketWriter; + + private Logger logger; + private ServerConfig config; + private SessionManager sessionManager; + private volatile boolean inited = false; + private Map coreServicesByName; + private Map configByService; + private IEventListener eventHandler; + private WebSocketService webSocketService; + private ProtocolHandler protocolHandler; + private ConnectionFilter connectionFilter; + private FixedIndexThreadPool threadPool; + + public static BitSwarmEngine getInstance() { + if (__engine__ == null) { + __engine__ = new BitSwarmEngine(); + } + return __engine__; + } + + private BitSwarmEngine() { + setName("BitSwarmEngine"); + } + + private void initializeServerEngine() { + logger = Logger.getLogger(BitSwarmEngine.class); + this.config = TPServer.me().getConfig(); + inited = true; + } + + + private final void bootSequence() throws Exception { + startCoreServices(); + + bindSockets(config.socketAddresses); + for (IService service : coreServicesByName.values()) { + if (service != null) { + service.init(configByService.get(service)); + } + } + } + + private final void setConnectionFilterConfig() { + for (String blockedIp : config.ipFilter.addressBlackList) { + this.connectionFilter.addBannedAddress(blockedIp); + } + + for (String allowedIp : config.ipFilter.addressWhiteList) { + this.connectionFilter.addWhiteListAddress(allowedIp); + } + + this.connectionFilter.setMaxConnectionsPerIp(config.ipFilter.maxConnectionsPerAddress); + } + + /** + * write response packet. no blocking + * @param response + */ + public void write(Packet response) { + try { + if (this.config.webSocketConfig.isActive) { + final List webSocketRecipients = new ArrayList(); + final List socketRecipients = new ArrayList(); + for (final Session session : response.getRecipients()) { + if (session.getType() == SessionType.WEBSOCKET) { + webSocketRecipients.add(session); + } + else { + socketRecipients.add(session); + } + } + if (webSocketRecipients.size() > 0) { + response.setRecipients(socketRecipients); + final Packet webSocketResponse = response.clone(); + webSocketResponse.setRecipients(webSocketRecipients); + if (response.getId() != SystemController.ACTION_PINGPONG) { + long index = Thread.currentThread().getId(); + this.threadPool.execute((int) index, webSocketResponse); + } else { + writeToWebSocket(response); + } + } + } + }finally { + if (response.getId() != SystemController.ACTION_PINGPONG) { + long index = Thread.currentThread().getId(); + this.threadPool.execute((int) index, response); + } else { + writeToSocket(response); + } + } + + } + + /** + * write response packet. no blocking + * @param response 广播服,没有前后顺序的需求,需要尽可能的把包分发给不同的线程 + */ + public void write(Packet response, int weightId) { + if (weightId == 0) + { + weightId = (int)(Math.random() * 1000); + } + try { + if (this.config.webSocketConfig.isActive) { + final List webSocketRecipients = new ArrayList(); + final List socketRecipients = new ArrayList(); + for (final Session session : response.getRecipients()) { + if (session.getType() == SessionType.WEBSOCKET) { + webSocketRecipients.add(session); + } + else { + socketRecipients.add(session); + } + } + if (webSocketRecipients.size() > 0) { + response.setRecipients(socketRecipients); + final Packet webSocketResponse = response.clone(); + webSocketResponse.setRecipients(webSocketRecipients); + if (response.getId() != SystemController.ACTION_PINGPONG) { + this.threadPool.execute(weightId, webSocketResponse); + } else { + writeToWebSocket(response); + } + } + } + }finally { + if (response.getId() != SystemController.ACTION_PINGPONG) { + this.threadPool.execute(weightId, response); + } else { + writeToSocket(response); + } + } + + } + + private void writeToSocket(Packet res) { + socketWriter.getIOHandler().onDataWrite(res); + } + + private void writeToWebSocket(Packet res) { + webSocketService.onDataWrite(res); + } + + + private void startCoreServices() throws Exception { + sessionManager = SessionManager.getInstance(); + sessionManager.setName(DefaultConstants.SERVICE_SESSION_MANAGER); + + socketReader = new SocketReader(config.socketReaderThreadPoolSize); + // instance io handler + IOHandler ioHandler = new IOHandler(); + socketReader.setIoHandler(ioHandler); + + // instance socket acceptor + socketAcceptor = new SocketAcceptor(config.socketAcceptorThreadPoolSize); + // instance socket writer + socketWriter = new SocketWriter(config.socketWriterThreadPoolSize); + socketWriter.setIOHandler(ioHandler); + threadPool = new FixedIndexThreadPool(config.socketWriterThreadPoolSize, "PacketWrite", PacketWriteWork.class); + + if(config.webSocketConfig.isActive) { + webSocketService = new WebSocketService(); + webSocketService.setName(DefaultConstants.SERVICE_WEB_SOCKET); + coreServicesByName.put(DefaultConstants.SERVICE_WEB_SOCKET, webSocketService); + } + + socketAcceptor.setName(DefaultConstants.SERVICE_SOCKET_ACCEPTOR); + socketReader.setName(DefaultConstants.SERVICE_SOCKET_READER); + socketWriter.setName(DefaultConstants.SERVICE_SOCKET_WRITER); + + coreServicesByName.put(DefaultConstants.SERVICE_SESSION_MANAGER, sessionManager); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_ACCEPTOR, socketAcceptor); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_READER, socketReader); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_WRITER, socketWriter); + + } + + private void stopCoreServices() throws Exception { + socketWriter.destroy(null); + socketReader.destroy(null); + if(webSocketService!=null) { + webSocketService.destroy(null); + } + int pw_count = threadPool.shutdown(); + logger.info("PacketWrite stopped. Unprocessed tasks: " + pw_count); + Thread.sleep(2000L); + + sessionManager.destroy(null); + socketAcceptor.destroy(null); + } + + private void bindSockets(List bindableSockets) { + for (SocketAddress socketCfg : bindableSockets) { + try { + this.socketAcceptor.bindSocket(socketCfg); + } catch (IOException e) { + logger.error(e); + logger.warn("Was not able to bind socket: " + socketCfg); + } + } + + List sockets = socketAcceptor.getBoundSockets(); + String message = "Listening Sockets: "; + for (BindableSocket socket : sockets) { + message = message + socket.toString() + " "; + } + logger.info(message); + } + + public IService getServiceByName(String serviceName) { + return coreServicesByName.get(serviceName); + } + + public SocketAcceptor getSocketAcceptor() { + return this.socketAcceptor; + } + + public SocketReader getSocketReader() { + return this.socketReader; + } + + public SocketWriter getSocketWriter() { + return this.socketWriter; + } + + public ProtocolHandler getProtocolHandler() { + return this.protocolHandler; + } + + public Logger getLogger() { + return this.logger; + } + + public void setLogger(Logger logger) { + this.logger = logger; + } + + public ServerConfig getConfig() { + return this.config; + } + + public ConnectionFilter getConnectionFilter() { + return connectionFilter; + } + + public SessionManager getSessionManager() { + return this.sessionManager; + } + + public void init(Object o) { + if (!inited) { + initializeServerEngine(); + } + logger.info("Start Bit Swarm Engine!"); + + eventHandler = new IEventListener() { + public void handleEvent(Event event) { + dispatchEvent(event); + } + }; + + protocolHandler = new ProtocolHandler(); + connectionFilter = new ConnectionFilter(); + setConnectionFilterConfig(); + coreServicesByName = new ConcurrentHashMap(); + configByService = new HashMap(); + + try { + bootSequence(); + } catch (Exception e) { + throw new RuntimeException(e); + } + socketReader.addEventListener(TPEvents.SESSION_LOST, this.eventHandler); + } + + public void destroy(Object o) { + try { + stopCoreServices(); + } catch (Exception e) { + logger.error("Destroy exception!\n",e); + } + } + + public static final class PacketWriteWork extends FixedIndexThreadPool.Work { + + @Override + protected void handlerTask(Object task) throws Exception { + Packet packet = (Packet) task; + List list = packet.getRecipients(); + if(list.size() > 0) { + SessionType type = list.get(0).getType(); + if(type == SessionType.WEBSOCKET) { + BitSwarmEngine.getInstance().writeToWebSocket(packet); + }else { + BitSwarmEngine.getInstance().writeToSocket(packet); + } + } + } + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java new file mode 100644 index 0000000..e42fa07 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java @@ -0,0 +1,159 @@ +package com.taurus.permanent.core; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.util.Logger; + + +/** + * ip连接过滤 + * + */ +public class ConnectionFilter { + private final Set addressWhiteList; + private final Set bannedAddresses; + private final ConcurrentMap addressMap; + private int maxConnectionsPerIp = 10; + private Logger logger; + + public ConnectionFilter() { + this.addressWhiteList = new HashSet(); + this.bannedAddresses = new HashSet(); + this.addressMap = new ConcurrentHashMap(); + logger = Logger.getLogger(ConnectionFilter.class); + } + /** + * 获取所有黑名单列表 + */ + public void addBannedAddress(String ipAddress) { + synchronized (bannedAddresses) { + bannedAddresses.add(ipAddress); + } + } + + /** + * 获取所有白名单列表 + */ + public void addWhiteListAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + this.addressWhiteList.add(ipAddress); + } + } + + /** + * 获取所有黑名单列表 + */ + public String[] getBannedAddresses() { + String[] set = (String[]) null; + + synchronized (this.bannedAddresses) { + set = new String[bannedAddresses.size()]; + set = (String[]) bannedAddresses.toArray(set); + } + + return set; + } + + /** + * 获取每个IP最大的连接数 + */ + public int getMaxConnectionsPerIp() { + return this.maxConnectionsPerIp; + } + + /** + * 获取白名单列表 + */ + public String[] getWhiteListAddresses() { + String[] set = (String[]) null; + + synchronized (this.addressWhiteList) { + set = new String[this.addressWhiteList.size()]; + set = (String[]) this.addressWhiteList.toArray(set); + } + + return set; + } + + public void removeAddress(String ipAddress) { + synchronized (this.addressMap) { + AtomicInteger count = (AtomicInteger) this.addressMap.get(ipAddress); + + if (count != null) { + int value = count.decrementAndGet(); + + if (value == 0) + this.addressMap.remove(ipAddress); + } + } + } + + /** + * 移除黑名单IP地址 + */ + public void removeBannedAddress(String ipAddress) { + synchronized (this.bannedAddresses) { + this.bannedAddresses.remove(ipAddress); + } + } + + /** + * 移除白名单IP地址 + */ + public void removeWhiteListAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + this.addressWhiteList.remove(ipAddress); + } + } + + /** + * 获取每个IP最大连接数 + */ + public void setMaxConnectionsPerIp(int max) { + this.maxConnectionsPerIp = max; + } + + public boolean validateAndAddAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + if (this.addressWhiteList.contains(ipAddress)) { + return true; + } + } + + if (isAddressBanned(ipAddress)) { + logger.warn("Ip Address: " + ipAddress + " is banned!"); + return false; + } + + synchronized (this.addressMap) { + AtomicInteger count = (AtomicInteger) addressMap.get(ipAddress); + + if ((count != null) && (count.intValue() >= maxConnectionsPerIp)) { + logger.warn("Refused connection. Ip Address: " + ipAddress + " has reached maximum allowed connections."); + return false; + } + + if (count == null) { + count = new AtomicInteger(1); + this.addressMap.put(ipAddress, count); + } else { + count.incrementAndGet(); + } + } + return true; + } + + private boolean isAddressBanned(String ip) { + boolean isBanned = false; + + synchronized (this.bannedAddresses) { + isBanned = this.bannedAddresses.contains(ip); + } + + return isBanned; + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java new file mode 100644 index 0000000..1e389fc --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java @@ -0,0 +1,20 @@ +package com.taurus.permanent.core; + +/** + * 常量表 + * + */ +public final class DefaultConstants { + public static String SERVER_CFG_FILE = "config/taurus-permanent.xml"; + + + public static final String SERVICE_SOCKET_ACCEPTOR = "socketAcceptor"; + public static final String SERVICE_SOCKET_READER = "socketReader"; + public static final String SERVICE_SOCKET_WRITER = "socketWriter"; + public static final String SERVICE_SESSION_MANAGER = "sessionManager"; + public static final String SERVICE_WEB_SOCKET = "webSocket"; + + + public static final String SESSION_SELECTION_KEY = "SessionSelectionKey"; + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java new file mode 100644 index 0000000..e3f4124 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java @@ -0,0 +1,61 @@ +package com.taurus.permanent.core; + + +/** + * ip连接过滤通用接口 + * + */ +public interface IConnectionFilter { + /** + * 添加黑名单IP地址 + * @param ipAddress + */ + public void addBannedAddress(String ipAddress); + + /** + * 移除黑名单IP地址 + * @param ipAddress + */ + public void removeBannedAddress(String ipAddress); + + /** + * 获取所有黑名单列表 + * @return + */ + public String[] getBannedAddresses(); + + + public boolean validateAndAddAddress(String ipAddress); + + public void removeAddress(String ipAddress); + + /** + * 添加白名单地址 + * @param ipAddress + */ + public void addWhiteListAddress(String ipAddress); + + /** + * 移除白名单地址 + * @param ipAddress + */ + public void removeWhiteListAddress(String ipAddress); + + /** + * 获取白名单列表 + * @return + */ + public String[] getWhiteListAddresses(); + + /** + * 获取每个IP最大的连接数 + * @return + */ + public int getMaxConnectionsPerIp(); + + /** + * 设置每个IP最大的连接数 + * @param max + */ + public void setMaxConnectionsPerIp(int max); +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java new file mode 100644 index 0000000..1bc194d --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java @@ -0,0 +1,181 @@ +package com.taurus.permanent.core; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +/** + * 服务器配置信息 + * + */ +public class ServerConfig { + public volatile List socketAddresses = new ArrayList(); + public volatile IpFilterConfig ipFilter = new IpFilterConfig(); + public volatile int timerThreadPoolSize = 1; + public volatile int protocolCompression = 512; + + public String readBufferType = "HEAP"; + public String writeBufferType = "HEAP"; + public int maxPacketSize = 4096; + public int maxReadBufferSize = 1024; + public int maxWriteBufferSize = 32768; + public int socketAcceptorThreadPoolSize = 1; + public int socketReaderThreadPoolSize = 1; + public int socketWriterThreadPoolSize = 1; + public int sessionPacketQueueSize = 120; + public int sessionTimeout = 15; + public boolean tcpNoDelay = false; + + public ExecutorConfig systemThreadPoolConfig = new ExecutorConfig(); + public ExecutorConfig extensionThreadPoolConfig = new ExecutorConfig(); + public ExtensionConfig extensionConfig = new ExtensionConfig(); + public WebSocketConfig webSocketConfig = new WebSocketConfig(); + + /** + * ip过滤设置 + * + */ + public static final class IpFilterConfig { + public List addressBlackList = new ArrayList(); + public List addressWhiteList = new ArrayList(); + public volatile int maxConnectionsPerAddress = 99999; + } + + /** + * server ip_port绑定 + * + */ + public static final class SocketAddress { + public static final String TYPE_UDP = "UDP"; + public static final String TYPE_TCP = "TCP"; + public String address = "127.0.0.1"; + public int port = 9339; + public String type = TYPE_TCP; + + public String toString() { + return String.format("[%s]%s:%d", type, address, port); + } + } + + /** + * Taurus Thread pool config + * + * + */ + public static final class ExecutorConfig { + /** + * 线程池名称 + */ + public String name; + /** + * 核心线程大小 + */ + public int corePoolSize=4; + /** + * 最大线程大小 + */ + public int maxPoolSize=16; + /** + * 线程最大空闲时间(毫秒) + */ + public int keepAliveTime =60000; + /** + * 最大队列大小 + */ + public int maxQueueSize=20000; + } + + /** + * 自定义启动控制设置 + * + * + */ + public static final class ExtensionConfig { + public String name = ""; + public String className = ""; + } + + /** + * web socket + * + * + */ + public static final class WebSocketConfig { + public boolean isActive = true; + public String address = "0.0.0.0"; + public int port = 8080; + } + + private static final void loadThreadPoolConfig(Element em,ExecutorConfig config) { + config.name = em.getChildTextTrim("name"); + config.corePoolSize = Integer.parseInt(em.getChildTextTrim("corePoolSize")); + config.maxPoolSize = Integer.parseInt(em.getChildTextTrim("maxPoolSize")); + config.keepAliveTime = Integer.parseInt(em.getChildTextTrim("keepAliveTime")); + config.maxQueueSize = Integer.parseInt(em.getChildTextTrim("maxQueueSize")); + } + + public final void load(InputStream is) throws Exception{ + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + + this.timerThreadPoolSize = Integer.parseInt(root.getChildTextTrim("timerThreadPoolSize")); + this.protocolCompression = Integer.parseInt(root.getChildTextTrim("protocolCompression")); + this.readBufferType = root.getChildTextTrim("readBufferType"); + this.writeBufferType = root.getChildTextTrim("writeBufferType"); + this.maxPacketSize = Integer.parseInt(root.getChildTextTrim("maxPacketSize")); + this.maxReadBufferSize = Integer.parseInt(root.getChildTextTrim("maxReadBufferSize")); + this.maxWriteBufferSize = Integer.parseInt(root.getChildTextTrim("maxWriteBufferSize")); + this.socketAcceptorThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketAcceptorThreadPoolSize")); + this.socketReaderThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketReaderThreadPoolSize")); + this.socketWriterThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketWriterThreadPoolSize")); + this.maxPacketSize = Integer.parseInt(root.getChildTextTrim("maxPacketSize")); + this.sessionPacketQueueSize = Integer.parseInt(root.getChildTextTrim("sessionPacketQueueSize")); + this.sessionTimeout = Integer.parseInt(root.getChildTextTrim("sessionTimeout")); + this.tcpNoDelay = Boolean.parseBoolean(root.getChildTextTrim("tcpNoDelay")); + + Element addressesEm = root.getChild("socketAddresses"); + Iterator itr = (addressesEm.getChildren("socket")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + SocketAddress sa = new SocketAddress(); + sa.address = socketEm.getAttributeValue("address", "0.0.0.0"); + sa.port = Integer.parseInt(socketEm.getAttributeValue("port", "9339")); + sa.type = socketEm.getAttributeValue("type", SocketAddress.TYPE_TCP); + socketAddresses.add(sa); + } + + + Element ipFilterEm = root.getChild("ipFilter"); + Element addressBlackListEm = ipFilterEm.getChild("addressBlackList"); + itr = (addressBlackListEm.getChildren("string")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + ipFilter.addressBlackList.add(socketEm.getTextTrim()); + } + Element addressWhiteListEm = ipFilterEm.getChild("addressWhiteList"); + itr = (addressWhiteListEm.getChildren("string")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + ipFilter.addressWhiteList.add(socketEm.getTextTrim()); + } + ipFilter.maxConnectionsPerAddress = Integer.parseInt(ipFilterEm.getChildTextTrim("maxConnectionsPerAddress")); + + Element extensionConfigEm = root.getChild("extensionConfig"); + extensionConfig.className = extensionConfigEm.getChildTextTrim("className"); + extensionConfig.name = extensionConfigEm.getChildTextTrim("name"); + + + Element webSocketEm = root.getChild("webSocket"); + webSocketConfig.isActive = Boolean.parseBoolean(webSocketEm.getChildTextTrim("isActive")); + + loadThreadPoolConfig(root.getChild("systemThreadPoolConfig"),systemThreadPoolConfig); + + loadThreadPoolConfig(root.getChild("extensionThreadPoolConfig"),extensionThreadPoolConfig); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java new file mode 100644 index 0000000..8b8e1d1 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java @@ -0,0 +1,11 @@ +package com.taurus.permanent.core; + +/** + * 服务器状态 + * + */ +public enum ServerState { + STARTING, + STARTED, + REBOOTING; +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java new file mode 100644 index 0000000..46d7af0 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java @@ -0,0 +1,313 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.taurus.core.events.Event; +import com.taurus.core.service.AbstractService; +import com.taurus.core.util.Logger; +import com.taurus.core.util.task.ITaskHandler; +import com.taurus.core.util.task.Task; +import com.taurus.core.util.task.TaskScheduler; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.IPacketQueue; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.NonBlockingPacketQueue; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +/** + * session管理器,负责创建,添加和删除session + * + */ +public final class SessionManager extends AbstractService { + private static final String SESSION_CLEANING_TASK_ID = "SessionCleanerTask"; + private static final int SESSION_CLEANING_INTERVAL_SECONDS = 10; + private static SessionManager __instance__; + private Logger logger; + private final ConcurrentMap sessionsById; + private BitSwarmEngine engine = null; + private final List sessionList; + private final ConcurrentMap sessionsByConnection; + private Task sessionCleanTask; + private TaskScheduler systemScheduler; + private int highestCCS = 0; + + public static SessionManager getInstance() { + if (__instance__ == null) { + __instance__ = new SessionManager(); + } + return __instance__; + } + + private SessionManager() { + sessionsById = new ConcurrentHashMap(); + sessionList = new ArrayList(); + sessionsByConnection = new ConcurrentHashMap(); + } + + public void init(Object o) { + name = "DefaultSessionManager"; + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(SessionManager.class); + + systemScheduler = TPServer.me().getTaskScheduler(); + sessionCleanTask = new Task(SESSION_CLEANING_TASK_ID); + systemScheduler.addScheduledTask(sessionCleanTask, SESSION_CLEANING_INTERVAL_SECONDS, true, new SessionCleaner()); + + active = true; + logger.info("session manager init!"); + } + + public void destroy(Object o) { + super.destroy(o); + sessionCleanTask.setActive(false); + shutDownLocalSessions(); + sessionsByConnection.clear(); + } + + /** + * 添加session对象 + * @param session + */ + public void addSession(Session session) { + synchronized (sessionList) { + sessionList.add(session); + } + sessionsById.put(session.getId(), session); + sessionsByConnection.put(session.getConnection().getChannel(), session); + + + if (sessionList.size() > highestCCS) { + highestCCS = sessionList.size(); + } + logger.info("Session created: " + session); + } + + /** + * 检查session是否存在 + * @param session + * @return + */ + public boolean containsSession(Session session) { + return sessionsById.containsKey(session.getId()); + } + + /** + * 移除指定session对象 + * @param session + */ + public void removeSession(Session session) { + if (session == null)return; + if(!sessionsById.containsKey(session.getId()))return; + synchronized (sessionList) { + sessionList.remove(session); + } + ISocketChannel connection = session.getConnection(); + sessionsById.remove(session.getId()); + if (connection != null) { + sessionsByConnection.remove(connection.getChannel()); + } + if ((session.getType() == SessionType.NORMAL) || (session.getType() == SessionType.WEBSOCKET)) { + engine.getConnectionFilter().removeAddress(session.getAddress()); + } + + logger.info("Session removed: " + session); + } + + /** + * 移除指定ID的session + * @param id + * @return + */ + public Session removeSession(int id) { + Session session = sessionsById.get(id); + if (session != null) { + removeSession(session); + } + return session; + } + + /** + * 移除指定channel的session + * @param connection + * @return + */ + public Session removeSession(Object connection) { + Session session = getSessionByConnection(connection); + if (session != null) { + removeSession(session); + } + return session; + } + + /** + * channel链接断开处理 + * @param connection + * @throws IOException + */ + public void onSocketDisconnected(Object connection) throws IOException { + Session session = sessionsByConnection.get(connection); + if (session == null) { + return; + } + sessionsByConnection.remove(connection); + session.setConnected(false); + removeSession(session); + dispatchLostSessionEvent(session); + } + + /** + * 获取服务器所有session + * @return + */ + public List getAllSessions() { + List allSessions = null; + + synchronized (sessionList) { + allSessions = new ArrayList(sessionList); + } + + return allSessions; + } + + /** + * 获取指定channel的session + * @param connection + * @return + */ + public Session getSessionByConnection(Object connection) { + return sessionsByConnection.get(connection); + } + + /** + * 获取指定ID的session + * @param id + * @return + */ + public Session getSessionById(int id) { + return sessionsById.get(Integer.valueOf(id)); + } + + /** + * 获取最高的流量数量 + * @return + */ + public int getHighestCCS() { + return highestCCS; + } + + /** + * 关闭本地所有session + */ + public void shutDownLocalSessions() { + synchronized (sessionList) { + for (Iterator it = sessionList.iterator(); it.hasNext();) { + Session session = (Session) it.next(); + it.remove(); + try { + session.close(); + } catch (IOException e) { + logger.warn("I/O Error while closing session: " + session); + } + } + } + } + + /** + * 创建 session + * @param channel + * @return + */ + public Session createSession(ISocketChannel channel,SessionType type) { + Session session = new Session(); + session.setConnection(channel); + session.setTimeout(engine.getConfig().sessionTimeout); + session.setType(type); + IPacketQueue packetQueue = new NonBlockingPacketQueue(engine.getConfig().sessionPacketQueueSize); + session.setPacketQueue(packetQueue); + return session; + } + + /** + * 获取当前session链接数 + * @return + */ + public int getSessionCount() { + return sessionList.size(); + } + + private void applySessionCleaning() { + if (getSessionCount() > 0) { + for (Session session : getAllSessions()) { + if ((session == null) || (session.isFrozen())) { + continue; + } + if (session.isMarkedForEviction()) { + terminateSession(session); + logger.info("Terminated idle logged-in session: " + session); + } else { + if (!session.isIdle()) { + continue; + } + if (session.getHashId()!=null) { + logger.info("session timeout:" + session); + + session.setMarkedForEviction(); + dispatchSessionIdleEvent(session); + } else { + terminateSession(session); + } + } + } + } + + Event event = new Event(TPEvents.SESSION_IDLE_CHECK_COMPLETE); + engine.dispatchEvent(event); + } + + private void terminateSession(Session session) { + if (session.getType() == SessionType.NORMAL) { + ISocketChannel connection = session.getConnection(); + + try { + connection.close(); + session.setConnected(false); + } catch (Exception err) { + this.logger.warn("Failed closing connection while removing idle Session: " + session); + } + } + + removeSession(session); + dispatchLostSessionEvent(session); + } + + private void dispatchLostSessionEvent(Session closedSession) { + Event event = new Event(TPEvents.SESSION_LOST); + event.setParameter(TPEvents.PARAM_SESSION, closedSession); + engine.dispatchEvent(event); + } + + private void dispatchSessionIdleEvent(Session idleSession) { + Event event = new Event(TPEvents.SESSION_IDLE); + event.setParameter(TPEvents.PARAM_SESSION, idleSession); + engine.dispatchEvent(event); + } + + /** + * 清理session 任务 + */ + private final class SessionCleaner implements ITaskHandler { + private SessionCleaner() { + } + + public void doTask(Task task) throws Exception { + applySessionCleaning(); + } + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java new file mode 100644 index 0000000..2ed5aef --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java @@ -0,0 +1,338 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadPoolExecutor; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.events.Event; +import com.taurus.core.events.EventManager; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.ActionMapping; +import com.taurus.core.routes.IController; +import com.taurus.core.routes.Routes; +import com.taurus.core.service.IService; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 核心控制器基类 + * + * + */ +public class SystemController implements IService { + public static final String CONNECT_TOKE = "$t"; + public static final String CONNECT_PROT_COMPRESSION = "$pc"; + public static final String REQUEST_CMD = "$c"; + public static final String REQUEST_GID = "$gi"; + public static final String REQUEST_PARM = "$p"; + public static final String REQUEST_RESULT = "$r"; +// public static logger = Logger.getLogger(SystemController.class); + + /** + * pingpong + */ + public static final int ACTION_PINGPONG = 0; + /** + * 客户端请求 + */ + public static final int ACTION_REQUST_CMD = 1; + /** + * 服务器事件消息 + */ + public static final int ACTION_EVENT_CMD = 2; + + private volatile boolean active; + private String name = "SystemController"; + private ThreadPoolExecutor threadPool; + + private final Logger logger; + private final TPServer taurus; + + private SessionManager sessionManager; + private ActionMapping actionMapping; + private final Routes routes; + + public SystemController() { + logger = Logger.getLogger(SystemController.class); + taurus = TPServer.me(); + sessionManager = taurus.getSessionManager(); + routes = new Routes(Routes.CONTROLLER_INSTANCE) { + public void config() { + } + }; + routes.setAddSlash(false); + } + + public void init(Object o) { + if (active) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + threadPool = taurus.getExtensionExecutor(); + taurus.getExtension().configRoute(routes); + + actionMapping = new ActionMapping(routes); + actionMapping.buildActionMapping(); + active = true; + } + + public void destroy(Object o) { + active = false; + List leftOvers = threadPool.shutdownNow(); + EventManager eventManager = taurus.getEventManager(); + eventManager.removeAllListener(); + logger.info("SystemController stopping: " + getClass().getName() + ", Unprocessed tasks: " + leftOvers.size()); + } + + public void enqueueRequest(Packet request) { + threadPool.execute(new Runnable() { + @Override + public void run() { + if (active) { + try { + processRequest(request); + } catch (Exception e) { + logger.error(e); + } + } + } + }); + } + + private final void processRequest(Packet packet) throws Exception { + Session sender = packet.getSender(); + if (sender.isIdle() || sender.isMarkedForEviction()) + return; + if (!sessionManager.containsSession(sender)) { + logger.warn(" session is already expired!"); + return; + } + + byte reqId = (byte) packet.getId(); + + switch (reqId) { + case ACTION_PINGPONG: + onPingPong(sender); + break; + case ACTION_REQUST_CMD: + onRequest(sender, packet); + break; + } + } + + private final void onPingPong(Session sender) { + Packet packet = new Packet(); + packet.setId(ACTION_PINGPONG); + packet.setRecipient(sender); + packet.setData(new TObject()); + BitSwarmEngine.getInstance().write(packet); + } + + private final void onRequest(Session sender, Packet packet) throws Exception { + ITObject parm = (ITObject) packet.getData(); + String key = parm.getString(REQUEST_CMD); + Action action = actionMapping.getAction(key); + + if (action == null) { + return; + } + + IController controller = action.getController(); + if(controller == null) { + controller = action.getControllerClass().newInstance(); + } + int gid = 0; + if (parm.containsKey(REQUEST_GID)) + gid = parm.getInt(REQUEST_GID); + ITObject p = null; + if (parm.containsKey(REQUEST_PARM)) { + p = parm.getTObject(REQUEST_PARM); + } + logger.info("gid:"+gid); + logger.info("controller:"+controller); + + logger.info("parm:"+parm); + + + if (action.getInterceptor() != null) { + action.getInterceptor().intercept(action, controller,sender,p,gid); + } else { + action.getMethod().invoke(controller,sender,p,gid); + } + + } + + /** + * 断开session + * + * @param session + */ + public void disconnect(Session session) { + if (session == null) { + throw new RuntimeException("Session object is null."); + } + + try { + if (session.getHashId() != null) { + Event evt = new Event(TPEvents.EVENT_SESSION_DISCONNECT); + evt.setParameter(TPEvents.PARAM_SESSION, session); + taurus.getEventManager().dispatchEvent(evt); + session.setHashId(null); + } + if (session.isConnected()) { + session.close(); + } + } catch (IOException err) { + throw new RuntimeException(err); + } + } + + /** + * 发送事件给单一客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendEvent(String actionKey, ITObject params, Session recipient) { + if(!recipient.isConnected())return; + List msgRecipients = new ArrayList(); + msgRecipients.add(recipient); + sendEvent(actionKey, params, msgRecipients); + } + + public void sendEvents(String actionKey, ITObject params, Session recipient) { + List msgRecipients = new ArrayList(); + msgRecipients.add(recipient); + sendEvent(actionKey, params, msgRecipients); + } + + + /** + * 发送事件给单一客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendEvent(String actionKey, int weightId, ITObject params, Session recipient) { + if(!recipient.isConnected())return; + List msgRecipients = new ArrayList(); + msgRecipients.add(recipient); + sendEvent(actionKey, weightId, params, msgRecipients); + } + + /** + * 发送事件给客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipients 客户端session列表 + */ + public void sendEvent(String actionKey, ITObject params, List recipients) { + logger.info("sendEvent: ------"); + ITObject resObj = TObject.newInstance(); + resObj.putString(REQUEST_CMD, actionKey); + if (params != null) { + resObj.putTObject(REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(ACTION_EVENT_CMD); + packet.setData(resObj); + packet.setRecipients(recipients); + BitSwarmEngine.getInstance().write(packet); + logger.info("sendEvent-----退出"); + } + + /** + * 发送事件给客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipients 客户端session列表 + */ + public void sendEvent(String actionKey, int weightId, ITObject params, List recipients) { + ITObject resObj = TObject.newInstance(); + resObj.putString(REQUEST_CMD, actionKey); + if (params != null) { + resObj.putTObject(REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(ACTION_EVENT_CMD); + packet.setData(resObj); + packet.setRecipients(recipients); + BitSwarmEngine.getInstance().write(packet, weightId); + } + + /** + * 动态响应客户端请示 + * + * @param gid + * @param result 响应结果 0成功 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendResponse(int gid,int result, ITObject params, Session recipient) { + if(gid==0)return; + if(!recipient.isConnected())return; + ITObject resObj = TObject.newInstance(); + resObj.putInt(SystemController.REQUEST_RESULT, result); + resObj.putInt(SystemController.REQUEST_GID, gid); + if (params != null) { + resObj.putTObject(SystemController.REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(SystemController.ACTION_REQUST_CMD); + packet.setData(resObj); + packet.setRecipient(recipient); + BitSwarmEngine.getInstance().write(packet); + } + + /** + * 动态响应客户端请示 + * + * @param gid + * @param result 响应结果 0成功 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendResponse(int gid,int result, int weightId, ITObject params, Session recipient) { + if(gid==0)return; + if(!recipient.isConnected())return; + ITObject resObj = TObject.newInstance(); + resObj.putInt(SystemController.REQUEST_RESULT, result); + resObj.putInt(SystemController.REQUEST_GID, gid); + if (params != null) { + resObj.putTObject(SystemController.REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(SystemController.ACTION_REQUST_CMD); + packet.setData(resObj); + packet.setRecipient(recipient); + BitSwarmEngine.getInstance().write(packet, weightId); + } + + public final Logger getLogger() { + return logger; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public boolean isActive() { + return active; + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java b/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java new file mode 100644 index 0000000..0f0eb50 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java @@ -0,0 +1,28 @@ +package com.taurus.permanent.core; + +/** + * TPEvents + * + * + */ +public class TPEvents { + /** + * session丢失或被清理时间 + */ + public static final String SESSION_LOST = "sessionLost"; + /** + * session空闲事件 + */ + public static final String SESSION_IDLE = "sessionIdle"; + /** + * 完成检测需要清理的session事件 + */ + public static final String SESSION_IDLE_CHECK_COMPLETE = "sessionIdleCheckComplete"; + /** + * session断开连接事件 + */ + public static final String EVENT_SESSION_DISCONNECT = "session_disconnect"; + + public static final String PARAM_SESSION = "session"; + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java new file mode 100644 index 0000000..a4bd191 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java @@ -0,0 +1,37 @@ +package com.taurus.permanent.data; + +import java.nio.channels.SelectableChannel; + +/** + * BindableSocket + * + */ +public class BindableSocket { + protected SelectableChannel channel; + private String address; + private int port; + + public BindableSocket(SelectableChannel channel, String address, int port) { + this.address = address; + this.port = port; + + this.channel = channel; + } + + public SelectableChannel getChannel() { + return channel; + } + + public String getAddress() { + return address; + } + + public int getPort() { + return port; + } + + + public String toString() { + return String.format("%s[%d]", address, port); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java new file mode 100644 index 0000000..b7bd82d --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java @@ -0,0 +1,66 @@ +package com.taurus.permanent.data; + +/** + * 网络包队列接口 + * + */ +public interface IPacketQueue { + /** + * 返回队列头部的元素 + * @return + */ + public Packet peek(); + + /** + * 移除并返回队列头部的元素 + * @return + */ + public Packet take(); + + /** + * 队列是否为空 + * @return + */ + public boolean isEmpty(); + + /** + * 队列是否已满 + * @return + */ + public boolean isFull(); + + /** + * 获取队列当前大小 + * @return + */ + public int getSize(); + + /** + * 获取队列最大大小 + * @return + */ + public int getMaxSize(); + + /** + * 设置队列最大大小 + * @param size + */ + public void setMaxSize(int size); + + /** + * 队列当前使用百分比 + * @return + */ + public float getPercentageUsed(); + + /** + * 清理队列 + */ + public void clear(); + + /** + * 添加一个元素 + * @param packet + */ + public void put(Packet packet); +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java new file mode 100644 index 0000000..4b1709e --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java @@ -0,0 +1,21 @@ +package com.taurus.permanent.data; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.ByteBuffer; + +public interface ISocketChannel{ + long write(ByteBuffer buffer); + + void write(final String p0); + + boolean checkConnection(); + + Object getChannel(); + + SocketAddress getRemoteAddress(); + + SocketAddress getLocalAddress(); + + void close() throws IOException; +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java new file mode 100644 index 0000000..83fc0e1 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java @@ -0,0 +1,82 @@ +package com.taurus.permanent.data; + +import java.util.LinkedList; + +/** + * 非阻塞网络包队列 + * + */ +public final class NonBlockingPacketQueue implements IPacketQueue { + private final LinkedList queue; + private int maxSize; + + public NonBlockingPacketQueue(int maxSize) { + this.queue = new LinkedList(); + this.maxSize = maxSize; + } + + public void clear() { + synchronized (this.queue) { + queue.clear(); + } + } + + public int getSize() { + return queue.size(); + } + + public int getMaxSize() { + return maxSize; + } + + public boolean isEmpty() { + return queue.size() == 0; + } + + public boolean isFull() { + return queue.size() >= maxSize; + } + + public float getPercentageUsed() { + if (this.maxSize == 0) { + return 0.0F; + } + return queue.size() * 100 / maxSize; + } + + public Packet peek() { + Packet packet = null; + + synchronized (this.queue) { + if (!isEmpty()) { + packet = queue.get(0); + } + } + return packet; + } + + public void put(Packet packet){ + if (isFull()) { + throw new RuntimeException("packet is full!"); + } + + synchronized (queue) { + queue.addLast(packet); + } + } + + public void setMaxSize(int size) { + maxSize = size; + } + + public Packet take() { + Packet packet = null; + + synchronized (queue) { + packet = queue.removeFirst(); + } + + return packet; + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java new file mode 100644 index 0000000..884a912 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java @@ -0,0 +1,6 @@ +package com.taurus.permanent.data; + +public enum PackDataType { + BINARY, + TEXT +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java new file mode 100644 index 0000000..efd4d27 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java @@ -0,0 +1,94 @@ +package com.taurus.permanent.data; + +import java.util.ArrayList; +import java.util.List; + +/** + * Packet data object + * + */ +public class Packet { + protected int id; + protected Object data; + protected Session sender; + protected List recipients; + protected byte[] fragmentBuffer; + protected PackDataType dataType = PackDataType.BINARY; + + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Object getData() { + return this.data; + } + + public void setData(Object data) { + this.data = data; + } + + public Session getSender() { + return this.sender; + } + + public void setSender(Session sender) { + this.sender = sender; + } + + public List getRecipients() { + return this.recipients; + } + + public void setRecipients(List recipients) { + this.recipients = recipients; + } + + public void setRecipient(Session session) { + List recipients = new ArrayList(); + recipients.add(session); + setRecipients(recipients); + } + + public boolean isFragmented() { + return this.fragmentBuffer != null; + } + + public byte[] getFragmentBuffer() { + return this.fragmentBuffer; + } + + public void setFragmentBuffer(byte[] bb) { + this.fragmentBuffer = bb; + } + + public PackDataType getDataType() { + return dataType; + } + + public void setDataType(PackDataType dataType) { + this.dataType = dataType; + } + + public String toString() { + return String.format("{ data: %s }", data.getClass().getName()); + } + + public Packet clone() { + Packet newPacket = new Packet(); + newPacket.id = this.id; + newPacket.data = data; + List recipients = new ArrayList(); + recipients.addAll(this.recipients); + newPacket.recipients = recipients; + newPacket.sender = this.sender; + newPacket.dataType = this.dataType; + newPacket.fragmentBuffer = this.fragmentBuffer; + return newPacket; + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java new file mode 100644 index 0000000..95ba371 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java @@ -0,0 +1,467 @@ +package com.taurus.permanent.data; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.permanent.core.SessionManager; + +/** + * 核心用户session对象 + * + */ +public final class Session { + public static final String DATA_BUFFER = "session_data_buffer"; + public static final String PACKET_READ_STATE = "read_state"; + private static final String NO_IP = "NO_IP"; + + + private static AtomicInteger idCounter = new AtomicInteger(0); + + private volatile long readBytes = 0L; + private volatile long writtenBytes = 0L; + private volatile int droppedMessages = 0; + private ISocketChannel connection; + private volatile long creationTime; + private volatile long lastReadTime; + private volatile long lastWriteTime; + private volatile long lastActivityTime; + private int id; + private volatile String hashId; + private SessionType type; + private volatile String clientIpAddress = NO_IP; + private volatile int clientPort; + private int serverPort; + private String serverAddress; + private int timeout; + private volatile boolean frozen = false; + private boolean markedForEviction = false; + private volatile boolean connected = false; + private IPacketQueue packetQueue; + private Map systemProperties; + + public Session() { + creationTime = lastReadTime = lastWriteTime = lastActivityTime = System.currentTimeMillis(); + + setId(getUniqueId()); + + systemProperties = new ConcurrentHashMap(); + } + + private static int getUniqueId() { + return idCounter.incrementAndGet(); + } + + /** + * 统计当前session接收字节流大小 + * @param amount + */ + public void addReadBytes(long amount) { + this.readBytes += amount; + } + + /** + * 统计当前session发送字节流大小 + * @param amount + */ + public void addWrittenBytes(long amount) { + this.writtenBytes += amount; + } + + /** + * 获取channe连接对象 + * @return + */ + public ISocketChannel getConnection() { + return this.connection; + } + + /** + * 获取session创建时间 + * @return + */ + public long getCreationTime() { + return this.creationTime; + } + + /** + * 获取hashid + * @return + */ + public String getHashId() { + return this.hashId; + } + + /** + * 获取session id + * @return + */ + public int getId() { + return this.id; + } + + /** + * 获取客户端详细地址 + * @return + */ + public String getFullIpAddress() { + return clientPort > 0 ? getAddress() + ":" + clientPort : getAddress(); + } + + /** + * 获取客户端地址 + * @return + */ + public String getAddress() { + return this.clientIpAddress; + } + + /** + * 获取客户端端口 + * @return + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * 获取服务器监听端口 + * @return + */ + public int getServerPort() { + return this.serverPort; + } + + /** + * 获取服务器详细地址 + * @return + */ + public String getFullServerIpAddress() { + return this.serverAddress + ":" + this.serverPort; + } + + /** + * 获取服务器地址 + * @return + */ + public String getServerAddress() { + return this.serverAddress; + } + + /** + * 获取最后激活时间 + * @return + */ + public long getLastActivityTime() { + return this.lastActivityTime; + } + + /** + * 获取最后读时间 + * @return + */ + public long getLastReadTime() { + return this.lastReadTime; + } + + /** + * 获取最后写时间 + * @return + */ + public long getLastWriteTime() { + return this.lastWriteTime; + } + + /** + * 获取超时时间 + * @return + */ + public int getTimeout() { + return this.timeout; + } + + /** + * 获取网络包队列 + * @return + */ + public IPacketQueue getPacketQueue() { + return this.packetQueue; + } + + /** + * 获取服务器内部属性 + * @param key + * @return + */ + public Object getSystemProperty(String key) { + return this.systemProperties.get(key); + } + + /** + * 获取属性 + * @param key + */ + public void removeSystemProperty(String key) { + this.systemProperties.remove(key); + } + + /** + * 获取session类型 + * @return + */ + public SessionType getType() { + return this.type; + } + + /** + * 获取当前session接收字节流大小 + * @return + */ + public long getReadBytes() { + return this.readBytes; + } + + /** + * 获取当前session发送字节流大小 + * @return + */ + public long getWrittenBytes() { + return this.writtenBytes; + } + + /** + * 当前连接状态 + * @return + */ + public boolean isConnected() { + return this.connected; + } + + /** + * 设置连接状态 + * @param value + */ + public void setConnected(boolean value) { + this.connected = value; + } + + + /** + * session 是否空闲,做超时踢出处理 + * @return + */ + public boolean isIdle() { + return isSocketIdle(); + } + + private boolean isSocketIdle() { + boolean isIdle = false; + + if (this.timeout > 0) { + long elapsedSinceLastActivity = System.currentTimeMillis() - this.lastActivityTime; + isIdle = elapsedSinceLastActivity / 1000L > this.timeout; + } + + return isIdle; + } + + public boolean isMarkedForEviction() { + return this.markedForEviction; + } + + /** + * 设置channel连接对象 + * @param connection + */ + public void setConnection(ISocketChannel connection) { + if (connection == null) { + return; + } + + if (this.connection != null) { + throw new IllegalArgumentException("You cannot overwrite the connection linked to a Session!"); + } + if(connection.checkConnection()) { + setSocketConnection(connection); + this.connected = true; + } + } + + private void setSocketConnection(ISocketChannel connection) { + this.connection = connection; + String svr_host = connection.getLocalAddress().toString().substring(1); + String[] svr_adr =svr_host.split("\\:"); + this.serverAddress = svr_adr[0]; + try { + this.serverPort = Integer.parseInt(svr_adr[1]); + } catch (NumberFormatException localNumberFormatException) { + } + + + String client_host = connection.getRemoteAddress().toString().substring(1); + String[] client_adr = client_host.split("\\:"); + this.clientIpAddress = client_adr[0]; + try { + this.clientPort = Integer.parseInt(client_adr[1]); + } catch (NumberFormatException localNumberFormatException) { + } + + } + + /** + * 设置网络包队列 + * @param queue + */ + public void setPacketQueue(IPacketQueue queue) { + if (this.packetQueue != null) { + throw new IllegalStateException("Cannot reassing the packet queue. Queue already exists!"); + } + this.packetQueue = queue; + } + + /** + * 设置创建时间 + * @param timestamp + */ + public void setCreationTime(long timestamp) { + this.creationTime = timestamp; + } + + /** + * 设置hashID + * @param hash + */ + public void setHashId(String hash) { + this.hashId = hash; + } + + /** + * 设置session id + * @param id + */ + public void setId(int id) { + this.id = id; + } + + /** + * 设置最后读取网络字节时间 + * @param timestamp + */ + public void setLastReadTime(long timestamp) { + this.lastReadTime = timestamp; + if(this.hashId!=null) { + this.lastActivityTime = timestamp; + } + } + + /** + * 设置最后写网络字节时间 + * @param timestamp + */ + public void setLastWriteTime(long timestamp) { + this.lastWriteTime = timestamp; + if(this.hashId!=null) { + this.lastActivityTime = timestamp; + } + } + + public void updateLastActivityTime() { + this.lastActivityTime = System.currentTimeMillis(); + } + + /** + * session 标记为驱逐 + */ + public void setMarkedForEviction() { + this.markedForEviction = true; + this.frozen = true; + } + + /** + * 设置超时时间 + * @param idleTime + */ + public void setTimeout(int idleTime) { + this.timeout = idleTime; + } + + /** + * 设置服务器内部属性 + * @param key + * @param property + */ + public void setSystemProperty(String key, Object property) { + this.systemProperties.put(key, property); + } + + /** + * 设置session 类型 + * @param type + */ + public void setType(SessionType type) { + this.type = type; + + if (type == SessionType.VOID) { + this.clientIpAddress = NO_IP; + this.clientPort = 0; + } + } + + /** + * 获取丢包数量 + * @return + */ + public int getDroppedMessages() { + return this.droppedMessages; + } + + /** + * 统计丢包数量 + */ + public void addDroppedMessages(int amount) { + this.droppedMessages += amount; + } + + /** + * session 是否被冻结 + * @return + */ + public boolean isFrozen() { + return this.frozen; + } + + /** + * 关闭session + * @throws IOException + */ + public void close() throws IOException { + this.packetQueue = null; + this.frozen = true; + try { + if(connection!=null) { + connection.close(); + } + } finally { + connected = false; + SessionManager.getInstance().removeSession(this); + } + } + + public String toString() { + return String.format("{ Id: %s, Type: %s, IP: %s }", id + (hashId!=null ? ("[" + this.hashId + "]") : ""), type, getFullIpAddress()); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Session)) { + return false; + } + boolean isEqual = false; + Session session = (Session) obj; + + if (session.getId() == this.id) { + isEqual = true; + } + return isEqual; + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java b/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java new file mode 100644 index 0000000..3e0b480 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java @@ -0,0 +1,17 @@ +package com.taurus.permanent.data; + +/** + * session 类型 + * + */ +public enum SessionType{ + /** + * 普通 tcp udp 长链接 + */ + NORMAL, + /** + * websocket 长链接 + */ + WEBSOCKET, + VOID +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java new file mode 100644 index 0000000..9309052 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java @@ -0,0 +1,242 @@ +package com.taurus.permanent.io; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 协议包字节流解析 + * + */ +public class BinaryIoHandler { + + private static final int INT_SIZE = 4; + private final Logger log; + private final BitSwarmEngine engine; + private volatile long packetsRead = 0L; + private volatile long droppedIncomingPackets = 0L; + private final int maxPacketSize; + + public BinaryIoHandler(IOHandler parentHandler) { + this.log = Logger.getLogger(getClass()); + this.engine = BitSwarmEngine.getInstance(); + this.maxPacketSize = engine.getConfig().maxPacketSize; + } + + public long getReadPackets() { + return this.packetsRead; + } + + public long getIncomingDroppedPackets() { + return this.droppedIncomingPackets; + } + + public void handleWrite(Packet packet) throws Exception { + engine.getProtocolHandler().onPacketWrite(packet); + int protocolCompressionThreshold = TPServer.me().getConfig().protocolCompression; + byte[] binData = null; + try { + binData = ((TObject)packet.getData()).toBinary(); + } catch (Exception e) { + log.error(e); + log.error(((TObject)packet.getData()).toString()); + log.error(((TObject)packet.getData()).toJson()); + return; + } + boolean compression = binData.length > protocolCompressionThreshold; + if(compression) { + binData = Utils.compress(binData); + } + ByteBuffer packetBuffer = ByteBuffer.allocate(INT_SIZE + 1 + binData.length); + packetBuffer.put(compression?(byte)1:(byte)0); + packetBuffer.putInt(binData.length); + packetBuffer.put(binData); + packet.setData(packetBuffer.array()); + engine.getSocketWriter().enqueuePacket(packet); + } + + public void handleRead(Session session, byte[] data) { + + PacketReadState readState = (PacketReadState) session.getSystemProperty(Session.PACKET_READ_STATE); + try { + while (data.length > 0) { + if (readState == PacketReadState.WAIT_NEW_PACKET) { + ProcessedPacket process = handleNewPacket(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState == PacketReadState.WAIT_DATA_SIZE) { + ProcessedPacket process = handleDataSize(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState == PacketReadState.WAIT_DATA_SIZE_FRAGMENT) { + ProcessedPacket process = handleDataSizeFragment(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState != PacketReadState.WAIT_DATA) + continue; + ProcessedPacket process = handlePacketData(session, data); + readState = process.getState(); + data = process.getData(); + } + + } catch (Exception err) { + this.log.error(err); + readState = PacketReadState.WAIT_NEW_PACKET; + } + + session.setSystemProperty(Session.PACKET_READ_STATE, readState); + } + + private ProcessedPacket handleNewPacket(Session session, byte[] data) { + PendingPacket pp = new PendingPacket(); + pp.compressed = data[0] > 0; + session.setSystemProperty(Session.DATA_BUFFER, pp); + data = Utils.resizeByteArray(data, 1, data.length - 1); + return new ProcessedPacket(PacketReadState.WAIT_DATA_SIZE, data); + } + + private ProcessedPacket handleDataSize(Session session, byte[] data) { + PacketReadState state = PacketReadState.WAIT_DATA; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + int dataSize = -1; + int sizeBytes = INT_SIZE; + + if (data.length >= INT_SIZE) { + dataSize = 0; + for (int i = 0; i < INT_SIZE; i++) { + int pow256 = (int) Math.pow(256.0D, 3 - i); + int intByte = data[i] & 0xFF; + dataSize += pow256 * intByte; + } + } + + if (dataSize != -1) { + validateIncomingDataSize(session, dataSize); + pending.setExpectedLen(dataSize); + pending.setBuffer(ByteBuffer.allocate(dataSize)); + data = Utils.resizeByteArray(data, sizeBytes, data.length - sizeBytes); + } else { + state = PacketReadState.WAIT_DATA_SIZE_FRAGMENT; + ByteBuffer sizeBuffer = ByteBuffer.allocate(INT_SIZE); + sizeBuffer.put(data); + pending.setBuffer(sizeBuffer); + data = new byte[0]; + } + return new ProcessedPacket(state, data); + } + + private ProcessedPacket handleDataSizeFragment(Session session, byte[] data) { + PacketReadState state = PacketReadState.WAIT_DATA_SIZE_FRAGMENT; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + ByteBuffer sizeBuffer = (ByteBuffer) pending.getBuffer(); + + int remaining = INT_SIZE - sizeBuffer.position(); + + if (data.length >= remaining) { + sizeBuffer.put(data, 0, remaining); + sizeBuffer.flip(); + int dataSize = sizeBuffer.getInt(); + + validateIncomingDataSize(session, dataSize); + pending.setExpectedLen(dataSize); + pending.setBuffer(ByteBuffer.allocate(dataSize)); + state = PacketReadState.WAIT_DATA; + + if (data.length > remaining) + data = Utils.resizeByteArray(data, remaining, data.length - remaining); + else { + data = new byte[0]; + } + + } else { + sizeBuffer.put(data); + data = new byte[0]; + } + + return new ProcessedPacket(state, data); + } + + private ProcessedPacket handlePacketData(Session session, byte[] data) throws Exception { + PacketReadState state = PacketReadState.WAIT_DATA; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + ByteBuffer dataBuffer = (ByteBuffer) pending.getBuffer(); + int readLen = dataBuffer.remaining(); + boolean isThereMore = data.length > readLen; + + if (data.length >= readLen) { + dataBuffer.put(data, 0, readLen); + + if (pending.getExpectedLen() != dataBuffer.capacity()) { + throw new IllegalStateException("Expected: " + pending.getExpectedLen() + ", Buffer size: " + dataBuffer.capacity()); + } + final byte[] tembytes = dataBuffer.array(); + final boolean compressed = pending.compressed; + dispatchRequest(session,tembytes,compressed); + this.packetsRead += 1L; + state = PacketReadState.WAIT_NEW_PACKET; + + } else { + dataBuffer.put(data); + } + + if (isThereMore) + data = Utils.resizeByteArray(data, readLen, data.length - readLen); + else { + data = new byte[0]; + } + return new ProcessedPacket(state, data); + } + + + private void dispatchRequest(Session session, byte[] data,boolean compressed) { + if(compressed) { + try { + data = Utils.uncompress(data); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + ITObject requestObject = TObject.newFromBinaryData(data); + Packet newPacket = new Packet(); + newPacket.setSender(session); + newPacket.setData(requestObject); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + /** + * 验证字节流数据大小 + * @param session + * @param dataSize + */ + private void validateIncomingDataSize(Session session, int dataSize) { + String who = session.toString(); + + if (dataSize < 1) { + this.droppedIncomingPackets += 1L; + throw new IllegalArgumentException("Illegal request size: " + dataSize + " bytes, from: " + who); + } + + if (dataSize > this.maxPacketSize) { + TPServer.me().getController().disconnect(session); + this.droppedIncomingPackets += 1L; + + throw new IllegalArgumentException(String.format("Incoming request size too large: %s, Current limit: %s, From: %s", dataSize, this.maxPacketSize, who)); + } + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java new file mode 100644 index 0000000..6ad430c --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java @@ -0,0 +1,73 @@ +package com.taurus.permanent.io; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 读写网络字节流 + * + */ +public class IOHandler { + private final BinaryIoHandler binHandler; + private final Logger logger; + + public IOHandler() { + logger = Logger.getLogger(getClass()); + binHandler = new BinaryIoHandler(this); + + } + + /** + * 读取网络包字节流 + * @param session + * @param data + */ + public void onDataRead(Session session, byte[] data) { + if ((data == null) || (data.length < 1)) { + throw new IllegalArgumentException("Unexpected null or empty byte array!"); + } + + PacketReadState readState = (PacketReadState) session.getSystemProperty(Session.PACKET_READ_STATE); + if(readState==null){ + if (data[0] == 60) { + return; + } + session.setSystemProperty(Session.PACKET_READ_STATE, PacketReadState.WAIT_NEW_PACKET); + } + + binHandler.handleRead(session, data); + } + + /** + * 数据写入网络字节流,发送给指定客户端 + * @param packet + */ + public void onDataWrite(Packet packet) { + if (packet.getRecipients().size() > 0) { + try { + this.binHandler.handleWrite(packet); + } catch (Exception e) { + logger.error(e); + } + } + } + + /** + * 统计丢包数量 + * @return + */ + public long getReadPackets() { + return binHandler.getReadPackets(); + } + + /** + * 统计丢包数量 + * @return + */ + public long getIncomingDroppedPackets() { + return binHandler.getIncomingDroppedPackets(); + } + + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java new file mode 100644 index 0000000..6bcdbad --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java @@ -0,0 +1,21 @@ +package com.taurus.permanent.io; + +/** + * PacketReadState + * + */ +public enum PacketReadState { + /** + * 等待新包读取 + */ + WAIT_NEW_PACKET, + /** + * 等待读取包大小 + */ + WAIT_DATA_SIZE, + /** + * 等待读取碎片包 + */ + WAIT_DATA_SIZE_FRAGMENT, + WAIT_DATA; +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java new file mode 100644 index 0000000..6b6a059 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java @@ -0,0 +1,37 @@ +package com.taurus.permanent.io; + +/** + * PendingPacket + * + */ +public class PendingPacket { + private Object buffer; + private int expectedLen = -1; + public boolean compressed; + + public PendingPacket() { + + } + + + + public Object getBuffer() { + return buffer; + } + + public void setBuffer(Object buffer) { + this.buffer = buffer; + } + + public int getExpectedLen() { + return this.expectedLen; + } + + public void setExpectedLen(int len) { + this.expectedLen = len; + } + + public String toString() { + return buffer.toString(); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java new file mode 100644 index 0000000..741e0e3 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java @@ -0,0 +1,23 @@ +package com.taurus.permanent.io; + +/** + * ProcessedPacket + * + */ +public class ProcessedPacket { + private byte[] data; + private PacketReadState state; + + public ProcessedPacket(PacketReadState state, byte[] data) { + this.state = state; + this.data = data; + } + + public byte[] getData() { + return data; + } + + public PacketReadState getState() { + return state; + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java b/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java new file mode 100644 index 0000000..2a3e4f9 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java @@ -0,0 +1,42 @@ +package com.taurus.permanent.io; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Packet; + +/** + * ProtocolHandler + * + * + */ +public class ProtocolHandler { + private static final String ACTION_ID = "a"; + private static final String PARAM_ID = "p"; + + public void onPacketWrite(Packet packet) { + ITObject params = TObject.newInstance(); + params.putByte(ACTION_ID, (byte) packet.getId()); + params.putTObject(PARAM_ID, (ITObject) packet.getData()); + packet.setData(params); + } + + public void onPacketRead(Packet packet) { + ITObject requestObject = (ITObject)packet.getData(); + if (requestObject.isNull(ACTION_ID)) { + throw new IllegalStateException("Request rejected: No Action ID in request!"); + } + if (requestObject.isNull(PARAM_ID)) { + throw new IllegalStateException("Request rejected: Missing parameters field!"); + } + + packet.setId(requestObject.getByte(ACTION_ID)); + if(requestObject.containsKey(PARAM_ID)) { + packet.setData(requestObject.getTObject(PARAM_ID)); + }else { + packet.setData(null); + } + + TPServer.me().getController().enqueueRequest(packet); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java b/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java new file mode 100644 index 0000000..1d3d67f --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java @@ -0,0 +1,71 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; + +import com.taurus.permanent.data.ISocketChannel; + +public class NormalSocketChannel implements ISocketChannel{ + private final SocketChannel channel; + + public NormalSocketChannel(SocketChannel channel) { + this.channel = channel; + } + @Override + public long write(ByteBuffer buffer) { + try { + return channel.write(buffer); + } catch (IOException e) { + return 0; + } + } + + @Override + public void write(String p0) { + // TODO Auto-generated method stub + + } + + @Override + public SocketAddress getRemoteAddress() { + if(checkConnection()) { + return channel.socket().getRemoteSocketAddress(); + } + return null; + } + + @Override + public SocketAddress getLocalAddress() { + if(checkConnection()) { + return channel.socket().getLocalSocketAddress(); + } + return null; + } + + @Override + public void close() throws IOException{ + Socket socket = channel.socket(); + if ((socket != null) && (!socket.isClosed())) { + socket.shutdownInput(); + socket.shutdownOutput(); + socket.close(); + channel.close(); + } + } + @Override + public Object getChannel() { + return channel; + } + + @Override + public boolean checkConnection() { + if((channel != null) && (channel.socket() != null) && (!channel.socket().isClosed())) { + return true; + } + return false; + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java new file mode 100644 index 0000000..e7ecc9d --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java @@ -0,0 +1,259 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.ConnectionFilter; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig.SocketAddress; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.BindableSocket; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +/** + * SocketAcceptor + * + * + */ +public class SocketAcceptor extends BaseCoreService implements Runnable { + private final BitSwarmEngine engine; + private final Logger logger; + private volatile int threadId = 1; + private int threadPoolSize = 1; + private final ExecutorService threadPool; + private LinkedList acceptableConnections; + private List boundSockets; + + private SessionManager sessionManager; + private SocketReader socketReader; + private Selector acceptSelector; + private volatile boolean isActive = false; + + public SocketAcceptor(int threadPoolSize) { + this.threadPoolSize = threadPoolSize; + + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(SocketAcceptor.class); + + threadPool = Executors.newFixedThreadPool(threadPoolSize); + + acceptableConnections = new LinkedList(); + boundSockets = new ArrayList(); + socketReader = engine.getSocketReader(); + + try { + acceptSelector = Selector.open(); + logger.info("AcceptSelector opened"); + } catch (IOException e) { + logger.warn("Problems during SocketAcceptor init: " + e); + logger.error(e); + } + } + + public void init(Object o) { + super.init(o); + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + if (threadPoolSize < 1) { + throw new IllegalArgumentException("Illegal value for a thread pool size: " + threadPoolSize); + } + sessionManager = engine.getSessionManager(); + + isActive = true; + initThreadPool(); + + logger.info("SocketAcceptor initialized (pool size:"+threadPoolSize+")"); + checkBoundSockets(); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + shutDownBoundSockets(); + + List leftOvers = threadPool.shutdownNow(); + try { + Thread.sleep(500L); + + acceptSelector.close(); + } catch (Exception e) { + logger.warn("Error when shutting down Accept selector: " + e.getMessage()); + } + + logger.info("SocketAcceptor stopped. Unprocessed tasks: " + leftOvers.size()); + } + + private void initThreadPool() { + for (int j = 0; j < threadPoolSize; j++) + threadPool.execute(this); + } + + public void run() { + Thread.currentThread().setName("SocketAcceptor-" + threadId++); + + while (isActive) { + try { + acceptLoop(); + } catch (IOException e) { + logger.info("I/O Error with Accept Selector: " + e.getMessage()); + logger.error(e); + } + } + + logger.info("SocketAcceptor threadpool shutting down."); + } + + private void acceptLoop() throws IOException { + acceptSelector.select(); + List _list = null; + synchronized (acceptSelector) { + Set readyKeys = acceptSelector.selectedKeys(); + _list = new ArrayList(readyKeys); + readyKeys.clear(); + } + + for (SelectionKey key : _list) { + try { + ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel(); + SocketChannel clientChannel = ssChannel.accept(); + synchronized (acceptableConnections) { + acceptableConnections.addLast(clientChannel); + } + } catch (IOException error) { + logger.info("I/O Error during accept loop: " + error.getMessage()); + } + } + + if (isActive) + socketReader.getSelector().wakeup(); + } + + public void handleAcceptableConnections() { + if (acceptableConnections.size() == 0) { + return; + } + SocketChannel connection = null; + synchronized (acceptableConnections) { + connection = acceptableConnections.removeFirst(); + } + if (connection == null) + return; + ConnectionFilter connectionFilter = engine.getConnectionFilter(); + + try { + Socket socket = connection.socket(); + InetAddress iAddr = null; + if (socket != null && !socket.isClosed()) { + iAddr = socket.getInetAddress(); + } + if (iAddr == null) { + handleAcceptableConnections(); + return; + } + if (!connectionFilter.validateAndAddAddress(iAddr.getHostAddress())) { + try { + connection.socket().shutdownInput(); + connection.socket().shutdownOutput(); + connection.close(); + } catch (IOException e1) { + logger.warn("Additional problem with refused connection. Was not able to shut down the channel: " + e1.getMessage()); + } + handleAcceptableConnections(); + return; + } + connection.configureBlocking(false); + connection.socket().setTcpNoDelay(engine.getConfig().tcpNoDelay); + + SelectionKey selectionKey = connection.register(socketReader.getSelector(), SelectionKey.OP_READ); + Session session = sessionManager.createSession(new NormalSocketChannel(connection), SessionType.NORMAL); + session.setSystemProperty(DefaultConstants.SESSION_SELECTION_KEY, selectionKey); + sessionManager.addSession(session); + } catch (IOException e) { + StringBuilder sb = new StringBuilder("Failed accepting connection: "); + + if ((connection != null) && (connection.socket() != null)) { + sb.append(connection.socket().getInetAddress().getHostAddress()); + } + logger.info(sb.toString()); + } + handleAcceptableConnections(); + } + + public void bindSocket(SocketAddress socketConfig) throws IOException { + if (socketConfig.type.equalsIgnoreCase(SocketAddress.TYPE_TCP)) { + bindTcpSocket(socketConfig.address, socketConfig.port); + } else + throw new UnsupportedOperationException("Invalid transport type!"); + } + + public List getBoundSockets() { + ArrayList list = null; + + synchronized (boundSockets) { + list = new ArrayList(boundSockets); + } + + return list; + } + + private void bindTcpSocket(String address, int port) throws IOException { + ServerSocketChannel socketChannel = ServerSocketChannel.open(); + socketChannel.configureBlocking(false); + socketChannel.socket().bind(new InetSocketAddress(address, port)); + socketChannel.socket().setReuseAddress(true); + socketChannel.register(acceptSelector, SelectionKey.OP_ACCEPT); + + synchronized (boundSockets) { + boundSockets.add(new BindableSocket(socketChannel, address, port)); + } + + logger.info("Added bound tcp socket --> " + address + ":" + port); + } + + private void checkBoundSockets() { + if (boundSockets.size() < 1) + logger.error("No bound sockets! Check the boot logs for possible problems!"); + } + + private void shutDownBoundSockets() { + List problematicSockets = null; + + for (BindableSocket bindableSocket : boundSockets) { + try { + bindableSocket.getChannel().close(); + } catch (IOException e) { + if (problematicSockets == null) { + problematicSockets = new ArrayList(); + } + problematicSockets.add(bindableSocket); + } + } + + if (problematicSockets != null) { + StringBuilder sb = new StringBuilder("Problems closing bound socket(s). The following socket(s) raised exceptions: "); + + for (BindableSocket socket : problematicSockets) { + sb.append(socket.toString()).append(" "); + } + throw new RuntimeException(sb.toString()); + } + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java new file mode 100644 index 0000000..d4d3a16 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java @@ -0,0 +1,233 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.taurus.core.util.FixedIndexThreadPool; +import com.taurus.core.util.FixedIndexThreadPool.Work; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.io.IOHandler; + +/** + * SocketReader + * + * + */ +public class SocketReader extends BaseCoreService implements Runnable { + private final BitSwarmEngine engine; + private final Logger logger; + private int threadPoolSize = 1; + private ExecutorService threadPool; + private FixedIndexThreadPool packetReaderPool; + private SessionManager sessionManager; + private SocketAcceptor socketAcceptor; + private SocketWriter socketWriter; + private Selector readSelector; + private IOHandler ioHandler; + private volatile boolean isActive = false; + private volatile long readBytes = 0L; + + public SocketReader(int nThreads) { + threadPoolSize = nThreads; + + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(getClass()); + try { + readSelector = Selector.open(); + logger.info("TCP Selector opened"); + } catch (IOException e) { + logger.error("Failed opening UDP Selector: " + e.toString()); + e.printStackTrace(); + } + } + + public void init(Object o) { + super.init(o); + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + sessionManager = engine.getSessionManager(); + socketAcceptor = engine.getSocketAcceptor(); + socketWriter = engine.getSocketWriter(); + isActive = true; + initThreadPool(); + + logger.info("SocketReader started (pool size:"+threadPoolSize+")"); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + List leftOvers = threadPool.shutdownNow(); + int pr_count = packetReaderPool.shutdown(); + try { + Thread.sleep(500L); + readSelector.close(); + } catch (Exception e) { + logger.warn("Error when shutting down TCP Selector: " + e.getMessage()); + logger.error(e); + } + + logger.info("SocketReader stopped. Unprocessed tasks: " + leftOvers.size()); + logger.info("PacketReader stopped. Unprocessed tasks: " + pr_count); + } + + public void initThreadPool() { + threadPool = Executors.newSingleThreadExecutor(); + threadPool.execute(this); + packetReaderPool = new FixedIndexThreadPool(threadPoolSize, "PacketReader", PacketReaderWork.class); + } + + public void run() { + Thread.currentThread().setName("SocketReader"); + + while (isActive) { + try { + socketAcceptor.handleAcceptableConnections(); + readIncomingSocketData(); + + Thread.sleep(5L); + } catch (Throwable t) { + logger.warn("Problems in SocketReader main loop: " + t + ", Thread: " + Thread.currentThread()); + logger.error(t); + } + } + + logger.info("SocketReader threadpool shutting down."); + } + + private void readIncomingSocketData() { + SocketChannel channel = null; + SelectionKey key = null; + try { + int readyKeyCount = readSelector.selectNow(); + + if (readyKeyCount > 0) { + Set readyKeys = readSelector.selectedKeys(); + + for (Iterator it = readyKeys.iterator(); it.hasNext();) { + key = (SelectionKey) it.next(); + it.remove(); + + if (!key.isValid()) { + continue; + } + channel = (SocketChannel) key.channel(); + Session session = sessionManager.getSessionByConnection(channel); + packetReaderPool.execute(session.getId(), session); + } + } + + } catch (ClosedSelectorException e) { + logger.debug("Selector is closed!"); + } catch (CancelledKeyException localCancelledKeyException) { + } catch (IOException ioe) { + logger.warn("I/O reading/selection error: " + ioe); + logger.error(ioe); + } catch (Exception err) { + logger.warn("Generic reading/selection error: " + err); + logger.error(err); + } + } + + private void readTcpData(Session session,SocketChannel channel, ByteBuffer readBuffer) throws IOException { + SelectionKey key = (SelectionKey) session.getSystemProperty(DefaultConstants.SESSION_SELECTION_KEY); + if (!key.isValid()) { + return; + } + if (key.isWritable()) { + key.interestOps(SelectionKey.OP_READ); + socketWriter.continueWriteOp(session); + } + if (!key.isReadable()) { + return; + } + readBuffer.clear(); + long byteCount = channel.read(readBuffer); + + if (byteCount == -1L) { + closeConnection(channel); + } else if (byteCount > 0L) { + session.setLastReadTime(System.currentTimeMillis()); + readBytes += byteCount; + session.addReadBytes(byteCount); + readBuffer.flip(); + byte[] binaryData = new byte[readBuffer.limit()]; + readBuffer.get(binaryData); + ioHandler.onDataRead(session, binaryData); + } + } + + private void closeConnection(SelectableChannel channel) throws IOException { + channel.close(); + if (channel instanceof SocketChannel) + sessionManager.onSocketDisconnected(channel); + } + + public IOHandler getIOHandler() { + return ioHandler; + } + + public Selector getSelector() { + return readSelector; + } + + public void setIoHandler(IOHandler handler) { + if (handler == null) { + throw new IllegalStateException("IOHandler si already set!"); + } + ioHandler = handler; + } + + public long getReadBytes() { + return readBytes; + } + + public long getReadPackets() { + return ioHandler.getReadPackets(); + } + + public static final class PacketReaderWork extends Work { + private ByteBuffer readBuffer; + private BitSwarmEngine engine; + private SocketReader reader; + + public PacketReaderWork() { + engine = BitSwarmEngine.getInstance(); + reader = (SocketReader) engine.getSocketReader(); + readBuffer = Utils.allocateBuffer(engine.getConfig().maxReadBufferSize, engine.getConfig().readBufferType); + } + + @Override + protected void handlerTask(Object task) throws Exception { + Session session = (Session) task; + SocketChannel channel = (SocketChannel) session.getConnection().getChannel(); + ByteBuffer buffer = ByteBuffer.allocate(1024); + buffer = (ByteBuffer) buffer.clear(); // 显式转换 + + try { + reader.readTcpData(session,channel, readBuffer); + } catch (IOException e) { + reader.closeConnection(channel); + } + } + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java new file mode 100644 index 0000000..c256e63 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java @@ -0,0 +1,278 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SelectionKey; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.data.IPacketQueue; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; +import com.taurus.permanent.io.IOHandler; + +/** + * SocketWriter + * + * + */ +public final class SocketWriter extends BaseCoreService implements Runnable { + private BitSwarmEngine engine; + private IOHandler ioHandler; + private final Logger logger; + private final ExecutorService threadPool; + private final BlockingQueue sessionTicketsQueue; + private volatile int threadId = 1; + private volatile boolean isActive = false; + private volatile long droppedPacketsCount = 0L; + private volatile long writtenBytes = 0L; + private volatile long writtenPackets = 0L; + private int threadPoolSize; + + public SocketWriter(int threadPoolSize) { + this.threadPoolSize = threadPoolSize; + + threadPool = Executors.newFixedThreadPool(threadPoolSize); + logger = Logger.getLogger(SocketWriter.class); + + sessionTicketsQueue = new LinkedBlockingQueue(); + } + + public void init(Object o) { + super.init(o); + + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + if (threadPoolSize < 1) { + throw new IllegalArgumentException("Illegal value for a thread pool size: " + threadPoolSize); + } + engine = BitSwarmEngine.getInstance(); + isActive = true; + + initThreadPool(); + + logger.info("Socket Writer started (pool size:" + threadPoolSize + ")"); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + List leftOvers = threadPool.shutdownNow(); + logger.info("SocketWriter stopped. Unprocessed tasks: " + leftOvers.size()); + } + + public int getQueueSize() { + return sessionTicketsQueue.size(); + } + + public int getThreadPoolSize() { + return threadPoolSize; + } + + public IOHandler getIOHandler() { + return ioHandler; + } + + public void setIOHandler(IOHandler ioHandler) { + if (this.ioHandler != null) { + throw new IllegalStateException("You cannot reassign the IOHandler class!"); + } + this.ioHandler = ioHandler; + } + + public void continueWriteOp(Session session) { + if (session != null) + sessionTicketsQueue.add(session); + } + + private void initThreadPool() { + for (int j = 0; j < threadPoolSize; j++) + threadPool.execute(this); + } + + public void run() { + Thread.currentThread().setName("SocketWriter-" + threadId++); + + ServerConfig setting = TPServer.me().getConfig(); + ByteBuffer writeBuffer = Utils.allocateBuffer(setting.maxWriteBufferSize, setting.writeBufferType); + + while (isActive) { + try { + Session session = sessionTicketsQueue.take(); + processSessionQueue(writeBuffer, session); + } catch (InterruptedException e) { + logger.warn("SocketWriter thread interrupted: " + Thread.currentThread()); + isActive = false; + } catch (Throwable t) { + logger.warn("Problems in SocketWriter main loop, Thread: " + Thread.currentThread()); + logger.error(t); + } + } + + logger.info("SocketWriter threadpool shutting down."); + } + + private void processSessionQueue(ByteBuffer writeBuffer, Session session) { + if (session != null) { + SessionType type = session.getType(); + + if (type == SessionType.NORMAL) { + processRegularSession(writeBuffer, session); + }else if (type == SessionType.VOID) + return; + } + } + + private void processRegularSession(ByteBuffer writeBuffer, Session session) { + if (session.isFrozen()) { + return; + } + Packet packet = null; + try { + IPacketQueue sessionQ = session.getPacketQueue(); + + synchronized (sessionQ) { + if (!sessionQ.isEmpty()) { + packet = sessionQ.peek(); + + if (packet == null) { + return; + } + tcpSend(writeBuffer, sessionQ, session, packet); + } + } + + } catch (ClosedChannelException cce) { + logger.debug("Socket closed during write operation for session: " + session); + } catch (IOException localIOException) {} catch (Exception e) { + logger.warn("Error during write. Session: " + session); + logger.error(e); + } + } + + private void tcpSend(ByteBuffer writeBuffer, IPacketQueue sessionQ, Session session, Packet packet) throws Exception { + ISocketChannel channel = session.getConnection(); + if (channel == null) { + logger.debug("Skipping packet, found null socket for Session: " + session); + return; + } +// buffer = (ByteBuffer) buffer.clear(); // 强制转换 + + writeBuffer=(ByteBuffer)writeBuffer.clear(); + + byte[] buffer = packet.isFragmented() ? packet.getFragmentBuffer() : (byte[]) packet.getData(); + if (writeBuffer.capacity() < buffer.length) { + writeBuffer = Utils.allocateBuffer(buffer.length, engine.getConfig().writeBufferType); + } + writeBuffer.put(buffer); + writeBuffer.flip(); + + long toWrite = writeBuffer.remaining(); + + long bytesWritten = channel.write(writeBuffer); + if(bytesWritten == 0)throw new IOException("Written Bytes excetion!"); + + writtenBytes += bytesWritten; + session.addWrittenBytes(bytesWritten); + if (bytesWritten < toWrite) { + byte[] bb = new byte[writeBuffer.remaining()]; + writeBuffer.get(bb); + packet.setFragmentBuffer(bb); + + SelectionKey sk = (SelectionKey) session.getSystemProperty(DefaultConstants.SESSION_SELECTION_KEY); + if ((sk != null) && (sk.isValid())) { + sk.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); + } else { + logger.warn("Could not OP_WRITE for Session: " + session + ", written bytes: " + bytesWritten); + } + } else { + writtenPackets += 1L; + + sessionQ.take(); + if (!sessionQ.isEmpty()) { + sessionTicketsQueue.add(session); + } + } + } + + public void enqueuePacket(Packet packet) { + enqueueLocal(packet); + } + + private void enqueueLocal(Packet packet) { + Collection recipients = packet.getRecipients(); + int size = recipients.size(); + + if ((recipients != null) && (size > 0)) { + if (packet.getSender() != null) { + packet.getSender().setLastWriteTime(System.currentTimeMillis()); + } + if (size == 1) { + enqueueLocalPacket((Session) packet.getRecipients().iterator().next(), packet); + } else + for (Session session : recipients) { + enqueueLocalPacket(session, packet.clone()); + } + } + } + + private void enqueueLocalPacket(Session session, Packet packet) { + IPacketQueue sessionQ = session.getPacketQueue(); + + if (sessionQ != null) { + synchronized (sessionQ) { + try { + boolean wasEmpty = sessionQ.isEmpty(); + + sessionQ.put(packet); + + if ((wasEmpty)) { + sessionTicketsQueue.add(session); + } + + packet.setRecipients(null); + } catch (Exception error) { + dropOneMessage(session); + } + } + } + } + + /** + * 丢包处理 + * @param session + */ + private void dropOneMessage(Session session) { + session.addDroppedMessages(1); + droppedPacketsCount += 1L; + } + + public long getDroppedPacketsCount() { + return droppedPacketsCount; + } + + + public long getWrittenBytes() { + return writtenBytes; + } + + public long getWrittenPackets() { + return writtenPackets; + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java b/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java new file mode 100644 index 0000000..07cdf74 --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java @@ -0,0 +1,82 @@ +package com.taurus.permanent.util; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.core.SystemController; +import com.taurus.permanent.data.Session; + +import java.util.ArrayList; +import java.util.List; + +/** + * GhostUserHunter + * + * + * + */ +public class GhostUserHunter { + private static final String EOL = System.getProperty("line.separator"); + private final TPServer taurus; + private SessionManager sm; + private SystemController controller; + private final Logger log; + private static final int TOT_CYCLES = 2; + private int cycleCounter = 0; + + public GhostUserHunter() { + taurus = TPServer.me(); + this.controller = TPServer.me().getController(); + log = Logger.getLogger(getClass()); + } + + public void hunt() { + if (sm == null) { + sm = taurus.getSessionManager(); + } + + if (++cycleCounter < TOT_CYCLES) { + return; + } + cycleCounter = 0; + + List ghosts = searchGhosts(); + if (ghosts.size() > 0) { + log.info(buildReport(ghosts)); + } + + for (Session ghost : ghosts) + controller.disconnect(ghost); + } + + private List searchGhosts() { + List allUsers = taurus.getSessionManager().getAllSessions(); + List ghosts = new ArrayList(); + + for (Session u : allUsers) { + Session sess = u; + + if ((!sm.containsSession(sess)) || (sess.isIdle()) || (sess.isMarkedForEviction())) { + ghosts.add(u); + } + } + return ghosts; + } + + private String buildReport(List ghosts) { + StringBuilder sb = new StringBuilder("GHOST REPORT"); + sb.append(EOL).append("Total ghosts: ").append(ghosts.size()).append(EOL); + + for (Session ghost : ghosts) { + Session ss = ghost; + + if (ss == null) { + sb.append(ghost.getId()).append(", ").append(" -> Null session").append(", SessionById: ").append(this.sm.getSessionById(ghost.getId())); + } else { + sb.append(ghost.getId()).append(", ").append(", Connected: ").append(ss.isConnected()).append(", Idle: ").append(ss.isIdle()).append(", Marked: ") + .append(ss.isMarkedForEviction()).append(", Frozen: ").append(ss.isFrozen()).append(", SessionById: ").append(this.sm.getSessionById(ghost.getId())); + } + } + return sb.toString(); + } +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java b/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java new file mode 100644 index 0000000..13e363a --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java @@ -0,0 +1,56 @@ +package com.taurus.permanent.websocket; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.ByteBuffer; + +import com.taurus.permanent.data.ISocketChannel; + +import io.undertow.websockets.core.WebSocketChannel; +import io.undertow.websockets.core.WebSockets; + +public class UndertowWebSocketChannel implements ISocketChannel{ + + private WebSocketChannel channel; + + public UndertowWebSocketChannel (WebSocketChannel channel) { + this.channel = channel; + } + + @Override + public long write(ByteBuffer buffer) { + return 0; + } + + @Override + public void write(String message) { + WebSockets.sendText(message, channel, null); + } + + @Override + public SocketAddress getRemoteAddress() { + return channel.getPeerAddress(); + } + + @Override + public SocketAddress getLocalAddress() { + return channel.getLocalAddress(); + } + + @Override + public void close() throws IOException{ + channel.close(); + } + + @Override + public Object getChannel() { + return channel; + } + + @Override + public boolean checkConnection() { + if(channel!=null&&channel.isOpen())return true; + return false; + } + +} diff --git a/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java b/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java new file mode 100644 index 0000000..b932a4b --- /dev/null +++ b/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java @@ -0,0 +1,195 @@ +package com.taurus.permanent.websocket; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.PackDataType; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.websockets.WebSocketConnectionCallback; +import io.undertow.websockets.core.AbstractReceiveListener; +import io.undertow.websockets.core.BufferedBinaryMessage; +import io.undertow.websockets.core.BufferedTextMessage; +import io.undertow.websockets.core.CloseMessage; +import io.undertow.websockets.core.WebSocketChannel; +import io.undertow.websockets.core.WebSockets; +import io.undertow.websockets.spi.WebSocketHttpExchange; + +/** + * WebSocket service + * + * + */ +public class WebSocketService extends BaseCoreService{ + private Undertow server; + private final BitSwarmEngine engine; + private SessionManager sessionManager; + private Logger logger; + + public WebSocketService() { + engine = BitSwarmEngine.getInstance(); + sessionManager = engine.getSessionManager(); + logger = Logger.getLogger(WebSocketService.class); + } + + public void init(Object o) { + super.init(o); + WSConnectionListener listener = new WSConnectionListener(this); + ServerConfig config = TPServer.me().getConfig(); + server = Undertow.builder().addHttpListener(config.webSocketConfig.port, config.webSocketConfig.address) + .setHandler(Handlers.path().addPrefixPath("/websocket", Handlers.websocket(listener))) + .build(); + server.start(); + logger.info("Websocket listen --> "+config.webSocketConfig.address+":"+config.webSocketConfig.port); + logger.info("Websocket service start!"); + } + + public void destroy(Object o) { + super.destroy(o); + server.stop(); + server = null; + logger.info("Websocket service shutdown!"); + } + + private void openAction(WebSocketChannel channel) { + Session session = sessionManager.createSession(new UndertowWebSocketChannel(channel), SessionType.WEBSOCKET); + sessionManager.addSession(session); + } + + private void readTextAction(WebSocketChannel channel,String data) { + Session session = sessionManager.getSessionByConnection(channel); + Packet newPacket = new Packet(); + newPacket.setDataType(PackDataType.TEXT); + newPacket.setSender(session); + ITObject requestObject = TObject.newFromJsonData(data); + newPacket.setData(requestObject); + session.setLastReadTime(System.currentTimeMillis()); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + private void readBinaryAction(WebSocketChannel channel,ByteBuffer data) { + Session session = sessionManager.getSessionByConnection(channel); + Packet newPacket = new Packet(); + newPacket.setDataType(PackDataType.BINARY); + boolean compressed = data.get() >0; + byte[] bytes = new byte[data.remaining()]; + data.get(bytes); + if(compressed) { + try { + bytes = Utils.uncompress(bytes); + } catch (IOException e) { + logger.error(e); + return; + } + } + newPacket.setSender(session); + ITObject requestObject = TObject.newFromBinaryData(bytes); + newPacket.setData(requestObject); + session.setLastReadTime(System.currentTimeMillis()); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + + /** + * send packet + */ + public void onDataWrite(Packet packet){ + if (packet.getRecipients().size() > 0) { + packet.setDataType(PackDataType.BINARY); + engine.getProtocolHandler().onPacketWrite(packet); + int protocolCompressionThreshold = TPServer.me().getConfig().protocolCompression; + byte[] binData = ((TObject)packet.getData()).toBinary(); + boolean compression = binData.length > protocolCompressionThreshold; + if(compression) { + try { + binData = Utils.compress(binData); + } catch (IOException e) { + logger.error(e); + return; + } + } + ByteBuffer writeBuffer = ByteBuffer.allocate(1 + binData.length); + writeBuffer.put(compression?(byte)1:(byte)0); + writeBuffer.put(binData); + writeBuffer.flip(); + for (final Session session : packet.getRecipients()) { + session.setLastWriteTime(System.currentTimeMillis()); + final ISocketChannel channel = session.getConnection(); + WebSockets.sendBinary(writeBuffer, (WebSocketChannel)channel.getChannel(), null); + } + } + } + + private void closeAction(WebSocketChannel channel) { + try { + sessionManager.onSocketDisconnected(channel); + } catch (IOException e) { + throw new RuntimeException("WebSocket Disconnected exception!",e); + } + } + + private static final class WSConnectionListener implements WebSocketConnectionCallback{ + private WSListener listener; + private WebSocketService wsService; + + public WSConnectionListener(WebSocketService wsService) { + this.wsService = wsService; + this.listener = new WSListener(wsService); + } + + @Override + public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) { + channel.getReceiveSetter().set(this.listener); + channel.resumeReceives(); + wsService.openAction(channel); + } + + } + + private static final class WSListener extends AbstractReceiveListener{ + private WebSocketService wsService; + + public WSListener(WebSocketService wsService) { + this.wsService = wsService; + } + + @Override + protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) { + wsService.readTextAction(channel, message.getData()); + } + + + protected void onCloseMessage(CloseMessage cm, WebSocketChannel channel) { + wsService.closeAction(channel); + } + + protected void onFullPingMessage(final WebSocketChannel channel, BufferedBinaryMessage message) throws IOException { + super.onFullBinaryMessage(channel, message); + } + + protected void onFullBinaryMessage(final WebSocketChannel channel, BufferedBinaryMessage message) throws IOException { + ByteBuffer[] bufferList= message.getData().getResource(); + for (ByteBuffer tem : bufferList) { + wsService.readBinaryAction(channel, tem); + } + message.getData().free(); + } + + } + + +} diff --git a/taurus-permanent/src/test/java/com/taurus/T1Controller.java b/taurus-permanent/src/test/java/com/taurus/T1Controller.java new file mode 100644 index 0000000..1e9cba6 --- /dev/null +++ b/taurus-permanent/src/test/java/com/taurus/T1Controller.java @@ -0,0 +1,16 @@ +package com.taurus; + +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +public class T1Controller implements IController{ + + @ActionKey("test") + public void test(Session sender,TObject params,int gid) { + System.out.println("t1 test"); + TPServer.me().getController().sendResponse(gid, 0, params, sender); + } +} diff --git a/taurus-permanent/src/test/java/com/taurus/T2Controller.java b/taurus-permanent/src/test/java/com/taurus/T2Controller.java new file mode 100644 index 0000000..82b8e99 --- /dev/null +++ b/taurus-permanent/src/test/java/com/taurus/T2Controller.java @@ -0,0 +1,22 @@ +package com.taurus; + +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +public class T2Controller implements IController{ + + @ActionKey("test") + public void test(Session sender,TObject params,int gid) { + System.out.println("t1 test"); + TPServer.me().getController().sendResponse(gid, 0, params, sender); + } + + @ActionKey("test1") + public void test1(Session sender,TObject params,int gid) { + System.out.println("t2 test"); + TPServer.me().getController().sendResponse(gid, 1, params, sender); + } +} diff --git a/taurus-permanent/src/test/java/com/taurus/TestExtension.java b/taurus-permanent/src/test/java/com/taurus/TestExtension.java new file mode 100644 index 0000000..2fc031a --- /dev/null +++ b/taurus-permanent/src/test/java/com/taurus/TestExtension.java @@ -0,0 +1,43 @@ +package com.taurus; + +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; + +/** + * + * @version V2.9 + */ +public class TestExtension extends Extension{ + + public TestExtension() { + super(); +// login_cmd_map.put("req_test", true); + } + + @Override + public void configRoute(Routes me) { + me.add("t1", new T1Controller()); + me.add("t2", new T2Controller()); + } + +// @Override +// public void handleEvent(Event event) { +// if( event.getName() == TPEvents.EVENT_SESSION_DISCONNECT){ +// Session session = (Session) event.getParameter(TPEvents.PARAM_SESSION); +// logger.info("session:" + session.isIdle()); +// } +// +// } +// +// @Override +// protected void handlerRequest(Session sender, String cmdName, ITObject params, int gid) { +// // TODO Auto-generated method stub +// params.putInt("ttt", 1); +// sendResponse(gid, 0, params, sender); +// +// //api.disconnect(sender); +// } + + + +} diff --git a/taurus-server/pom.xml b/taurus-server/pom.xml new file mode 100644 index 0000000..50f6dca --- /dev/null +++ b/taurus-server/pom.xml @@ -0,0 +1,124 @@ + + + 4.0.0 + com.taurus + taurus-server + pom + 1.0.1 + taurus-server + + + UTF-8 + 1.8 + 1.8 + + + + taurus-permanent + taurus-web + taurus-core + + + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-permanent + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + junit + junit + 3.8.1 + test + + + + + + + + jdom + jdom + + + + + log4j + log4j + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + UTF-8 + + + + + + + + \ No newline at end of file diff --git a/taurus-server/taurus-core/config/log4j.properties b/taurus-server/taurus-core/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/taurus-server/taurus-core/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/taurus-server/taurus-core/config/taurus-core.xml b/taurus-server/taurus-core/config/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/taurus-server/taurus-core/config/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/taurus-server/taurus-core/pom.xml b/taurus-server/taurus-core/pom.xml new file mode 100644 index 0000000..570dfed --- /dev/null +++ b/taurus-server/taurus-core/pom.xml @@ -0,0 +1,117 @@ + + + 4.0.0 + + com.taurus + taurus-server + 1.0.1 + + jar + taurus-core + 1.0.1 + + + + + redis.clients + jedis + + + + + com.zaxxer + HikariCP + + + + + jdom + jdom + + + + + log4j + log4j + + + + + mysql + mysql-connector-java + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/*.properties + + + + + org.apache.maven.plugins + maven-source-plugin + 2.4 + + true + + + + compile + + jar + + + + + + + + + releases + Nexus Release Repository + http://192.168.1.236:8081/nexus/content/repositories/releases/ + + + snapshots + Nexus Snapshot Repository + http://192.168.1.236:8081/nexus/content/repositories/snapshots/ + + + + diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITArray.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITArray.java new file mode 100644 index 0000000..4426747 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITArray.java @@ -0,0 +1,83 @@ +package com.taurus.core.entity; + +import java.util.Iterator; + +/** + * object array interface + * + * + */ +public interface ITArray { + + public Iterator iterator(); + + public TDataWrapper get(int index); + + public void del(int index); + + public int size(); + + public void clear(); + + public byte[] toBinary(); + + public String toJson(); + + public void addNull(); + + public void addBool(boolean value); + + public void addByte(byte value); + + public void addShort(short value); + + public void addInt(int value); + + public void addLong(long value); + + public void addFloat(float value); + + public void addDouble(double value); + + public void addString(String value); + + public void addUtfString(String value); + + public void addByteArray(byte[] data); + + public void addTArray(ITArray array); + + public void addTObject(ITObject object); + + public void add(TDataWrapper wrapper); + + public boolean isNull(int index); + + public Boolean getBool(int index); + + public Byte getByte(int index); + + public Integer getUByte(int index); + + public Short getShort(int index); + + public Integer getInt(int index); + + public Long getLong(int index); + + public Float getFloat(int index); + + public Double getDouble(int index); + + public String getString(int index); + + public String getUtfString(int index); + + public byte[] getByteArray(int index); + + public ITArray getTArray(int index); + + public ITObject getTObject(int index); + + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITObject.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITObject.java new file mode 100644 index 0000000..d80bf4c --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/ITObject.java @@ -0,0 +1,87 @@ +package com.taurus.core.entity; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * object map interface + * + * + */ +public interface ITObject { + public boolean isNull(String key); + + public boolean containsKey(String key); + + public boolean remove(String key); + + public Set getKeys(); + + public int size(); + + public Iterator> iterator(); + + public byte[] toBinary(); + + public String toJson(); + + public TDataWrapper get(String key); + + public Boolean getBoolean(String key); + + public Byte getByte(String key); + + public Integer getUByte(String key); + + public Short getShort(String key); + + public Integer getInt(String key); + + public Long getLong(String key); + + public Float getFloat(String key); + + public Double getDouble(String key); + + public String getString(String key); + + public String getUtfString(String key); + + public byte[] getByteArray(String key); + + public ITArray getTArray(String key); + + public ITObject getTObject(String key); + + public void putNull(String key); + + public void putBoolean(String key, boolean value); + + public void putByte(String key, byte value); + + public void putShort(String key, short value); + + public void putInt(String key, int value); + + public void putLong(String key, long value); + + public void putFloat(String key, float value); + + public void putDouble(String key, double value); + + public void putString(String key, String value); + + public void putUtfString(String key, String value); + + public void putByteArray(String key, byte[] data); + + public void putTArray(String key, ITArray array); + + public void putTObject(String key, ITObject object); + + public void put(String key, TDataWrapper wrapper); + + public void del(String key); + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArray.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArray.java new file mode 100644 index 0000000..f0125c2 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArray.java @@ -0,0 +1,226 @@ +package com.taurus.core.entity; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * object array entity + * + * + */ +public class TArray implements ITArray { + private List dataHolder; + private boolean isChange = false; + + public TArray() { + dataHolder = new ArrayList(); + } + + public static ITArray newFromBinaryData(byte[] bytes) { + return TDataSerializer.me().binary2array(bytes); + } + + public static ITArray newFromJsonData(String jsonStr) { + return TDataSerializer.me().json2array(jsonStr); + } + + public static ITArray newFromResultSet(ResultSet rs) throws SQLException { + return TDataSerializer.me().resultSet2array(rs); + } + + public static TArray newInstance() { + return new TArray(); + } + + public byte[] toBinary() { + return TDataSerializer.me().array2binary(this); + } + + public String toJson() { + return TDataSerializer.me().array2json(flatten()); + } + + public boolean isNull(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + + if (wrapper == null) { + return false; + } + return wrapper.getTypeId() == TDataType.NULL; + } + + public TDataWrapper get(int index) { + return (TDataWrapper) this.dataHolder.get(index); + } + + public Boolean getBool(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Boolean) wrapper.getObject() : null; + } + + public Byte getByte(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Byte) wrapper.getObject() : null; + } + + public Integer getUByte(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? Integer.valueOf(TDataSerializer.me().getUByte(((Byte) wrapper.getObject()).byteValue())) : null; + } + + public Short getShort(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Short) wrapper.getObject() : null; + } + + public Integer getInt(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Integer) wrapper.getObject() : null; + } + + public Long getLong(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Long) wrapper.getObject() : null; + } + + public Float getFloat(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Float) wrapper.getObject() : null; + } + + public Double getDouble(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (Double) wrapper.getObject() : null; + } + + public String getString(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (String) wrapper.getObject() : null; + } + + public byte[] getByteArray(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (byte[]) wrapper.getObject() : null; + } + + public ITArray getTArray(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (ITArray) wrapper.getObject() : null; + } + + public ITObject getTObject(int index) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(index); + return wrapper != null ? (ITObject) wrapper.getObject() : null; + } + + public void addBool(boolean value) { + addObject(Boolean.valueOf(value), TDataType.BOOL); + } + + public void addByte(byte value) { + addObject(Byte.valueOf(value), TDataType.BYTE); + } + + public void addByteArray(byte[] value) { + addObject(value, TDataType.BYTE_ARRAY); + } + + public void addDouble(double value) { + addObject(Double.valueOf(value), TDataType.DOUBLE); + } + + public void addFloat(float value) { + addObject(Float.valueOf(value), TDataType.FLOAT); + } + + public void addInt(int value) { + addObject(Integer.valueOf(value), TDataType.INT); + } + + public void addLong(long value) { + addObject(Long.valueOf(value), TDataType.LONG); + } + + public void addNull() { + addObject(null, TDataType.NULL); + } + + public void addTArray(ITArray value) { + addObject(value, TDataType.TARRAY); + } + + public void addTObject(ITObject value) { + addObject(value, TDataType.TOBJECT); + } + + public void addShort(short value) { + addObject(Short.valueOf(value), TDataType.SHORT); + } + + public void addString(String value) { + addObject(value, TDataType.STRING); + } + + public void add(TDataWrapper wrappedObject) { + this.dataHolder.add(wrappedObject); + } + + public Object getAt(int index) { + Object item = null; + TDataWrapper wrapper = (TDataWrapper) dataHolder.get(index); + + if (wrapper != null) + item = wrapper.getObject(); + return item; + } + + public Iterator iterator() { + return this.dataHolder.iterator(); + } + + public void del(int index) { + this.dataHolder.remove(index); + } + + public int size() { + return this.dataHolder.size(); + } + + public void clear() { + this.dataHolder.clear(); + } + + public String toString() { + return dataHolder.toString(); + } + + private void addObject(Object value, TDataType typeId) { + dataHolder.add(new TDataWrapper(typeId, value)); + isChange = true; + } + + public boolean equals(Object obj) { + boolean isEquals = isChange; + isChange = false; + return isEquals; + } + + private List flatten() { + List list = new ArrayList(); + TDataSerializer.me().flattenArray(list, this); + return list; + } + + @Override + public void addUtfString(String value) { + this.addString(value); + } + + @Override + public String getUtfString(int index) { + return getString(index); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArrayLite.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArrayLite.java new file mode 100644 index 0000000..c34f723 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TArrayLite.java @@ -0,0 +1,28 @@ +package com.taurus.core.entity; + +/** + * TArrayLite + * + * + */ +public class TArrayLite extends TArray { + public static TArrayLite newInstance() { + return new TArrayLite(); + } + + public Byte getByte(int index) { + Integer i = super.getInt(index); + + return i != null ? Byte.valueOf(i.byteValue()) : null; + } + + public Short getShort(int index) { + Integer i = super.getInt(index); + return i != null ? Short.valueOf(i.shortValue()) : null; + } + + public Float getFloat(int index) { + Double d = super.getDouble(index); + return d != null ? Float.valueOf(d.floatValue()) : null; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataSerializer.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataSerializer.java new file mode 100644 index 0000000..ca491e2 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataSerializer.java @@ -0,0 +1,646 @@ +package com.taurus.core.entity; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.sql.Blob; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.json.JSONUtils; + +/** + * TDataSerializer + * + * + */ +public class TDataSerializer { + private static TDataSerializer instance = new TDataSerializer(); + private static int BUFFER_CHUNK_SIZE = 512; + + private static Logger logger = Logger.getLogger(TDataSerializer.class); + + public static TDataSerializer me() { + return instance; + } + + private TDataSerializer() { + } + + public int getUByte(byte b) { + return 0xFF & b; + } + + public ITArray binary2array(byte[] data) { + if (data.length < 3) { + throw new IllegalStateException("Can't decode an Array. Size: " + data.length + " bytes"); + } + ByteBuffer buffer = ByteBuffer.allocate(data.length); + buffer.put(data); + buffer.flip(); + return decodeTArray(buffer); + } + + private ITArray decodeTArray(ByteBuffer buffer) { + ITArray array = TArray.newInstance(); + byte headerBuffer = buffer.get(); + if (headerBuffer != TDataType.TARRAY.getTypeID()) { + throw new IllegalStateException("Invalid DataType. Expected: " + TDataType.TARRAY.getTypeID() + ", found: " + headerBuffer); + } + short size = buffer.getShort(); + if (size < 0) { + throw new IllegalStateException("Can't decode Array. Size is negative = " + size); + } + + try { + for (int i = 0; i < size; i++) { + TDataWrapper decodedObject = decodeObject(buffer); + + if (decodedObject != null) + array.add(decodedObject); + else { + throw new IllegalStateException("Array item is null! index: " + i); + } + } + } catch (RuntimeException codecError) { + throw new IllegalArgumentException(codecError.getMessage()); + } + return array; + } + + public ITObject binary2object(byte[] data) { + if (data.length < 3) { + throw new IllegalStateException("Can't decode an Object. Size: " + data.length + " bytes"); + } + ByteBuffer buffer = ByteBuffer.allocate(data.length); + buffer.put(data); + buffer = (ByteBuffer) buffer.flip(); // 强制转换 + + return decodeTObject(buffer); + } + + private ITObject decodeTObject(ByteBuffer buffer) { + ITObject tobj = TObject.newInstance(); + byte headerBuffer = buffer.get(); + if (headerBuffer != TDataType.TOBJECT.getTypeID()) { + throw new IllegalStateException("Invalid DataType. Expected: " + TDataType.TOBJECT.getTypeID() + ", found: " + headerBuffer); + } + short size = buffer.getShort(); + if (size < 0) { + throw new IllegalStateException("Can't decode Object. Size is negative = " + size); + } + + for (int i = 0; i < size; i++) { + short keySize = buffer.getShort(); + if ((keySize < 0) || (keySize > 255)) { + throw new IllegalStateException("Invalid Object key length. Found = " + keySize); + } + byte[] keyData = new byte[keySize]; + buffer.get(keyData, 0, keyData.length); + String key = new String(keyData); + TDataWrapper decodedObject = decodeObject(buffer); + if (decodedObject != null) + tobj.put(key, decodedObject); + else { + throw new IllegalStateException("Could not decode value for key: " + keyData); + } + } + return tobj; + } + + /** + * + * @param jsonStr + * @return + */ + @SuppressWarnings("unchecked") + public ITObject json2object(String jsonStr) { + if (jsonStr.length() < 2) { + throw new IllegalStateException("Can't decode Object. JSON String is too short. Len: " + jsonStr.length()); + } + + Object o = JSONUtils.parse(jsonStr); + return decodeTObject((HashMap) o); + } + + /** + * + * @param jsonStr + * @return + */ + @SuppressWarnings("unchecked") + public ITArray json2array(String jsonStr) { + if (jsonStr.length() < 2) { + throw new IllegalStateException("Can't decode Object. JSON String is too short. Len: " + jsonStr.length()); + } + Object jsa = JSONUtils.parse(jsonStr); + return decodeTArray((List) jsa); + } + + private ITArray decodeTArray(List jsa) { + ITArray array = TArrayLite.newInstance(); + + for (Object value : jsa) { + TDataWrapper decodedObject = decodeJsonObject(value); + if (decodedObject != null) + array.add(decodedObject); + else { + throw new IllegalStateException("(json2sfarray) Could not decode value for object: " + value); + } + } + return array; + } + + private ITObject decodeTObject(HashMap jso) { + + ITObject object = TObjectLite.newInstance(); + for (Entry entry : jso.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + TDataWrapper decodedObject = decodeJsonObject(value); + if (decodedObject != null) + object.put(key, decodedObject); + else { + throw new IllegalStateException("(json2tobj) Could not decode value for key: " + key); + } + } + return object; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private TDataWrapper decodeJsonObject(Object o) { + + if ((o instanceof Integer)) { + return new TDataWrapper(TDataType.INT, o); + } + if ((o instanceof Long)) { + return new TDataWrapper(TDataType.LONG, o); + } + if ((o instanceof Double)) { + return new TDataWrapper(TDataType.DOUBLE, o); + } + if ((o instanceof Boolean)) { + return new TDataWrapper(TDataType.BOOL, o); + } + if ((o instanceof String)) { + return new TDataWrapper(TDataType.STRING, o); + } + if ((o instanceof HashMap)) { + HashMap jso = (HashMap) o; + return new TDataWrapper(TDataType.TOBJECT, decodeTObject(jso)); + } + if ((o instanceof List)) { + return new TDataWrapper(TDataType.TARRAY, decodeTArray((List) o)); + } + + throw new IllegalArgumentException(String.format("Unknown DataType! %s", o == null ? "null" : o.getClass())); + } + + public TObject resultSet2object(ResultSet rset) throws SQLException { + ResultSetMetaData metaData = rset.getMetaData(); + TObject sfso = new TObject(); + + if (rset.isBeforeFirst()) { + rset.next(); + } + for (int col = 1; col <= metaData.getColumnCount(); col++) { + String colName = metaData.getColumnLabel(col); + int type = metaData.getColumnType(col); + + Object rawDataObj = rset.getObject(col); + if (rawDataObj == null) { + continue; + } + + if (type == Types.NULL) { + sfso.putNull(colName); + } else if (type == Types.BOOLEAN) { + sfso.putBoolean(colName, rset.getBoolean(col)); + } else if (type == Types.DATE) { + sfso.putLong(colName, rset.getDate(col).getTime()); + } else if ((type == Types.FLOAT) || (type == Types.DOUBLE) || (type == Types.DECIMAL) || (type == Types.REAL)) { + sfso.putDouble(colName, rset.getDouble(col)); + } else if ((type == Types.INTEGER) || (type == Types.TINYINT) || (type == Types.SMALLINT)) { + sfso.putInt(colName, rset.getInt(col)); + } else if ((type == Types.CHAR) || (type == Types.VARCHAR) || (type == Types.LONGVARCHAR)) { + sfso.putString(colName, rset.getString(col)); + } else if ((type == Types.NCHAR) || (type == Types.NVARCHAR) || (type == Types.LONGNVARCHAR)) { + sfso.putString(colName, rset.getNString(col)); + } else if (type == Types.TIMESTAMP) { + sfso.putLong(colName, rset.getTimestamp(col).getTime()); + } else if (type == Types.BIGINT) { + sfso.putLong(colName, rset.getLong(col)); + } else if (type == Types.LONGVARBINARY) { + byte[] binData = getBlobData(colName, rset.getBinaryStream(col)); + + if (binData != null) { + sfso.putByteArray(colName, binData); + } + } else if (type == Types.BLOB) { + Blob blob = rset.getBlob(col); + sfso.putByteArray(colName, blob.getBytes(0L, (int) blob.length())); + } else { + logger.info("Skipping Unsupported SQL TYPE: " + type + ", Column:" + colName); + } + } + + return sfso; + } + + private byte[] getBlobData(String colName, InputStream stream) { + BufferedInputStream bis = new BufferedInputStream(stream); + byte[] bytes = (byte[]) null; + try { + bytes = new byte[bis.available()]; + bis.read(bytes); + } catch (IOException ex) { + logger.warn("Object serialize error. Failed reading BLOB data for column: " + colName); + } finally { + try { + bis.close(); + } catch (IOException e) { + logger.error(e); + } + } + + return bytes; + } + + public TArray resultSet2array(ResultSet rset) throws SQLException { + TArray array = new TArray(); + + while (rset.next()) { + array.addTObject(resultSet2object(rset)); + } + + return array; + } + + public byte[] object2binary(ITObject object) { + ByteBuffer buffer = ByteBuffer.allocate(BUFFER_CHUNK_SIZE); + buffer.put((byte) TDataType.TOBJECT.getTypeID()); + buffer.putShort((short) object.size()); + return obj2bin(object, buffer); + } + + private byte[] obj2bin(ITObject object, ByteBuffer buffer) { + Set keys = object.getKeys(); + for (String key : keys) { + TDataWrapper wrapper = object.get(key); + buffer = encodeTObjectKey(buffer, key); + buffer = encodeObject(buffer, wrapper); + } + + int pos = buffer.position(); + byte[] result = new byte[pos]; + buffer.flip(); + buffer.get(result, 0, pos); + return result; + } + + public byte[] array2binary(ITArray array) { + ByteBuffer buffer = ByteBuffer.allocate(BUFFER_CHUNK_SIZE); + buffer.put((byte) TDataType.TARRAY.getTypeID()); + buffer.putShort((short) array.size()); + return arr2bin(array, buffer); + } + + private byte[] arr2bin(ITArray array, ByteBuffer buffer) { + Iterator iter = array.iterator(); + while (iter.hasNext()) { + TDataWrapper wrapper = (TDataWrapper) iter.next(); + buffer = encodeObject(buffer, wrapper); + } + + int pos = buffer.position(); + byte[] result = new byte[pos]; + buffer.flip(); + buffer.get(result, 0, pos); + return result; + } + + public String object2json(Map map) { + return JSONUtils.toJSONString(map); + } + + public String array2json(List array) { + return JSONUtils.toJSONString(array); + } + + public void flattenObject(Map map, ITObject obj) { + for (Iterator> it = obj.iterator(); it.hasNext();) { + Entry entry = it.next(); + String key = (String) entry.getKey(); + TDataWrapper value = (TDataWrapper) entry.getValue(); + if (value.getTypeId() == TDataType.TOBJECT) { + Map newMap = new HashMap(); + map.put(key, newMap); + flattenObject(newMap, (ITObject) value.getObject()); + } else if (value.getTypeId() == TDataType.TARRAY) { + List newList = new ArrayList(); + map.put(key, newList); + flattenArray(newList, (ITArray) value.getObject()); + } else { + map.put(key, value.getObject()); + } + } + } + + public void flattenArray(List array, ITArray tarray) { + for (Iterator it = tarray.iterator(); it.hasNext();) { + TDataWrapper value = (TDataWrapper) it.next(); + if (value.getTypeId() == TDataType.TOBJECT) { + Map newMap = new HashMap(); + array.add(newMap); + flattenObject(newMap, (TObject) value.getObject()); + } else if (value.getTypeId() == TDataType.TARRAY) { + List newList = new ArrayList(); + array.add(newList); + flattenArray(newList, (ITArray) value.getObject()); + } else { + array.add(value.getObject()); + } + } + } + + private TDataWrapper decodeObject(ByteBuffer buffer) throws RuntimeException { + TDataWrapper decodedObject = null; + byte headerByte = buffer.get(); + + if (headerByte == TDataType.NULL.getTypeID()) { + decodedObject = binDecode_NULL(buffer); + } else if (headerByte == TDataType.BOOL.getTypeID()) { + decodedObject = binDecode_BOOL(buffer); + } else if (headerByte == TDataType.BYTE.getTypeID()) { + decodedObject = binDecode_BYTE(buffer); + } else if (headerByte == TDataType.BYTE_ARRAY.getTypeID()) { + decodedObject = binDecode_BYTE_ARRAY(buffer); + } else if (headerByte == TDataType.SHORT.getTypeID()) { + decodedObject = binDecode_SHORT(buffer); + } else if (headerByte == TDataType.INT.getTypeID()) { + decodedObject = binDecode_INT(buffer); + } else if (headerByte == TDataType.LONG.getTypeID()) { + decodedObject = binDecode_LONG(buffer); + } else if (headerByte == TDataType.FLOAT.getTypeID()) { + decodedObject = binDecode_FLOAT(buffer); + } else if (headerByte == TDataType.DOUBLE.getTypeID()) { + decodedObject = binDecode_DOUBLE(buffer); + } else if (headerByte == TDataType.STRING.getTypeID()) { + decodedObject = binDecode_STRING(buffer); + } else if (headerByte == TDataType.TARRAY.getTypeID()) { + buffer.position(buffer.position() - 1); + decodedObject = new TDataWrapper(TDataType.TARRAY, decodeTArray(buffer)); + } else if (headerByte == TDataType.TOBJECT.getTypeID()) { + buffer.position(buffer.position() - 1); + ITObject tobj = decodeTObject(buffer); + TDataType type = TDataType.TOBJECT; + Object finalTObj = tobj; + decodedObject = new TDataWrapper(type, finalTObj); + } else { + throw new RuntimeException("Unknow DataType ID: " + headerByte); + } + return decodedObject; + } + + private ByteBuffer encodeObject(ByteBuffer buffer, TDataWrapper wrapper) { + TDataType typeId = wrapper.getTypeId(); + Object object = wrapper.getObject(); + + switch (typeId) { + case NULL: + buffer = binEncode_NULL(buffer); + break; + case BOOL: + buffer = binEncode_BOOL(buffer, (Boolean) object); + break; + case BYTE: + buffer = binEncode_BYTE(buffer, (Byte) object); + break; + case SHORT: + buffer = binEncode_SHORT(buffer, (Short) object); + break; + case INT: + buffer = binEncode_INT(buffer, (Integer) object); + break; + case LONG: + buffer = binEncode_LONG(buffer, (Long) object); + break; + case FLOAT: + buffer = binEncode_FLOAT(buffer, (Float) object); + break; + case DOUBLE: + buffer = binEncode_DOUBLE(buffer, (Double) object); + break; + case STRING: + buffer = binEncode_STRING(buffer, (String) object); + break; + case BYTE_ARRAY: + buffer = binEncode_BYTE_ARRAY(buffer, (byte[]) object); + break; + case TARRAY: + buffer = addData(buffer, array2binary((TArray) object)); + break; + case TOBJECT: + buffer = addData(buffer, object2binary((TObject) object)); + break; + default: + throw new IllegalArgumentException("Unrecognized type in TObject serialization: " + typeId); + } + + return buffer; + } + + private TDataWrapper binDecode_NULL(ByteBuffer buffer) { + return new TDataWrapper(TDataType.NULL, null); + } + + private TDataWrapper binDecode_BOOL(ByteBuffer buffer) throws RuntimeException { + byte boolByte = buffer.get(); + Boolean bool = null; + if (boolByte == 0) + bool = new Boolean(false); + else if (boolByte == 1) + bool = new Boolean(true); + else { + throw new RuntimeException("Error decoding Bool type. Illegal value: " + bool); + } + return new TDataWrapper(TDataType.BOOL, bool); + } + + private TDataWrapper binDecode_BYTE(ByteBuffer buffer) { + byte boolByte = buffer.get(); + return new TDataWrapper(TDataType.BYTE, Byte.valueOf(boolByte)); + } + + private TDataWrapper binDecode_SHORT(ByteBuffer buffer) { + short shortValue = buffer.getShort(); + return new TDataWrapper(TDataType.SHORT, Short.valueOf(shortValue)); + } + + private TDataWrapper binDecode_INT(ByteBuffer buffer) { + int intValue = buffer.getInt(); + return new TDataWrapper(TDataType.INT, Integer.valueOf(intValue)); + } + + private TDataWrapper binDecode_LONG(ByteBuffer buffer) { + long longValue = buffer.getLong(); + return new TDataWrapper(TDataType.LONG, Long.valueOf(longValue)); + } + + private TDataWrapper binDecode_FLOAT(ByteBuffer buffer) { + float floatValue = buffer.getFloat(); + return new TDataWrapper(TDataType.FLOAT, Float.valueOf(floatValue)); + } + + private TDataWrapper binDecode_DOUBLE(ByteBuffer buffer) { + double doubleValue = buffer.getDouble(); + return new TDataWrapper(TDataType.DOUBLE, Double.valueOf(doubleValue)); + } + + private TDataWrapper binDecode_STRING(ByteBuffer buffer) throws RuntimeException { + int strLen = buffer.getShort(); + if (strLen < 0) { + throw new RuntimeException("Error decoding String. Negative size: " + strLen); + } + if(strLen == 0) { + return new TDataWrapper(TDataType.STRING, StringUtil.Empty); + } + byte[] strData = new byte[strLen]; + buffer.get(strData, 0, strLen); + String decodedString = StringUtil.Empty; + try { + decodedString = StringUtil.getString(strData); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + return new TDataWrapper(TDataType.STRING, decodedString); + } + + private TDataWrapper binDecode_BYTE_ARRAY(ByteBuffer buffer) throws RuntimeException { + int arraySize = buffer.getInt(); + if (arraySize < 0) { + throw new RuntimeException("Error decoding typed array size. Negative size: " + arraySize); + } + + byte[] byteData = new byte[arraySize]; + buffer.get(byteData, 0, arraySize); + return new TDataWrapper(TDataType.BYTE_ARRAY, byteData); + } + + private ByteBuffer binEncode_NULL(ByteBuffer buffer) { + return addData(buffer, new byte[1]); + } + + private ByteBuffer binEncode_BOOL(ByteBuffer buffer, Boolean value) { + byte[] data = new byte[2]; + data[0] = (byte) TDataType.BOOL.getTypeID(); + data[1] = (byte) (value.booleanValue() ? 1 : 0); + return addData(buffer, data); + } + + private ByteBuffer binEncode_BYTE(ByteBuffer buffer, Byte value) { + byte[] data = new byte[2]; + data[0] = (byte) TDataType.BYTE.getTypeID(); + data[1] = value.byteValue(); + return addData(buffer, data); + } + + private ByteBuffer binEncode_SHORT(ByteBuffer buffer, Short value) { + ByteBuffer buf = ByteBuffer.allocate(3); + buf.put((byte) TDataType.SHORT.getTypeID()); + buf.putShort(value.shortValue()); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_INT(ByteBuffer buffer, Integer value) { + ByteBuffer buf = ByteBuffer.allocate(5); + buf.put((byte) TDataType.INT.getTypeID()); + buf.putInt(value.intValue()); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_LONG(ByteBuffer buffer, Long value) { + ByteBuffer buf = ByteBuffer.allocate(9); + buf.put((byte) TDataType.LONG.getTypeID()); + buf.putLong(value.longValue()); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_FLOAT(ByteBuffer buffer, Float value) { + ByteBuffer buf = ByteBuffer.allocate(5); + buf.put((byte) TDataType.FLOAT.getTypeID()); + buf.putFloat(value.floatValue()); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_DOUBLE(ByteBuffer buffer, Double value) { + ByteBuffer buf = ByteBuffer.allocate(9); + buf.put((byte) TDataType.DOUBLE.getTypeID()); + buf.putDouble(value.doubleValue()); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_STRING(ByteBuffer buffer, String value) { + if (StringUtil.isEmpty(value)) { + ByteBuffer buf = ByteBuffer.allocate(3); + buf.put((byte) TDataType.STRING.getTypeID()); + buf.putShort((short)0); + return addData(buffer, buf.array()); + } + byte[] stringBytes = null; + try { + stringBytes = StringUtil.getBytes(value); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + ByteBuffer buf = ByteBuffer.allocate(3 + stringBytes.length); + buf.put((byte) TDataType.STRING.getTypeID()); + buf.putShort((short)stringBytes.length); + buf.put(stringBytes); + return addData(buffer, buf.array()); + } + + private ByteBuffer binEncode_BYTE_ARRAY(ByteBuffer buffer, byte[] value) { + ByteBuffer buf = ByteBuffer.allocate(5 + value.length); + buf.put((byte) TDataType.BYTE_ARRAY.getTypeID()); + buf.putInt(value.length); + buf.put(value); + return addData(buffer, buf.array()); + } + + private ByteBuffer encodeTObjectKey(ByteBuffer buffer, String value) { + ByteBuffer buf = ByteBuffer.allocate(2 + value.length()); + buf.putShort((short) value.length()); + buf.put(value.getBytes()); + return addData(buffer, buf.array()); + } + + private ByteBuffer addData(ByteBuffer buffer, byte[] newData) { + if (buffer.remaining() < newData.length) { + int newSize = BUFFER_CHUNK_SIZE; + if (newSize < newData.length) { + newSize = newData.length; + } + ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() + newSize); + buffer.flip(); + newBuffer.put(buffer); + buffer = newBuffer; + } + buffer.put(newData); + return buffer; + } + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataType.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataType.java new file mode 100644 index 0000000..b21cfec --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataType.java @@ -0,0 +1,41 @@ +package com.taurus.core.entity; + +/** + * TDataType + * + * + */ +public enum TDataType{ + NULL(0), + BOOL(1), + BYTE(2), + SHORT(3), + INT(4), + LONG(5), + FLOAT(6), + DOUBLE(7), + STRING(8), + BYTE_ARRAY(9), + TARRAY(10), + TOBJECT(11); + + private int typeID; + + private TDataType(int typeID) { + this.typeID = typeID; + } + + public static TDataType fromTypeId(int typeId) { + for (TDataType item : values()) { + if (item.getTypeID() == typeId) { + return item; + } + } + + throw new IllegalArgumentException("Unknown typeId for MPDataType"); + } + + public int getTypeID() { + return this.typeID; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataWrapper.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataWrapper.java new file mode 100644 index 0000000..9672f29 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TDataWrapper.java @@ -0,0 +1,30 @@ +package com.taurus.core.entity; + +import java.util.ArrayList; + +/** + * TDataWrapper + * + * + */ +public class TDataWrapper extends ArrayList { + private TDataType typeId; + private Object object; + + public TDataWrapper(TDataType typeId, Object object) { + this.typeId = typeId; + this.object = object; + } + + public TDataType getTypeId() { + return typeId; + } + + public Object getObject() { + return object; + } + + public String toString() { + return object.toString(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObject.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObject.java new file mode 100644 index 0000000..8017226 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObject.java @@ -0,0 +1,291 @@ +package com.taurus.core.entity; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import com.taurus.core.util.StringUtil; + +/** + * object map entity + * + * + */ +public class TObject implements ITObject { + private Map dataHolder; + private boolean isChange; + + public static ITObject newFromBinaryData(byte[] bytes) { + return TDataSerializer.me().binary2object(bytes); + } + + public static ITObject newFromJsonData(String jsonStr) { + return TDataSerializer.me().json2object(jsonStr); + } + + public static ITObject newFromResultSet(ResultSet rs) throws SQLException{ + return TDataSerializer.me().resultSet2object(rs); + } + + public static TObject newInstance() { + return new TObject(); + } + + public TObject() { + dataHolder = new ConcurrentHashMap(); + } + + public Iterator> iterator() { + return this.dataHolder.entrySet().iterator(); + } + + public boolean containsKey(String key) { + return this.dataHolder.containsKey(key); + } + + public boolean remove(String key) { + return this.dataHolder.remove(key) != null; + } + + public int size() { + return this.dataHolder.size(); + } + + public byte[] toBinary() { + return TDataSerializer.me().object2binary(this); + } + + public String toJson() { + return TDataSerializer.me().object2json(flatten()); + } + + public boolean isNull(String key) { + TDataWrapper wrapper = (TDataWrapper) this.dataHolder.get(key); + + if (wrapper == null) { + return false; + } + return wrapper.getTypeId() == TDataType.NULL; + } + + public TDataWrapper get(String key) { + return (TDataWrapper) this.dataHolder.get(key); + } + + public Boolean getBoolean(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return (Boolean) o.getObject(); + } + + public Byte getByte(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return (Byte) o.getObject(); + } + + public byte[] getByteArray(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (byte[]) o.getObject(); + } + + public Double getDouble(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (Double) o.getObject(); + } + + public Float getFloat(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (Float) o.getObject(); + } + + public Integer getInt(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (Integer) o.getObject(); + } + + public Set getKeys() { + return dataHolder.keySet(); + } + + public Long getLong(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return (Long) o.getObject(); + } + + public ITArray getTArray(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return (ITArray) o.getObject(); + } + + public ITObject getTObject(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (ITObject) o.getObject(); + } + + public Short getShort(String key) { + TDataWrapper o = (TDataWrapper) dataHolder.get(key); + + if (o == null) { + return null; + } + return (Short) o.getObject(); + } + + public Integer getUByte(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return Integer.valueOf(TDataSerializer.me().getUByte(((Byte) o.getObject()).byteValue())); + } + + public String getString(String key) { + TDataWrapper o = (TDataWrapper) this.dataHolder.get(key); + + if (o == null) { + return null; + } + return (String) o.getObject(); + } + + public void putBoolean(String key, boolean value) { + putObj(key, Boolean.valueOf(value), TDataType.BOOL); + } + + public void putByte(String key, byte value) { + putObj(key, Byte.valueOf(value), TDataType.BYTE); + } + + public void putByteArray(String key, byte[] value) { + putObj(key, value, TDataType.BYTE_ARRAY); + } + + public void putDouble(String key, double value) { + putObj(key, Double.valueOf(value), TDataType.DOUBLE); + } + + public void putFloat(String key, float value) { + putObj(key, Float.valueOf(value), TDataType.FLOAT); + } + + public void putInt(String key, int value) { + putObj(key, Integer.valueOf(value), TDataType.INT); + } + + public void putLong(String key, long value) { + putObj(key, Long.valueOf(value), TDataType.LONG); + } + + public void putNull(String key) { + this.dataHolder.put(key, new TDataWrapper(TDataType.NULL, null)); + } + + public void putTArray(String key, ITArray value) { + putObj(key, value, TDataType.TARRAY); + } + + public void putTObject(String key, ITObject value) { + putObj(key, value, TDataType.TOBJECT); + } + + public void putShort(String key, short value) { + putObj(key, Short.valueOf(value), TDataType.SHORT); + } + + public void putString(String key, String value) { + if(value==null)value = StringUtil.Empty; + putObj(key, value, TDataType.STRING); + } + + public void put(String key, TDataWrapper wrappedObject) { + putObj(key, wrappedObject, null); + } + + public String toString() { + return dataHolder.toString(); + } + + private void putObj(String key, Object value, TDataType typeId) { + if (key == null) { + throw new IllegalArgumentException("TObject requires a non-null key for a 'put' operation!"); + } + if (key.length() > 255) { + throw new IllegalArgumentException("TObject keys must be less than 255 characters!"); + } + if (value == null) { + throw new IllegalArgumentException("TObject requires a non-null value! If you need to add a null use the putNull() method."); + } + if ((value instanceof TDataWrapper)) + dataHolder.put(key, (TDataWrapper) value); + else + dataHolder.put(key, new TDataWrapper(typeId, value)); + isChange = true; + } + + public boolean equals(Object obj) { + boolean isEquals = isChange; + isChange = false; + return isEquals; + } + + private Map flatten() { + Map map = new HashMap(); + TDataSerializer.me().flattenObject(map, this); + return map; + } + + @Override + public void del(String key) { + dataHolder.remove(key); + } + + @Override + public String getUtfString(String key) { + return this.getString(key); + } + + @Override + public void putUtfString(String key, String value) { + this.putString(key, value); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObjectLite.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObjectLite.java new file mode 100644 index 0000000..2ad448c --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/entity/TObjectLite.java @@ -0,0 +1,33 @@ +package com.taurus.core.entity; + +/** + * TObjectLite + * + * + */ +public final class TObjectLite extends TObject { + public static TObject newInstance() { + return new TObjectLite(); + } + + @Override + public Byte getByte(String key) { + Integer i = super.getInt(key); + + return i != null ? Byte.valueOf(i.byteValue()) : null; + } + + @Override + public Short getShort(String key) { + Integer i = super.getInt(key); + + return i != null ? Short.valueOf(i.shortValue()) : null; + } + + @Override + public Float getFloat(String key) { + Double d = super.getDouble(key); + + return d != null ? Float.valueOf(d.floatValue()) : null; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/events/Event.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/Event.java new file mode 100644 index 0000000..76a91c6 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/Event.java @@ -0,0 +1,60 @@ +package com.taurus.core.events; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Event. + * + */ +public class Event { + + protected Object target; + protected String name; + protected Map paramMap; + + public Event(String name) { + this.name = name; + } + + public Event(String name, Object source) { + this.target = source; + this.name = name; + } + + public Object getTarget() { + return this.target; + } + + public String getName() { + return this.name; + } + + public void setTarget(Object target) { + this.target = target; + } + + public void setName(String name) { + this.name = name; + } + + public Object getParameter(String key) { + Object tem = null; + + if (paramMap != null) { + tem = paramMap.get(key); + } + return tem; + } + + public void setParameter(String key, Object value) { + if (paramMap == null) { + paramMap = new ConcurrentHashMap(); + } + paramMap.put(key, value); + } + + public String toString() { + return "Event { Name:" + name + ", Source: " + target + ", Params: " + paramMap + " }"; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventDispatcher.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventDispatcher.java new file mode 100644 index 0000000..c4c98b3 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventDispatcher.java @@ -0,0 +1,93 @@ +package com.taurus.core.events; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ThreadPoolExecutor; + +import com.taurus.core.util.Logger; + +/** + * EventDispatcher 事件派发器类,负责进行事件的发送和侦听。 +*/ +public class EventDispatcher implements IEventDispatcher { + + private final Map> listenersByEvent; + private ThreadPoolExecutor threadPool; + + public EventDispatcher(){ + listenersByEvent = new ConcurrentHashMap>(); + } + + public EventDispatcher(ThreadPoolExecutor threadPool){ + this(); + this.threadPool = threadPool; + } + + @Override + public synchronized void addEventListener(String eventName, IEventListener listener) { + Set listeners = listenersByEvent.get(eventName); + if (listeners == null) { + listeners = new CopyOnWriteArraySet(); + listenersByEvent.put(eventName, listeners); + } + + listeners.add(listener); + } + + @Override + public boolean hasEventListener(String eventName) { + boolean found = false; + Set listeners = listenersByEvent.get(eventName); + if ((listeners != null) && (listeners.size() > 0)) { + found = true; + } + return found; + } + + @Override + public synchronized void removeEventListener(String eventName, IEventListener listener) { + Set listeners = listenersByEvent.get(eventName); + if (listeners != null) + listeners.remove(listener); + } + + @Override + public void dispatchEvent(Event event) { + Set listeners = (Set) listenersByEvent.get(event.getName()); + if ((listeners != null) && (listeners.size() > 0)) { + for (IEventListener listenerObj : listeners) { + if(threadPool!=null){ + threadPool.execute(new EventRunner(listenerObj,event)); + }else{ + listenerObj.handleEvent(event); + } + + } + } + } + + @Override + public void removeAllListener() { + listenersByEvent.clear(); + } + + private static final class EventRunner implements Runnable { + private final IEventListener listener; + private final Event event; + + public EventRunner(IEventListener listener, Event event) { + this.listener = listener; + this.event = event; + } + + public void run() { + try { + listener.handleEvent(event); + } catch (Exception e) { + Logger.getLogger(getClass()).warn("Error in event handler: " + e + ", Event: " + event + " Listener: " + listener); + } + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventManager.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventManager.java new file mode 100644 index 0000000..0d99d8b --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/EventManager.java @@ -0,0 +1,63 @@ +package com.taurus.core.events; + +import java.util.concurrent.ThreadPoolExecutor; + +import com.taurus.core.service.AbstractService; +import com.taurus.core.util.Logger; + +/** + * 事件管理,处理框架内部事件 + * + * + * + */ +public final class EventManager extends AbstractService implements IEventDispatcher { + private final ThreadPoolExecutor threadPool; + private final EventDispatcher dispatcher; + private final Logger logger; + + public EventManager(ThreadPoolExecutor threadPool) { + setName("EventManager"); + logger = Logger.getLogger(EventManager.class); + + this.threadPool = threadPool; + dispatcher = new EventDispatcher(threadPool); + } + + public void init(Object o) { + super.init(o); + logger.info(this.name + " init."); + } + + public void destroy(Object o) { + super.init(o); + dispatcher.removeAllListener(); + logger.info(this.name + " shut down."); + } + + public ThreadPoolExecutor getThreadPool() { + return this.threadPool; + } + + public void addEventListener(String eventName, IEventListener listener) { + dispatcher.addEventListener(eventName, listener); + } + + public boolean hasEventListener(String eventName) { + return dispatcher.hasEventListener(eventName); + } + + public void removeEventListener(String eventName, IEventListener listener) { + dispatcher.removeEventListener(eventName, listener); + } + + public void dispatchEvent(Event event) { + dispatcher.dispatchEvent(event); + } + + @Override + public void removeAllListener() { + dispatcher.removeAllListener(); + } + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventDispatcher.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventDispatcher.java new file mode 100644 index 0000000..b7128c2 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventDispatcher.java @@ -0,0 +1,40 @@ +package com.taurus.core.events; + +/** + * 事件派发器通用接口 + * + */ +public interface IEventDispatcher { + + /** + * 添加指定类型的事件监听 + * @param eventName + * @param listener + */ + public void addEventListener(String eventName, IEventListener listener); + + /** + * 检查指定类型事件监听器是否存在 + * @param eventName + * @return + */ + public boolean hasEventListener(String eventName); + + /** + * 删除指定的事件监听 + * @param eventName + * @param listener + */ + public void removeEventListener(String eventName, IEventListener listener); + + /** + * 删除所有的事件监听 + */ + public void removeAllListener(); + + /** + * + * @param event + */ + public void dispatchEvent(Event event); +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventListener.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventListener.java new file mode 100644 index 0000000..2281095 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/events/IEventListener.java @@ -0,0 +1,14 @@ +package com.taurus.core.events; + +/** + * 事件监听接口 + * + */ +public interface IEventListener { + + /** + * + * @param event + */ + public void handleEvent(Event event); +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/IPlugin.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/IPlugin.java new file mode 100644 index 0000000..6406aec --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/IPlugin.java @@ -0,0 +1,23 @@ + +package com.taurus.core.plugin; + +import org.jdom.Element; + +/** + * IPlugin + */ +public interface IPlugin { + String getId(); + + void setId(String id); + + /** + * 加载配置 + * @param element + * @return + */ + boolean loadConfig(Element element); + + boolean start(); + boolean stop(); +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/PluginService.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/PluginService.java new file mode 100644 index 0000000..dd33c7f --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/PluginService.java @@ -0,0 +1,149 @@ +package com.taurus.core.plugin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Collection; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +public class PluginService { + private static final String CONFIG_PATH = "config/taurus-core.xml"; + private final Logger logger; + + /** + * 插件列表 + */ + final ConcurrentMap pluginMap; + + private static PluginService _instance; + + /** + * get main instance + */ + public static PluginService me() { + if (_instance == null) { + _instance = new PluginService(); + } + return _instance; + } + + private PluginService() { + logger = Logger.getLogger(PluginService.class); + pluginMap = new ConcurrentHashMap(); + } + + /** + * 加载配置 + * @throws Exception + */ + public void loadConfig() throws Exception{ + loadConfig(System.getProperty("user.dir")); + } + + private IPlugin createPlugin(String pclass) throws RuntimeException { + if (StringUtil.isEmpty(pclass)) { + logger.info("Plugin class not find!"); + return null; + } + IPlugin plugin = null; + try { + Class extensionClass = Class.forName(pclass); + if (!IPlugin.class.isAssignableFrom(extensionClass)) { + throw new RuntimeException("Controller does not implement IPlugin! "+pclass); + } + plugin = (IPlugin) extensionClass.newInstance(); + } catch (IllegalAccessException e) { + throw new RuntimeException("Illegal access while instantiating class: " + pclass); + } catch (InstantiationException e) { + throw new RuntimeException("Cannot instantiate class: " + pclass); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Class not found: " + pclass); + } + return plugin; + } + + /** + * 加载配置 + * @param path + * @throws Exception + */ + public void loadConfig(String path) throws Exception{ + File file = new File(path+"/"+CONFIG_PATH); + if(!file.exists())return; + InputStream is = new FileInputStream(file); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + + String log4jPath = root.getChildTextTrim("log4jPath"); + if(StringUtil.isNotEmpty(log4jPath)) { + try { + Class.forName("org.apache.log4j.PropertyConfigurator"); + log4jPath = path+"/config/" + log4jPath; + org.apache.log4j.PropertyConfigurator.configure(log4jPath); + }catch (ClassNotFoundException e) { + } + } + + Iterator itr = (root.getChildren("plugin")).iterator(); + while(itr.hasNext()) { + Element pluginEm = (Element)itr.next(); + String pid = pluginEm.getChildTextTrim("id"); + if(StringUtil.isEmpty(pid)) { + throw new RuntimeException("Plugin id is null!"); + } + String pclass = pluginEm.getChildTextTrim("class"); + if(StringUtil.isEmpty(pclass)) { + throw new RuntimeException("Plugin class is null!"); + } + IPlugin plugin = createPlugin(pclass); + plugin.setId(pid); + plugin.loadConfig(pluginEm); + putPlugin(plugin); + logger.info("plugin["+plugin.getId()+"] load success!"); + } + } + + /** + * put plugin instance + * @param plugin + */ + public final void putPlugin(IPlugin plugin) { + if(pluginMap.containsKey(plugin.getId()))return; + plugin.start(); + pluginMap.put(plugin.getId(),plugin); + } + + /** + * remove plugin + * @param pluginId plugin key id + */ + public final void removePlugin(String pluginId) { + IPlugin plugin =pluginMap.remove(pluginId); + if(plugin!=null) { + plugin.stop(); + } + } + + /** + * stop all plugin + */ + public final void stop() { + Collection list = pluginMap.values(); + for(IPlugin plugin : list) { + plugin.stop(); + } + pluginMap.clear(); + } + + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBase.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBase.java new file mode 100644 index 0000000..c693f6a --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBase.java @@ -0,0 +1,62 @@ +package com.taurus.core.plugin.database; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.taurus.core.util.StringUtil; +import com.zaxxer.hikari.HikariDataSource; + +/** + * DataBase 数据库工具 + *
+ * DataBase.use().executeQueryByTArray("SELECT * FROM table");
+ * 
+ * + * + */ +public class DataBase { + static Db mainDb = null; + + static final ConcurrentMap dbMap = new ConcurrentHashMap(); + + static void addDb(Db db) { + if (db == null) + throw new IllegalArgumentException("cache can not be null"); + if (dbMap.containsKey(db.getName())) + throw new IllegalArgumentException("The cache name already exists"); + + dbMap.put(db.getName(), db); + if (mainDb == null) + mainDb = db; + } + + static void removeDb(String dbName) { + Db db = dbMap.remove(dbName); + if(db == mainDb) { + ((HikariDataSource)db.ds).close(); + mainDb = null; + } + } + + /** + * set mainDb + */ + public static void setMainDb(String dbName) { + if (StringUtil.isEmpty(dbName)) + throw new IllegalArgumentException("dbName can not be blank"); + dbName = dbName.trim(); + Db db = dbMap.get(dbName); + if (db == null) + throw new IllegalArgumentException("the db not exists: " + dbName); + + DataBase.mainDb = db; + } + + public static Db use() { + return mainDb; + } + + public static Db use(String dbName) { + return dbMap.get(dbName); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBasePlugin.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBasePlugin.java new file mode 100644 index 0000000..48599ac --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/DataBasePlugin.java @@ -0,0 +1,132 @@ +package com.taurus.core.plugin.database; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.jdom.Element; + +import com.taurus.core.plugin.IPlugin; +import com.taurus.core.plugin.database.DataBasePlugin.DatabaseConfig.DbConfig; +import com.taurus.core.plugin.database.DataBasePlugin.DatabaseConfig.PoolConfig; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +/** + * DataBasePlugin 支持多个数据库连接组件 + * + * + * + */ +public class DataBasePlugin implements IPlugin { + private String id; + + private DatabaseConfig config; + + public DataBasePlugin() { + this.config = new DatabaseConfig(); + } + + @Override + public boolean start() { + + for (DbConfig dbconfig : this.config.dbList) { + PoolConfig config = this.config.poolConfig; + + HikariConfig hk_config = new HikariConfig(); + hk_config.setPoolName(dbconfig.name); + hk_config.setJdbcUrl(dbconfig.jdbcUrl); + hk_config.setUsername(dbconfig.userName); + hk_config.setPassword(dbconfig.password); + hk_config.setDriverClassName(dbconfig.driverName); + hk_config.setMaximumPoolSize(config.maxPool); + hk_config.setMinimumIdle(config.minIdle); + hk_config.setConnectionTimeout(config.connectionTimeout); + hk_config.setIdleTimeout(config.idleTimeout); + hk_config.setMaxLifetime(config.maxLifetime); + hk_config.setConnectionTestQuery(config.validationQuery); + hk_config.setDataSourceProperties(config.props); + + HikariDataSource dbPool = new HikariDataSource(hk_config); + Db db = new Db(dbconfig.name, dbPool); + DataBase.addDb(db); + } + + return true; + } + + @Override + public boolean stop() { + Set keys = DataBase.dbMap.keySet(); + for (String key : keys) { + DataBase.removeDb(key); + } + return true; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public boolean loadConfig(Element element) { + Element pcEm = element.getChild("poolConfig"); + this.config.poolConfig.maxPool = Integer.parseInt(pcEm.getChild("maxPool").getTextTrim()); + this.config.poolConfig.minIdle = Integer.parseInt(pcEm.getChild("minIdle").getTextTrim()); + this.config.poolConfig.maxLifetime = Integer.parseInt(pcEm.getChild("maxLifetime").getTextTrim()); + this.config.poolConfig.validationQuery = pcEm.getChild("validationQuery").getTextTrim(); + this.config.poolConfig.connectionTimeout = Integer.parseInt(pcEm.getChild("connectionTimeout").getTextTrim()); + this.config.poolConfig.idleTimeout = Integer.parseInt(pcEm.getChild("idleTimeout").getTextTrim()); + Element propsEm = pcEm.getChild("props"); + List props = propsEm.getChildren(); + for (Object obj : props) { + Element pEm = (Element) obj; + this.config.poolConfig.props.put(pEm.getName(), pEm.getTextTrim()); + } + + Element dblistEm = element.getChild("databases"); + Iterator itr = (dblistEm.getChildren()).iterator(); + while (itr.hasNext()) { + Element dbEm = (Element) itr.next(); + DbConfig dbconfig = new DbConfig(); + dbconfig.name = dbEm.getChildTextTrim("name"); + dbconfig.driverName = dbEm.getChildTextTrim("driverName"); + dbconfig.jdbcUrl = dbEm.getChildTextTrim("jdbcUrl"); + dbconfig.userName = dbEm.getChildTextTrim("userName"); + dbconfig.password = dbEm.getChildTextTrim("password"); + this.config.dbList.add(dbconfig); + } + return true; + } + + public static final class DatabaseConfig { + public volatile PoolConfig poolConfig = new PoolConfig(); + public volatile List dbList = new ArrayList(); + + public static final class PoolConfig { + public int maxPool = 8; + public int minIdle = 8; + public int maxLifetime = 6000; + public int connectionTimeout = 3000; + public int idleTimeout = 60000; + public String validationQuery = "select 1"; + public Properties props = new Properties(); + } + + public static final class DbConfig { + public String name = ""; + public String driverName = ""; + public String jdbcUrl = ""; + public String userName = ""; + public String password = ""; + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/Db.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/Db.java new file mode 100644 index 0000000..5a9cb4c --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/database/Db.java @@ -0,0 +1,807 @@ +package com.taurus.core.plugin.database; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.sql.DataSource; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TDataWrapper; +import com.taurus.core.util.StringUtil; + +/** + * Db 数据库工具 + * + * + */ +public class Db { + protected String name; + protected DataSource ds; + + private static final String STR_NULL = ""; + private static final char CHAR_COMMA = ','; + private static final char CHAR_QUOTES = '\''; + private static final char CHAR_UNKNOWN = '?'; + private static final String TYPE_BOOLEAN = "boolean"; + + public Db(String name, DataSource ds) { + this.name = name; + this.ds = ds; + } + + /** + * 数据库 exec select + * + * @param sql select 数据 + * @return + * @throws SQLException + */ + public List> executeQuery(String sql) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rset = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + rset = stmt.executeQuery(); + + ResultSetMetaData rsmd = rset.getMetaData(); + int dataSize = rsmd.getColumnCount(); + + List> list = new ArrayList>(); + + while (rset.next()) { + if (rset.isBeforeFirst()) { + rset.next(); + } + Map map = new HashMap(); + for (int i = 1; i <= dataSize; i++) { + String columnName = rsmd.getColumnName(i); + if (StringUtil.isEmpty(columnName)) + continue; + Object column = rset.getObject(columnName); + String columnStr = null; + if (column == null || StringUtil.isEmpty(column.toString())) { + columnStr = STR_NULL; + } else { + columnStr = column.toString(); + } + map.put(columnName, columnStr); + } + list.add(map); + } + return list; + } finally { + try { + if (rset != null) + rset.close(); + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + + } + + private static void writeValueFromSetter(Field field, Object pojo, Object fieldValue) throws Exception { + String setterName = "set" + StringUtil.capitalize(field.getName()); + Method setterMethod = pojo.getClass().getMethod(setterName, new Class[] { field.getType() }); + setterMethod.invoke(pojo, new Object[] { fieldValue }); + } + + private static final void setFieldValue(Object pojo, Field field, Object fieldValue) throws Exception { + int modifiers = field.getModifiers(); + if ((Modifier.isTransient(modifiers)) || (Modifier.isStatic(modifiers))) { + return; + } + if (Modifier.isPublic(modifiers)) + field.set(pojo, fieldValue); + else + writeValueFromSetter(field, pojo, fieldValue); + } + + private static Object readValueFromGetter(String fieldName, String type, Object pojo) throws Exception { + Object value = null; + boolean isBool = type.equalsIgnoreCase(TYPE_BOOLEAN); + String getterName = isBool ? "is" : "get" + StringUtil.capitalize(fieldName); + Method getterMethod = pojo.getClass().getMethod(getterName, new Class[0]); + value = getterMethod.invoke(pojo, new Object[0]); + + return value; + } + + private static final Object getFieldValue(Field field, Object pojo) throws Exception { + int modifiers = field.getModifiers(); + if ((Modifier.isTransient(modifiers)) || (Modifier.isStatic(modifiers))) { + return null; + } + Object fieldValue = null; + + if (Modifier.isPublic(modifiers)) { + fieldValue = field.get(pojo); + } else { + fieldValue = readValueFromGetter(field.getName(), field.getType().getSimpleName(), pojo); + } + + return fieldValue; + } + + /** + * 数据库 exec select + * + * @param sql select 数据 + * @param pojoClazz + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + public List executeQuery(String sql, Class clazz) throws Exception { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rset = null; + + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + rset = stmt.executeQuery(); + + List list = new ArrayList(); + + while (rset.next()) { + if (rset.isBeforeFirst()) { + rset.next(); + } + Object pojo = clazz.newInstance(); + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + int modifiers = field.getModifiers(); + if ((Modifier.isTransient(modifiers)) || (Modifier.isStatic(modifiers))) { + continue; + } + Object column = null; + try { + column = rset.getObject(field.getName()); + if (column == null) { + continue; + } + } catch (Exception e) { + continue; + } + setFieldValue(pojo, field, column); + } + list.add((T) pojo); + } + return list; + } finally { + try { + if (rset != null) + rset.close(); + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + } + + /** + * 数据库 exec select + * + * @param sql select 数据 + * @return + * @throws SQLException + */ + public ITArray executeQueryByTArray(String sql) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rset = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + + rset = stmt.executeQuery(); + ITArray list = TArray.newFromResultSet(rset); + return list; + } finally { + try { + if (rset != null) + rset.close(); + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + } + + /** + * 数据库 exec select + * + * @param sql select 数据 + * @return + * @throws SQLException + */ + public ITArray executeQueryByTArrayLogin(String sql, String[] params) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rset = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + + if (stmt == null) + throw new SQLException(sql + "sql error!"); + if (params.length != 0) { + for (int i = 0; i < params.length; i++) { + stmt.setString(i + 1, params[i]); + + } + } + rset = stmt.executeQuery(); + ITArray list = TArray.newFromResultSet(rset); + return list; + } finally { + try { + if (rset != null) + rset.close(); + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + } + + /** + * 数据库 exec sql + * + * @param sql sql数据 + * @return + * @throws SQLException + */ + public int executeUpdate(String sql) throws SQLException { + return __executeUpdate(sql); + } + + /** + * 数据库 exec sql + * + * @param sql sql数据 + * @return + * @throws SQLException + */ + public int executeUpdateLogin(String sql, String params[]) throws SQLException { + return __executeUpdateLogin(sql, params); + } + + private int __executeUpdateLogin(String sql, String params[]) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + if (params.length != 0) { + for (int i = 0; i < params.length; i++) { + stmt.setString(i + 1, params[i]); + } + } + int result = stmt.executeUpdate(); + return result; + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + + private int __executeUpdate(String sql) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + int result = stmt.executeUpdate(); + return result; + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + + /** + * 数据库 insert into tableName values() + * + * @param table 表名 + * @param data insert数据 + * @return + * @throws SQLException + */ + public int insert(String table, ITObject data) throws SQLException { + if (StringUtil.isEmpty(table)) { + throw new SQLException("table is null!"); + } + if (data == null) { + throw new SQLException("data is null!"); + } + StringBuilder valuesql = new StringBuilder(); + StringBuilder keysql = new StringBuilder(); + Set keys = data.getKeys(); + int count = 0; + for (String key : keys) { + TDataWrapper wrapper = data.get(key); + if (count > 0) { + keysql.append(CHAR_COMMA); + valuesql.append(CHAR_COMMA); + } + count++; + keysql.append(key); + switch (wrapper.getTypeId()) { + case SHORT: + case INT: + case DOUBLE: + case FLOAT: + case BYTE: + case BOOL: + case LONG: + valuesql.append(wrapper.getObject()); + break; + case STRING: + valuesql.append(CHAR_QUOTES); + valuesql.append(wrapper.getObject()); + valuesql.append(CHAR_QUOTES); + break; + case TOBJECT: + ITObject mo = (ITObject) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(mo.toJson()); + valuesql.append(CHAR_QUOTES); + break; + case TARRAY: + ITArray ao = (ITArray) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(ao.toJson()); + valuesql.append(CHAR_QUOTES); + break; + default: + break; + } + } + + String sql = String.format("INSERT INTO %s (%s) VALUES(%s)", table, keysql, valuesql); + return __executeUpdate(sql); + } + + /** + * 数据库 insert into tableName values() + * + * @param table 表名 + * @param data insert数据 + * @return + * @throws SQLException + */ + public int insert(String table, T data) throws Exception { + if (StringUtil.isEmpty(table)) { + throw new SQLException("table is null!"); + } + if (data == null) { + throw new SQLException("data is null!"); + } + StringBuilder valuesql = new StringBuilder(); + StringBuilder keysql = new StringBuilder(); + // 获取类中的全部定义字段 + Field[] fields = data.getClass().getDeclaredFields(); + int count = 0; + for (Field field : fields) { + Object value = getFieldValue(field, data); + if (value == null) + continue; + if (count > 0) { + keysql.append(CHAR_COMMA); + valuesql.append(CHAR_COMMA); + } + count++; + keysql.append(field.getName()); + if ((value instanceof Boolean) || (value instanceof Byte) || (value instanceof Short) + || (value instanceof Integer) || (value instanceof Long) || (value instanceof Float) + || (value instanceof Double)) { + valuesql.append(value); + } else if ((value instanceof String)) { + valuesql.append(CHAR_QUOTES); + valuesql.append(value); + valuesql.append(CHAR_QUOTES); + } + } + String sql = String.format("INSERT INTO %s (%s) VALUES(%s)", table, keysql, valuesql); + return __executeUpdate(sql); + } + + /** + * 数据库 insert into tableName values() + * + * @param table 表名 + * @param list insert数据 + * @return + * @throws SQLException + */ + public int insertBatch(String table, List list) throws Exception { + if (StringUtil.isEmpty(table)) { + throw new SQLException("table is null!"); + } + if (list == null) { + throw new SQLException("list is null!"); + } + if (list.size() == 0) + return 0; + + StringBuilder valuesql = new StringBuilder(); + StringBuilder keysql = new StringBuilder(); + // 获取类中的全部定义字段 + T data = list.get(0); + Class classz = data.getClass(); + Field[] fields = classz.getDeclaredFields(); + + int count = 0; + List methodList = new ArrayList<>(); + for (Field field : fields) { + int modifiers = field.getModifiers(); + if ((Modifier.isTransient(modifiers)) || (Modifier.isStatic(modifiers))) { + continue; + } + String fieldName = field.getName(); + boolean isBool = field.getType().getSimpleName().equalsIgnoreCase(TYPE_BOOLEAN); + String getterName = isBool ? "is" : "get" + StringUtil.capitalize(fieldName); + Method getterMethod = classz.getMethod(getterName, new Class[0]); + methodList.add(getterMethod); + if (count > 0) { + keysql.append(CHAR_COMMA); + valuesql.append(CHAR_COMMA); + } + count++; + keysql.append(field.getName()); + valuesql.append(CHAR_UNKNOWN); + } + String sql = String.format("INSERT INTO %s (%s) VALUES(%s)", table, keysql, valuesql); + Connection conn = null; + PreparedStatement stmt = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareStatement(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + conn.setAutoCommit(false); + for (int i = 0; i < list.size(); ++i) { + T obj = list.get(i); + for (int k = 1; k <= count; ++k) { + Method method = methodList.get(k - 1); + Object value = method.invoke(obj, new Object[0]); + stmt.setObject(k, value); + } + stmt.addBatch(); + } + stmt.executeBatch(); + conn.commit(); + return 0; + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + + /** + * 数据库 update tableName set + * + * @param table 表名 + * @param data 更新的字段 + * @param where sql条件 + * @return + * @throws SQLException + */ + public int update(String table, ITObject data, String where) throws SQLException { + if (StringUtil.isEmpty(table)) { + throw new SQLException("table is null!"); + } + if (data == null || data.size() == 0) { + throw new SQLException("data is null!"); + } + StringBuilder valuesql = new StringBuilder(); + Set keys = data.getKeys(); + int count = 0; + for (String key : keys) { + TDataWrapper wrapper = data.get(key); + if (count > 0) { + valuesql.append(CHAR_COMMA); + } + count++; + valuesql.append(key); + valuesql.append("="); + switch (wrapper.getTypeId()) { + case SHORT: + case INT: + case DOUBLE: + case FLOAT: + case BYTE: + case BOOL: + case LONG: + valuesql.append(wrapper.getObject()); + break; + case STRING: + valuesql.append(CHAR_QUOTES); + valuesql.append(wrapper.getObject()); + valuesql.append(CHAR_QUOTES); + break; + case TOBJECT: + ITObject mo = (ITObject) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(mo.toJson()); + valuesql.append(CHAR_QUOTES); + break; + case TARRAY: + ITArray ao = (ITArray) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(ao.toJson()); + valuesql.append(CHAR_QUOTES); + break; + default: + break; + } + } + + String sql = String.format("UPDATE %s SET %s ", table, valuesql); + if (where != null && where.length() > 0) + sql = sql + "where " + where; + return __executeUpdate(sql); + } + + /** + * 数据库 update tableName set + * + * @param table 表名 + * @param data 更新的字段 + * @param where sql条件 + * @return + * @throws Exception + */ + public int update(String table, T data, String where) throws Exception { + if (StringUtil.isEmpty(table)) { + throw new SQLException("table is null!"); + } + if (data == null) { + throw new SQLException("data is null!"); + } + StringBuilder valuesql = new StringBuilder(); + + // 获取类中的全部定义字段 + Field[] fields = data.getClass().getDeclaredFields(); + int count = 0; + for (Field field : fields) { + Object value = getFieldValue(field, data); + if (value == null) + continue; + if (count > 0) { + valuesql.append(CHAR_COMMA); + } + count++; + valuesql.append(field.getName()); + valuesql.append("="); + if ((value instanceof Boolean) || (value instanceof Byte) || (value instanceof Short) + || (value instanceof Integer) || (value instanceof Long) || (value instanceof Float) + || (value instanceof Double)) { + valuesql.append(value); + } else if ((value instanceof String)) { + valuesql.append(CHAR_QUOTES); + valuesql.append(value); + valuesql.append(CHAR_QUOTES); + } + } + + String sql = String.format("UPDATE %s SET %s ", table, valuesql); + if (where != null && where.length() > 0) + sql = sql + "where " + where; + return __executeUpdate(sql); + } + + /** + * 存储过程调用 call prepareName() + * + * @param prepareName 存储过程名 + * @param data 数据 + * @return + * @throws SQLException + */ + public ITArray prepareCall(String prepareName, ITArray data) throws SQLException { + return prepareCall(prepareName, data, true); + } + + /** + * 存储过程调用 call prepareName() + * + * @param prepareName 存储过程名 + * @param data 数据 + * @return + * @throws SQLException + */ + public void prepareCallNonResult(String prepareName, ITArray data) throws SQLException { + prepareCall(prepareName, data, false); + } + + /** + * 存储过程调用 call prepareName() + * + * @param prepareName 存储过程名 + * @param data 数据 + * @return + * @throws SQLException + */ + private ITArray prepareCall(String prepareName, ITArray data, boolean resultSet) throws SQLException { + if (StringUtil.isEmpty(prepareName)) { + throw new SQLException("prepare name is null!"); + } + if (data == null) { + throw new SQLException("data is null!"); + } + StringBuilder valuesql = new StringBuilder(); + + int count = 0; + for (int i = 0; i < data.size(); ++i) { + + TDataWrapper wrapper = data.get(i); + if (count > 0) { + valuesql.append(CHAR_COMMA); + } + count++; + switch (wrapper.getTypeId()) { + case SHORT: + case INT: + case DOUBLE: + case FLOAT: + case BYTE: + case BOOL: + case LONG: + valuesql.append(wrapper.getObject()); + break; + case STRING: + valuesql.append(CHAR_QUOTES); + valuesql.append(wrapper.getObject()); + valuesql.append(CHAR_QUOTES); + break; + case TOBJECT: + ITObject mo = (ITObject) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(mo.toJson()); + valuesql.append(CHAR_QUOTES); + break; + case TARRAY: + ITArray ao = (ITArray) wrapper.getObject(); + valuesql.append(CHAR_QUOTES); + valuesql.append(ao.toJson()); + valuesql.append(CHAR_QUOTES); + break; + default: + break; + } + } + String sql = String.format("{call %s(%s)}", prepareName, valuesql); + return executeCall(sql, resultSet); + } + + /** + * 存储过程调用 + * + * @param sql + * @param resultSet + * @return + * @throws SQLException + */ + public ITArray executeCall(String sql, boolean resultSet) throws SQLException { + Connection conn = null; + CallableStatement stmt = null; + ResultSet rset = null; + try { + conn = ds.getConnection(); + if (conn == null) + throw new SQLException("db connection is null!"); + stmt = conn.prepareCall(sql); + if (stmt == null) + throw new SQLException(sql + "sql error!"); + if (resultSet) { + rset = stmt.executeQuery(); + ITArray list = TArray.newFromResultSet(rset); + return list; + } else { + stmt.executeUpdate(); + return null; + } + } finally { + try { + if (rset != null) + rset.close(); + } finally { + try { + if (stmt != null) + stmt.close(); + } finally { + if (conn != null) + conn.close(); + } + } + } + } + + /** + * 获取当前DB名称 + * + * @return + */ + public String getName() { + return name; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Cache.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Cache.java new file mode 100644 index 0000000..e64c941 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Cache.java @@ -0,0 +1,1220 @@ +package com.taurus.core.plugin.redis; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPubSub; +import redis.clients.jedis.Pipeline; + +/** + * Cache. + * Cache api 添加了中文注释,便于工程师更方便使用,另外还原样保持了 + * Jedis api 的方法名称及使用方法,以便于仅仅通过查看 Redis 文档 + * 即可快速掌握使用方法 + * Redis 命令参考: http://redisdoc.com/ + */ +public class Cache { + + protected String name; + protected JedisPool jedisPool; + private final static Logger log; + + static { + log = Logger.getLogger(Cache.class); + } + + + protected Cache() { + + } + + public Cache(String name, JedisPool jedisPool) { + this.name = name; + this.jedisPool = jedisPool; + } + + /** + * 存放 key value 对到 redis + * 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。 + * 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。 + */ + public String set(String key, String value) { + Jedis jedis = getJedis(); + try { + return jedis.set(key, value); + } + finally {close(jedis);} + } + + /** + * 存放 key value 对到 redis,并将 key 的生存时间设为 seconds (以秒为单位)。 + * 如果 key 已经存在, SETEX 命令将覆写旧值。 + */ + public String setex(String key, int seconds, String value) { + Jedis jedis = getJedis(); + try { + return jedis.setex(key, seconds, value); + } + finally {close(jedis);} + } + + /** + * 将 key 的值设为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作。 SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
+ *1 设置成功
+ *0 设置失败 + */ + public Long setnx(String key, String value) { + Jedis jedis = getJedis(); + try { + return jedis.setnx(key, value); + } + finally {close(jedis);} + } + + /** + * 返回 key 所关联的 value 值 + * 如果 key 不存在那么返回特殊值 nil 。 + */ + public String get(String key) { + Jedis jedis = getJedis(); + try { + return jedis.get(key); + } + finally {close(jedis);} + } + + /** + * 删除给定的一个 key + * 不存在的 key 会被忽略。 + */ + public Long del(String key) { + Jedis jedis = getJedis(); + try { + return jedis.del(key); + } + finally {close(jedis);} + } + + /** + * 删除给定的多个 key + * 不存在的 key 会被忽略。 + */ + public Long del(String... keys) { + Jedis jedis = getJedis(); + try { + return jedis.del(keys); + } + finally {close(jedis);} + } + + /** + * 查找所有符合给定模式 pattern 的 key 。 + * KEYS * 匹配数据库中所有 key 。 + * KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 + * KEYS h*llo 匹配 hllo 和 heeeeello 等。 + * KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。 + * 特殊符号用 \ 隔开 + */ + public Set keys(String pattern) { + Jedis jedis = getJedis(); + try { + return jedis.keys(pattern); + } + finally {close(jedis);} + } + + /** + * 同时设置一个或多个 key-value 对。 + * 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。 + * MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。 + *
+	 * 例子:
+	 * Cache cache = RedisKit.use();			// 使用 Redis 的 cache
+	 * cache.mset("k1", "v1", "k2", "v2");		// 放入多个 key value 键值对
+	 * List list = cache.mget("k1", "k2");		// 利用多个键值得到上面代码放入的值
+	 * 
+ */ + public String mset(String... keysValues) { + if (keysValues.length % 2 != 0) + throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd"); + Jedis jedis = getJedis(); + try { + String[] kv = new String[keysValues.length]; + for (int i=0; i mget(String... keys) { + Jedis jedis = getJedis(); + try { + List data = jedis.mget(keys); + return data; + } + finally {close(jedis);} + } + + /** + * 将 key 中储存的数字值减一。 + * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。 + * 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 + * 本操作的值限制在 64 位(bit)有符号数字表示之内。 + * 关于递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。 + */ + public Long decr(String key) { + Jedis jedis = getJedis(); + try { + return jedis.decr(key); + } + finally {close(jedis);} + } + + /** + * 将 key 所储存的值减去减量 decrement 。 + * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。 + * 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 + * 本操作的值限制在 64 位(bit)有符号数字表示之内。 + * 关于更多递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。 + */ + public Long decrBy(String key, long longValue) { + Jedis jedis = getJedis(); + try { + return jedis.decrBy(key, longValue); + } + finally {close(jedis);} + } + + /** + * 将 key 中储存的数字值增一。 + * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。 + * 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 + * 本操作的值限制在 64 位(bit)有符号数字表示之内。 + */ + public Long incr(String key) { + Jedis jedis = getJedis(); + try { + return jedis.incr(key); + } + finally {close(jedis);} + } + + /** + * 将 key 所储存的值加上增量 increment 。 + * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。 + * 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 + * 本操作的值限制在 64 位(bit)有符号数字表示之内。 + * 关于递增(increment) / 递减(decrement)操作的更多信息,参见 INCR 命令。 + */ + public Long incrBy(String key, long longValue) { + Jedis jedis = getJedis(); + try { + return jedis.incrBy(key, longValue); + } + finally {close(jedis);} + } + + /** + * 检查给定 key 是否存在。 + */ + public boolean exists(String key) { + Jedis jedis = getJedis(); + try { + return jedis.exists(key); + } + finally {close(jedis);} + } + + /** + * 从当前数据库中随机返回(不删除)一个 key 。 + */ + public String randomKey() { + Jedis jedis = getJedis(); + try { + return jedis.randomKey(); + } + finally {close(jedis);} + } + + /** + * 将 key 改名为 newkey 。 + * 当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。 + * 当 newkey 已经存在时, RENAME 命令将覆盖旧值。 + */ + public String rename(String oldkey, String newkey) { + Jedis jedis = getJedis(); + try { + return jedis.rename(oldkey, newkey); + } + finally {close(jedis);} + } + + /** + * 将当前数据库的 key 移动到给定的数据库 db 当中。 + * 如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。 + * 因此,也可以利用这一特性,将 MOVE 当作锁(locking)原语(primitive)。 + */ + public Long move(String key, int dbIndex) { + Jedis jedis = getJedis(); + try { + return jedis.move(key, dbIndex); + } + finally {close(jedis);} + } + + /** + * 将 key 原子性地从当前实例传送到目标实例的指定数据库上,一旦传送成功, key 保证会出现在目标实例上,而当前实例上的 key 会被删除。 + */ + public String migrate(String host, int port, String key, int destinationDb, int timeout) { + Jedis jedis = getJedis(); + try { + return jedis.migrate(host, port, key, destinationDb, timeout); + } + finally {close(jedis);} + } + + /** + * 切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。 + * 默认使用 0 号数据库。 + * 注意:在 Jedis 对象被关闭时,数据库又会重新被设置为初始值,所以本方法 select(...) + * 正常工作需要使用如下方式之一: + * 1:使用 RedisInterceptor,在本线程内共享同一个 Jedis 对象 + * 2:使用 Redis.call(ICallback) 进行操作 + * 3:自行获取 Jedis 对象进行操作 + */ + public String select(int databaseIndex) { + Jedis jedis = getJedis(); + try { + return jedis.select(databaseIndex); + } + finally {close(jedis);} + } + + /** + * 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。 + * 在 Redis 中,带有生存时间的 key 被称为『易失的』(volatile)。 + */ + public Long expire(String key, int seconds) { + Jedis jedis = getJedis(); + try { + return jedis.expire(key, seconds); + } + finally {close(jedis);} + } + + /** + * EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置生存时间。不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。 + */ + public Long expireAt(String key, long unixTime) { + Jedis jedis = getJedis(); + try { + return jedis.expireAt(key, unixTime); + } + finally {close(jedis);} + } + + /** + * 这个命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。 + */ + public Long pexpire(String key, long milliseconds) { + Jedis jedis = getJedis(); + try { + return jedis.pexpire(key, milliseconds); + } + finally {close(jedis);} + } + + /** + * 这个命令和 EXPIREAT 命令类似,但它以毫秒为单位设置 key 的过期 unix 时间戳,而不是像 EXPIREAT 那样,以秒为单位。 + */ + public Long pexpireAt(String key, long millisecondsTimestamp) { + Jedis jedis = getJedis(); + try { + return jedis.pexpireAt(key, millisecondsTimestamp); + } + finally {close(jedis);} + } + + /** + * 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 + * 当 key 存在但不是字符串类型时,返回一个错误。 + */ + public String getSet(String key, String value) { + Jedis jedis = getJedis(); + try { + return jedis.getSet(key, value); + } + finally {close(jedis);} + } + + /** + * 移除给定 key 的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。 + */ + public Long persist(String key) { + Jedis jedis = getJedis(); + try { + return jedis.persist(key); + } + finally {close(jedis);} + } + + /** + * 返回 key 所储存的值的类型。 + */ + public String type(String key) { + Jedis jedis = getJedis(); + try { + return jedis.type(key); + } + finally {close(jedis);} + } + + /** + * 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。 + */ + public Long ttl(String key) { + Jedis jedis = getJedis(); + try { + return jedis.ttl(key); + } + finally {close(jedis);} + } + + /** + * 这个命令类似于 TTL 命令,但它以毫秒为单位返回 key 的剩余生存时间,而不是像 TTL 命令那样,以秒为单位。 + */ + public Long pttl(String key) { + Jedis jedis = getJedis(); + try { + return jedis.pttl(key); + } + finally {close(jedis);} + } + + /** + * 对象被引用的数量 + */ + public Long objectRefcount(String key) { + Jedis jedis = getJedis(); + try { + return jedis.objectRefcount(key); + } + finally {close(jedis);} + } + + /** + * 对象没有被访问的空闲时间 + */ + public Long objectIdletime(String key) { + Jedis jedis = getJedis(); + try { + return jedis.objectIdletime(key); + } + finally {close(jedis);} + } + + /** + * 将哈希表 key 中的域 field 的值设为 value 。 + * 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。 + * 如果域 field 已经存在于哈希表中,旧值将被覆盖。 + */ + public Long hset(String key, String field, String value) { + Jedis jedis = getJedis(); + try { + return jedis.hset(key, field, value); + } + finally {close(jedis);} + } + + /** + * 只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。如果字段已存在,该操作无效果。
+ * 1:如果字段是个新的字段,并成功赋值
+ * 0:如果哈希集中已存在该字段,没有操作被执行 + */ + public Long hsetnx(String key, String field, String value) { + Jedis jedis = getJedis(); + try { + return jedis.hsetnx(key, field, value); + } + finally {close(jedis);} + } + + + /** + * 同时将多个 field-value (域-值)对设置到哈希表 key 中。 + * 此命令会覆盖哈希表中已存在的域。 + * 如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。 + */ + public String hmset(String key, Map hash) { + Jedis jedis = getJedis(); + try { + return jedis.hmset(key, hash); + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中给定域 field 的值。 + */ + public String hget(String key, String field) { + Jedis jedis = getJedis(); + try { + return jedis.hget(key, field); + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中,一个或多个给定域的值。 + * 如果给定的域不存在于哈希表,那么返回一个 nil 值。 + * 因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。 + */ + public List hmget(String key, String... fields) { + Jedis jedis = getJedis(); + try { + return jedis.hmget(key, fields); + } + finally {close(jedis);} + } + + /** + * 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。 + */ + public Long hdel(String key, String... fields) { + Jedis jedis = getJedis(); + try { + return jedis.hdel(key, fields); + } + finally {close(jedis);} + } + + /** + * 查看哈希表 key 中,给定域 field 是否存在。 + */ + public boolean hexists(String key, String field) { + Jedis jedis = getJedis(); + try { + return jedis.hexists(key, field); + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中,所有的域和值。 + * 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。 + */ + public Map hgetAll(String key) { + Jedis jedis = getJedis(); + try { + Map data = jedis.hgetAll(key); + return data; + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中所有域的值。 + */ + public List hvals(String key) { + Jedis jedis = getJedis(); + try { + List data = jedis.hvals(key); + return data; + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中的所有域。 + * 底层实现此方法取名为 hfields 更为合适,在此仅为与底层保持一致 + */ + public Set hkeys(String key) { + Jedis jedis = getJedis(); + try { + Set fieldSet = jedis.hkeys(key); + return fieldSet; + } + finally {close(jedis);} + } + + /** + * 返回哈希表 key 中域的数量。 + */ + public Long hlen(String key) { + Jedis jedis = getJedis(); + try { + return jedis.hlen(key); + } + finally {close(jedis);} + } + + /** + * 为哈希表 key 中的域 field 的值加上增量 increment 。 + * 增量也可以为负数,相当于对给定域进行减法操作。 + * 如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。 + * 如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。 + * 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。 + * 本操作的值被限制在 64 位(bit)有符号数字表示之内。 + */ + public Long hincrBy(String key, String field, long value) { + Jedis jedis = getJedis(); + try { + return jedis.hincrBy(key, field, value); + } + finally {close(jedis);} + } + + /** + * 为哈希表 key 中的域 field 加上浮点数增量 increment 。 + * 如果哈希表中没有域 field ,那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ,然后再执行加法操作。 + * 如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。 + * 当以下任意一个条件发生时,返回一个错误: + * 1:域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型) + * 2:域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number) + * HINCRBYFLOAT 命令的详细功能和 INCRBYFLOAT 命令类似,请查看 INCRBYFLOAT 命令获取更多相关信息。 + */ + public Double hincrByFloat(String key, String field, double value) { + Jedis jedis = getJedis(); + try { + return jedis.hincrByFloat(key, field, value); + } + finally {close(jedis);} + } + + /** + * 返回列表 key 中,下标为 index 的元素。 + * 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 + * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 + * 如果 key 不是列表类型,返回一个错误。 + */ + + /** + * 返回列表 key 中,下标为 index 的元素。 + * 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素, + * 以 1 表示列表的第二个元素,以此类推。 + * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 + * 如果 key 不是列表类型,返回一个错误。 + */ + public String lindex(String key, long index) { + Jedis jedis = getJedis(); + try { + return jedis.lindex(key, index); + } + finally {close(jedis);} + } + + /** + * 获取记数器的值 + */ + public Long getCounter(String key) { + Jedis jedis = getJedis(); + try { + String ret = jedis.get(key); + return ret != null ? Long.parseLong(ret) : null; + } + finally {close(jedis);} + } + + /** + * 返回列表 key 的长度。 + * 如果 key 不存在,则 key 被解释为一个空列表,返回 0 . + * 如果 key 不是列表类型,返回一个错误。 + */ + public Long llen(String key) { + Jedis jedis = getJedis(); + try { + return jedis.llen(key); + } + finally {close(jedis);} + } + + /** + * 移除并返回列表 key 的头元素。 + */ + public String lpop(String key) { + Jedis jedis = getJedis(); + try { + return jedis.lpop(key); + } + finally {close(jedis);} + } + + /** + * 将一个或多个值 value 插入到列表 key 的表头 + * 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说, + * 对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a , + * 这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。 + * 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。 + * 当 key 存在但不是列表类型时,返回一个错误。 + */ + public Long lpush(String key, String... values) { + Jedis jedis = getJedis(); + try { + return jedis.lpush(key, values); + } + finally {close(jedis);} + } + + /** + * 将列表 key 下标为 index 的元素的值设置为 value 。 + * 当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,返回一个错误。 + * 关于列表下标的更多信息,请参考 LINDEX 命令。 + */ + public String lset(String key, long index, String value) { + Jedis jedis = getJedis(); + try { + return jedis.lset(key, index, value); + } + finally {close(jedis);} + } + + /** + * 根据参数 count 的值,移除列表中与参数 value 相等的元素。 + * count 的值可以是以下几种: + * count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。 + * count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。 + * count = 0 : 移除表中所有与 value 相等的值。 + */ + public Long lrem(String key, long count, String value) { + Jedis jedis = getJedis(); + try { + return jedis.lrem(key, count, value); + } + finally {close(jedis);} + } + + /** + * 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。 + * 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 + * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 + *
+	 * 例子:
+	 * 获取 list 中所有数据:cache.lrange(listKey, 0, -1);
+	 * 获取 list 中下标 1 到 3 的数据: cache.lrange(listKey, 1, 3);
+	 * 
+ */ + public List lrange(String key, long start, long end) { + Jedis jedis = getJedis(); + try { + List data = jedis.lrange(key, start, end); + return data; + } + finally {close(jedis);} + } + + /** + * 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 + * 举个例子,执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除。 + * 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 + * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 + * 当 key 不是列表类型时,返回一个错误。 + */ + public String ltrim(String key, long start, long end) { + Jedis jedis = getJedis(); + try { + return jedis.ltrim(key, start, end); + } + finally {close(jedis);} + } + + /** + * 移除并返回列表 key 的尾元素。 + */ + public String rpop(String key) { + Jedis jedis = getJedis(); + try { + return jedis.rpop(key); + } + finally {close(jedis);} + } + + /** + * 命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作: + * 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。 + * 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。 + */ + public String rpoplpush(String srcKey, String dstKey) { + Jedis jedis = getJedis(); + try { + return jedis.rpoplpush(srcKey, dstKey); + } + finally {close(jedis);} + } + + /** + * 将一个或多个值 value 插入到列表 key 的表尾(最右边)。 + * 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如 + * 对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c , + * 等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。 + * 如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。 + * 当 key 存在但不是列表类型时,返回一个错误。 + */ + public Long rpush(String key, String... values) { + Jedis jedis = getJedis(); + try { + return jedis.rpush(key, values); + } + finally {close(jedis);} + } + + /** + * BLPOP 是列表的阻塞式(blocking)弹出原语。 + * 它是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。 + * 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。 + * + * 参考:http://redisdoc.com/list/blpop.html + * 命令行:BLPOP key [key ...] timeout + */ + public List blpop(int timeout, String... keys) { + Jedis jedis = getJedis(); + try { + List data = jedis.blpop(timeout, keys); + return data; + } + finally {close(jedis);} + } + + /** + * BRPOP 是列表的阻塞式(blocking)弹出原语。 + * 它是 RPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP 命令阻塞,直到等待超时或发现可弹出元素为止。 + * 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。 + * 关于阻塞操作的更多信息,请查看 BLPOP 命令, BRPOP 除了弹出元素的位置和 BLPOP 不同之外,其他表现一致。 + * + * 参考:http://redisdoc.com/list/brpop.html + * 命令行:BRPOP key [key ...] timeout + */ + public List brpop(int timeout, String... keys) { + Jedis jedis = getJedis(); + try { + List data = jedis.brpop(timeout, keys); + return data; + } + finally {close(jedis);} + } + + /** + * 使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。 + * 通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值。 + */ + public String ping() { + Jedis jedis = getJedis(); + try { + return jedis.ping(); + } + finally {close(jedis);} + } + + /** + * 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。 + * 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。 + * 当 key 不是集合类型时,返回一个错误。 + */ + public Long sadd(String key, String... members) { + Jedis jedis = getJedis(); + try { + return jedis.sadd(key, members); + } + finally {close(jedis);} + } + + /** + * 返回集合 key 的基数(集合中元素的数量)。 + */ + public Long scard(String key) { + Jedis jedis = getJedis(); + try { + return jedis.scard(key); + } + finally {close(jedis);} + } + + /** + * 移除并返回集合中的一个随机元素。 + * 如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。 + */ + public String spop(String key) { + Jedis jedis = getJedis(); + try { + return jedis.spop(key); + } + finally {close(jedis);} + } + + /** + * 返回集合 key 中的所有成员。 + * 不存在的 key 被视为空集合。 + */ + public Set smembers(String key) { + Jedis jedis = getJedis(); + try { + Set data = jedis.smembers(key); + return data; + } + finally {close(jedis);} + } + + /** + * 判断 member 元素是否集合 key 的成员。 + */ + public boolean sismember(String key, String member) { + Jedis jedis = getJedis(); + try { + return jedis.sismember(key, member); + } + finally {close(jedis);} + } + + /** + * 返回多个集合的交集,多个集合由 keys 指定 + */ + public Set sinter(String... keys) { + Jedis jedis = getJedis(); + try { + Set data = jedis.sinter(keys); + return data; + } + finally {close(jedis);} + } + + /** + * 返回集合中的一个随机元素。 + */ + public String srandmember(String key) { + Jedis jedis = getJedis(); + try { + return jedis.srandmember(key); + } + finally {close(jedis);} + } + + /** + * 返回集合中的 count 个随机元素。 + * 从 Redis 2.6 版本开始, SRANDMEMBER 命令接受可选的 count 参数: + * 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。 + * 如果 count 大于等于集合基数,那么返回整个集合。 + * 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。 + * 该操作和 SPOP 相似,但 SPOP 将随机元素从集合中移除并返回,而 SRANDMEMBER 则仅仅返回随机元素,而不对集合进行任何改动。 + */ + public List srandmember(String key, int count) { + Jedis jedis = getJedis(); + try { + List data = jedis.srandmember(key, count); + return data; + } + finally {close(jedis);} + } + + /** + * 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。 + */ + public Long srem(String key, String... members) { + Jedis jedis = getJedis(); + try { + return jedis.srem(key, members); + } + finally {close(jedis);} + } + + /** + * 返回多个集合的并集,多个集合由 keys 指定 + * 不存在的 key 被视为空集。 + */ + public Set sunion(String... keys) { + Jedis jedis = getJedis(); + try { + Set data = jedis.sunion(keys); + return data; + } + finally {close(jedis);} + } + + /** + * 返回一个集合的全部成员,该集合是所有给定集合之间的差集。 + * 不存在的 key 被视为空集。 + */ + public Set sdiff(String... keys) { + Jedis jedis = getJedis(); + try { + Set data = jedis.sdiff(keys); + return data; + } + finally {close(jedis);} + } + + /** + * 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。 + * 如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值, + * 并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。 + */ + public Long zadd(String key, double score, String member) { + Jedis jedis = getJedis(); + try { + return jedis.zadd(key, score, member); + } + finally {close(jedis);} + } + + public Long zadd(String key, Map scoreMembers) { + Jedis jedis = getJedis(); + try { +// Map para = new HashMap(); +// for (Entry e : scoreMembers.entrySet()) +// para.put(e.getKey(), e.getValue()); // valueToBytes is important + return jedis.zadd(key, scoreMembers); + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 的基数。 + */ + public Long zcard(String key) { + Jedis jedis = getJedis(); + try { + return jedis.zcard(key); + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。 + * 关于参数 min 和 max 的详细使用方法,请参考 ZRANGEBYSCORE 命令。 + */ + public Long zcount(String key, double min, double max) { + Jedis jedis = getJedis(); + try { + return jedis.zcount(key, min, max); + } + finally {close(jedis);} + } + + /** + * 为有序集 key 的成员 member 的 score 值加上增量 increment 。 + */ + public Double zincrby(String key, double score, String member) { + Jedis jedis = getJedis(); + try { + return jedis.zincrby(key, score, member); + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中,指定区间内的成员。 + * 其中成员的位置按 score 值递增(从小到大)来排序。 + * 具有相同 score 值的成员按字典序(lexicographical order )来排列。 + * 如果你需要成员按 score 值递减(从大到小)来排列,请使用 ZREVRANGE 命令。 + */ + public Set zrange(String key, long start, long end) { + Jedis jedis = getJedis(); + try { + Set data = jedis.zrange(key, start, end); + return data; + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中,指定区间内的成员。 + * 其中成员的位置按 score 值递减(从大到小)来排列。 + * 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。 + * 除了成员按 score 值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。 + */ + public Set zrevrange(String key, long start, long end) { + Jedis jedis = getJedis(); + try { + Set data = jedis.zrevrange(key, start, end); + return data; + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。 + * 有序集成员按 score 值递增(从小到大)次序排列。 + */ + public Set zrangeByScore(String key, double min, double max) { + Jedis jedis = getJedis(); + try { + Set data = jedis.zrangeByScore(key, min, max); + return data; + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。 + * 排名以 0 为底,也就是说, score 值最小的成员排名为 0 。 + * 使用 ZREVRANK 命令可以获得成员按 score 值递减(从大到小)排列的排名。 + */ + public Long zrank(String key, String member) { + Jedis jedis = getJedis(); + try { + return jedis.zrank(key, member); + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。 + * 排名以 0 为底,也就是说, score 值最大的成员排名为 0 。 + * 使用 ZRANK 命令可以获得成员按 score 值递增(从小到大)排列的排名。 + */ + public Long zrevrank(String key, String member) { + Jedis jedis = getJedis(); + try { + return jedis.zrevrank(key, member); + } + finally {close(jedis);} + } + + /** + * 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。 + * 当 key 存在但不是有序集类型时,返回一个错误。 + */ + public Long zrem(String key, String... members) { + Jedis jedis = getJedis(); + try { + return jedis.zrem(key, members); + } + finally {close(jedis);} + } + + /** + * 返回有序集 key 中,成员 member 的 score 值。 + * 如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。 + */ + public Double zscore(String key, String member) { + Jedis jedis = getJedis(); + try { + return jedis.zscore(key, member); + } + finally {close(jedis);} + } + + + /** + * del key + * rpush key values + */ + public void rpushAll(final String key, final List values) { + Jedis jedis = getJedis(); + try { + Pipeline pipeline = getJedis().pipelined(); + pipeline.del(key); + for (String value : values) { + pipeline.rpush(key, value); + } + pipeline.sync(); + } finally { + close(jedis); + } + + } + + /** + * call script + * @param func + * @return + */ + public Object call(final String func) { + return call(func,0,new String[0]); + } + + /** + * call script + * @param func + * @param keyCount + * @param params + * @return + */ + public Object call(final String func,int keyCount, String... params) { + Jedis jedis = getJedis(); + try { + String sha = jedis.get("script#"+func); + if(StringUtil.isNotEmpty(sha)) { + return jedis.evalsha(sha,keyCount,params); + } + }finally {close(jedis);} + return null; + } + + /* ======================================Pub/Sub====================================== */ + + /** + * publish 订阅 + */ + public Long publish(final String channel, final String message) { + Jedis jedis =getJedis(); + try { + return jedis.publish(channel, message); + } + finally {close(jedis);} + + } + + /** + * 订阅给定的一个频道的信息 + */ + public void subscribe(final JedisPubSub jedisPubSub, final String channel) { + Jedis jedis =getJedis(); + try { + jedis.subscribe(jedisPubSub, channel); + } + finally {close(jedis);} + } + + /** + * 取消订阅 + */ + public void unsubscribe(final JedisPubSub jedisPubSub) { + jedisPubSub.unsubscribe(); + } + + + // --------- + + public String getName() { + return name; + } + + public JedisPool getJedisPool() { + return jedisPool; + } + // --------- + + public Jedis getJedis() { +// log.info("连接池使用:"+jedisPool.getNumActive()); + + Jedis jedis = jedisPool.getResource(); + return jedis; + } + + public void close(Jedis jedis) { + if (jedis != null) + jedis.close(); + } + + +} + + + + + + diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Redis.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Redis.java new file mode 100644 index 0000000..a76d4b3 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/Redis.java @@ -0,0 +1,70 @@ +package com.taurus.core.plugin.redis; + +import java.util.concurrent.ConcurrentHashMap; + +import com.taurus.core.util.StringUtil; + +/** + * Redis. + * redis 工具类 + *
+ * 例如:
+ * Redis.use().set("key", "value");
+ * Redis.use().get("key");
+ * 
+ */ +public class Redis { + + static Cache mainCache = null; + + static final ConcurrentHashMap cacheMap = new ConcurrentHashMap(); + + static void addCache(Cache cache) { + if (cache == null) + throw new IllegalArgumentException("cache can not be null"); + if (cacheMap.containsKey(cache.getName())) + throw new IllegalArgumentException("The cache name already exists"); + + cacheMap.put(cache.getName(), cache); + if (mainCache == null) + mainCache = cache; + } + + static void removeCache(String cacheName) { + Cache cache = cacheMap.remove(cacheName); + if(cache == mainCache) { + cache.jedisPool.destroy(); + mainCache = null; + } + } + + /** + * 提供一个设置设置主缓存 mainCache 的机会,否则第一个被初始化的 Cache 将成为 mainCache + */ + public static void setMainCache(String cacheName) { + if (StringUtil.isEmpty(cacheName)) + throw new IllegalArgumentException("cacheName can not be blank"); + cacheName = cacheName.trim(); + Cache cache = cacheMap.get(cacheName); + if (cache == null) + throw new IllegalArgumentException("the cache not exists: " + cacheName); + + Redis.mainCache = cache; + } + + public static Cache use() { + return mainCache; + } + + public static Cache use(String cacheName) { + return cacheMap.get(cacheName); + } + + public static ConcurrentHashMap getCacheMap() { + return cacheMap; + } +} + + + + diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisLock.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisLock.java new file mode 100644 index 0000000..8028caf --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisLock.java @@ -0,0 +1,76 @@ +package com.taurus.core.plugin.redis; + +import java.util.UUID; + +import redis.clients.jedis.Jedis; + +/** + * RedisLock + */ +public class RedisLock { + private static final long DEFAULT_TIME_OUT = 180000; + private static final int EXPIRE = 10000; + private static final String LOCK_SUCCESS = "OK"; + private static final String SET_IF_NOT_EXIST = "NX"; + private static final String SET_WITH_EXPIRE_TIME = "PX"; + private static final String checkAndDelScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " + + "return redis.call('del', KEYS[1]) " + + "else " + + "return 0 " + + "end"; + + private Jedis jedis; + private String key; + private String lock_value; + + /** + * This creates a RedisLock + * + * @param key key + * @param jedis + */ + public RedisLock(String key, Jedis jedis) { + this.key = key + "{lock}"; + this.jedis = jedis; + lock_value = UUID.randomUUID().toString()+Thread.currentThread().getId() + System.nanoTime(); + } + + /** + * lock(); try { doSomething(); } finally { unlock() } + */ + public boolean lock() { + long time = System.currentTimeMillis(); + try { + while ((System.currentTimeMillis() - time) < DEFAULT_TIME_OUT) { + String result = jedis.set(key, lock_value, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, EXPIRE); + if (LOCK_SUCCESS.equals(result)) { + return true; + } + Thread.sleep(5); + } + } catch (Exception e) { + throw new RuntimeException("Locking error", e); + } + return false; + } + + /** + * lock(); try { doSomething(); } finally { unlock() } + */ + public void unlock() { + unlock(true); + } + + /** + * lock(); try { doSomething(); } finally { unlock() } + */ + public void unlock(boolean closeJedis) { + try { + jedis.eval(checkAndDelScript, 1, key, lock_value); + } finally { + if (closeJedis) { + this.jedis.close(); + } + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisPlugin.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisPlugin.java new file mode 100644 index 0000000..ed30d09 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/plugin/redis/RedisPlugin.java @@ -0,0 +1,141 @@ +package com.taurus.core.plugin.redis; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.jdom.Element; + +import com.taurus.core.plugin.IPlugin; +import com.taurus.core.plugin.redis.RedisPlugin.RedisConfig.InfoConfig; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +/** + * RedisPlugin. + * RedisPlugin 支持多个 Redis 服务端,只需要创建多个 RedisPlugin 对象 + * 对应这多个不同的 Redis 服务端即可。也支持多个 RedisPlugin 对象对应同一 + */ +public class RedisPlugin implements IPlugin{ + private static final int TIMEOUT = 5000; + private String id; + private final RedisConfig config; + + + + public RedisPlugin() { + config = new RedisConfig(); + } + + public boolean start() { + JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); + jedisPoolConfig.setMaxTotal(config.poolConfig.maxTotal); + jedisPoolConfig.setMaxIdle(config.poolConfig.maxIdle); + jedisPoolConfig.setMaxIdle(config.poolConfig.minIdle); + jedisPoolConfig.setMaxWaitMillis(config.poolConfig.maxWaitMillis); + jedisPoolConfig.setTestOnBorrow(config.poolConfig.testOnBorrow); + jedisPoolConfig.setTestOnReturn(config.poolConfig.testOnReturn); + jedisPoolConfig.setTestWhileIdle(config.poolConfig.testWhileIdle); + jedisPoolConfig.setNumTestsPerEvictionRun(config.poolConfig.numTestsPerEvictionRun); + jedisPoolConfig.setMinEvictableIdleTimeMillis(config.poolConfig.minEvictableIdleTimeMillis); + jedisPoolConfig.setTimeBetweenEvictionRunsMillis(config.poolConfig.timeBetweenEvictionRunsMillis); + jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(config.poolConfig.softMinEvictableIdleTimeMillis); + jedisPoolConfig.setBlockWhenExhausted(config.poolConfig.blockWhenExhausted); + + for (InfoConfig sis : config.infos) { + String passwd = StringUtil.isEmpty(sis.password) ? null : sis.password; + JedisPool jedisPool = new JedisPool(jedisPoolConfig, sis.host, sis.port, TIMEOUT, passwd, sis.database); + Cache cache = new Cache(sis.name, jedisPool); + Redis.addCache(cache); + } + return true; + } + + public boolean stop() { + Set keys = Redis.cacheMap.keySet(); + for(String key : keys) { + Redis.removeCache(key); + } + return true; + } + + + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public boolean loadConfig(Element element) { + Element pcEm = element.getChild("poolConfig"); + this.config.poolConfig.maxTotal = Integer.parseInt(pcEm.getChild("maxTotal").getTextTrim()); + this.config.poolConfig.maxIdle = Integer.parseInt(pcEm.getChild("maxIdle").getTextTrim()); + this.config.poolConfig.minIdle = Integer.parseInt(pcEm.getChild("minIdle").getTextTrim()); + this.config.poolConfig.maxWaitMillis = Integer.parseInt(pcEm.getChild("maxWaitMillis").getTextTrim()); + this.config.poolConfig.testOnBorrow = Boolean.parseBoolean(pcEm.getChild("testOnBorrow").getTextTrim()); + this.config.poolConfig.testOnReturn = Boolean.parseBoolean(pcEm.getChild("testOnReturn").getTextTrim()); + this.config.poolConfig.testWhileIdle = Boolean.parseBoolean(pcEm.getChild("testWhileIdle").getTextTrim()); + this.config.poolConfig.numTestsPerEvictionRun = Integer.parseInt(pcEm.getChild("numTestsPerEvictionRun").getTextTrim()); + this.config.poolConfig.minEvictableIdleTimeMillis = Integer.parseInt(pcEm.getChild("minEvictableIdleTimeMillis").getTextTrim()); + this.config.poolConfig.timeBetweenEvictionRunsMillis = Integer.parseInt(pcEm.getChild("timeBetweenEvictionRunsMillis").getTextTrim()); + this.config.poolConfig.softMinEvictableIdleTimeMillis = Integer.parseInt(pcEm.getChild("softMinEvictableIdleTimeMillis").getTextTrim()); + this.config.poolConfig.blockWhenExhausted = Boolean.parseBoolean(pcEm.getChild("blockWhenExhausted").getTextTrim()); + + Element dblistEm = element.getChild("infos"); + + Iterator itr = (dblistEm.getChildren()).iterator(); + while(itr.hasNext()) { + Element infoEm = (Element)itr.next(); + InfoConfig infoConfig = new InfoConfig(); + infoConfig.name = infoEm.getAttributeValue("name", StringUtil.Empty); + infoConfig.host = infoEm.getAttributeValue("host", "127.0.0.1"); + infoConfig.port = Integer.parseInt(infoEm.getAttributeValue("port", "6379")); + infoConfig.database = Integer.parseInt(infoEm.getAttributeValue("database", "0")); + infoConfig.password = infoEm.getAttributeValue("password"); + this.config.infos.add(infoConfig); + } + return true; + } + + public static final class RedisConfig{ + + public volatile PoolConfig poolConfig = new PoolConfig(); + + public volatile List infos = new ArrayList(); + + + public static final class PoolConfig { + public int maxTotal = 8; + public int maxIdle = 8; + public int minIdle = 0; + public int maxWaitMillis = 8; + public boolean testOnBorrow = true; + public boolean testOnReturn = true; + public boolean testWhileIdle = true; + public int numTestsPerEvictionRun = 3; + public int minEvictableIdleTimeMillis = 6000; + public int timeBetweenEvictionRunsMillis = 3000; + public int softMinEvictableIdleTimeMillis = 1000; + public boolean blockWhenExhausted = true; + } + + public static final class InfoConfig { + public String name =""; + public String host = "127.0.0.1"; + public int port = 6379; + public String password = ""; + public int database = 0; + } + } +} + + diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Action.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Action.java new file mode 100644 index 0000000..2a306a5 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Action.java @@ -0,0 +1,68 @@ +package com.taurus.core.routes; + +import java.lang.reflect.Method; + +/** + * Action. + * + * + */ +public class Action { + private final Class controllerClass; + private final IController controller; + private final String controllerKey; + private final String actionKey; + private final Method method; + private final String methodName; + private final Interceptor interceptor; + private final ActionKey actionKeyObj; + + public Action(String controllerKey, String actionKey, Class ctrClass,IController controller, Method method, String methodName,Interceptor interceptor,ActionKey actionKeyObj) { + this.controllerKey = controllerKey; + this.controller = controller; + this.actionKey = actionKey; + this.controllerClass = ctrClass; + this.method = method; + this.methodName = methodName; + this.interceptor = interceptor; + this.actionKeyObj = actionKeyObj; + } + + public Class getControllerClass() { + return controllerClass; + } + + public IController getController() { + return controller; + } + + public String getControllerKey() { + return controllerKey; + } + + public String getActionKey() { + return actionKey; + } + + public Method getMethod() { + return method; + } + + + public String getMethodName() { + return methodName; + } + + public Interceptor getInterceptor() { + return interceptor; + } + + public ActionKey getActionKeyObj() { + return actionKeyObj; + } + + @Override + public String toString() { + return actionKey; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionKey.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionKey.java new file mode 100644 index 0000000..d3415ad --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionKey.java @@ -0,0 +1,23 @@ +package com.taurus.core.routes; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ActionKey is used to configure actionKey for method of controller. + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ActionKey { + String value(); + + int validate() default 0; + + /**参数{"a","1","b","2"}*/ + String[] params() default {}; +} + diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionMapping.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionMapping.java new file mode 100644 index 0000000..3743634 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/ActionMapping.java @@ -0,0 +1,94 @@ +package com.taurus.core.routes; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.taurus.core.routes.Routes.Route; +import com.taurus.core.util.StringUtil; + +/** + * ActionMapping. + * + * + */ +public class ActionMapping { + protected static final String SLASH = "/"; + protected Routes routes; + protected Map mapping = new HashMap(2048, 0.5F); + + public ActionMapping(Routes routes) { + this.routes = routes; + } + + protected List getRoutesList() { + List routesList = Routes.getRoutesList(); + List ret = new ArrayList(routesList.size() + 1); + ret.add(routes); + ret.addAll(routesList); + return ret; + } + + public void buildActionMapping() { + mapping.clear(); + for (Routes routes : getRoutesList()) { + for (Route route : routes.getRouteItemList()) { + Class controllerClass = route.getControllerClass(); + + Method[] methods = controllerClass.getMethods(); + for (Method method : methods) { + String methodName = method.getName(); + if (!Modifier.isPublic(method.getModifiers())) + continue ; + ActionKey ak = method.getAnnotation(ActionKey.class); + if (ak == null)continue ; + String controllerKey = route.getControllerKey(); + String actionKey = ak.value().trim(); + if (StringUtil.isEmpty(actionKey)) + throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank."); + Interceptor interceptor = routes.getInterceptor(); + Action action = new Action(controllerKey, actionKey, route.getControllerClass(), + route.getController(),method, methodName,interceptor,ak); + if(!StringUtil.isEmpty(controllerKey)) { + actionKey =controllerKey.equals(SLASH) ? SLASH+ actionKey : (controllerKey + SLASH+actionKey); + } + if (mapping.put(actionKey, action) != null) { + throw new RuntimeException(buildMsg(actionKey, controllerClass, method)); + } + } + } + } + } + + protected String buildMsg(String actionKey, Class controllerClass, Method method) { + StringBuilder sb = new StringBuilder("The action \"") + .append(controllerClass.getName()).append(".") + .append(method.getName()).append("()\" can not be mapped, ") + .append("actionKey \"").append(actionKey).append("\" is already in use."); + + String msg = sb.toString(); + System.err.println("\nException: " + msg); + return msg; + } + + /** + * Support four types of url + */ + public Action getAction(String url) { + Action action = mapping.get(url); + if (action != null) { + return action; + } + return action; + } + + public List getAllActionKeys() { + List allActionKeys = new ArrayList(mapping.keySet()); + Collections.sort(allActionKeys); + return allActionKeys; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Extension.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Extension.java new file mode 100644 index 0000000..14084ae --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Extension.java @@ -0,0 +1,57 @@ +package com.taurus.core.routes; + +/** + * Extension class. + * + * + */ +public abstract class Extension { + private String name; + + /** + * Config route + */ + public abstract void configRoute(Routes me); + + /** + * Call back server start + */ + public void onStart() {} + + /** + * Call back server stop + */ + public void onStop() {} + + /** + * set extension name + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * read ver + * @return + */ + public int readVersion() { + return 0; + } + + /** + * get extension name + * @return + */ + public String getName() { + return this.name; + } + + /** + * get conncurrent number + * @return + */ + public int getConcurrentSize() { + return 0; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/IController.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/IController.java new file mode 100644 index 0000000..68590a5 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/IController.java @@ -0,0 +1,11 @@ +package com.taurus.core.routes; + + +/** + * Controller interface + * + * + */ +public interface IController { + +} \ No newline at end of file diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Interceptor.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Interceptor.java new file mode 100644 index 0000000..1792166 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Interceptor.java @@ -0,0 +1,10 @@ +package com.taurus.core.routes; + +/** + * Interceptor + * + * + */ +public interface Interceptor { + void intercept(Action action,IController controller,Object... args) throws Exception; +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Routes.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Routes.java new file mode 100644 index 0000000..24f0443 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/routes/Routes.java @@ -0,0 +1,155 @@ +package com.taurus.core.routes; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.taurus.core.util.StringUtil; + +/** + * Routes + * + * + */ +public abstract class Routes { + /**controller to class*/ + public static final int CONTROLLER_CLASS = 1; + /**controller to instance*/ + public static final int CONTROLLER_INSTANCE = 2; + private static List routesList = new ArrayList(); + private static Set controllerKeySet = new HashSet(); + + private List routeItemList = new ArrayList(); + private Interceptor interceptor; + private boolean addSlash = true; + + private int falg = CONTROLLER_CLASS; + + public Routes(int falg) { + this.falg = falg; + } + + /** + * Implement this method to add route, add interceptor and set baseViewPath + */ + public abstract void config(); + + /** + * 设置拦截器 + * @param interceptor + */ + public void setInterceptor(Interceptor interceptor) { + this.interceptor = interceptor; + } + + /** + * Add Routes + */ + public Routes add(Routes routes) { + routes.config(); + routesList.add(routes); + return this; + } + + /** + * Add route + * @param controllerKey A key can find controller + * @param controller Controller Class + */ + public Routes add(String controllerKey, Class controller) { + if((falg &CONTROLLER_CLASS) == 0) { + throw new RuntimeException("class is not supported!"); + } + routeItemList.add(new Route(controllerKey, controller,this.addSlash)); + return this; + } + + /** + * Add route + * @param controllerKey A key can find controller + * @param controller Controller instance + */ + public Routes add(String controllerKey, IController controller) { + if((falg &CONTROLLER_INSTANCE) == 0) { + throw new RuntimeException("instance is not supported!"); + } + routeItemList.add(new Route(controllerKey, controller,this.addSlash)); + return this; + } + + public static List getRoutesList() { + return routesList; + } + + public List getRouteItemList() { + return routeItemList; + } + + public Interceptor getInterceptor() { + return interceptor; + } + + public void setAddSlash(boolean add) { + this.addSlash =add; + } + + + public static class Route { + private String controllerKey; + private Class ctrClass; + private IController controller; + + public Route(String controllerKey, Class controller,boolean addSlash) { + if (StringUtil.isEmpty(controllerKey)) { + throw new IllegalArgumentException("controllerKey can not be blank"); + } + if (controller == null) { + throw new IllegalArgumentException("controllerClass can not be null"); + } + + this.controllerKey = processControllerKey(controllerKey,addSlash); + this.ctrClass = controller; + } + + public Route(String controllerKey, IController controller,boolean addSlash) { + if (controllerKey == null) { + throw new IllegalArgumentException("controllerKey can not be blank"); + } + if (controller == null) { + throw new IllegalArgumentException("controllerClass can not be null"); + } + + this.controllerKey = processControllerKey(controllerKey,addSlash); + this.controller = controller; + this.ctrClass = controller.getClass(); + } + + private String processControllerKey(String controllerKey,boolean addSlash) { + controllerKey = controllerKey.trim(); + if(addSlash) { + if (!controllerKey.startsWith("/")) { + controllerKey = "/" + controllerKey; + } + } + if (controllerKeySet.contains(controllerKey)) { + throw new IllegalArgumentException("controllerKey already exists: " + controllerKey); + } + controllerKeySet.add(controllerKey); + return controllerKey; + } + + public String getControllerKey() { + return controllerKey; + } + + public Class getControllerClass() { + return ctrClass; + } + + public IController getController() { + return controller; + } + + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/service/AbstractService.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/service/AbstractService.java new file mode 100644 index 0000000..8376864 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/service/AbstractService.java @@ -0,0 +1,48 @@ +package com.taurus.core.service; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * AbstractService + * + * + */ +public abstract class AbstractService implements IService { + private static final AtomicInteger serviceId = new AtomicInteger(0); + private static final String DEFAULT_NAME = "Service-"; + protected String name; + protected volatile boolean active = false; + + public void init(Object o) { + name = getServiceId(); + active = true; + } + + public void destroy(Object o) { + active = false; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void handleMessage(Object param) { + throw new UnsupportedOperationException("This method should be overridden by the child class!"); + } + + public boolean isActive() { + return active; + } + + public String toString() { + return "[Core Service]: " + name + ", State: " + (isActive() ? "active" : "not active"); + } + + protected static String getServiceId() { + return DEFAULT_NAME + serviceId.getAndIncrement(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/service/IService.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/service/IService.java new file mode 100644 index 0000000..8c12297 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/service/IService.java @@ -0,0 +1,39 @@ +package com.taurus.core.service; + +/** + * 通用服务接口 + * + * + */ +public interface IService { + + /** + * 初始化Service + * @param o + */ + public void init(Object o); + + /** + * 销毁Service + * @param o + */ + public void destroy(Object o); + + /** + * 获取Service名称 + * @return + */ + public String getName(); + + /** + * 设置Service名称 + * @param name + */ + public void setName(String name); + + /** + * Service是否激活 + * @return + */ + public boolean isActive(); +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Base64.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Base64.java new file mode 100644 index 0000000..9dc80fd --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Base64.java @@ -0,0 +1,239 @@ +package com.taurus.core.util; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +/** + * base64 + */ +public final class Base64 { + private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final int[] IA = new int[256]; + + static { + Arrays.fill(IA, -1); + int i = 0; + for (int iS = CA.length; i < iS; i++) { + IA[CA[i]] = i; + } + IA[61] = 0; + } + + private static final char[] encodeToChar(byte[] sArr, boolean lineSep) { + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) { + return new char[0]; + } + int eLen = sLen / 3 * 3; + int cCnt = (sLen - 1) / 3 + 1 << 2; + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); + char[] dArr = new char[dLen]; + + int s = 0; + int d = 0; + for (int cc = 0; s < eLen;) { + int i = (sArr[(s++)] & 0xFF) << 16 | (sArr[(s++)] & 0xFF) << 8 | sArr[(s++)] & 0xFF; + + dArr[(d++)] = CA[(i >>> 18 & 0x3F)]; + dArr[(d++)] = CA[(i >>> 12 & 0x3F)]; + dArr[(d++)] = CA[(i >>> 6 & 0x3F)]; + dArr[(d++)] = CA[(i & 0x3F)]; + if (lineSep) { + cc++; + if ((cc == 19) && (d < dLen - 2)) { + dArr[(d++)] = '\r'; + dArr[(d++)] = '\n'; + cc = 0; + } + } + } + int left = sLen - eLen; + if (left > 0) { + int i = (sArr[eLen] & 0xFF) << 10 | (left == 2 ? (sArr[(sLen - 1)] & 0xFF) << 2 : 0); + + dArr[(dLen - 4)] = CA[(i >> 12)]; + dArr[(dLen - 3)] = CA[(i >>> 6 & 0x3F)]; + dArr[(dLen - 2)] = (left == 2 ? CA[(i & 0x3F)] : '='); + dArr[(dLen - 1)] = '='; + } + return dArr; + } + + /** + * Encodes all bytes from the specified byte array into a newly-allocated + * byte array using the {@link Base64} encoding scheme. The returned byte + * array is of the length of the resulting bytes. + * + * @param src the byte array to encode + * @return A newly-allocated byte array containing the resulting encoded bytes. + */ + private static final String encodeToString(byte[] src, boolean lineSep) { + return new String(encodeToChar(src, lineSep)); + } + + /** + * Encodes all bytes from the specified byte array into a newly-allocated + * byte array using the {@link Base64} encoding scheme. The returned byte + * array is of the length of the resulting bytes. + * + * @param src the byte array to encode + * @return A newly-allocated byte array containing the resulting encoded bytes. + */ + public static final byte[] encode(String src) { + try { + return StringUtil.getBytes(encodeToString(StringUtil.getBytes(src), false)); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Encodes all bytes from the specified byte array into a newly-allocated + * byte array using the {@link Base64} encoding scheme. The returned byte + * array is of the length of the resulting bytes. + * + * @param src the byte array to encode + * @return A newly-allocated byte array containing the resulting encoded bytes. + */ + public static final byte[] encode(byte[] src) { + try { + return StringUtil.getBytes(encodeToString(src, false)); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Encodes all bytes from the specified byte array into a newly-allocated + * byte array using the {@link Base64} encoding scheme. The returned byte + * array is of the length of the resulting bytes. + * + * @param src the byte array to encode + * @return A newly-allocated byte array containing the resulting encoded bytes. + */ + public static final String encodeToString(String src) { + try { + return encodeToString(StringUtil.getBytes(src), false); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Encodes all bytes from the specified byte array into a newly-allocated + * byte array using the {@link Base64} encoding scheme. The returned byte + * array is of the length of the resulting bytes. + * + * @param src the byte array to encode + * @return A newly-allocated byte array containing the resulting encoded bytes. + */ + public static final String encodeToString(byte[] src) { + return encodeToString(src, false); + } + + /** + * Decodes all bytes from the input byte array using the {@link Base64} + * encoding scheme, writing the results into a newly-allocated output + * byte array. The returned byte array is of the length of the resulting + * bytes. + * + * @param src the byte array to decode + * @return A newly-allocated byte array containing the decoded bytes. + */ + public static final String decodeToString(byte[] src) { + try { + return StringUtil.getString(decode(src)); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Decodes all bytes from the input byte array using the {@link Base64} + * encoding scheme, writing the results into a newly-allocated output + * byte array. The returned byte array is of the length of the resulting + * bytes. + * + * @param src the byte array to decode + * @return A newly-allocated byte array containing the decoded bytes. + */ + public static final String decodeToString(String src) { + try { + return StringUtil.getString(decode(src)); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Decodes all bytes from the input byte array using the {@link Base64} + * encoding scheme, writing the results into a newly-allocated output + * byte array. The returned byte array is of the length of the resulting + * bytes. + * + * @param src the byte array to decode + * @return A newly-allocated byte array containing the decoded bytes. + */ + public static final byte[] decode(byte[] src) { + try { + return decode(StringUtil.getString(src)); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * Decodes all bytes from the input byte array using the {@link Base64} + * encoding scheme, writing the results into a newly-allocated output + * byte array. The returned byte array is of the length of the resulting + * bytes. + * + * @param src the byte array to decode + * @return A newly-allocated byte array containing the decoded bytes. + */ + public static final byte[] decode(String src) { + int sLen = src != null ? src.length() : 0; + if (sLen == 0) { + return new byte[0]; + } + int sepCnt = 0; + for (int i = 0; i < sLen; i++) { + if (IA[src.charAt(i)] < 0) { + sepCnt++; + } + } + if ((sLen - sepCnt) % 4 != 0) { + return null; + } + int pad = 0; + for (int i = sLen; (i > 1) && (IA[src.charAt(--i)] <= 0);) { + if (src.charAt(i) == '=') { + pad++; + } + } + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; + + int s = 0; + for (int d = 0; d < len;) { + int i = 0; + for (int j = 0; j < 4; j++) { + int c = IA[src.charAt(s++)]; + if (c >= 0) { + i |= c << 18 - j * 6; + } else { + j--; + } + } + dArr[(d++)] = ((byte) (i >> 16)); + if (d < len) { + dArr[(d++)] = ((byte) (i >> 8)); + if (d < len) { + dArr[(d++)] = ((byte) i); + } + } + } + return dArr; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ByteArray.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ByteArray.java new file mode 100644 index 0000000..c74b8b9 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ByteArray.java @@ -0,0 +1,259 @@ +package com.taurus.core.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +/** + * byte array + * + */ +public class ByteArray { + private byte[] buffer; + private int _position; + private boolean compressed; + + public ByteArray() { + _position = 0; + buffer = new byte[0]; + } + + public ByteArray(byte[] buf) { + _position = 0; + buffer = buf; + } + + public byte[] reverseOrder(byte[] dt) { + return dt; + } + + public void writeByte(byte b) { + byte[] buf = new byte[1]; + buf[0] = b; + writeBytes(buf); + } + + public void writeBytes(byte[] data) { + writeBytes(data,0, data.length); + } + + public void writeBytes(byte[] data, int ofs,int count) { + byte[] dst = new byte[count + buffer.length]; + System.arraycopy(buffer, 0, dst, 0, buffer.length); + System.arraycopy(data, ofs, dst, buffer.length, count); + this.buffer = dst; + } + + public void writeBool(boolean b) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeByte(b ? 1 : 0); + writeBytes(bos.toByteArray()); + } + + public void writeInt(int i) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeInt(i); + writeBytes(reverseOrder(bos.toByteArray())); + } + + public void writeShort(short s) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeShort(s); + writeBytes(reverseOrder(bos.toByteArray())); + } + + public void writeUShort(int s) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + byte[] tem = new byte[2]; + int b1 = (s & 0xFF00) >> 8; + int b2 = s & 0xFF; + tem[0] = (byte)b1; + tem[1] = (byte)b2; + dos.writeByte((byte) b1); + dos.writeByte((byte) b2); + writeBytes(bos.toByteArray()); + } + + public void writeLong(long l) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeLong(l); + writeBytes(reverseOrder(bos.toByteArray())); + } + + public void writeFloat(float f) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeFloat(f); + writeBytes(reverseOrder(bos.toByteArray())); + } + + public void writeDouble(double d) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeDouble(d); + writeBytes(reverseOrder(bos.toByteArray())); + } + + public void writeString(String str) throws IOException { + if(StringUtil.isEmpty(str)) { + writeInt(0); + return; + } + try { + byte[] bytes = StringUtil.getBytes(str); + int utfLen = bytes.length; + writeInt(utfLen); + writeBytes(bytes); + } catch (UnsupportedEncodingException e) { + throw new IOException("Error writing to data buffer"); + } + } + + public byte readByte() throws IOException { + return this.buffer[(this._position++)]; + } + + public byte[] readBytes(int count) { + byte[] res = new byte[count]; + ByteBuffer buf = ByteBuffer.wrap(this.buffer); + buf.position(this._position); + buf.get(res); + this._position += count; + return res; + } + + public boolean readBool() throws IOException { + return this.buffer[(this._position++)] == 1; + } + + public int readInt() throws IOException { + byte[] data = reverseOrder(readBytes(4)); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + return dis.readInt(); + } + + public short readShort() throws IOException { + byte[] data = reverseOrder(readBytes(2)); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + return dis.readShort(); + } + + public int readUShort() throws IOException { + byte[] data = reverseOrder(readBytes(2)); + + int ib1 = new Integer(data[0]).intValue(); + if (ib1 < 0) { + ib1 = data[0] & 0x80; + ib1 += (data[0] & 0x7F); + } + int ib2 = new Integer(data[1]).intValue(); + if (ib2 < 0) { + ib2 = data[1] & 0x80; + ib2 += (data[1] & 0x7F); + } + return ib1 * 256 + ib2; + } + + public long readLong() throws IOException { + byte[] data = reverseOrder(readBytes(8)); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + return dis.readLong(); + } + + public float readFloat() throws IOException { + byte[] data = reverseOrder(readBytes(4)); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + return dis.readFloat(); + + } + + public double readDouble() throws IOException { + byte[] data = reverseOrder(readBytes(8)); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + return dis.readDouble(); + } + + public String readString() throws IOException { + int size = readInt(); + if (size == 0) { + return null; + } + byte[] data = readBytes(size); + return StringUtil.getString(data); + } + + public byte[] bytes() { + return this.buffer; + } + + public ByteArray bytes(byte[] buffer) { + this.buffer = buffer; + return this; + } + + public int length() { + return this.buffer.length; + } + + public int position() { + return this._position; + } + + public ByteArray position(int position) { + this._position = position; + return this; + } + + public boolean isCompressed() { + return this.compressed; + } + + public void setCompressed(final boolean compressed) { + this.compressed = compressed; + } + + public void compress() throws Exception { + if (this.compressed) { + throw new Exception("Buffer is already compressed"); + } + try { + buffer = Utils.compress(this.buffer); + this._position = 0; + this.compressed = true; + }catch (IOException e) { + throw new Exception("Error compressing data"); + } + } + + public void uncompress() throws Exception { + try { + buffer = Utils.uncompress(this.buffer); + this._position = 0; + this.compressed = false; + }catch (IOException e2) { + throw new Exception("Error decompressing data"); + } + } + + public int bytesAvailable() { + int val = this.buffer.length - this._position; + if ((val > this.buffer.length) || (val < 0)) { + val = 0; + } + return val; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/DateUtils.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/DateUtils.java new file mode 100644 index 0000000..33e9769 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/DateUtils.java @@ -0,0 +1,191 @@ +package com.taurus.core.util; + +import java.util.Calendar; + +/** + * date util class + * + * + */ +public class DateUtils { + + /** + * 获取当天的开始时间 + * @param cal + */ + private static void setDayBegin(Calendar cal) { + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + } + + /** + * 获取当天的结束时间 + * @param cal + */ + private static void setDayEnd(Calendar cal) { + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 999); + } + + private static int getTimeSec(Calendar cal) { + int timeSec = (int) (cal.getTimeInMillis() / 1000); + return timeSec; + } + + /** + * 今天开始时间 + * @return + */ + public static int getBeginDay() { + Calendar cal= Calendar.getInstance(); + setDayBegin(cal); + return getTimeSec(cal); + } + + /** + * 今天结束时间 + * @return + */ + public static int getEndDay() { + Calendar cal= Calendar.getInstance(); + setDayEnd(cal); + return getTimeSec(cal); + } + + + /** + * 获取昨天的开始时间 + * @return + */ + public static int getBeginLastday() { + return getBeginDay() - 24*60*60; + } + + /** + * 获取昨天的结束时间 + * @return + */ + public static int getEndLastDay() { + return getBeginDay()-1; + } + + /** + * 获取本周的开始时间 + * @return + */ + public static int getBeginWeek() { + Calendar cal = Calendar.getInstance(); + int dayofweek = cal.get(Calendar.DAY_OF_WEEK); + if (dayofweek == 1) { + dayofweek += 7; + } + cal.add(Calendar.DATE, 2 - dayofweek); + setDayBegin(cal); + return getTimeSec(cal); + } + + /** + * 获取本周的结束时间 + * @return + */ + public static int getEndWeek() { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(getBeginWeek()*1000L); + cal.add(Calendar.DAY_OF_WEEK, 6); + setDayEnd(cal); + return getTimeSec(cal); + } + + /** + * 获取上周的开始时间 + * @return + */ + public static int getBeginLastWeek() { + Calendar cal = Calendar.getInstance(); + int dayofweek = cal.get(Calendar.DAY_OF_WEEK); + if (dayofweek == 1) { + dayofweek += 7; + } + cal.add(Calendar.DATE, 2 - dayofweek - 7); + setDayBegin(cal); + return getTimeSec(cal); + } + + /** + * 获取上周的结束时间 + * @return + */ + public static int getEndLastWeek() { + return getBeginWeek() -1 ; + } + + /** + * 获取本月的开始时间 + */ + public static int getBeginMonth() { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, 0); + cal.set(Calendar.DAY_OF_MONTH, 1); + setDayBegin(cal); + return getTimeSec(cal); + } + + /** + * 获取本月的结束时间 + * @return + */ + public static int getEndMonth() { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, 1); + cal.set(Calendar.DAY_OF_MONTH, 0); + setDayEnd(cal); + return getTimeSec(cal); + } + + /** + * 获取上月的开始时间 + */ + public static int getBeginLastMonth() { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, -1); + cal.set(Calendar.DAY_OF_MONTH, 1); + setDayBegin(cal); + return getTimeSec(cal); + } + + /** + * 获取上月的结束时间 + * @return + */ + public static int getEndLastMonth() { + return getBeginMonth() -1; + } + + /** + * 两个日期相减得到的天数 + * @param begin + * @param end + * @return + */ + public static int getDiffDays(int begin, int end) { + int diff = (end- begin) / (60 * 60 * 24); + return diff; + } + + /** + * 两个日期相减得到的毫秒数 + * @param begin + * @param end + * @return + */ + public static int dateDiff(int begin, int end) { + return end - begin; + } + + + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FileUtil.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FileUtil.java new file mode 100644 index 0000000..9e907ab --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FileUtil.java @@ -0,0 +1,89 @@ +package com.taurus.core.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * 文件处理工具 + * + * + * + */ +public class FileUtil { + + /** + * delete file + * @param file + */ + public static void delete(File file) { + if (file != null && file.exists()) { + if (file.isFile()) { + file.delete(); + } else if (file.isDirectory()) { + File files[] = file.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + delete(files[i]); + } + } + file.delete(); + } + } + } + + /** + * get file extension + * @param fileFullName + * @return + */ + public static String getFileExtension(String fileFullName) { + if (StringUtil.isEmpty(fileFullName)) { + throw new RuntimeException("fileFullName is empty"); + } + return getFileExtension(new File(fileFullName)); + } + + /** + * get file extension + * @param file + * @return + */ + public static String getFileExtension(File file) { + if (null == file) { + throw new NullPointerException(); + } + String fileName = file.getName(); + int dotIdx = fileName.lastIndexOf('.'); + return (dotIdx == -1) ? StringUtil.Empty : fileName.substring(dotIdx + 1); + } + + /** + * read utf text file + * @param path + * @return + * @throws Exception + */ + public static String readTxt(String path) throws Exception { + InputStream is = new FileInputStream(path); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + is.close(); + String str = new String(bytes,StringUtil.UTF_8); + return str; + } + + /** + * read binary file + * @param path + * @return + * @throws Exception + */ + public static byte[] readBytes(String path) throws Exception { + InputStream is = new FileInputStream(path); + byte[] bytes = new byte[is.available()]; + is.read(bytes); + is.close(); + return bytes; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FixedIndexThreadPool.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FixedIndexThreadPool.java new file mode 100644 index 0000000..9b7726e --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/FixedIndexThreadPool.java @@ -0,0 +1,136 @@ +package com.taurus.core.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * fixed index thread pool class. + * + * + * + */ +public class FixedIndexThreadPool { + private int poolSize; + private String poolName; + private volatile boolean _run; + private List works; + + public FixedIndexThreadPool(int poolSize, String poolName, Class workClass) { + this.poolSize = poolSize; + this.poolName = poolName; + _run = true; + works = new ArrayList(); + try { + for (int i = 0; i < poolSize; ++i) { + Work work = workClass.newInstance(); + work.init(this, i); + works.add(work); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * execute task + * + * @param index + * @param task + */ + public void execute(int index, Object task) { + Work work = works.get(index % poolSize); + work.addTask(task); + } + + /** + * shut down all work + * + * @return + */ + public synchronized int shutdown() { + int count = 0; + this._run = false; + for (Work work : works) { + count += work.stop(); + } + return count; + } + + public boolean isRun() { + return _run; + } + + /** + * get thread pool name + * + * @return + */ + public String getPoolName() { + return poolName; + } + + /** + * Thread work class + */ + public static abstract class Work implements Runnable { + protected FixedIndexThreadPool pool; + protected Thread thread; + protected BlockingQueue taskQueue; + protected Logger log; + + public void init(FixedIndexThreadPool pool, int id) { + this.pool = pool; + this.thread = new Thread(this, pool.poolName + "-" + id); + this.thread.start(); + taskQueue = new LinkedBlockingQueue(); + log = Logger.getLogger(this.getClass()); + } + + /** + * 添加任务 + * @param task + */ + public void addTask(Object task) { + if (task != null) { + taskQueue.add(task); + } + } + + /** + * stop work + * @return + */ + public synchronized int stop() { + if (thread != null) { + thread.interrupt(); + thread = null; + } + return taskQueue.size(); + } + + /** + * 处理任务 + * @param task + * @throws Exception + */ + protected abstract void handlerTask(Object task) throws Exception; + + @Override + public void run() { + while (pool.isRun()) { + try { + Object task = taskQueue.take(); + if (task != null) { + handlerTask(task); + } + } catch (InterruptedException e) { + log.error(e); + } catch (Exception e) { + log.error(e); + } + } + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ICallback.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ICallback.java new file mode 100644 index 0000000..437c681 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/ICallback.java @@ -0,0 +1,13 @@ +package com.taurus.core.util; + +/** + * Callback 监听接口 + * + * + */ +public interface ICallback{ + + + public void action(T t); + +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Logger.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Logger.java new file mode 100644 index 0000000..1cf5873 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Logger.java @@ -0,0 +1,214 @@ +package com.taurus.core.util; + +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Logger日志类 + * + * + * + */ +public class Logger { + private static final String NULL = ""; + private static final String ROOT_LOGGER_NAME = "ROOT"; + + private static Class _customClass; + private String _name = ROOT_LOGGER_NAME; + + /** + * 设置自定义Class + * + * @param className + */ + public static final void setCustomClass(Class customClass) { + _customClass = customClass; + } + + public static final Logger getLogger(Class log_class) { + Logger logger = null; + if (_customClass != null) { + if (Logger.class.isAssignableFrom(_customClass)) { + try { + Constructor c1 = _customClass.getDeclaredConstructor(new Class[] { Class.class }); + c1.setAccessible(true); + logger = (Logger) c1.newInstance(log_class); + return logger; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + try { + Class.forName("org.apache.log4j.Logger"); + logger = new Log4j(log_class); + return logger; + } catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + logger = new Logger(log_class); + return logger; + } + + public static final Logger getLogger(String name) { + Logger logger = null; + if (_customClass != null) { + if (Logger.class.isAssignableFrom(_customClass)) { + try { + Constructor c1 = _customClass.getDeclaredConstructor(new Class[] { Class.class }); + c1.setAccessible(true); + logger = (Logger) c1.newInstance(name); + return logger; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + try { + Class.forName("org.apache.log4j.Logger"); + logger = new Log4j(name); + return logger; + } catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + logger = new Logger(name); + return logger; + } + + protected Logger(Class log_class) { + _name = log_class == null ? ROOT_LOGGER_NAME : log_class.getSimpleName(); + } + + protected Logger(String name) { + _name = name; + } + + public String getName() { + return _name; + } + + private void printThrowable(PrintStream print, Throwable throwable) { + print.println(throwable); + StackTraceElement[] trace = throwable.getStackTrace(); + for (StackTraceElement traceElement : trace) + print.println("\tat " + traceElement); + } + + protected void print(LoggerLevel level, Object msg, Throwable throwable) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(calendar.getTime()); + msg = StringUtil.isEmpty(msg.toString()) ? NULL : msg; + msg = String.format("%s %-5s [%s] %s -%s", date, level.name(), Thread.currentThread().getName(), _name, msg); + System.out.println(msg); + if (throwable != null) { + printThrowable(System.out, throwable); + } + } + + public void trace(Object msg) { + print(LoggerLevel.TRACE, msg, null); + } + + public void trace(Object msg, Object... params) { + String str = String.format(msg.toString(), params); + trace(str); + } + + public void debug(Object msg) { + print(LoggerLevel.DEBUG, msg, null); + } + + public void debug(Object msg, Object... params) { + String str = String.format(msg.toString(), params); + debug(str); + } + + public void info(Object msg) { + print(LoggerLevel.INFO, msg, null); + } + + public void info(Object msg, Object... params) { + String str = String.format(msg.toString(), params); + info(str); + } + + public void warn(Object msg) { + print(LoggerLevel.WARN, msg, null); + } + + public void warn(Object msg, Object... params) { + String str = String.format(msg.toString(), params); + warn(str); + } + + public void error(Object msg) { + print(LoggerLevel.ERROR, msg, null); + } + + public void error(Object msg, Object... params) { + String str = String.format(msg.toString(), params); + error(str); + } + + public void error(Throwable throwable) { + error(NULL, throwable); + } + + public void error(Object msg, Throwable throwable) { + print(LoggerLevel.ERROR, msg, throwable); + } + + /** + * 日志等级 + * + * + * + */ + public static enum LoggerLevel { + DEBUG, INFO, WARN, ERROR, TRACE + } + + /** + * log4j 扩展 + * + * + */ + public static final class Log4j extends Logger { + private org.apache.log4j.Logger logger; + + protected Log4j(Class log_class) { + super(log_class); + logger = org.apache.log4j.Logger.getLogger(log_class); + } + + protected Log4j(String name) { + super(name); + logger = org.apache.log4j.Logger.getLogger(name); + } + + @Override + protected void print(LoggerLevel level, Object msg, Throwable throwable) { + switch (level) { + case DEBUG: + logger.debug(msg); + break; + case ERROR: + logger.error(msg, throwable); + break; + case WARN: + logger.warn(msg); + break; + case TRACE: + logger.trace(msg); + break; + case INFO: + logger.info(msg); + break; + } + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/MD5.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/MD5.java new file mode 100644 index 0000000..4975b04 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/MD5.java @@ -0,0 +1,48 @@ +package com.taurus.core.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * md5 + */ +public final class MD5 { + private static MD5 _instance = new MD5(); + private MessageDigest messageDigest; + private final Logger log; + + private MD5() { + this.log = Logger.getLogger(getClass()); + try { + this.messageDigest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + this.log.error("Could not instantiate the MD5 Message Digest!"); + } + } + + public static MD5 getInstance() { + return _instance; + } + + public synchronized String getHash(String s) { + byte[] data = s.getBytes(); + + this.messageDigest.update(data); + + return toHexString(this.messageDigest.digest()); + } + + private String toHexString(byte[] byteData) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < byteData.length; i++) { + String hex = Integer.toHexString(byteData[i] & 0xFF); + if (hex.length() == 1) { + hex = "0" + hex; + } + sb.append(hex); + } + + return sb.toString(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/SHA1.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/SHA1.java new file mode 100644 index 0000000..dcafcff --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/SHA1.java @@ -0,0 +1,54 @@ +package com.taurus.core.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * sha1 + */ +public final class SHA1 { + private static SHA1 _instance = new SHA1(); + private MessageDigest messageDigest; + private final Logger log; + + private SHA1() { + this.log = Logger.getLogger(getClass()); + try { + this.messageDigest = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + this.log.error("Could not instantiate the SHA-1 Message Digest!"); + } + } + + public static SHA1 getInstance() { + return _instance; + } + + public synchronized String getHash(String s) { + byte[] data = s.getBytes(); + this.messageDigest.update(data); + + return toHexString(this.messageDigest.digest()); + } + + public synchronized String getBase64Hash(String s) { + byte[] data = s.getBytes(); + this.messageDigest.update(data); + + return Base64.encodeToString(this.messageDigest.digest()); + } + + private String toHexString(byte[] byteData) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < byteData.length; i++) { + String hex = Integer.toHexString(byteData[i] & 0xFF); + if (hex.length() == 1) { + hex = "0" + hex; + } + sb.append(hex); + } + + return sb.toString(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/StringUtil.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/StringUtil.java new file mode 100644 index 0000000..d9318da --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/StringUtil.java @@ -0,0 +1,233 @@ +package com.taurus.core.util; + +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * string tools + * + */ +public class StringUtil { + + public static final String UTF_8 = "UTF-8"; + /** + * 空字符 + */ + public static final String Empty = ""; + + private static final String EMOJI_FILTER ="[\ud800\udc00-\udbff\udfff\ud800-\udfff]"; + /** + * 流数据转换为字符串 UTF-8 + * @param bytes + * @return + * @throws UnsupportedEncodingException + */ + public static String getString(byte[] bytes) throws UnsupportedEncodingException { + return new String(bytes,UTF_8); + } + + public static byte[] getBytes(String str) throws UnsupportedEncodingException { + return str==null?null:str.getBytes(UTF_8); + } + + /** + * 获得非空 + * @param str + * @return + */ + public static String getStr(String str) { + if (isEmpty(str)) return StringUtil.Empty; + return str; + } + + /** + * + * @param str + * @return + */ + public static int getBytesLength(String str) { + if (isEmpty(str)) { + return 0; + } + return str.getBytes().length; + } + + /** + * 字符串是否为空 + * @param str + * @return + */ + public static boolean isEmpty(String str) { + if (str == null) { + return true; + } + int len = str.length(); + if (len == 0) { + return true; + } + for (int i = 0; i < len; i++) { + switch (str.charAt(i)) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + return false; + } + } + return false; + } + + /** + * 字符串不为空 + * @param str + * @return + */ + public static boolean isNotEmpty(String str) { + return !isEmpty(str); + } + + private static final String DEFAULT_STR = "?"; + /** + * 将emoji表情替换成空串 + * + * @param source + * @return 过滤后的字符串 + */ + public static String filterEmoji(String source) { + if(StringUtil.isEmpty(source)) { + return DEFAULT_STR; + } + source = source.replaceAll(EMOJI_FILTER, StringUtil.Empty); + if(StringUtil.isEmpty(source)) { + return DEFAULT_STR; + } + return source; + } + + /** + * 首字母大写 + * @param str + * @return + */ + public static String capitalize(final String str) { + final int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + return new StringBuffer(strLen).append(Character.toTitleCase(str.charAt(0))).append(str.substring(1)).toString(); + } + + /** + * 首字母小写 + * @param str + * @return + */ + public static String uncapitalize(final String str) { + final int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + return new StringBuffer(strLen).append(Character.toLowerCase(str.charAt(0))).append(str.substring(1)).toString(); + } + + public static String getCurrentTime() { + SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd"); + String time = f.format(new Date()); + return time; + } + + public static Object removeEndChar(String object, String cha) { + while ((isNotEmpty(object)) && (object.endsWith(cha))) { + object = object.substring(0, object.length() - 1); + } + return object; + } + + /** + * 获取正则表达式转换后的字符串 + * @param str + * @param regex 正则表达式 + * @return + */ + public static String getRegexStr(String str, String regex) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(str); + if (m.find()) { + return m.group(1); + } + + return null; + } + + /** + * 获取正则表达式转换后的字符串数组 + * @param str + * @param regex 正则表达式 + * @return + */ + public static List getRegexStrs(String str, String regex) { + List list = new ArrayList(); + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(str); + while (m.find()) { + list.add(m.group(1)); + } + return list; + } + + /** + * 获取MD5字符串 + * @param str + * @return + */ + public static String getMD5(String str) { + String result = MD5.getInstance().getHash(str); + return result; + } + + public static boolean isInteger(String str, Integer big, Integer small) { + boolean returnb; + if (isNotEmpty(str)) { + try { + int intStr = Integer.parseInt(str); + if ((big.intValue() == 0) && (small.intValue() == 0)) { + returnb = true; + } else if ((intStr <= big.intValue()) && (intStr >= small.intValue())) { + returnb = true; + } else { + returnb = false; + } + } catch (Exception e) { + returnb = false; + } + } else { + returnb = false; + } + + return returnb; + } + + /** + * 判断字符串是否是电话号码 + * @param telephone + * @return + */ + public static boolean isPhone(String telephone) { + boolean b; + if (isEmpty(telephone)) { + b = false; + } else { + Pattern p = Pattern.compile("^[1]([3|5|4|7|8][0-9]{1})[0-9]{8}$"); + Matcher m = p.matcher(telephone); + b = m.matches(); + } + return b; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Utils.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Utils.java new file mode 100644 index 0000000..50c7a13 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/Utils.java @@ -0,0 +1,313 @@ +package com.taurus.core.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TDataType; +import com.taurus.core.entity.TDataWrapper; +import com.taurus.core.entity.TObject; + +import java.util.Map.Entry; + +/** + * 工具类 + * + */ +public final class Utils { + private static final String DELIMITER = "__"; + private static final String BUFFER_TYPE_DIRCT = "DIRECT"; + private static final String BUFFER_TYPE_HEAP = "HEAP"; + public static final Random rand = new Random(); + static { + rand.setSeed(System.currentTimeMillis()); + } + + /** + * 重置byte数组大小 + * @param source + * @param pos + * @param size + * @return + */ + public static byte[] resizeByteArray(byte[] source, int pos, int size) { + byte[] tTArray = new byte[size]; + System.arraycopy(source, pos, tTArray, 0, size); + return tTArray; + } + + public static ITObject bytesToJson(byte[] bytes) throws IOException { + if (bytes == null) + return null; + String json = uncompressString(bytes); + ITObject p = TObject.newFromJsonData(json); + return p; + } + + public static byte[] jsonToBytes(ITObject json) throws IOException { + if (json != null) { + return compress(StringUtil.getBytes(json.toJson())); + } + return null; + } + + /** + * 将密码字符串转换为MD5 + * @param session + * @param clearPass + * @return + */ + public static String getClientPassword(String hashId, String clearPass) { + return MD5.getInstance().getHash(hashId + clearPass); + } + + /** + * 获取字符串转换为MD5 + * @param str + * @return + */ + public static String getMD5Hash(String str) { + return MD5.getInstance().getHash(str); + } + + /** + * 生成session hash key + * @param fullIpAddress + * @return + */ + public static String getUniqueSessionToken(String fullIpAddress) { + String key = fullIpAddress + DELIMITER + String.valueOf(rand.nextInt()) + System.currentTimeMillis(); + + return MD5.getInstance().getHash(key); + } + + /** + * 获取十六进制文件名 + * @param name + * @return + */ + public static String getHexFileName(String name) { + StringBuilder sb = new StringBuilder(); + char[] c = name.toCharArray(); + for (int i = 0; i < c.length; i++) { + sb.append(Integer.toHexString(c[i])); + } + + return sb.toString(); + } + + /** + * 根据类型创建ByteBuffer + * @param size + * @param type + * @return + */ + public static ByteBuffer allocateBuffer(int size, String type) { + ByteBuffer bb = null; + if (type.equalsIgnoreCase(BUFFER_TYPE_DIRCT)) { + bb = ByteBuffer.allocateDirect(size); + } else if (type.equalsIgnoreCase(BUFFER_TYPE_HEAP)) { + bb = ByteBuffer.allocate(size); + } + return bb; + } + + + /** + * ITArray 深拷贝 + * @param from + * @param to + */ + public static final void arrayCopyDeep(ITArray from, ITArray to) { + for (Iterator it = from.iterator(); it.hasNext();) { + TDataWrapper value = (TDataWrapper) it.next(); + if (value.getTypeId() == TDataType.TOBJECT) { + ITObject obj = TObject.newInstance(); + to.addTObject(obj); + objectCopyDeep((ITObject) value.getObject(),obj); + } else if (value.getTypeId() == TDataType.TARRAY) { + ITArray arr = TArray.newInstance(); + to.addTArray(arr); + arrayCopyDeep((ITArray) value.getObject(),arr); + } else { + TDataWrapper v = new TDataWrapper(value.getTypeId(), value.getObject()); + to.add(v); + } + } + } + + /** + * TObject 深拷贝 + * + * @param from + * @param to + */ + public static final void objectCopyDeep(ITObject from, ITObject to) { + for (Iterator> it = from.iterator(); it.hasNext();) { + Entry entry = it.next(); + String key = (String) entry.getKey(); + TDataWrapper value = (TDataWrapper) entry.getValue(); + if (value.getTypeId() == TDataType.TOBJECT) { + ITObject obj = TObject.newInstance(); + to.putTObject(key, obj); + objectCopyDeep((ITObject) value.getObject(),obj); + } else if (value.getTypeId() == TDataType.TARRAY) { + ITArray arr = TArray.newInstance(); + to.putTArray(key, arr); + arrayCopyDeep((ITArray) value.getObject(),arr); + } else { + TDataWrapper v = new TDataWrapper(value.getTypeId(), value.getObject()); + to.put(key, v); + } + } + } + + /** + * TArray copy + * @param from + * @param to + */ + public static final void arrayCopy(ITArray from,ITArray to) { + for (Iterator it = from.iterator(); it.hasNext();) { + TDataWrapper value = (TDataWrapper) it.next(); + to.add(value); + } + } + + /** + * TObject copy + * @param from + * @param to + */ + public static final void objectCopy(ITObject from,ITObject to) { + for (Iterator> it = from.iterator(); it.hasNext();) { + Entry entry = it.next(); + String key = (String) entry.getKey(); + TDataWrapper value = (TDataWrapper) entry.getValue(); + to.put(key, value); + } + } + + /** + * TObject to {@code Map} + * @param from + * @param map + */ + public static final void objectToMap(ITObject from,Map map) { + for (Iterator> it = from.iterator(); it.hasNext();) { + Entry entry = it.next(); + String key = (String) entry.getKey(); + TDataWrapper value = (TDataWrapper) entry.getValue(); + if (value.getTypeId() == TDataType.TOBJECT || value.getTypeId() == TDataType.TARRAY) { + map.put(key, ((ITObject) value.getObject()).toJson()); + }else { + map.put(key, value.getObject().toString()); + } + } + } + + /** + * list to TArray + * @param list + * @return + */ + public static final ITArray toTArray(List list) { + ITArray result = new TArray(); + for (Integer card : list) { + result.addInt(card); + } + return result; + } + + /** + * 压缩字节数组 + * @param data + * @return + * @throws IOException + */ + public static byte[] compress(byte[] data) throws IOException{ + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + compress(data,bos); + byte[] output = bos.toByteArray(); + return output; + }finally { + bos.close(); + } + } + + /** + * 压缩 字节数组到输出流 + * @param data + * @param os + * @throws IOException + */ + public static void compress(byte[] data, OutputStream os) throws IOException { + Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, false); + DeflaterOutputStream dos = new DeflaterOutputStream(os,deflater); + dos.write(data, 0, data.length); + dos.finish(); + dos.flush(); + } + + /** + * 解压缩 字节数组 + * @param data + * @return + * @throws IOException + */ + public static String uncompressString(byte[] data) throws IOException { + byte[] output = uncompress(data); + String str= StringUtil.getString(output); + return str; + } + + /** + * 解压缩 字节数组 + * @param data + * @return + * @throws IOException + */ + public static byte[] uncompress(byte[] data) throws IOException { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + try { + byte[] output =uncompress(bis); + return output; + }finally { + bis.close(); + } + } + + /** + * 解压缩 输入流 到字节数组 + * @param is + * @return + * @throws IOException + */ + public static byte[] uncompress(InputStream is) throws IOException { + Inflater decompresser = new Inflater(false); + InflaterInputStream iis = new InflaterInputStream(is,decompresser); + ByteArrayOutputStream o = new ByteArrayOutputStream(1024); + int i = 1024; + byte[] buf = new byte[i]; + + while ((i = iis.read(buf, 0, i)) > 0) { + o.write(buf, 0, i); + } + return o.toByteArray(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONParser.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONParser.java new file mode 100644 index 0000000..f96d6d5 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONParser.java @@ -0,0 +1,370 @@ +package com.taurus.core.util.json; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class JSONParser { + + private String text; + private int index = 0; + private char ch; + + private Token token; + private String stringValue; + private long longValue; + private double doubleValue; + + public JSONParser(String text){ + this.text = text; + ch = text.charAt(0); + nextToken(); + } + + public Object parse() { + if (token == Token.LBRACE) { + return parseMap(); + } + + if (token == Token.INT) { + Object value; + if (this.longValue >= Integer.MIN_VALUE && this.longValue <= Integer.MAX_VALUE) { + value = (int) this.longValue; + } else { + value = this.longValue; + } + + nextToken(); + return value; + } + + if (token == Token.DOUBLE) { + Object value = this.doubleValue; + nextToken(); + return value; + } + + if (token == Token.STRING) { + Object value = this.stringValue; + nextToken(); + return value; + } + + if (token == Token.LBRACKET) { + return parseArray(); + } + + if (token == Token.TRUE) { + nextToken(); + return true; + } + + if (token == Token.FALSE) { + nextToken(); + return false; + } + + if (token == Token.NULL) { + nextToken(); + return null; + } + + throw new IllegalArgumentException("illegal token : " + token); + } + + public List parseArray() { + accept(Token.LBRACKET); + ArrayList list = new ArrayList(); + + for (;;) { + if (token == Token.RBRACKET) { + break; + } + + if (token == Token.COMMA) { + nextToken(); + continue; + } + + Object item = parse(); + list.add(item); + } + + accept(Token.RBRACKET); + return list; + } + + public Map parseMap() { + accept(Token.LBRACE); + Map map = new LinkedHashMap(); + + for (;;) { + if (token == Token.RBRACE) { + break; + } + + if (token == Token.COMMA) { + nextToken(); + continue; + } + + String key; + { + if (token != Token.STRING) { + throw new IllegalArgumentException("illegal json, " + token + " : " + text); + } + key = this.stringValue; + nextToken(); + } + + accept(Token.COLON); + + Object value = parse(); + + map.put(key, value); + } + + accept(Token.RBRACE); + return map; + } + + void accept(Token token) { + if (this.token == token) { + nextToken(); + return; + } + + throw new IllegalArgumentException("illegal token : " + this.token + ", expect " + token); + } + private final static boolean[] whitespaceFlags = new boolean[256]; + static { + for (int i = 0; i <= 32; ++i) { + whitespaceFlags[i] = true; + } + + whitespaceFlags[0x1A] = false; + for (int i = 0x7F; i <= 0xA0; ++i) { + whitespaceFlags[i] = true; + } + + whitespaceFlags[160] = true; // 特别处理 + } + public static boolean isWhitespace(char c) { + return (c <= whitespaceFlags.length && whitespaceFlags[c]) // + || c == ' '; // Chinese space + } + + final void nextToken() { + if (index == Integer.MIN_VALUE) { + token = Token.EOF; + return; + } + + for (;;) { + if (isWhitespace(ch)) { + nextChar(); + continue; + } + + if (index >= text.length()) { + token = Token.EOF; + return; + } + + break; + } + + switch (ch) { + case '{': + token = Token.LBRACE; + nextChar(); + break; + case '}': + token = Token.RBRACE; + nextChar(); + break; + case '[': + token = Token.LBRACKET; + nextChar(); + break; + case ']': + token = Token.RBRACKET; + nextChar(); + break; + case ',': + token = Token.COMMA; + nextChar(); + break; + case ':': + token = Token.COLON; + nextChar(); + break; + case '"': + scanString(); + break; + default: + if (isDigit(ch) || ch == '-') { + scanDigit(); + return; + } + + if (text.startsWith("null", index)) { + token = Token.NULL; + index += 3; + nextChar(); + return; + } + + if (text.startsWith("true", index)) { + token = Token.TRUE; + index += 3; + nextChar(); + return; + } + + if (text.startsWith("false", index)) { + token = Token.FALSE; + index += 4; + nextChar(); + return; + } + throw new IllegalArgumentException("illegal json char : " + ch); + } + } + + private void scanDigit() { + boolean isNegate = false; + if (ch == '-') { + isNegate = true; + nextChar(); + } + + int dotCount = 0; + StringBuilder digitBuf = new StringBuilder(); + for (;;) { + digitBuf.append(ch); + nextChar(); + + if (ch == '.') { + dotCount++; + digitBuf.append('.'); + nextChar(); + continue; + } + + if (!isDigit(ch)) { + break; + } + } + + if (dotCount == 0) { + long longValue = Long.parseLong(digitBuf.toString()); + if (isNegate) { + longValue = -longValue; + } + this.longValue = longValue; + token = Token.INT; + } else { + double doubleValue = Double.parseDouble(digitBuf.toString()); + if (isNegate) { + doubleValue = -doubleValue; + } + this.doubleValue = doubleValue; + token = Token.DOUBLE; + } + } + + private void scanString() { + nextChar(); + StringBuilder strBuf = new StringBuilder(); + for (;;) { + if (index >= text.length()) { + throw new IllegalArgumentException("illegal string : " + strBuf); + } + if (ch == '"') { + nextChar(); + break; + } + + if (ch == '\\') { + nextChar(); + if (ch == '"' || ch == '\\' || ch == '/') { + strBuf.append(ch); + } else if (ch == 'n') { + strBuf.append('\n'); + } else if (ch == 'r') { + strBuf.append('\r'); + } else if (ch == 'b') { + strBuf.append('\b'); + } else if (ch == 'f') { + strBuf.append('\f'); + } else if (ch == 't') { + strBuf.append('\t'); + } else if (ch == 'u') { + nextChar(); + char c1 = ch; + nextChar(); + char c2 = ch; + nextChar(); + char c3 = ch; + nextChar(); + char c4 = ch; + int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); + strBuf.append((char) val); + } else { + throw new IllegalArgumentException("illegal string : " + strBuf); + } + } else { + strBuf.append(ch); + } + nextChar(); + } + stringValue = strBuf.toString(); + token = Token.STRING; + } + + static boolean isDigit(char ch) { + return ch >= '0' && ch <= '9'; + } + + void nextChar() { + ++index; + if (index >= text.length()) { + index = Integer.MIN_VALUE; + return; + } + + ch = text.charAt(index); + } + + enum Token { + INT, // + DOUBLE, // + STRING, // + BOOLEAN, // + TRUE, // + FALSE, // + NULL, // + EOF, // + + LBRACE("{"), // + RBRACE("}"), // + LBRACKET("["), // + RBRACKET("]"), // + COMMA(","), // + COLON(":"), + + ; + + public final String name; + + Token(){ + this(null); + } + + Token(String name){ + this.name = name; + } + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONUtils.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONUtils.java new file mode 100644 index 0000000..70a8c32 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONUtils.java @@ -0,0 +1,15 @@ +package com.taurus.core.util.json; + +public class JSONUtils { + + public static String toJSONString(Object o) { + JSONWriter writer = new JSONWriter(); + writer.writeObject(o); + return writer.toString(); + } + + public static Object parse(String text) { + JSONParser parser = new JSONParser(text); + return parser.parse(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONWriter.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONWriter.java new file mode 100644 index 0000000..50d578b --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/json/JSONWriter.java @@ -0,0 +1,314 @@ + +package com.taurus.core.util.json; + + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +public class JSONWriter { + + private StringBuilder out; + + + + public JSONWriter(){ + this.out = new StringBuilder(); + } + + public void writeArrayStart() { + write('['); + } + + public void writeComma() { + write(','); + } + + public void writeArrayEnd() { + write(']'); + } + + public void writeNull() { + write("null"); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void writeObject(Object o) { + if (o == null) { + writeNull(); + return; + } + + if (o instanceof String) { + writeString((String) o); + return; + } + + if (o instanceof Number) { + write(o.toString()); + return; + } + + if (o instanceof Boolean) { + write(o.toString()); + return; + } + + if (o instanceof Date) { + writeDate((Date) o); + return; + } + + if (o instanceof Collection) { + writeArray((Collection) o); + return; + } + + if (o instanceof Throwable) { + writeError((Throwable) o); + return; + } + + if (o instanceof int[]) { + int[] array = (int[]) o; + write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + write(','); + } + write(array[i]); + } + write(']'); + return; + } + + if (o instanceof long[]) { + long[] array = (long[]) o; + write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + write(','); + } + write(array[i]); + } + write(']'); + return; + } + + if (o instanceof TabularData) { + writeTabularData((TabularData) o); + return; + } + + if (o instanceof CompositeData) { + writeCompositeData((CompositeData) o); + return; + } + + if (o instanceof Map) { + writeMap((Map) o); + return; + } + + throw new IllegalArgumentException("not support type : " + o.getClass()); + } + + public void writeDate(Date date) { + if (date == null) { + writeNull(); + return; + } + //SimpleDataFormat is not thread-safe, we need to make it local. + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + writeString(dateFormat.format(date)); + } + + public void writeError(Throwable error) { + if (error == null) { + writeNull(); + return; + } + error.printStackTrace(); + + write("{\"Class\":"); + writeString(error.getClass().getName()); + write(",\"Message\":"); + writeString(error.getMessage()); + write(",\"StackTrace\":"); + writeString(getStackTrace(error)); + write('}'); + } + + public static String getStackTrace(Throwable ex) { + StringWriter buf = new StringWriter(); + ex.printStackTrace(new PrintWriter(buf)); + + return buf.toString(); + } + + public void writeArray(Object[] array) { + if (array == null) { + writeNull(); + return; + } + + write('['); + + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + write(','); + } + writeObject(array[i]); + } + + write(']'); + } + + public void writeArray(Collection list) { + if (list == null) { + writeNull(); + return; + } + + int entryIndex = 0; + write('['); + + for (Object entry : list) { + if (entryIndex != 0) { + write(','); + } + writeObject(entry); + entryIndex++; + } + + write(']'); + } + + public void writeString(String text) { + if (text == null) { + writeNull(); + return; + } + + write('"'); + for (int i = 0; i < text.length(); ++i) { + char c = text.charAt(i); + if (c == '"') { + write("\\\""); + } else if (c == '\n') { + write("\\n"); + } else if (c == '\r') { + write("\\r"); + } else if (c == '\\') { + write("\\\\"); + } else if (c == '\t') { + write("\\t"); + } else if (c < 16) { + write("\\u000"); + write(Integer.toHexString(c)); + } else if (c < 32) { + write("\\u00"); + write(Integer.toHexString(c)); + } else if (c >= 0x7f && c <= 0xA0) { + write("\\u00"); + write(Integer.toHexString(c)); + } else { + write(c); + } + } + write('"'); + } + + public void writeTabularData(TabularData tabularData) { + if (tabularData == null) { + writeNull(); + return; + } + + int entryIndex = 0; + write('['); + + for (Object item : tabularData.values()) { + if (entryIndex != 0) { + write(','); + } + CompositeData row = (CompositeData) item; + writeCompositeData(row); + + entryIndex++; + } + write(']'); + } + + public void writeCompositeData(CompositeData compositeData) { + if (compositeData == null) { + writeNull(); + return; + } + + int entryIndex = 0; + write('{'); + + for (Object key : compositeData.getCompositeType().keySet()) { + if (entryIndex != 0) { + write(','); + } + writeString((String) key); + write(':'); + Object value = compositeData.get((String) key); + writeObject(value); + entryIndex++; + } + + write('}'); + } + + public void writeMap(Map map) { + if (map == null) { + writeNull(); + return; + } + + int entryIndex = 0; + write('{'); + for (Map.Entry entry : map.entrySet()) { + if (entryIndex != 0) { + write(','); + } + + writeString(entry.getKey()); + write(':'); + writeObject(entry.getValue()); + + entryIndex++; + } + + write('}'); + } + + protected void write(String text) { + out.append(text); + } + + protected void write(char c) { + out.append(c); + } + + protected void write(int c) { + out.append(c); + } + + protected void write(long c) { + out.append(c); + } + + public String toString() { + return out.toString(); + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/ITaskHandler.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/ITaskHandler.java new file mode 100644 index 0000000..c08d297 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/ITaskHandler.java @@ -0,0 +1,16 @@ +package com.taurus.core.util.task; + +/** + * 任务处理器通用接口 + * + * + */ +public interface ITaskHandler { + + /** + * + * @param task + * @throws Exception + */ + public void doTask(Task ask) throws Exception; +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/Task.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/Task.java new file mode 100644 index 0000000..c8afa95 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/Task.java @@ -0,0 +1,45 @@ +package com.taurus.core.util.task; + +import java.util.HashMap; +import java.util.Map; + +/** + * 任务数据基类 + * + * + */ +public class Task { + private Object id; + private Map parameters; + private volatile boolean active = true; + + public Task() { + this.parameters = new HashMap(); + } + + public Task(Object id) { + this(); + this.id = id; + } + + public Task(Object id, Map mapObj) { + this.id = id; + this.parameters = mapObj; + } + + public Object getId() { + return this.id; + } + + public Map getParameters() { + return this.parameters; + } + + public boolean isActive() { + return this.active; + } + + public void setActive(boolean active) { + this.active = active; + } +} diff --git a/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/TaskScheduler.java b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/TaskScheduler.java new file mode 100644 index 0000000..1e9dc23 --- /dev/null +++ b/taurus-server/taurus-core/src/main/java/com/taurus/core/util/task/TaskScheduler.java @@ -0,0 +1,139 @@ +package com.taurus.core.util.task; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.service.AbstractService; +import com.taurus.core.util.Logger; + +/** + * 计时器/任务调度器 + * + * + */ +public class TaskScheduler extends AbstractService implements Runnable { + private static AtomicInteger schedulerId = new AtomicInteger(0); + + private volatile int threadId = 1; + private long SLEEP_TIME = 250L; + private ExecutorService taskExecutor; + private LinkedList taskList; + private LinkedList addList; + private Logger logger; + private volatile boolean running = false; + + public TaskScheduler() { + schedulerId.incrementAndGet(); + this.taskList = new LinkedList(); + this.addList = new LinkedList(); + this.logger = Logger.getLogger(TaskScheduler.class); + } + + public void init(Object o) { + super.init(o); + startService(); + } + + public void destroy(Object o) { + super.destroy(o); + stopService(); + } + + public void handleMessage(Object message) { + throw new UnsupportedOperationException("not supported in this class version"); + } + + public void startService() { + running = true; + taskExecutor = Executors.newSingleThreadExecutor(); + taskExecutor.execute(this); + } + + public void stopService() { + running = false; + List leftOvers = taskExecutor.shutdownNow(); + taskExecutor = null; + logger.info("Scheduler stopped. Unprocessed tasks: " + leftOvers.size()); + } + + public void run() { + Thread.currentThread().setName("Scheduler" + schedulerId.get() + "-thread-" + this.threadId++); + logger.info("Scheduler started: " + name); + + while (running) { + try { + executeTasks(); + Thread.sleep(SLEEP_TIME); + } catch (InterruptedException ie) { + logger.warn("Scheduler: " + name + " interrupted."); + } catch (Exception e) { + logger.error( "Scheduler: " + name + " caught a generic exception: " + e, e); + } + } + } + + public void addScheduledTask(Task task, int interval, boolean loop, ITaskHandler callback) { + synchronized (addList) { + addList.add(new ScheduledTask(task, interval, loop, callback)); + } + } + + private void executeTasks() { + long now = System.currentTimeMillis(); + + if (taskList.size() > 0) { + synchronized (taskList) { + for (Iterator it = taskList.iterator(); it.hasNext();) { + ScheduledTask t = (ScheduledTask) it.next(); + + if (!t.task.isActive()) { + it.remove(); + } else { + if (now < t.expiry) { + continue; + } + try { + t.callback.doTask(t.task); + } catch (Exception e) { + logger.error("Scheduler callback exception. Callback: " + t.callback + ", Exception: " + e, e); + } + + if (t.loop) { + t.expiry += t.interval * 1000; + } else { + it.remove(); + } + } + } + } + + } + + if (addList.size() > 0) { + synchronized (taskList) { + taskList.addAll(addList); + addList.clear(); + } + } + } + + private final class ScheduledTask { + long expiry; + int interval; + boolean loop; + ITaskHandler callback; + Task task; + + public ScheduledTask(Task t, int interval, boolean loop, ITaskHandler callback) { + this.task = t; + this.interval = interval; + this.expiry = (System.currentTimeMillis() + interval * 1000); + this.callback = callback; + this.loop = loop; + } + } +} diff --git a/taurus-server/taurus-core/src/test/java/Test.java b/taurus-server/taurus-core/src/test/java/Test.java new file mode 100644 index 0000000..f04b677 --- /dev/null +++ b/taurus-server/taurus-core/src/test/java/Test.java @@ -0,0 +1,221 @@ +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; +import org.jdom.output.XMLOutputter; + +import com.mysql.cj.util.Util; +import com.sun.management.OperatingSystemMXBean; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.TArray; +import com.taurus.core.plugin.PluginService; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Utils; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Transaction; + +public class Test { + private static final int[] PIDS= { + 48,49,50,51,52,53,54,55,56,57, +// 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, + 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122 + }; + private static final Random rnd = new Random(System.currentTimeMillis()); + + private static final String rndId() { + char[] chars = new char[8]; + for(int i=0;i searchFiles(File folder, final String keyword) { + List result = new ArrayList(); + if (folder.isFile()) + result.add(folder); + + File[] subFolders = folder.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + if (file.isDirectory()) { + return true; + } + if (file.getName().toLowerCase().contains(keyword)) { + return true; + } + return false; + } + }); + + if (subFolders != null) { + for (File file : subFolders) { + if (file.isFile()) { + // 如果是文件则将文件添加到结果列表中 + result.add(file); + } else { + // 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中 + result.addAll(searchFiles(file, keyword)); + } + } + } + + return result; + } + + private static void read(Data data) throws Exception { + InputStream is = new FileInputStream(data.file); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + is.close(); + data.document = document; + data.root = root; + data.id = root.getAttributeValue("id"); + } + + private static final class Data{ + public File file; + public Document document; + public Element root; + public String id; + + public boolean equals(Object obj) { + if(obj instanceof Data) { + return this == obj; + } + if(obj instanceof String) { + return id.equals(obj); + } + return false; + } + } + + private static final String exceId(List datas) { + String id = rndId(); + if(datas.contains(id)) { + return exceId(datas); + } + return id; + } + + private static void emoji_test() { + try { + PluginService.me().loadConfig(); + String sql = "insert into test(nick) values('12🦌🦌🦌12')"; + long time = System.currentTimeMillis(); + for(int i=0;i<1;++i) { + DataBase.use().executeUpdate(sql); + } + System.out.println("use time:"+(System.currentTimeMillis() - time)); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void find_test() { + try { + PluginService.me().loadConfig(); + String sql = "select * from test"; + long time = System.currentTimeMillis(); + for(int i=0;i<2000;++i) { + DataBase.use().executeQueryByTArray(sql); + } + System.out.println("use time:"+(System.currentTimeMillis() - time)); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + private static OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + public static int cpuLoad() { + double cpuLoad = osmxb.getSystemCpuLoad(); + int percentCpuLoad = (int) (cpuLoad * 100); + return percentCpuLoad; + } + + public static void main(String[] args) { + try { + PluginService.me().loadConfig(); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + new Thread(() -> { + while (true) { + long bac = 1000000; + bac = bac >> 1; + } + }).start();; + + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + System.out.println(cpuLoad()); + } + + + + +// find_test(); +// for(int i =0;i<100;++i) +// System.out.println(rndId()); + + /* + List files = searchFiles(new File("F:\\work\\pro\\qyq_client\\client\\new_pro\\qyq_new_ui\\"), "package.xml"); + List files1 = searchFiles(new File("F:\\work\\pro\\qyq_client\\client\\new_pro\\qyq_exinfo_ui\\"), "package.xml"); + files.addAll(files1); + List datas = new ArrayList<>(); + try { + for(File f : files) { + Data d = new Data(); + d.file = f; + read(d); + datas.add(d); + } + }catch (Exception e) { + e.printStackTrace(); + } + List listTemp = new ArrayList(); + for(int i=0;i + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/taurus-server/taurus-permanent/config/taurus-permanent.xml b/taurus-server/taurus-permanent/config/taurus-permanent.xml new file mode 100644 index 0000000..6c629f3 --- /dev/null +++ b/taurus-server/taurus-permanent/config/taurus-permanent.xml @@ -0,0 +1,75 @@ + + + 4 + + 100 + + Heap + + Heap + + 524288 + + 1024 + + 32768 + + 160 + + + 2 + 3 + 3 + + + true + + 15 + + + + + + + + + + 1.2.3.4 + + + 127.0.0.1 + + 10000 + + + + true +
0.0.0.0
+ 8080 +
+ + + + extension - test + com.taurus.TestExtension + + + + + Sys + 4 + 16 + 60000 + 20000 + + + + + Ext + 4 + 16 + 60000 + 20000 + + +
\ No newline at end of file diff --git a/taurus-server/taurus-permanent/pom.xml b/taurus-server/taurus-permanent/pom.xml new file mode 100644 index 0000000..7fa00c5 --- /dev/null +++ b/taurus-server/taurus-permanent/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + com.taurus + taurus-server + 1.0.1 + + jar + taurus-permanent + 1.0.1 + + + + + junit + junit + + + + + com.taurus + taurus-core + + + + + io.undertow + undertow-core + 2.0.16.Final + + + diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/Main.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/Main.java new file mode 100644 index 0000000..9156073 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/Main.java @@ -0,0 +1,9 @@ +package com.taurus.permanent; + +public class Main { + + public static void main(String[] args) { + TPServer taurus = TPServer.me(); + taurus.start(); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java new file mode 100644 index 0000000..b7b2c9f --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/TPServer.java @@ -0,0 +1,319 @@ +package com.taurus.permanent; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.events.Event; +import com.taurus.core.events.EventManager; +import com.taurus.core.events.IEventListener; +import com.taurus.core.plugin.PluginService; +import com.taurus.core.routes.Extension; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.task.TaskScheduler; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.core.ServerConfig.ExecutorConfig; +import com.taurus.permanent.core.ServerState; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.core.SystemController; +import com.taurus.permanent.core.TPEvents; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.util.GhostUserHunter; + +/** + * The server main class. + * + * + * + */ +public final class TPServer { + /** + * The server version. + */ + private final String version = "1.0.1"; + /** + * The server class instance. + */ + private static TPServer _instance = null; + private final BitSwarmEngine bitSwarmEngine; + private final Logger log; + private volatile ServerState state = ServerState.STARTING; + private volatile boolean initialized = false; + private volatile long serverStartTime; + private ServerConfig config; + private IEventListener networkEvtListener; + private ScheduledThreadPoolExecutor timerPool; + private TaskScheduler taskScheduler; + private EventManager eventManager; + private GhostUserHunter ghostUserHunter; + private SystemController controller; + private Extension extension; + private ThreadPoolExecutor systemExecutor; + private ThreadPoolExecutor extensionExecutor; + + /** + * get main instance + */ + public static TPServer me() { + if (_instance == null) { + _instance = new TPServer(); + } + return _instance; + } + + private TPServer() { + bitSwarmEngine = BitSwarmEngine.getInstance(); + + networkEvtListener = new NetworkEvtListener(); + timerPool = new ScheduledThreadPoolExecutor(1); + log = Logger.getLogger(getClass()); + + } + + public String getVersion() { + return version; + } + + private static final ServerConfig loadServerSettings() throws Exception { + FileInputStream is = new FileInputStream(DefaultConstants.SERVER_CFG_FILE); + ServerConfig config = new ServerConfig(); + config.load(is); + return config; + } + + public void start() { + System.out.println("\n==============================================================================\n" + + ">>Begin start taurus-permanent server....\n" + + "============================================================================== \n"); + if (!initialized) { + initialize(); + } + + try { + + PluginService.me().loadConfig(); + log.info("Load taurus-core config finish"); + + this.config = loadServerSettings(); + initExecutors(); + + this.taskScheduler = new TaskScheduler(); + this.taskScheduler.init(null); + + this.eventManager = new EventManager(systemExecutor); + eventManager.init(null); + + timerPool.setCorePoolSize(config.timerThreadPoolSize); + bitSwarmEngine.init(null); + + log.info("\n\n==============================================================================\n" + + ">>Init Extension...\n"+ + "============================================================================== \n"); + controller = new SystemController(); + ghostUserHunter = new GhostUserHunter(); + extension = instanceExtension(); + controller.init(null); + extension.onStart(); + + state = ServerState.STARTED; + log.info("\n\n==============================================================================\n" + + ">>Server(" + version + ") ready!\n" + + "============================================================================== \n"); + + serverStartTime = System.currentTimeMillis(); + } catch (FileNotFoundException e) { + log.error("Not find taurus-core.xml and taurus-permanent.xml", e); + } catch (Exception e) { + log.error("Server start exception!", e); + } + } + + private void initExecutors() { + final ExecutorConfig sys_cfg = this.config.systemThreadPoolConfig; + this.systemExecutor = new ThreadPoolExecutor(sys_cfg.corePoolSize, sys_cfg.maxPoolSize, sys_cfg.keepAliveTime, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(sys_cfg.maxQueueSize), new TPThreadFactory(sys_cfg.name)); + + final ExecutorConfig ext_cfg = this.config.extensionThreadPoolConfig; + this.extensionExecutor = new ThreadPoolExecutor(ext_cfg.corePoolSize, ext_cfg.maxPoolSize, ext_cfg.keepAliveTime, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(ext_cfg.maxQueueSize), new TPThreadFactory(ext_cfg.name)); + } + + /** + * shut down server. + */ + public void shutdown() { + try { + log.info("Server shutdown!"); + List awaitingExecution = timerPool.shutdownNow(); + log.info("stopping timer pool: " + awaitingExecution.size()); + + bitSwarmEngine.destroy(null); + eventManager.destroy(null); + this.controller.destroy(null); + extension.onStop(); + } catch (Exception e) { + log.error("shut down exception!", e); + } + } + + public ScheduledThreadPoolExecutor getTimerPool() { + return timerPool; + } + + public TaskScheduler getTaskScheduler() { + return taskScheduler; + } + + public ThreadPoolExecutor getSystemExecutor() { + return systemExecutor; + } + + public ThreadPoolExecutor getExtensionExecutor() { + return extensionExecutor; + } + + public EventManager getEventManager() { + return eventManager; + } + + public SessionManager getSessionManager() { + return bitSwarmEngine.getSessionManager(); + } + + public SystemController getController() { + return controller; + } + + public Extension getExtension() { + return extension; + } + + public ServerState getState() { + return state; + } + + public ServerConfig getConfig() { + return config; + } + + /** + * 获取服务器启动时间 + * + * @return + */ + public long getUptime() { + if (serverStartTime == 0L) { + throw new IllegalStateException("Server not ready yet, cannot provide uptime!"); + } + return System.currentTimeMillis() - serverStartTime; + } + + private void initialize() { + if (initialized) { + throw new IllegalStateException("SmartFoxServer engine already initialized!"); + } + bitSwarmEngine.addEventListener(TPEvents.SESSION_LOST, networkEvtListener); + bitSwarmEngine.addEventListener(TPEvents.SESSION_IDLE, networkEvtListener); + bitSwarmEngine.addEventListener(TPEvents.SESSION_IDLE_CHECK_COMPLETE, networkEvtListener); + + initialized = true; + } + + private Extension instanceExtension() { + ServerConfig.ExtensionConfig extensionConfig = config.extensionConfig; + if (StringUtil.isEmpty(extensionConfig.className)) { + throw new RuntimeException("Extension className parameter is missing!"); + } + if (StringUtil.isEmpty(extensionConfig.name)) { + throw new RuntimeException("Extension name parameter is missing!"); + } + Extension extension = null; + try { + Class extensionClass = Class.forName(extensionConfig.className); + if (!Extension.class.isAssignableFrom(extensionClass)) { + throw new RuntimeException("Extension does not extends Extension: " + extensionConfig.name); + } + extension = (Extension) extensionClass.newInstance(); + extension.setName(extensionConfig.name); + } catch (IllegalAccessException e) { + throw new RuntimeException("Illegal access while instantiating class: " + extensionConfig.className); + } catch (InstantiationException e) { + throw new RuntimeException("Cannot instantiate class: " + extensionConfig.className); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Class not found: " + extensionConfig.className); + } + return extension; + } + + private void onSessionClosed(Session session) { + controller.disconnect(session); + } + + private void onSessionIdle(Session idleSession) { + controller.disconnect(idleSession); + } + + /** + * session 网络事件监听 + */ + private class NetworkEvtListener implements IEventListener { + private NetworkEvtListener() { + } + + public void handleEvent(Event event) { + String evtName = event.getName(); + + if (evtName.equals(TPEvents.SESSION_LOST)) { + Session session = (Session) event.getParameter(TPEvents.PARAM_SESSION); + + if (session == null) { + throw new RuntimeException("session is null!"); + } + onSessionClosed(session); + } else if ((evtName.equals(TPEvents.SESSION_IDLE_CHECK_COMPLETE))) { + ghostUserHunter.hunt(); + } else if (evtName.equals(TPEvents.SESSION_IDLE)) { + onSessionIdle((Session) event.getParameter(TPEvents.PARAM_SESSION)); + } + } + } + + private static final class TPThreadFactory implements ThreadFactory { + private static final AtomicInteger POOL_ID; + private static final String THREAD_BASE_NAME = "%s:%s"; + private final AtomicInteger threadId; + private final String poolName; + + static { + POOL_ID = new AtomicInteger(0); + } + + public TPThreadFactory(final String poolName) { + this.threadId = new AtomicInteger(1); + this.poolName = poolName; + TPThreadFactory.POOL_ID.incrementAndGet(); + } + + @Override + public Thread newThread(final Runnable r) { + final Thread t = new Thread(r, + String.format(THREAD_BASE_NAME, (this.poolName != null) ? this.poolName : TPThreadFactory.POOL_ID.get(), this.threadId.getAndIncrement())); + if (t.isDaemon()) { + t.setDaemon(false); + } + if (t.getPriority() != 5) { + t.setPriority(5); + } + return t; + } + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java new file mode 100644 index 0000000..c750488 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BaseCoreService.java @@ -0,0 +1,46 @@ +package com.taurus.permanent.core; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.events.EventDispatcher; +import com.taurus.core.service.IService; + +/** + * BaseCoreService + * + */ +public abstract class BaseCoreService extends EventDispatcher implements IService { + private static final AtomicInteger serviceId = new AtomicInteger(0); + private static final String DEFAULT_NAME = "Service-"; + protected String name; + protected volatile boolean active = false; + + public void init(Object o) { + name = getServiceId(); + active = true; + } + + public void destroy(Object o) { + active = false; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isActive() { + return active; + } + + public String toString() { + return "[Core Service]: " + name + ", State: " + (isActive() ? "active" : "not active"); + } + + protected static String getServiceId() { + return DEFAULT_NAME + serviceId.getAndIncrement(); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java new file mode 100644 index 0000000..e733060 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/BitSwarmEngine.java @@ -0,0 +1,337 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.taurus.core.events.Event; +import com.taurus.core.events.IEventListener; +import com.taurus.core.service.IService; +import com.taurus.core.util.FixedIndexThreadPool; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.ServerConfig.SocketAddress; +import com.taurus.permanent.data.BindableSocket; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; +import com.taurus.permanent.io.IOHandler; +import com.taurus.permanent.io.ProtocolHandler; +import com.taurus.permanent.normal.SocketAcceptor; +import com.taurus.permanent.normal.SocketReader; +import com.taurus.permanent.normal.SocketWriter; +import com.taurus.permanent.websocket.WebSocketService; + +/** + * 核心网络字节群处理类 + * + */ +public final class BitSwarmEngine extends BaseCoreService { + private static BitSwarmEngine __engine__; + private SocketAcceptor socketAcceptor; + private SocketReader socketReader; + private SocketWriter socketWriter; + + private Logger logger; + private ServerConfig config; + private SessionManager sessionManager; + private volatile boolean inited = false; + private Map coreServicesByName; + private Map configByService; + private IEventListener eventHandler; + private WebSocketService webSocketService; + private ProtocolHandler protocolHandler; + private ConnectionFilter connectionFilter; + private FixedIndexThreadPool threadPool; + + public static BitSwarmEngine getInstance() { + if (__engine__ == null) { + __engine__ = new BitSwarmEngine(); + } + return __engine__; + } + + private BitSwarmEngine() { + setName("BitSwarmEngine"); + } + + private void initializeServerEngine() { + logger = Logger.getLogger(BitSwarmEngine.class); + this.config = TPServer.me().getConfig(); + inited = true; + } + + + private final void bootSequence() throws Exception { + startCoreServices(); + + bindSockets(config.socketAddresses); + for (IService service : coreServicesByName.values()) { + if (service != null) { + service.init(configByService.get(service)); + } + } + } + + private final void setConnectionFilterConfig() { + for (String blockedIp : config.ipFilter.addressBlackList) { + this.connectionFilter.addBannedAddress(blockedIp); + } + + for (String allowedIp : config.ipFilter.addressWhiteList) { + this.connectionFilter.addWhiteListAddress(allowedIp); + } + + this.connectionFilter.setMaxConnectionsPerIp(config.ipFilter.maxConnectionsPerAddress); + } + + /** + * write response packet. no blocking + * @param response + */ + public void write(Packet response) { + try { + if (this.config.webSocketConfig.isActive) { + final List webSocketRecipients = new ArrayList(); + final List socketRecipients = new ArrayList(); + for (final Session session : response.getRecipients()) { + if (session.getType() == SessionType.WEBSOCKET) { + webSocketRecipients.add(session); + } + else { + socketRecipients.add(session); + } + } + if (webSocketRecipients.size() > 0) { + response.setRecipients(socketRecipients); + final Packet webSocketResponse = response.clone(); + webSocketResponse.setRecipients(webSocketRecipients); + if (response.getId() != SystemController.ACTION_PINGPONG) { + long index = Thread.currentThread().getId(); + this.threadPool.execute((int) index, webSocketResponse); + } else { + writeToWebSocket(response); + } + } + } + }finally { + if (response.getId() != SystemController.ACTION_PINGPONG) { + long index = Thread.currentThread().getId(); + this.threadPool.execute((int) index, response); + } else { + writeToSocket(response); + } + } + + } + + /** + * write response packet. no blocking + * @param response 广播服,没有前后顺序的需求,需要尽可能的把包分发给不同的线程 + */ + public void write(Packet response, int weightId) { + if (weightId == 0) + { + weightId = (int)(Math.random() * 1000); + } + try { + if (this.config.webSocketConfig.isActive) { + final List webSocketRecipients = new ArrayList(); + final List socketRecipients = new ArrayList(); + for (final Session session : response.getRecipients()) { + if (session.getType() == SessionType.WEBSOCKET) { + webSocketRecipients.add(session); + } + else { + socketRecipients.add(session); + } + } + if (webSocketRecipients.size() > 0) { + response.setRecipients(socketRecipients); + final Packet webSocketResponse = response.clone(); + webSocketResponse.setRecipients(webSocketRecipients); + if (response.getId() != SystemController.ACTION_PINGPONG) { + this.threadPool.execute(weightId, webSocketResponse); + } else { + writeToWebSocket(response); + } + } + } + }finally { + if (response.getId() != SystemController.ACTION_PINGPONG) { + this.threadPool.execute(weightId, response); + } else { + writeToSocket(response); + } + } + + } + + private void writeToSocket(Packet res) { + socketWriter.getIOHandler().onDataWrite(res); + } + + private void writeToWebSocket(Packet res) { + webSocketService.onDataWrite(res); + } + + + private void startCoreServices() throws Exception { + sessionManager = SessionManager.getInstance(); + sessionManager.setName(DefaultConstants.SERVICE_SESSION_MANAGER); + + socketReader = new SocketReader(config.socketReaderThreadPoolSize); + // instance io handler + IOHandler ioHandler = new IOHandler(); + socketReader.setIoHandler(ioHandler); + + // instance socket acceptor + socketAcceptor = new SocketAcceptor(config.socketAcceptorThreadPoolSize); + // instance socket writer + socketWriter = new SocketWriter(config.socketWriterThreadPoolSize); + socketWriter.setIOHandler(ioHandler); + threadPool = new FixedIndexThreadPool(config.socketWriterThreadPoolSize, "PacketWrite", PacketWriteWork.class); + + if(config.webSocketConfig.isActive) { + webSocketService = new WebSocketService(); + webSocketService.setName(DefaultConstants.SERVICE_WEB_SOCKET); + coreServicesByName.put(DefaultConstants.SERVICE_WEB_SOCKET, webSocketService); + } + + socketAcceptor.setName(DefaultConstants.SERVICE_SOCKET_ACCEPTOR); + socketReader.setName(DefaultConstants.SERVICE_SOCKET_READER); + socketWriter.setName(DefaultConstants.SERVICE_SOCKET_WRITER); + + coreServicesByName.put(DefaultConstants.SERVICE_SESSION_MANAGER, sessionManager); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_ACCEPTOR, socketAcceptor); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_READER, socketReader); + coreServicesByName.put(DefaultConstants.SERVICE_SOCKET_WRITER, socketWriter); + + } + + private void stopCoreServices() throws Exception { + socketWriter.destroy(null); + socketReader.destroy(null); + if(webSocketService!=null) { + webSocketService.destroy(null); + } + int pw_count = threadPool.shutdown(); + logger.info("PacketWrite stopped. Unprocessed tasks: " + pw_count); + Thread.sleep(2000L); + + sessionManager.destroy(null); + socketAcceptor.destroy(null); + } + + private void bindSockets(List bindableSockets) { + for (SocketAddress socketCfg : bindableSockets) { + try { + this.socketAcceptor.bindSocket(socketCfg); + } catch (IOException e) { + logger.error(e); + logger.warn("Was not able to bind socket: " + socketCfg); + } + } + + List sockets = socketAcceptor.getBoundSockets(); + String message = "Listening Sockets: "; + for (BindableSocket socket : sockets) { + message = message + socket.toString() + " "; + } + logger.info(message); + } + + public IService getServiceByName(String serviceName) { + return coreServicesByName.get(serviceName); + } + + public SocketAcceptor getSocketAcceptor() { + return this.socketAcceptor; + } + + public SocketReader getSocketReader() { + return this.socketReader; + } + + public SocketWriter getSocketWriter() { + return this.socketWriter; + } + + public ProtocolHandler getProtocolHandler() { + return this.protocolHandler; + } + + public Logger getLogger() { + return this.logger; + } + + public void setLogger(Logger logger) { + this.logger = logger; + } + + public ServerConfig getConfig() { + return this.config; + } + + public ConnectionFilter getConnectionFilter() { + return connectionFilter; + } + + public SessionManager getSessionManager() { + return this.sessionManager; + } + + public void init(Object o) { + if (!inited) { + initializeServerEngine(); + } + logger.info("Start Bit Swarm Engine!"); + + eventHandler = new IEventListener() { + public void handleEvent(Event event) { + dispatchEvent(event); + } + }; + + protocolHandler = new ProtocolHandler(); + connectionFilter = new ConnectionFilter(); + setConnectionFilterConfig(); + coreServicesByName = new ConcurrentHashMap(); + configByService = new HashMap(); + + try { + bootSequence(); + } catch (Exception e) { + throw new RuntimeException(e); + } + socketReader.addEventListener(TPEvents.SESSION_LOST, this.eventHandler); + } + + public void destroy(Object o) { + try { + stopCoreServices(); + } catch (Exception e) { + logger.error("Destroy exception!\n",e); + } + } + + public static final class PacketWriteWork extends FixedIndexThreadPool.Work { + + @Override + protected void handlerTask(Object task) throws Exception { + Packet packet = (Packet) task; + List list = packet.getRecipients(); + if(list.size() > 0) { + SessionType type = list.get(0).getType(); + if(type == SessionType.WEBSOCKET) { + BitSwarmEngine.getInstance().writeToWebSocket(packet); + }else { + BitSwarmEngine.getInstance().writeToSocket(packet); + } + } + } + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java new file mode 100644 index 0000000..e42fa07 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ConnectionFilter.java @@ -0,0 +1,159 @@ +package com.taurus.permanent.core; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.core.util.Logger; + + +/** + * ip连接过滤 + * + */ +public class ConnectionFilter { + private final Set addressWhiteList; + private final Set bannedAddresses; + private final ConcurrentMap addressMap; + private int maxConnectionsPerIp = 10; + private Logger logger; + + public ConnectionFilter() { + this.addressWhiteList = new HashSet(); + this.bannedAddresses = new HashSet(); + this.addressMap = new ConcurrentHashMap(); + logger = Logger.getLogger(ConnectionFilter.class); + } + /** + * 获取所有黑名单列表 + */ + public void addBannedAddress(String ipAddress) { + synchronized (bannedAddresses) { + bannedAddresses.add(ipAddress); + } + } + + /** + * 获取所有白名单列表 + */ + public void addWhiteListAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + this.addressWhiteList.add(ipAddress); + } + } + + /** + * 获取所有黑名单列表 + */ + public String[] getBannedAddresses() { + String[] set = (String[]) null; + + synchronized (this.bannedAddresses) { + set = new String[bannedAddresses.size()]; + set = (String[]) bannedAddresses.toArray(set); + } + + return set; + } + + /** + * 获取每个IP最大的连接数 + */ + public int getMaxConnectionsPerIp() { + return this.maxConnectionsPerIp; + } + + /** + * 获取白名单列表 + */ + public String[] getWhiteListAddresses() { + String[] set = (String[]) null; + + synchronized (this.addressWhiteList) { + set = new String[this.addressWhiteList.size()]; + set = (String[]) this.addressWhiteList.toArray(set); + } + + return set; + } + + public void removeAddress(String ipAddress) { + synchronized (this.addressMap) { + AtomicInteger count = (AtomicInteger) this.addressMap.get(ipAddress); + + if (count != null) { + int value = count.decrementAndGet(); + + if (value == 0) + this.addressMap.remove(ipAddress); + } + } + } + + /** + * 移除黑名单IP地址 + */ + public void removeBannedAddress(String ipAddress) { + synchronized (this.bannedAddresses) { + this.bannedAddresses.remove(ipAddress); + } + } + + /** + * 移除白名单IP地址 + */ + public void removeWhiteListAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + this.addressWhiteList.remove(ipAddress); + } + } + + /** + * 获取每个IP最大连接数 + */ + public void setMaxConnectionsPerIp(int max) { + this.maxConnectionsPerIp = max; + } + + public boolean validateAndAddAddress(String ipAddress) { + synchronized (this.addressWhiteList) { + if (this.addressWhiteList.contains(ipAddress)) { + return true; + } + } + + if (isAddressBanned(ipAddress)) { + logger.warn("Ip Address: " + ipAddress + " is banned!"); + return false; + } + + synchronized (this.addressMap) { + AtomicInteger count = (AtomicInteger) addressMap.get(ipAddress); + + if ((count != null) && (count.intValue() >= maxConnectionsPerIp)) { + logger.warn("Refused connection. Ip Address: " + ipAddress + " has reached maximum allowed connections."); + return false; + } + + if (count == null) { + count = new AtomicInteger(1); + this.addressMap.put(ipAddress, count); + } else { + count.incrementAndGet(); + } + } + return true; + } + + private boolean isAddressBanned(String ip) { + boolean isBanned = false; + + synchronized (this.bannedAddresses) { + isBanned = this.bannedAddresses.contains(ip); + } + + return isBanned; + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java new file mode 100644 index 0000000..1e389fc --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/DefaultConstants.java @@ -0,0 +1,20 @@ +package com.taurus.permanent.core; + +/** + * 常量表 + * + */ +public final class DefaultConstants { + public static String SERVER_CFG_FILE = "config/taurus-permanent.xml"; + + + public static final String SERVICE_SOCKET_ACCEPTOR = "socketAcceptor"; + public static final String SERVICE_SOCKET_READER = "socketReader"; + public static final String SERVICE_SOCKET_WRITER = "socketWriter"; + public static final String SERVICE_SESSION_MANAGER = "sessionManager"; + public static final String SERVICE_WEB_SOCKET = "webSocket"; + + + public static final String SESSION_SELECTION_KEY = "SessionSelectionKey"; + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java new file mode 100644 index 0000000..e3f4124 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/IConnectionFilter.java @@ -0,0 +1,61 @@ +package com.taurus.permanent.core; + + +/** + * ip连接过滤通用接口 + * + */ +public interface IConnectionFilter { + /** + * 添加黑名单IP地址 + * @param ipAddress + */ + public void addBannedAddress(String ipAddress); + + /** + * 移除黑名单IP地址 + * @param ipAddress + */ + public void removeBannedAddress(String ipAddress); + + /** + * 获取所有黑名单列表 + * @return + */ + public String[] getBannedAddresses(); + + + public boolean validateAndAddAddress(String ipAddress); + + public void removeAddress(String ipAddress); + + /** + * 添加白名单地址 + * @param ipAddress + */ + public void addWhiteListAddress(String ipAddress); + + /** + * 移除白名单地址 + * @param ipAddress + */ + public void removeWhiteListAddress(String ipAddress); + + /** + * 获取白名单列表 + * @return + */ + public String[] getWhiteListAddresses(); + + /** + * 获取每个IP最大的连接数 + * @return + */ + public int getMaxConnectionsPerIp(); + + /** + * 设置每个IP最大的连接数 + * @param max + */ + public void setMaxConnectionsPerIp(int max); +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java new file mode 100644 index 0000000..1bc194d --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerConfig.java @@ -0,0 +1,181 @@ +package com.taurus.permanent.core; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +/** + * 服务器配置信息 + * + */ +public class ServerConfig { + public volatile List socketAddresses = new ArrayList(); + public volatile IpFilterConfig ipFilter = new IpFilterConfig(); + public volatile int timerThreadPoolSize = 1; + public volatile int protocolCompression = 512; + + public String readBufferType = "HEAP"; + public String writeBufferType = "HEAP"; + public int maxPacketSize = 4096; + public int maxReadBufferSize = 1024; + public int maxWriteBufferSize = 32768; + public int socketAcceptorThreadPoolSize = 1; + public int socketReaderThreadPoolSize = 1; + public int socketWriterThreadPoolSize = 1; + public int sessionPacketQueueSize = 120; + public int sessionTimeout = 15; + public boolean tcpNoDelay = false; + + public ExecutorConfig systemThreadPoolConfig = new ExecutorConfig(); + public ExecutorConfig extensionThreadPoolConfig = new ExecutorConfig(); + public ExtensionConfig extensionConfig = new ExtensionConfig(); + public WebSocketConfig webSocketConfig = new WebSocketConfig(); + + /** + * ip过滤设置 + * + */ + public static final class IpFilterConfig { + public List addressBlackList = new ArrayList(); + public List addressWhiteList = new ArrayList(); + public volatile int maxConnectionsPerAddress = 99999; + } + + /** + * server ip_port绑定 + * + */ + public static final class SocketAddress { + public static final String TYPE_UDP = "UDP"; + public static final String TYPE_TCP = "TCP"; + public String address = "127.0.0.1"; + public int port = 9339; + public String type = TYPE_TCP; + + public String toString() { + return String.format("[%s]%s:%d", type, address, port); + } + } + + /** + * Taurus Thread pool config + * + * + */ + public static final class ExecutorConfig { + /** + * 线程池名称 + */ + public String name; + /** + * 核心线程大小 + */ + public int corePoolSize=4; + /** + * 最大线程大小 + */ + public int maxPoolSize=16; + /** + * 线程最大空闲时间(毫秒) + */ + public int keepAliveTime =60000; + /** + * 最大队列大小 + */ + public int maxQueueSize=20000; + } + + /** + * 自定义启动控制设置 + * + * + */ + public static final class ExtensionConfig { + public String name = ""; + public String className = ""; + } + + /** + * web socket + * + * + */ + public static final class WebSocketConfig { + public boolean isActive = true; + public String address = "0.0.0.0"; + public int port = 8080; + } + + private static final void loadThreadPoolConfig(Element em,ExecutorConfig config) { + config.name = em.getChildTextTrim("name"); + config.corePoolSize = Integer.parseInt(em.getChildTextTrim("corePoolSize")); + config.maxPoolSize = Integer.parseInt(em.getChildTextTrim("maxPoolSize")); + config.keepAliveTime = Integer.parseInt(em.getChildTextTrim("keepAliveTime")); + config.maxQueueSize = Integer.parseInt(em.getChildTextTrim("maxQueueSize")); + } + + public final void load(InputStream is) throws Exception{ + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + + this.timerThreadPoolSize = Integer.parseInt(root.getChildTextTrim("timerThreadPoolSize")); + this.protocolCompression = Integer.parseInt(root.getChildTextTrim("protocolCompression")); + this.readBufferType = root.getChildTextTrim("readBufferType"); + this.writeBufferType = root.getChildTextTrim("writeBufferType"); + this.maxPacketSize = Integer.parseInt(root.getChildTextTrim("maxPacketSize")); + this.maxReadBufferSize = Integer.parseInt(root.getChildTextTrim("maxReadBufferSize")); + this.maxWriteBufferSize = Integer.parseInt(root.getChildTextTrim("maxWriteBufferSize")); + this.socketAcceptorThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketAcceptorThreadPoolSize")); + this.socketReaderThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketReaderThreadPoolSize")); + this.socketWriterThreadPoolSize = Integer.parseInt(root.getChildTextTrim("socketWriterThreadPoolSize")); + this.maxPacketSize = Integer.parseInt(root.getChildTextTrim("maxPacketSize")); + this.sessionPacketQueueSize = Integer.parseInt(root.getChildTextTrim("sessionPacketQueueSize")); + this.sessionTimeout = Integer.parseInt(root.getChildTextTrim("sessionTimeout")); + this.tcpNoDelay = Boolean.parseBoolean(root.getChildTextTrim("tcpNoDelay")); + + Element addressesEm = root.getChild("socketAddresses"); + Iterator itr = (addressesEm.getChildren("socket")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + SocketAddress sa = new SocketAddress(); + sa.address = socketEm.getAttributeValue("address", "0.0.0.0"); + sa.port = Integer.parseInt(socketEm.getAttributeValue("port", "9339")); + sa.type = socketEm.getAttributeValue("type", SocketAddress.TYPE_TCP); + socketAddresses.add(sa); + } + + + Element ipFilterEm = root.getChild("ipFilter"); + Element addressBlackListEm = ipFilterEm.getChild("addressBlackList"); + itr = (addressBlackListEm.getChildren("string")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + ipFilter.addressBlackList.add(socketEm.getTextTrim()); + } + Element addressWhiteListEm = ipFilterEm.getChild("addressWhiteList"); + itr = (addressWhiteListEm.getChildren("string")).iterator(); + while(itr.hasNext()) { + Element socketEm = (Element)itr.next(); + ipFilter.addressWhiteList.add(socketEm.getTextTrim()); + } + ipFilter.maxConnectionsPerAddress = Integer.parseInt(ipFilterEm.getChildTextTrim("maxConnectionsPerAddress")); + + Element extensionConfigEm = root.getChild("extensionConfig"); + extensionConfig.className = extensionConfigEm.getChildTextTrim("className"); + extensionConfig.name = extensionConfigEm.getChildTextTrim("name"); + + + Element webSocketEm = root.getChild("webSocket"); + webSocketConfig.isActive = Boolean.parseBoolean(webSocketEm.getChildTextTrim("isActive")); + + loadThreadPoolConfig(root.getChild("systemThreadPoolConfig"),systemThreadPoolConfig); + + loadThreadPoolConfig(root.getChild("extensionThreadPoolConfig"),extensionThreadPoolConfig); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java new file mode 100644 index 0000000..8b8e1d1 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/ServerState.java @@ -0,0 +1,11 @@ +package com.taurus.permanent.core; + +/** + * 服务器状态 + * + */ +public enum ServerState { + STARTING, + STARTED, + REBOOTING; +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java new file mode 100644 index 0000000..46d7af0 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SessionManager.java @@ -0,0 +1,313 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.taurus.core.events.Event; +import com.taurus.core.service.AbstractService; +import com.taurus.core.util.Logger; +import com.taurus.core.util.task.ITaskHandler; +import com.taurus.core.util.task.Task; +import com.taurus.core.util.task.TaskScheduler; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.IPacketQueue; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.NonBlockingPacketQueue; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +/** + * session管理器,负责创建,添加和删除session + * + */ +public final class SessionManager extends AbstractService { + private static final String SESSION_CLEANING_TASK_ID = "SessionCleanerTask"; + private static final int SESSION_CLEANING_INTERVAL_SECONDS = 10; + private static SessionManager __instance__; + private Logger logger; + private final ConcurrentMap sessionsById; + private BitSwarmEngine engine = null; + private final List sessionList; + private final ConcurrentMap sessionsByConnection; + private Task sessionCleanTask; + private TaskScheduler systemScheduler; + private int highestCCS = 0; + + public static SessionManager getInstance() { + if (__instance__ == null) { + __instance__ = new SessionManager(); + } + return __instance__; + } + + private SessionManager() { + sessionsById = new ConcurrentHashMap(); + sessionList = new ArrayList(); + sessionsByConnection = new ConcurrentHashMap(); + } + + public void init(Object o) { + name = "DefaultSessionManager"; + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(SessionManager.class); + + systemScheduler = TPServer.me().getTaskScheduler(); + sessionCleanTask = new Task(SESSION_CLEANING_TASK_ID); + systemScheduler.addScheduledTask(sessionCleanTask, SESSION_CLEANING_INTERVAL_SECONDS, true, new SessionCleaner()); + + active = true; + logger.info("session manager init!"); + } + + public void destroy(Object o) { + super.destroy(o); + sessionCleanTask.setActive(false); + shutDownLocalSessions(); + sessionsByConnection.clear(); + } + + /** + * 添加session对象 + * @param session + */ + public void addSession(Session session) { + synchronized (sessionList) { + sessionList.add(session); + } + sessionsById.put(session.getId(), session); + sessionsByConnection.put(session.getConnection().getChannel(), session); + + + if (sessionList.size() > highestCCS) { + highestCCS = sessionList.size(); + } + logger.info("Session created: " + session); + } + + /** + * 检查session是否存在 + * @param session + * @return + */ + public boolean containsSession(Session session) { + return sessionsById.containsKey(session.getId()); + } + + /** + * 移除指定session对象 + * @param session + */ + public void removeSession(Session session) { + if (session == null)return; + if(!sessionsById.containsKey(session.getId()))return; + synchronized (sessionList) { + sessionList.remove(session); + } + ISocketChannel connection = session.getConnection(); + sessionsById.remove(session.getId()); + if (connection != null) { + sessionsByConnection.remove(connection.getChannel()); + } + if ((session.getType() == SessionType.NORMAL) || (session.getType() == SessionType.WEBSOCKET)) { + engine.getConnectionFilter().removeAddress(session.getAddress()); + } + + logger.info("Session removed: " + session); + } + + /** + * 移除指定ID的session + * @param id + * @return + */ + public Session removeSession(int id) { + Session session = sessionsById.get(id); + if (session != null) { + removeSession(session); + } + return session; + } + + /** + * 移除指定channel的session + * @param connection + * @return + */ + public Session removeSession(Object connection) { + Session session = getSessionByConnection(connection); + if (session != null) { + removeSession(session); + } + return session; + } + + /** + * channel链接断开处理 + * @param connection + * @throws IOException + */ + public void onSocketDisconnected(Object connection) throws IOException { + Session session = sessionsByConnection.get(connection); + if (session == null) { + return; + } + sessionsByConnection.remove(connection); + session.setConnected(false); + removeSession(session); + dispatchLostSessionEvent(session); + } + + /** + * 获取服务器所有session + * @return + */ + public List getAllSessions() { + List allSessions = null; + + synchronized (sessionList) { + allSessions = new ArrayList(sessionList); + } + + return allSessions; + } + + /** + * 获取指定channel的session + * @param connection + * @return + */ + public Session getSessionByConnection(Object connection) { + return sessionsByConnection.get(connection); + } + + /** + * 获取指定ID的session + * @param id + * @return + */ + public Session getSessionById(int id) { + return sessionsById.get(Integer.valueOf(id)); + } + + /** + * 获取最高的流量数量 + * @return + */ + public int getHighestCCS() { + return highestCCS; + } + + /** + * 关闭本地所有session + */ + public void shutDownLocalSessions() { + synchronized (sessionList) { + for (Iterator it = sessionList.iterator(); it.hasNext();) { + Session session = (Session) it.next(); + it.remove(); + try { + session.close(); + } catch (IOException e) { + logger.warn("I/O Error while closing session: " + session); + } + } + } + } + + /** + * 创建 session + * @param channel + * @return + */ + public Session createSession(ISocketChannel channel,SessionType type) { + Session session = new Session(); + session.setConnection(channel); + session.setTimeout(engine.getConfig().sessionTimeout); + session.setType(type); + IPacketQueue packetQueue = new NonBlockingPacketQueue(engine.getConfig().sessionPacketQueueSize); + session.setPacketQueue(packetQueue); + return session; + } + + /** + * 获取当前session链接数 + * @return + */ + public int getSessionCount() { + return sessionList.size(); + } + + private void applySessionCleaning() { + if (getSessionCount() > 0) { + for (Session session : getAllSessions()) { + if ((session == null) || (session.isFrozen())) { + continue; + } + if (session.isMarkedForEviction()) { + terminateSession(session); + logger.info("Terminated idle logged-in session: " + session); + } else { + if (!session.isIdle()) { + continue; + } + if (session.getHashId()!=null) { + logger.info("session timeout:" + session); + + session.setMarkedForEviction(); + dispatchSessionIdleEvent(session); + } else { + terminateSession(session); + } + } + } + } + + Event event = new Event(TPEvents.SESSION_IDLE_CHECK_COMPLETE); + engine.dispatchEvent(event); + } + + private void terminateSession(Session session) { + if (session.getType() == SessionType.NORMAL) { + ISocketChannel connection = session.getConnection(); + + try { + connection.close(); + session.setConnected(false); + } catch (Exception err) { + this.logger.warn("Failed closing connection while removing idle Session: " + session); + } + } + + removeSession(session); + dispatchLostSessionEvent(session); + } + + private void dispatchLostSessionEvent(Session closedSession) { + Event event = new Event(TPEvents.SESSION_LOST); + event.setParameter(TPEvents.PARAM_SESSION, closedSession); + engine.dispatchEvent(event); + } + + private void dispatchSessionIdleEvent(Session idleSession) { + Event event = new Event(TPEvents.SESSION_IDLE); + event.setParameter(TPEvents.PARAM_SESSION, idleSession); + engine.dispatchEvent(event); + } + + /** + * 清理session 任务 + */ + private final class SessionCleaner implements ITaskHandler { + private SessionCleaner() { + } + + public void doTask(Task task) throws Exception { + applySessionCleaning(); + } + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java new file mode 100644 index 0000000..ea6cd03 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/SystemController.java @@ -0,0 +1,322 @@ +package com.taurus.permanent.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadPoolExecutor; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.events.Event; +import com.taurus.core.events.EventManager; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.ActionMapping; +import com.taurus.core.routes.IController; +import com.taurus.core.routes.Routes; +import com.taurus.core.service.IService; +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 核心控制器基类 + * + * + */ +public class SystemController implements IService { + public static final String CONNECT_TOKE = "$t"; + public static final String CONNECT_PROT_COMPRESSION = "$pc"; + public static final String REQUEST_CMD = "$c"; + public static final String REQUEST_GID = "$gi"; + public static final String REQUEST_PARM = "$p"; + public static final String REQUEST_RESULT = "$r"; + + /** + * pingpong + */ + public static final int ACTION_PINGPONG = 0; + /** + * 客户端请求 + */ + public static final int ACTION_REQUST_CMD = 1; + /** + * 服务器事件消息 + */ + public static final int ACTION_EVENT_CMD = 2; + + private volatile boolean active; + private String name = "SystemController"; + private ThreadPoolExecutor threadPool; + + private final Logger logger; + private final TPServer taurus; + + private SessionManager sessionManager; + private ActionMapping actionMapping; + private final Routes routes; + + public SystemController() { + logger = Logger.getLogger(SystemController.class); + taurus = TPServer.me(); + sessionManager = taurus.getSessionManager(); + routes = new Routes(Routes.CONTROLLER_INSTANCE) { + public void config() { + } + }; + routes.setAddSlash(false); + } + + public void init(Object o) { + if (active) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + threadPool = taurus.getExtensionExecutor(); + taurus.getExtension().configRoute(routes); + + actionMapping = new ActionMapping(routes); + actionMapping.buildActionMapping(); + active = true; + } + + public void destroy(Object o) { + active = false; + List leftOvers = threadPool.shutdownNow(); + EventManager eventManager = taurus.getEventManager(); + eventManager.removeAllListener(); + logger.info("SystemController stopping: " + getClass().getName() + ", Unprocessed tasks: " + leftOvers.size()); + } + + public void enqueueRequest(Packet request) { + threadPool.execute(new Runnable() { + @Override + public void run() { + if (active) { + try { + processRequest(request); + } catch (Exception e) { + logger.error(e); + } + } + } + }); + } + + private final void processRequest(Packet packet) throws Exception { + Session sender = packet.getSender(); + if (sender.isIdle() || sender.isMarkedForEviction()) + return; + if (!sessionManager.containsSession(sender)) { + logger.warn(" session is already expired!"); + return; + } + + byte reqId = (byte) packet.getId(); + + switch (reqId) { + case ACTION_PINGPONG: + onPingPong(sender); + break; + case ACTION_REQUST_CMD: + onRequest(sender, packet); + break; + } + } + + private final void onPingPong(Session sender) { + Packet packet = new Packet(); + packet.setId(ACTION_PINGPONG); + packet.setRecipient(sender); + packet.setData(new TObject()); + BitSwarmEngine.getInstance().write(packet); + } + + private final void onRequest(Session sender, Packet packet) throws Exception { + ITObject parm = (ITObject) packet.getData(); + String key = parm.getString(REQUEST_CMD); + Action action = actionMapping.getAction(key); + + if (action == null) { + return; + } + + IController controller = action.getController(); + if(controller == null) { + controller = action.getControllerClass().newInstance(); + } + int gid = 0; + if (parm.containsKey(REQUEST_GID)) + gid = parm.getInt(REQUEST_GID); + ITObject p = null; + if (parm.containsKey(REQUEST_PARM)) { + p = parm.getTObject(REQUEST_PARM); + } + if (action.getInterceptor() != null) { + action.getInterceptor().intercept(action, controller,sender,p,gid); + } else { + action.getMethod().invoke(controller,sender,p,gid); + } + + } + + /** + * 断开session + * + * @param session + */ + public void disconnect(Session session) { + if (session == null) { + throw new RuntimeException("Session object is null."); + } + + try { + if (session.getHashId() != null) { + Event evt = new Event(TPEvents.EVENT_SESSION_DISCONNECT); + evt.setParameter(TPEvents.PARAM_SESSION, session); + taurus.getEventManager().dispatchEvent(evt); + session.setHashId(null); + } + if (session.isConnected()) { + session.close(); + } + } catch (IOException err) { + throw new RuntimeException(err); + } + } + + /** + * 发送事件给单一客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendEvent(String actionKey, ITObject params, Session recipient) { + if(!recipient.isConnected())return; + List msgRecipients = new ArrayList(); + msgRecipients.add(recipient); + sendEvent(actionKey, params, msgRecipients); + } + + /** + * 发送事件给单一客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendEvent(String actionKey, int weightId, ITObject params, Session recipient) { + if(!recipient.isConnected())return; + List msgRecipients = new ArrayList(); + msgRecipients.add(recipient); + sendEvent(actionKey, weightId, params, msgRecipients); + } + + /** + * 发送事件给客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipients 客户端session列表 + */ + public void sendEvent(String actionKey, ITObject params, List recipients) { + ITObject resObj = TObject.newInstance(); + resObj.putString(REQUEST_CMD, actionKey); + if (params != null) { + resObj.putTObject(REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(ACTION_EVENT_CMD); + packet.setData(resObj); + packet.setRecipients(recipients); + BitSwarmEngine.getInstance().write(packet); + } + + /** + * 发送事件给客户端 + * + * @param actionKey 事件协议号 + * @param params 数据参数 + * @param recipients 客户端session列表 + */ + public void sendEvent(String actionKey, int weightId, ITObject params, List recipients) { + ITObject resObj = TObject.newInstance(); + resObj.putString(REQUEST_CMD, actionKey); + if (params != null) { + resObj.putTObject(REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(ACTION_EVENT_CMD); + packet.setData(resObj); + packet.setRecipients(recipients); + BitSwarmEngine.getInstance().write(packet, weightId); + } + + /** + * 动态响应客户端请示 + * + * @param gid + * @param result 响应结果 0成功 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendResponse(int gid,int result, ITObject params, Session recipient) { + if(gid==0)return; + if(!recipient.isConnected())return; + ITObject resObj = TObject.newInstance(); + resObj.putInt(SystemController.REQUEST_RESULT, result); + resObj.putInt(SystemController.REQUEST_GID, gid); + if (params != null) { + resObj.putTObject(SystemController.REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(SystemController.ACTION_REQUST_CMD); + packet.setData(resObj); + packet.setRecipient(recipient); + BitSwarmEngine.getInstance().write(packet); + } + + /** + * 动态响应客户端请示 + * + * @param gid + * @param result 响应结果 0成功 + * @param params 数据参数 + * @param recipient 客户端session + */ + public void sendResponse(int gid,int result, int weightId, ITObject params, Session recipient) { + if(gid==0)return; + if(!recipient.isConnected())return; + ITObject resObj = TObject.newInstance(); + resObj.putInt(SystemController.REQUEST_RESULT, result); + resObj.putInt(SystemController.REQUEST_GID, gid); + if (params != null) { + resObj.putTObject(SystemController.REQUEST_PARM, params); + } + Packet packet = new Packet(); + packet.setId(SystemController.ACTION_REQUST_CMD); + packet.setData(resObj); + packet.setRecipient(recipient); + BitSwarmEngine.getInstance().write(packet, weightId); + } + + public final Logger getLogger() { + return logger; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public boolean isActive() { + return active; + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java new file mode 100644 index 0000000..0f0eb50 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/core/TPEvents.java @@ -0,0 +1,28 @@ +package com.taurus.permanent.core; + +/** + * TPEvents + * + * + */ +public class TPEvents { + /** + * session丢失或被清理时间 + */ + public static final String SESSION_LOST = "sessionLost"; + /** + * session空闲事件 + */ + public static final String SESSION_IDLE = "sessionIdle"; + /** + * 完成检测需要清理的session事件 + */ + public static final String SESSION_IDLE_CHECK_COMPLETE = "sessionIdleCheckComplete"; + /** + * session断开连接事件 + */ + public static final String EVENT_SESSION_DISCONNECT = "session_disconnect"; + + public static final String PARAM_SESSION = "session"; + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java new file mode 100644 index 0000000..a4bd191 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/BindableSocket.java @@ -0,0 +1,37 @@ +package com.taurus.permanent.data; + +import java.nio.channels.SelectableChannel; + +/** + * BindableSocket + * + */ +public class BindableSocket { + protected SelectableChannel channel; + private String address; + private int port; + + public BindableSocket(SelectableChannel channel, String address, int port) { + this.address = address; + this.port = port; + + this.channel = channel; + } + + public SelectableChannel getChannel() { + return channel; + } + + public String getAddress() { + return address; + } + + public int getPort() { + return port; + } + + + public String toString() { + return String.format("%s[%d]", address, port); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java new file mode 100644 index 0000000..b7bd82d --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/IPacketQueue.java @@ -0,0 +1,66 @@ +package com.taurus.permanent.data; + +/** + * 网络包队列接口 + * + */ +public interface IPacketQueue { + /** + * 返回队列头部的元素 + * @return + */ + public Packet peek(); + + /** + * 移除并返回队列头部的元素 + * @return + */ + public Packet take(); + + /** + * 队列是否为空 + * @return + */ + public boolean isEmpty(); + + /** + * 队列是否已满 + * @return + */ + public boolean isFull(); + + /** + * 获取队列当前大小 + * @return + */ + public int getSize(); + + /** + * 获取队列最大大小 + * @return + */ + public int getMaxSize(); + + /** + * 设置队列最大大小 + * @param size + */ + public void setMaxSize(int size); + + /** + * 队列当前使用百分比 + * @return + */ + public float getPercentageUsed(); + + /** + * 清理队列 + */ + public void clear(); + + /** + * 添加一个元素 + * @param packet + */ + public void put(Packet packet); +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java new file mode 100644 index 0000000..4b1709e --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/ISocketChannel.java @@ -0,0 +1,21 @@ +package com.taurus.permanent.data; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.ByteBuffer; + +public interface ISocketChannel{ + long write(ByteBuffer buffer); + + void write(final String p0); + + boolean checkConnection(); + + Object getChannel(); + + SocketAddress getRemoteAddress(); + + SocketAddress getLocalAddress(); + + void close() throws IOException; +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java new file mode 100644 index 0000000..83fc0e1 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/NonBlockingPacketQueue.java @@ -0,0 +1,82 @@ +package com.taurus.permanent.data; + +import java.util.LinkedList; + +/** + * 非阻塞网络包队列 + * + */ +public final class NonBlockingPacketQueue implements IPacketQueue { + private final LinkedList queue; + private int maxSize; + + public NonBlockingPacketQueue(int maxSize) { + this.queue = new LinkedList(); + this.maxSize = maxSize; + } + + public void clear() { + synchronized (this.queue) { + queue.clear(); + } + } + + public int getSize() { + return queue.size(); + } + + public int getMaxSize() { + return maxSize; + } + + public boolean isEmpty() { + return queue.size() == 0; + } + + public boolean isFull() { + return queue.size() >= maxSize; + } + + public float getPercentageUsed() { + if (this.maxSize == 0) { + return 0.0F; + } + return queue.size() * 100 / maxSize; + } + + public Packet peek() { + Packet packet = null; + + synchronized (this.queue) { + if (!isEmpty()) { + packet = queue.get(0); + } + } + return packet; + } + + public void put(Packet packet){ + if (isFull()) { + throw new RuntimeException("packet is full!"); + } + + synchronized (queue) { + queue.addLast(packet); + } + } + + public void setMaxSize(int size) { + maxSize = size; + } + + public Packet take() { + Packet packet = null; + + synchronized (queue) { + packet = queue.removeFirst(); + } + + return packet; + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java new file mode 100644 index 0000000..884a912 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/PackDataType.java @@ -0,0 +1,6 @@ +package com.taurus.permanent.data; + +public enum PackDataType { + BINARY, + TEXT +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java new file mode 100644 index 0000000..efd4d27 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Packet.java @@ -0,0 +1,94 @@ +package com.taurus.permanent.data; + +import java.util.ArrayList; +import java.util.List; + +/** + * Packet data object + * + */ +public class Packet { + protected int id; + protected Object data; + protected Session sender; + protected List recipients; + protected byte[] fragmentBuffer; + protected PackDataType dataType = PackDataType.BINARY; + + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Object getData() { + return this.data; + } + + public void setData(Object data) { + this.data = data; + } + + public Session getSender() { + return this.sender; + } + + public void setSender(Session sender) { + this.sender = sender; + } + + public List getRecipients() { + return this.recipients; + } + + public void setRecipients(List recipients) { + this.recipients = recipients; + } + + public void setRecipient(Session session) { + List recipients = new ArrayList(); + recipients.add(session); + setRecipients(recipients); + } + + public boolean isFragmented() { + return this.fragmentBuffer != null; + } + + public byte[] getFragmentBuffer() { + return this.fragmentBuffer; + } + + public void setFragmentBuffer(byte[] bb) { + this.fragmentBuffer = bb; + } + + public PackDataType getDataType() { + return dataType; + } + + public void setDataType(PackDataType dataType) { + this.dataType = dataType; + } + + public String toString() { + return String.format("{ data: %s }", data.getClass().getName()); + } + + public Packet clone() { + Packet newPacket = new Packet(); + newPacket.id = this.id; + newPacket.data = data; + List recipients = new ArrayList(); + recipients.addAll(this.recipients); + newPacket.recipients = recipients; + newPacket.sender = this.sender; + newPacket.dataType = this.dataType; + newPacket.fragmentBuffer = this.fragmentBuffer; + return newPacket; + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java new file mode 100644 index 0000000..95ba371 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/Session.java @@ -0,0 +1,467 @@ +package com.taurus.permanent.data; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import com.taurus.permanent.core.SessionManager; + +/** + * 核心用户session对象 + * + */ +public final class Session { + public static final String DATA_BUFFER = "session_data_buffer"; + public static final String PACKET_READ_STATE = "read_state"; + private static final String NO_IP = "NO_IP"; + + + private static AtomicInteger idCounter = new AtomicInteger(0); + + private volatile long readBytes = 0L; + private volatile long writtenBytes = 0L; + private volatile int droppedMessages = 0; + private ISocketChannel connection; + private volatile long creationTime; + private volatile long lastReadTime; + private volatile long lastWriteTime; + private volatile long lastActivityTime; + private int id; + private volatile String hashId; + private SessionType type; + private volatile String clientIpAddress = NO_IP; + private volatile int clientPort; + private int serverPort; + private String serverAddress; + private int timeout; + private volatile boolean frozen = false; + private boolean markedForEviction = false; + private volatile boolean connected = false; + private IPacketQueue packetQueue; + private Map systemProperties; + + public Session() { + creationTime = lastReadTime = lastWriteTime = lastActivityTime = System.currentTimeMillis(); + + setId(getUniqueId()); + + systemProperties = new ConcurrentHashMap(); + } + + private static int getUniqueId() { + return idCounter.incrementAndGet(); + } + + /** + * 统计当前session接收字节流大小 + * @param amount + */ + public void addReadBytes(long amount) { + this.readBytes += amount; + } + + /** + * 统计当前session发送字节流大小 + * @param amount + */ + public void addWrittenBytes(long amount) { + this.writtenBytes += amount; + } + + /** + * 获取channe连接对象 + * @return + */ + public ISocketChannel getConnection() { + return this.connection; + } + + /** + * 获取session创建时间 + * @return + */ + public long getCreationTime() { + return this.creationTime; + } + + /** + * 获取hashid + * @return + */ + public String getHashId() { + return this.hashId; + } + + /** + * 获取session id + * @return + */ + public int getId() { + return this.id; + } + + /** + * 获取客户端详细地址 + * @return + */ + public String getFullIpAddress() { + return clientPort > 0 ? getAddress() + ":" + clientPort : getAddress(); + } + + /** + * 获取客户端地址 + * @return + */ + public String getAddress() { + return this.clientIpAddress; + } + + /** + * 获取客户端端口 + * @return + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * 获取服务器监听端口 + * @return + */ + public int getServerPort() { + return this.serverPort; + } + + /** + * 获取服务器详细地址 + * @return + */ + public String getFullServerIpAddress() { + return this.serverAddress + ":" + this.serverPort; + } + + /** + * 获取服务器地址 + * @return + */ + public String getServerAddress() { + return this.serverAddress; + } + + /** + * 获取最后激活时间 + * @return + */ + public long getLastActivityTime() { + return this.lastActivityTime; + } + + /** + * 获取最后读时间 + * @return + */ + public long getLastReadTime() { + return this.lastReadTime; + } + + /** + * 获取最后写时间 + * @return + */ + public long getLastWriteTime() { + return this.lastWriteTime; + } + + /** + * 获取超时时间 + * @return + */ + public int getTimeout() { + return this.timeout; + } + + /** + * 获取网络包队列 + * @return + */ + public IPacketQueue getPacketQueue() { + return this.packetQueue; + } + + /** + * 获取服务器内部属性 + * @param key + * @return + */ + public Object getSystemProperty(String key) { + return this.systemProperties.get(key); + } + + /** + * 获取属性 + * @param key + */ + public void removeSystemProperty(String key) { + this.systemProperties.remove(key); + } + + /** + * 获取session类型 + * @return + */ + public SessionType getType() { + return this.type; + } + + /** + * 获取当前session接收字节流大小 + * @return + */ + public long getReadBytes() { + return this.readBytes; + } + + /** + * 获取当前session发送字节流大小 + * @return + */ + public long getWrittenBytes() { + return this.writtenBytes; + } + + /** + * 当前连接状态 + * @return + */ + public boolean isConnected() { + return this.connected; + } + + /** + * 设置连接状态 + * @param value + */ + public void setConnected(boolean value) { + this.connected = value; + } + + + /** + * session 是否空闲,做超时踢出处理 + * @return + */ + public boolean isIdle() { + return isSocketIdle(); + } + + private boolean isSocketIdle() { + boolean isIdle = false; + + if (this.timeout > 0) { + long elapsedSinceLastActivity = System.currentTimeMillis() - this.lastActivityTime; + isIdle = elapsedSinceLastActivity / 1000L > this.timeout; + } + + return isIdle; + } + + public boolean isMarkedForEviction() { + return this.markedForEviction; + } + + /** + * 设置channel连接对象 + * @param connection + */ + public void setConnection(ISocketChannel connection) { + if (connection == null) { + return; + } + + if (this.connection != null) { + throw new IllegalArgumentException("You cannot overwrite the connection linked to a Session!"); + } + if(connection.checkConnection()) { + setSocketConnection(connection); + this.connected = true; + } + } + + private void setSocketConnection(ISocketChannel connection) { + this.connection = connection; + String svr_host = connection.getLocalAddress().toString().substring(1); + String[] svr_adr =svr_host.split("\\:"); + this.serverAddress = svr_adr[0]; + try { + this.serverPort = Integer.parseInt(svr_adr[1]); + } catch (NumberFormatException localNumberFormatException) { + } + + + String client_host = connection.getRemoteAddress().toString().substring(1); + String[] client_adr = client_host.split("\\:"); + this.clientIpAddress = client_adr[0]; + try { + this.clientPort = Integer.parseInt(client_adr[1]); + } catch (NumberFormatException localNumberFormatException) { + } + + } + + /** + * 设置网络包队列 + * @param queue + */ + public void setPacketQueue(IPacketQueue queue) { + if (this.packetQueue != null) { + throw new IllegalStateException("Cannot reassing the packet queue. Queue already exists!"); + } + this.packetQueue = queue; + } + + /** + * 设置创建时间 + * @param timestamp + */ + public void setCreationTime(long timestamp) { + this.creationTime = timestamp; + } + + /** + * 设置hashID + * @param hash + */ + public void setHashId(String hash) { + this.hashId = hash; + } + + /** + * 设置session id + * @param id + */ + public void setId(int id) { + this.id = id; + } + + /** + * 设置最后读取网络字节时间 + * @param timestamp + */ + public void setLastReadTime(long timestamp) { + this.lastReadTime = timestamp; + if(this.hashId!=null) { + this.lastActivityTime = timestamp; + } + } + + /** + * 设置最后写网络字节时间 + * @param timestamp + */ + public void setLastWriteTime(long timestamp) { + this.lastWriteTime = timestamp; + if(this.hashId!=null) { + this.lastActivityTime = timestamp; + } + } + + public void updateLastActivityTime() { + this.lastActivityTime = System.currentTimeMillis(); + } + + /** + * session 标记为驱逐 + */ + public void setMarkedForEviction() { + this.markedForEviction = true; + this.frozen = true; + } + + /** + * 设置超时时间 + * @param idleTime + */ + public void setTimeout(int idleTime) { + this.timeout = idleTime; + } + + /** + * 设置服务器内部属性 + * @param key + * @param property + */ + public void setSystemProperty(String key, Object property) { + this.systemProperties.put(key, property); + } + + /** + * 设置session 类型 + * @param type + */ + public void setType(SessionType type) { + this.type = type; + + if (type == SessionType.VOID) { + this.clientIpAddress = NO_IP; + this.clientPort = 0; + } + } + + /** + * 获取丢包数量 + * @return + */ + public int getDroppedMessages() { + return this.droppedMessages; + } + + /** + * 统计丢包数量 + */ + public void addDroppedMessages(int amount) { + this.droppedMessages += amount; + } + + /** + * session 是否被冻结 + * @return + */ + public boolean isFrozen() { + return this.frozen; + } + + /** + * 关闭session + * @throws IOException + */ + public void close() throws IOException { + this.packetQueue = null; + this.frozen = true; + try { + if(connection!=null) { + connection.close(); + } + } finally { + connected = false; + SessionManager.getInstance().removeSession(this); + } + } + + public String toString() { + return String.format("{ Id: %s, Type: %s, IP: %s }", id + (hashId!=null ? ("[" + this.hashId + "]") : ""), type, getFullIpAddress()); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Session)) { + return false; + } + boolean isEqual = false; + Session session = (Session) obj; + + if (session.getId() == this.id) { + isEqual = true; + } + return isEqual; + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java new file mode 100644 index 0000000..3e0b480 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/data/SessionType.java @@ -0,0 +1,17 @@ +package com.taurus.permanent.data; + +/** + * session 类型 + * + */ +public enum SessionType{ + /** + * 普通 tcp udp 长链接 + */ + NORMAL, + /** + * websocket 长链接 + */ + WEBSOCKET, + VOID +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java new file mode 100644 index 0000000..9309052 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/BinaryIoHandler.java @@ -0,0 +1,242 @@ +package com.taurus.permanent.io; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 协议包字节流解析 + * + */ +public class BinaryIoHandler { + + private static final int INT_SIZE = 4; + private final Logger log; + private final BitSwarmEngine engine; + private volatile long packetsRead = 0L; + private volatile long droppedIncomingPackets = 0L; + private final int maxPacketSize; + + public BinaryIoHandler(IOHandler parentHandler) { + this.log = Logger.getLogger(getClass()); + this.engine = BitSwarmEngine.getInstance(); + this.maxPacketSize = engine.getConfig().maxPacketSize; + } + + public long getReadPackets() { + return this.packetsRead; + } + + public long getIncomingDroppedPackets() { + return this.droppedIncomingPackets; + } + + public void handleWrite(Packet packet) throws Exception { + engine.getProtocolHandler().onPacketWrite(packet); + int protocolCompressionThreshold = TPServer.me().getConfig().protocolCompression; + byte[] binData = null; + try { + binData = ((TObject)packet.getData()).toBinary(); + } catch (Exception e) { + log.error(e); + log.error(((TObject)packet.getData()).toString()); + log.error(((TObject)packet.getData()).toJson()); + return; + } + boolean compression = binData.length > protocolCompressionThreshold; + if(compression) { + binData = Utils.compress(binData); + } + ByteBuffer packetBuffer = ByteBuffer.allocate(INT_SIZE + 1 + binData.length); + packetBuffer.put(compression?(byte)1:(byte)0); + packetBuffer.putInt(binData.length); + packetBuffer.put(binData); + packet.setData(packetBuffer.array()); + engine.getSocketWriter().enqueuePacket(packet); + } + + public void handleRead(Session session, byte[] data) { + + PacketReadState readState = (PacketReadState) session.getSystemProperty(Session.PACKET_READ_STATE); + try { + while (data.length > 0) { + if (readState == PacketReadState.WAIT_NEW_PACKET) { + ProcessedPacket process = handleNewPacket(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState == PacketReadState.WAIT_DATA_SIZE) { + ProcessedPacket process = handleDataSize(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState == PacketReadState.WAIT_DATA_SIZE_FRAGMENT) { + ProcessedPacket process = handleDataSizeFragment(session, data); + readState = process.getState(); + data = process.getData(); + } + + if (readState != PacketReadState.WAIT_DATA) + continue; + ProcessedPacket process = handlePacketData(session, data); + readState = process.getState(); + data = process.getData(); + } + + } catch (Exception err) { + this.log.error(err); + readState = PacketReadState.WAIT_NEW_PACKET; + } + + session.setSystemProperty(Session.PACKET_READ_STATE, readState); + } + + private ProcessedPacket handleNewPacket(Session session, byte[] data) { + PendingPacket pp = new PendingPacket(); + pp.compressed = data[0] > 0; + session.setSystemProperty(Session.DATA_BUFFER, pp); + data = Utils.resizeByteArray(data, 1, data.length - 1); + return new ProcessedPacket(PacketReadState.WAIT_DATA_SIZE, data); + } + + private ProcessedPacket handleDataSize(Session session, byte[] data) { + PacketReadState state = PacketReadState.WAIT_DATA; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + int dataSize = -1; + int sizeBytes = INT_SIZE; + + if (data.length >= INT_SIZE) { + dataSize = 0; + for (int i = 0; i < INT_SIZE; i++) { + int pow256 = (int) Math.pow(256.0D, 3 - i); + int intByte = data[i] & 0xFF; + dataSize += pow256 * intByte; + } + } + + if (dataSize != -1) { + validateIncomingDataSize(session, dataSize); + pending.setExpectedLen(dataSize); + pending.setBuffer(ByteBuffer.allocate(dataSize)); + data = Utils.resizeByteArray(data, sizeBytes, data.length - sizeBytes); + } else { + state = PacketReadState.WAIT_DATA_SIZE_FRAGMENT; + ByteBuffer sizeBuffer = ByteBuffer.allocate(INT_SIZE); + sizeBuffer.put(data); + pending.setBuffer(sizeBuffer); + data = new byte[0]; + } + return new ProcessedPacket(state, data); + } + + private ProcessedPacket handleDataSizeFragment(Session session, byte[] data) { + PacketReadState state = PacketReadState.WAIT_DATA_SIZE_FRAGMENT; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + ByteBuffer sizeBuffer = (ByteBuffer) pending.getBuffer(); + + int remaining = INT_SIZE - sizeBuffer.position(); + + if (data.length >= remaining) { + sizeBuffer.put(data, 0, remaining); + sizeBuffer.flip(); + int dataSize = sizeBuffer.getInt(); + + validateIncomingDataSize(session, dataSize); + pending.setExpectedLen(dataSize); + pending.setBuffer(ByteBuffer.allocate(dataSize)); + state = PacketReadState.WAIT_DATA; + + if (data.length > remaining) + data = Utils.resizeByteArray(data, remaining, data.length - remaining); + else { + data = new byte[0]; + } + + } else { + sizeBuffer.put(data); + data = new byte[0]; + } + + return new ProcessedPacket(state, data); + } + + private ProcessedPacket handlePacketData(Session session, byte[] data) throws Exception { + PacketReadState state = PacketReadState.WAIT_DATA; + PendingPacket pending = (PendingPacket) session.getSystemProperty(Session.DATA_BUFFER); + ByteBuffer dataBuffer = (ByteBuffer) pending.getBuffer(); + int readLen = dataBuffer.remaining(); + boolean isThereMore = data.length > readLen; + + if (data.length >= readLen) { + dataBuffer.put(data, 0, readLen); + + if (pending.getExpectedLen() != dataBuffer.capacity()) { + throw new IllegalStateException("Expected: " + pending.getExpectedLen() + ", Buffer size: " + dataBuffer.capacity()); + } + final byte[] tembytes = dataBuffer.array(); + final boolean compressed = pending.compressed; + dispatchRequest(session,tembytes,compressed); + this.packetsRead += 1L; + state = PacketReadState.WAIT_NEW_PACKET; + + } else { + dataBuffer.put(data); + } + + if (isThereMore) + data = Utils.resizeByteArray(data, readLen, data.length - readLen); + else { + data = new byte[0]; + } + return new ProcessedPacket(state, data); + } + + + private void dispatchRequest(Session session, byte[] data,boolean compressed) { + if(compressed) { + try { + data = Utils.uncompress(data); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + ITObject requestObject = TObject.newFromBinaryData(data); + Packet newPacket = new Packet(); + newPacket.setSender(session); + newPacket.setData(requestObject); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + /** + * 验证字节流数据大小 + * @param session + * @param dataSize + */ + private void validateIncomingDataSize(Session session, int dataSize) { + String who = session.toString(); + + if (dataSize < 1) { + this.droppedIncomingPackets += 1L; + throw new IllegalArgumentException("Illegal request size: " + dataSize + " bytes, from: " + who); + } + + if (dataSize > this.maxPacketSize) { + TPServer.me().getController().disconnect(session); + this.droppedIncomingPackets += 1L; + + throw new IllegalArgumentException(String.format("Incoming request size too large: %s, Current limit: %s, From: %s", dataSize, this.maxPacketSize, who)); + } + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java new file mode 100644 index 0000000..6ad430c --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/IOHandler.java @@ -0,0 +1,73 @@ +package com.taurus.permanent.io; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; + +/** + * 读写网络字节流 + * + */ +public class IOHandler { + private final BinaryIoHandler binHandler; + private final Logger logger; + + public IOHandler() { + logger = Logger.getLogger(getClass()); + binHandler = new BinaryIoHandler(this); + + } + + /** + * 读取网络包字节流 + * @param session + * @param data + */ + public void onDataRead(Session session, byte[] data) { + if ((data == null) || (data.length < 1)) { + throw new IllegalArgumentException("Unexpected null or empty byte array!"); + } + + PacketReadState readState = (PacketReadState) session.getSystemProperty(Session.PACKET_READ_STATE); + if(readState==null){ + if (data[0] == 60) { + return; + } + session.setSystemProperty(Session.PACKET_READ_STATE, PacketReadState.WAIT_NEW_PACKET); + } + + binHandler.handleRead(session, data); + } + + /** + * 数据写入网络字节流,发送给指定客户端 + * @param packet + */ + public void onDataWrite(Packet packet) { + if (packet.getRecipients().size() > 0) { + try { + this.binHandler.handleWrite(packet); + } catch (Exception e) { + logger.error(e); + } + } + } + + /** + * 统计丢包数量 + * @return + */ + public long getReadPackets() { + return binHandler.getReadPackets(); + } + + /** + * 统计丢包数量 + * @return + */ + public long getIncomingDroppedPackets() { + return binHandler.getIncomingDroppedPackets(); + } + + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java new file mode 100644 index 0000000..6bcdbad --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PacketReadState.java @@ -0,0 +1,21 @@ +package com.taurus.permanent.io; + +/** + * PacketReadState + * + */ +public enum PacketReadState { + /** + * 等待新包读取 + */ + WAIT_NEW_PACKET, + /** + * 等待读取包大小 + */ + WAIT_DATA_SIZE, + /** + * 等待读取碎片包 + */ + WAIT_DATA_SIZE_FRAGMENT, + WAIT_DATA; +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java new file mode 100644 index 0000000..6b6a059 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/PendingPacket.java @@ -0,0 +1,37 @@ +package com.taurus.permanent.io; + +/** + * PendingPacket + * + */ +public class PendingPacket { + private Object buffer; + private int expectedLen = -1; + public boolean compressed; + + public PendingPacket() { + + } + + + + public Object getBuffer() { + return buffer; + } + + public void setBuffer(Object buffer) { + this.buffer = buffer; + } + + public int getExpectedLen() { + return this.expectedLen; + } + + public void setExpectedLen(int len) { + this.expectedLen = len; + } + + public String toString() { + return buffer.toString(); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java new file mode 100644 index 0000000..741e0e3 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProcessedPacket.java @@ -0,0 +1,23 @@ +package com.taurus.permanent.io; + +/** + * ProcessedPacket + * + */ +public class ProcessedPacket { + private byte[] data; + private PacketReadState state; + + public ProcessedPacket(PacketReadState state, byte[] data) { + this.state = state; + this.data = data; + } + + public byte[] getData() { + return data; + } + + public PacketReadState getState() { + return state; + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java new file mode 100644 index 0000000..2a3e4f9 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/io/ProtocolHandler.java @@ -0,0 +1,42 @@ +package com.taurus.permanent.io; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Packet; + +/** + * ProtocolHandler + * + * + */ +public class ProtocolHandler { + private static final String ACTION_ID = "a"; + private static final String PARAM_ID = "p"; + + public void onPacketWrite(Packet packet) { + ITObject params = TObject.newInstance(); + params.putByte(ACTION_ID, (byte) packet.getId()); + params.putTObject(PARAM_ID, (ITObject) packet.getData()); + packet.setData(params); + } + + public void onPacketRead(Packet packet) { + ITObject requestObject = (ITObject)packet.getData(); + if (requestObject.isNull(ACTION_ID)) { + throw new IllegalStateException("Request rejected: No Action ID in request!"); + } + if (requestObject.isNull(PARAM_ID)) { + throw new IllegalStateException("Request rejected: Missing parameters field!"); + } + + packet.setId(requestObject.getByte(ACTION_ID)); + if(requestObject.containsKey(PARAM_ID)) { + packet.setData(requestObject.getTObject(PARAM_ID)); + }else { + packet.setData(null); + } + + TPServer.me().getController().enqueueRequest(packet); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java new file mode 100644 index 0000000..1d3d67f --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/NormalSocketChannel.java @@ -0,0 +1,71 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; + +import com.taurus.permanent.data.ISocketChannel; + +public class NormalSocketChannel implements ISocketChannel{ + private final SocketChannel channel; + + public NormalSocketChannel(SocketChannel channel) { + this.channel = channel; + } + @Override + public long write(ByteBuffer buffer) { + try { + return channel.write(buffer); + } catch (IOException e) { + return 0; + } + } + + @Override + public void write(String p0) { + // TODO Auto-generated method stub + + } + + @Override + public SocketAddress getRemoteAddress() { + if(checkConnection()) { + return channel.socket().getRemoteSocketAddress(); + } + return null; + } + + @Override + public SocketAddress getLocalAddress() { + if(checkConnection()) { + return channel.socket().getLocalSocketAddress(); + } + return null; + } + + @Override + public void close() throws IOException{ + Socket socket = channel.socket(); + if ((socket != null) && (!socket.isClosed())) { + socket.shutdownInput(); + socket.shutdownOutput(); + socket.close(); + channel.close(); + } + } + @Override + public Object getChannel() { + return channel; + } + + @Override + public boolean checkConnection() { + if((channel != null) && (channel.socket() != null) && (!channel.socket().isClosed())) { + return true; + } + return false; + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java new file mode 100644 index 0000000..e7ecc9d --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketAcceptor.java @@ -0,0 +1,259 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.ConnectionFilter; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig.SocketAddress; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.BindableSocket; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +/** + * SocketAcceptor + * + * + */ +public class SocketAcceptor extends BaseCoreService implements Runnable { + private final BitSwarmEngine engine; + private final Logger logger; + private volatile int threadId = 1; + private int threadPoolSize = 1; + private final ExecutorService threadPool; + private LinkedList acceptableConnections; + private List boundSockets; + + private SessionManager sessionManager; + private SocketReader socketReader; + private Selector acceptSelector; + private volatile boolean isActive = false; + + public SocketAcceptor(int threadPoolSize) { + this.threadPoolSize = threadPoolSize; + + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(SocketAcceptor.class); + + threadPool = Executors.newFixedThreadPool(threadPoolSize); + + acceptableConnections = new LinkedList(); + boundSockets = new ArrayList(); + socketReader = engine.getSocketReader(); + + try { + acceptSelector = Selector.open(); + logger.info("AcceptSelector opened"); + } catch (IOException e) { + logger.warn("Problems during SocketAcceptor init: " + e); + logger.error(e); + } + } + + public void init(Object o) { + super.init(o); + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + if (threadPoolSize < 1) { + throw new IllegalArgumentException("Illegal value for a thread pool size: " + threadPoolSize); + } + sessionManager = engine.getSessionManager(); + + isActive = true; + initThreadPool(); + + logger.info("SocketAcceptor initialized (pool size:"+threadPoolSize+")"); + checkBoundSockets(); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + shutDownBoundSockets(); + + List leftOvers = threadPool.shutdownNow(); + try { + Thread.sleep(500L); + + acceptSelector.close(); + } catch (Exception e) { + logger.warn("Error when shutting down Accept selector: " + e.getMessage()); + } + + logger.info("SocketAcceptor stopped. Unprocessed tasks: " + leftOvers.size()); + } + + private void initThreadPool() { + for (int j = 0; j < threadPoolSize; j++) + threadPool.execute(this); + } + + public void run() { + Thread.currentThread().setName("SocketAcceptor-" + threadId++); + + while (isActive) { + try { + acceptLoop(); + } catch (IOException e) { + logger.info("I/O Error with Accept Selector: " + e.getMessage()); + logger.error(e); + } + } + + logger.info("SocketAcceptor threadpool shutting down."); + } + + private void acceptLoop() throws IOException { + acceptSelector.select(); + List _list = null; + synchronized (acceptSelector) { + Set readyKeys = acceptSelector.selectedKeys(); + _list = new ArrayList(readyKeys); + readyKeys.clear(); + } + + for (SelectionKey key : _list) { + try { + ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel(); + SocketChannel clientChannel = ssChannel.accept(); + synchronized (acceptableConnections) { + acceptableConnections.addLast(clientChannel); + } + } catch (IOException error) { + logger.info("I/O Error during accept loop: " + error.getMessage()); + } + } + + if (isActive) + socketReader.getSelector().wakeup(); + } + + public void handleAcceptableConnections() { + if (acceptableConnections.size() == 0) { + return; + } + SocketChannel connection = null; + synchronized (acceptableConnections) { + connection = acceptableConnections.removeFirst(); + } + if (connection == null) + return; + ConnectionFilter connectionFilter = engine.getConnectionFilter(); + + try { + Socket socket = connection.socket(); + InetAddress iAddr = null; + if (socket != null && !socket.isClosed()) { + iAddr = socket.getInetAddress(); + } + if (iAddr == null) { + handleAcceptableConnections(); + return; + } + if (!connectionFilter.validateAndAddAddress(iAddr.getHostAddress())) { + try { + connection.socket().shutdownInput(); + connection.socket().shutdownOutput(); + connection.close(); + } catch (IOException e1) { + logger.warn("Additional problem with refused connection. Was not able to shut down the channel: " + e1.getMessage()); + } + handleAcceptableConnections(); + return; + } + connection.configureBlocking(false); + connection.socket().setTcpNoDelay(engine.getConfig().tcpNoDelay); + + SelectionKey selectionKey = connection.register(socketReader.getSelector(), SelectionKey.OP_READ); + Session session = sessionManager.createSession(new NormalSocketChannel(connection), SessionType.NORMAL); + session.setSystemProperty(DefaultConstants.SESSION_SELECTION_KEY, selectionKey); + sessionManager.addSession(session); + } catch (IOException e) { + StringBuilder sb = new StringBuilder("Failed accepting connection: "); + + if ((connection != null) && (connection.socket() != null)) { + sb.append(connection.socket().getInetAddress().getHostAddress()); + } + logger.info(sb.toString()); + } + handleAcceptableConnections(); + } + + public void bindSocket(SocketAddress socketConfig) throws IOException { + if (socketConfig.type.equalsIgnoreCase(SocketAddress.TYPE_TCP)) { + bindTcpSocket(socketConfig.address, socketConfig.port); + } else + throw new UnsupportedOperationException("Invalid transport type!"); + } + + public List getBoundSockets() { + ArrayList list = null; + + synchronized (boundSockets) { + list = new ArrayList(boundSockets); + } + + return list; + } + + private void bindTcpSocket(String address, int port) throws IOException { + ServerSocketChannel socketChannel = ServerSocketChannel.open(); + socketChannel.configureBlocking(false); + socketChannel.socket().bind(new InetSocketAddress(address, port)); + socketChannel.socket().setReuseAddress(true); + socketChannel.register(acceptSelector, SelectionKey.OP_ACCEPT); + + synchronized (boundSockets) { + boundSockets.add(new BindableSocket(socketChannel, address, port)); + } + + logger.info("Added bound tcp socket --> " + address + ":" + port); + } + + private void checkBoundSockets() { + if (boundSockets.size() < 1) + logger.error("No bound sockets! Check the boot logs for possible problems!"); + } + + private void shutDownBoundSockets() { + List problematicSockets = null; + + for (BindableSocket bindableSocket : boundSockets) { + try { + bindableSocket.getChannel().close(); + } catch (IOException e) { + if (problematicSockets == null) { + problematicSockets = new ArrayList(); + } + problematicSockets.add(bindableSocket); + } + } + + if (problematicSockets != null) { + StringBuilder sb = new StringBuilder("Problems closing bound socket(s). The following socket(s) raised exceptions: "); + + for (BindableSocket socket : problematicSockets) { + sb.append(socket.toString()).append(" "); + } + throw new RuntimeException(sb.toString()); + } + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java new file mode 100644 index 0000000..d4d3a16 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketReader.java @@ -0,0 +1,233 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.taurus.core.util.FixedIndexThreadPool; +import com.taurus.core.util.FixedIndexThreadPool.Work; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.io.IOHandler; + +/** + * SocketReader + * + * + */ +public class SocketReader extends BaseCoreService implements Runnable { + private final BitSwarmEngine engine; + private final Logger logger; + private int threadPoolSize = 1; + private ExecutorService threadPool; + private FixedIndexThreadPool packetReaderPool; + private SessionManager sessionManager; + private SocketAcceptor socketAcceptor; + private SocketWriter socketWriter; + private Selector readSelector; + private IOHandler ioHandler; + private volatile boolean isActive = false; + private volatile long readBytes = 0L; + + public SocketReader(int nThreads) { + threadPoolSize = nThreads; + + engine = BitSwarmEngine.getInstance(); + logger = Logger.getLogger(getClass()); + try { + readSelector = Selector.open(); + logger.info("TCP Selector opened"); + } catch (IOException e) { + logger.error("Failed opening UDP Selector: " + e.toString()); + e.printStackTrace(); + } + } + + public void init(Object o) { + super.init(o); + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + sessionManager = engine.getSessionManager(); + socketAcceptor = engine.getSocketAcceptor(); + socketWriter = engine.getSocketWriter(); + isActive = true; + initThreadPool(); + + logger.info("SocketReader started (pool size:"+threadPoolSize+")"); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + List leftOvers = threadPool.shutdownNow(); + int pr_count = packetReaderPool.shutdown(); + try { + Thread.sleep(500L); + readSelector.close(); + } catch (Exception e) { + logger.warn("Error when shutting down TCP Selector: " + e.getMessage()); + logger.error(e); + } + + logger.info("SocketReader stopped. Unprocessed tasks: " + leftOvers.size()); + logger.info("PacketReader stopped. Unprocessed tasks: " + pr_count); + } + + public void initThreadPool() { + threadPool = Executors.newSingleThreadExecutor(); + threadPool.execute(this); + packetReaderPool = new FixedIndexThreadPool(threadPoolSize, "PacketReader", PacketReaderWork.class); + } + + public void run() { + Thread.currentThread().setName("SocketReader"); + + while (isActive) { + try { + socketAcceptor.handleAcceptableConnections(); + readIncomingSocketData(); + + Thread.sleep(5L); + } catch (Throwable t) { + logger.warn("Problems in SocketReader main loop: " + t + ", Thread: " + Thread.currentThread()); + logger.error(t); + } + } + + logger.info("SocketReader threadpool shutting down."); + } + + private void readIncomingSocketData() { + SocketChannel channel = null; + SelectionKey key = null; + try { + int readyKeyCount = readSelector.selectNow(); + + if (readyKeyCount > 0) { + Set readyKeys = readSelector.selectedKeys(); + + for (Iterator it = readyKeys.iterator(); it.hasNext();) { + key = (SelectionKey) it.next(); + it.remove(); + + if (!key.isValid()) { + continue; + } + channel = (SocketChannel) key.channel(); + Session session = sessionManager.getSessionByConnection(channel); + packetReaderPool.execute(session.getId(), session); + } + } + + } catch (ClosedSelectorException e) { + logger.debug("Selector is closed!"); + } catch (CancelledKeyException localCancelledKeyException) { + } catch (IOException ioe) { + logger.warn("I/O reading/selection error: " + ioe); + logger.error(ioe); + } catch (Exception err) { + logger.warn("Generic reading/selection error: " + err); + logger.error(err); + } + } + + private void readTcpData(Session session,SocketChannel channel, ByteBuffer readBuffer) throws IOException { + SelectionKey key = (SelectionKey) session.getSystemProperty(DefaultConstants.SESSION_SELECTION_KEY); + if (!key.isValid()) { + return; + } + if (key.isWritable()) { + key.interestOps(SelectionKey.OP_READ); + socketWriter.continueWriteOp(session); + } + if (!key.isReadable()) { + return; + } + readBuffer.clear(); + long byteCount = channel.read(readBuffer); + + if (byteCount == -1L) { + closeConnection(channel); + } else if (byteCount > 0L) { + session.setLastReadTime(System.currentTimeMillis()); + readBytes += byteCount; + session.addReadBytes(byteCount); + readBuffer.flip(); + byte[] binaryData = new byte[readBuffer.limit()]; + readBuffer.get(binaryData); + ioHandler.onDataRead(session, binaryData); + } + } + + private void closeConnection(SelectableChannel channel) throws IOException { + channel.close(); + if (channel instanceof SocketChannel) + sessionManager.onSocketDisconnected(channel); + } + + public IOHandler getIOHandler() { + return ioHandler; + } + + public Selector getSelector() { + return readSelector; + } + + public void setIoHandler(IOHandler handler) { + if (handler == null) { + throw new IllegalStateException("IOHandler si already set!"); + } + ioHandler = handler; + } + + public long getReadBytes() { + return readBytes; + } + + public long getReadPackets() { + return ioHandler.getReadPackets(); + } + + public static final class PacketReaderWork extends Work { + private ByteBuffer readBuffer; + private BitSwarmEngine engine; + private SocketReader reader; + + public PacketReaderWork() { + engine = BitSwarmEngine.getInstance(); + reader = (SocketReader) engine.getSocketReader(); + readBuffer = Utils.allocateBuffer(engine.getConfig().maxReadBufferSize, engine.getConfig().readBufferType); + } + + @Override + protected void handlerTask(Object task) throws Exception { + Session session = (Session) task; + SocketChannel channel = (SocketChannel) session.getConnection().getChannel(); + ByteBuffer buffer = ByteBuffer.allocate(1024); + buffer = (ByteBuffer) buffer.clear(); // 显式转换 + + try { + reader.readTcpData(session,channel, readBuffer); + } catch (IOException e) { + reader.closeConnection(channel); + } + } + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java new file mode 100644 index 0000000..c256e63 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/normal/SocketWriter.java @@ -0,0 +1,278 @@ +package com.taurus.permanent.normal; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SelectionKey; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.DefaultConstants; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.data.IPacketQueue; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; +import com.taurus.permanent.io.IOHandler; + +/** + * SocketWriter + * + * + */ +public final class SocketWriter extends BaseCoreService implements Runnable { + private BitSwarmEngine engine; + private IOHandler ioHandler; + private final Logger logger; + private final ExecutorService threadPool; + private final BlockingQueue sessionTicketsQueue; + private volatile int threadId = 1; + private volatile boolean isActive = false; + private volatile long droppedPacketsCount = 0L; + private volatile long writtenBytes = 0L; + private volatile long writtenPackets = 0L; + private int threadPoolSize; + + public SocketWriter(int threadPoolSize) { + this.threadPoolSize = threadPoolSize; + + threadPool = Executors.newFixedThreadPool(threadPoolSize); + logger = Logger.getLogger(SocketWriter.class); + + sessionTicketsQueue = new LinkedBlockingQueue(); + } + + public void init(Object o) { + super.init(o); + + if (isActive) { + throw new IllegalArgumentException("Object is already initialized. Destroy it first!"); + } + if (threadPoolSize < 1) { + throw new IllegalArgumentException("Illegal value for a thread pool size: " + threadPoolSize); + } + engine = BitSwarmEngine.getInstance(); + isActive = true; + + initThreadPool(); + + logger.info("Socket Writer started (pool size:" + threadPoolSize + ")"); + } + + public void destroy(Object o) { + super.destroy(o); + + isActive = false; + List leftOvers = threadPool.shutdownNow(); + logger.info("SocketWriter stopped. Unprocessed tasks: " + leftOvers.size()); + } + + public int getQueueSize() { + return sessionTicketsQueue.size(); + } + + public int getThreadPoolSize() { + return threadPoolSize; + } + + public IOHandler getIOHandler() { + return ioHandler; + } + + public void setIOHandler(IOHandler ioHandler) { + if (this.ioHandler != null) { + throw new IllegalStateException("You cannot reassign the IOHandler class!"); + } + this.ioHandler = ioHandler; + } + + public void continueWriteOp(Session session) { + if (session != null) + sessionTicketsQueue.add(session); + } + + private void initThreadPool() { + for (int j = 0; j < threadPoolSize; j++) + threadPool.execute(this); + } + + public void run() { + Thread.currentThread().setName("SocketWriter-" + threadId++); + + ServerConfig setting = TPServer.me().getConfig(); + ByteBuffer writeBuffer = Utils.allocateBuffer(setting.maxWriteBufferSize, setting.writeBufferType); + + while (isActive) { + try { + Session session = sessionTicketsQueue.take(); + processSessionQueue(writeBuffer, session); + } catch (InterruptedException e) { + logger.warn("SocketWriter thread interrupted: " + Thread.currentThread()); + isActive = false; + } catch (Throwable t) { + logger.warn("Problems in SocketWriter main loop, Thread: " + Thread.currentThread()); + logger.error(t); + } + } + + logger.info("SocketWriter threadpool shutting down."); + } + + private void processSessionQueue(ByteBuffer writeBuffer, Session session) { + if (session != null) { + SessionType type = session.getType(); + + if (type == SessionType.NORMAL) { + processRegularSession(writeBuffer, session); + }else if (type == SessionType.VOID) + return; + } + } + + private void processRegularSession(ByteBuffer writeBuffer, Session session) { + if (session.isFrozen()) { + return; + } + Packet packet = null; + try { + IPacketQueue sessionQ = session.getPacketQueue(); + + synchronized (sessionQ) { + if (!sessionQ.isEmpty()) { + packet = sessionQ.peek(); + + if (packet == null) { + return; + } + tcpSend(writeBuffer, sessionQ, session, packet); + } + } + + } catch (ClosedChannelException cce) { + logger.debug("Socket closed during write operation for session: " + session); + } catch (IOException localIOException) {} catch (Exception e) { + logger.warn("Error during write. Session: " + session); + logger.error(e); + } + } + + private void tcpSend(ByteBuffer writeBuffer, IPacketQueue sessionQ, Session session, Packet packet) throws Exception { + ISocketChannel channel = session.getConnection(); + if (channel == null) { + logger.debug("Skipping packet, found null socket for Session: " + session); + return; + } +// buffer = (ByteBuffer) buffer.clear(); // 强制转换 + + writeBuffer=(ByteBuffer)writeBuffer.clear(); + + byte[] buffer = packet.isFragmented() ? packet.getFragmentBuffer() : (byte[]) packet.getData(); + if (writeBuffer.capacity() < buffer.length) { + writeBuffer = Utils.allocateBuffer(buffer.length, engine.getConfig().writeBufferType); + } + writeBuffer.put(buffer); + writeBuffer.flip(); + + long toWrite = writeBuffer.remaining(); + + long bytesWritten = channel.write(writeBuffer); + if(bytesWritten == 0)throw new IOException("Written Bytes excetion!"); + + writtenBytes += bytesWritten; + session.addWrittenBytes(bytesWritten); + if (bytesWritten < toWrite) { + byte[] bb = new byte[writeBuffer.remaining()]; + writeBuffer.get(bb); + packet.setFragmentBuffer(bb); + + SelectionKey sk = (SelectionKey) session.getSystemProperty(DefaultConstants.SESSION_SELECTION_KEY); + if ((sk != null) && (sk.isValid())) { + sk.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); + } else { + logger.warn("Could not OP_WRITE for Session: " + session + ", written bytes: " + bytesWritten); + } + } else { + writtenPackets += 1L; + + sessionQ.take(); + if (!sessionQ.isEmpty()) { + sessionTicketsQueue.add(session); + } + } + } + + public void enqueuePacket(Packet packet) { + enqueueLocal(packet); + } + + private void enqueueLocal(Packet packet) { + Collection recipients = packet.getRecipients(); + int size = recipients.size(); + + if ((recipients != null) && (size > 0)) { + if (packet.getSender() != null) { + packet.getSender().setLastWriteTime(System.currentTimeMillis()); + } + if (size == 1) { + enqueueLocalPacket((Session) packet.getRecipients().iterator().next(), packet); + } else + for (Session session : recipients) { + enqueueLocalPacket(session, packet.clone()); + } + } + } + + private void enqueueLocalPacket(Session session, Packet packet) { + IPacketQueue sessionQ = session.getPacketQueue(); + + if (sessionQ != null) { + synchronized (sessionQ) { + try { + boolean wasEmpty = sessionQ.isEmpty(); + + sessionQ.put(packet); + + if ((wasEmpty)) { + sessionTicketsQueue.add(session); + } + + packet.setRecipients(null); + } catch (Exception error) { + dropOneMessage(session); + } + } + } + } + + /** + * 丢包处理 + * @param session + */ + private void dropOneMessage(Session session) { + session.addDroppedMessages(1); + droppedPacketsCount += 1L; + } + + public long getDroppedPacketsCount() { + return droppedPacketsCount; + } + + + public long getWrittenBytes() { + return writtenBytes; + } + + public long getWrittenPackets() { + return writtenPackets; + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java new file mode 100644 index 0000000..07cdf74 --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/util/GhostUserHunter.java @@ -0,0 +1,82 @@ +package com.taurus.permanent.util; + +import com.taurus.core.util.Logger; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.core.SystemController; +import com.taurus.permanent.data.Session; + +import java.util.ArrayList; +import java.util.List; + +/** + * GhostUserHunter + * + * + * + */ +public class GhostUserHunter { + private static final String EOL = System.getProperty("line.separator"); + private final TPServer taurus; + private SessionManager sm; + private SystemController controller; + private final Logger log; + private static final int TOT_CYCLES = 2; + private int cycleCounter = 0; + + public GhostUserHunter() { + taurus = TPServer.me(); + this.controller = TPServer.me().getController(); + log = Logger.getLogger(getClass()); + } + + public void hunt() { + if (sm == null) { + sm = taurus.getSessionManager(); + } + + if (++cycleCounter < TOT_CYCLES) { + return; + } + cycleCounter = 0; + + List ghosts = searchGhosts(); + if (ghosts.size() > 0) { + log.info(buildReport(ghosts)); + } + + for (Session ghost : ghosts) + controller.disconnect(ghost); + } + + private List searchGhosts() { + List allUsers = taurus.getSessionManager().getAllSessions(); + List ghosts = new ArrayList(); + + for (Session u : allUsers) { + Session sess = u; + + if ((!sm.containsSession(sess)) || (sess.isIdle()) || (sess.isMarkedForEviction())) { + ghosts.add(u); + } + } + return ghosts; + } + + private String buildReport(List ghosts) { + StringBuilder sb = new StringBuilder("GHOST REPORT"); + sb.append(EOL).append("Total ghosts: ").append(ghosts.size()).append(EOL); + + for (Session ghost : ghosts) { + Session ss = ghost; + + if (ss == null) { + sb.append(ghost.getId()).append(", ").append(" -> Null session").append(", SessionById: ").append(this.sm.getSessionById(ghost.getId())); + } else { + sb.append(ghost.getId()).append(", ").append(", Connected: ").append(ss.isConnected()).append(", Idle: ").append(ss.isIdle()).append(", Marked: ") + .append(ss.isMarkedForEviction()).append(", Frozen: ").append(ss.isFrozen()).append(", SessionById: ").append(this.sm.getSessionById(ghost.getId())); + } + } + return sb.toString(); + } +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java new file mode 100644 index 0000000..13e363a --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/UndertowWebSocketChannel.java @@ -0,0 +1,56 @@ +package com.taurus.permanent.websocket; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.ByteBuffer; + +import com.taurus.permanent.data.ISocketChannel; + +import io.undertow.websockets.core.WebSocketChannel; +import io.undertow.websockets.core.WebSockets; + +public class UndertowWebSocketChannel implements ISocketChannel{ + + private WebSocketChannel channel; + + public UndertowWebSocketChannel (WebSocketChannel channel) { + this.channel = channel; + } + + @Override + public long write(ByteBuffer buffer) { + return 0; + } + + @Override + public void write(String message) { + WebSockets.sendText(message, channel, null); + } + + @Override + public SocketAddress getRemoteAddress() { + return channel.getPeerAddress(); + } + + @Override + public SocketAddress getLocalAddress() { + return channel.getLocalAddress(); + } + + @Override + public void close() throws IOException{ + channel.close(); + } + + @Override + public Object getChannel() { + return channel; + } + + @Override + public boolean checkConnection() { + if(channel!=null&&channel.isOpen())return true; + return false; + } + +} diff --git a/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java new file mode 100644 index 0000000..b932a4b --- /dev/null +++ b/taurus-server/taurus-permanent/src/main/java/com/taurus/permanent/websocket/WebSocketService.java @@ -0,0 +1,195 @@ +package com.taurus.permanent.websocket; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.taurus.core.util.Utils; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.core.BaseCoreService; +import com.taurus.permanent.core.BitSwarmEngine; +import com.taurus.permanent.core.ServerConfig; +import com.taurus.permanent.core.SessionManager; +import com.taurus.permanent.data.ISocketChannel; +import com.taurus.permanent.data.PackDataType; +import com.taurus.permanent.data.Packet; +import com.taurus.permanent.data.Session; +import com.taurus.permanent.data.SessionType; + +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.websockets.WebSocketConnectionCallback; +import io.undertow.websockets.core.AbstractReceiveListener; +import io.undertow.websockets.core.BufferedBinaryMessage; +import io.undertow.websockets.core.BufferedTextMessage; +import io.undertow.websockets.core.CloseMessage; +import io.undertow.websockets.core.WebSocketChannel; +import io.undertow.websockets.core.WebSockets; +import io.undertow.websockets.spi.WebSocketHttpExchange; + +/** + * WebSocket service + * + * + */ +public class WebSocketService extends BaseCoreService{ + private Undertow server; + private final BitSwarmEngine engine; + private SessionManager sessionManager; + private Logger logger; + + public WebSocketService() { + engine = BitSwarmEngine.getInstance(); + sessionManager = engine.getSessionManager(); + logger = Logger.getLogger(WebSocketService.class); + } + + public void init(Object o) { + super.init(o); + WSConnectionListener listener = new WSConnectionListener(this); + ServerConfig config = TPServer.me().getConfig(); + server = Undertow.builder().addHttpListener(config.webSocketConfig.port, config.webSocketConfig.address) + .setHandler(Handlers.path().addPrefixPath("/websocket", Handlers.websocket(listener))) + .build(); + server.start(); + logger.info("Websocket listen --> "+config.webSocketConfig.address+":"+config.webSocketConfig.port); + logger.info("Websocket service start!"); + } + + public void destroy(Object o) { + super.destroy(o); + server.stop(); + server = null; + logger.info("Websocket service shutdown!"); + } + + private void openAction(WebSocketChannel channel) { + Session session = sessionManager.createSession(new UndertowWebSocketChannel(channel), SessionType.WEBSOCKET); + sessionManager.addSession(session); + } + + private void readTextAction(WebSocketChannel channel,String data) { + Session session = sessionManager.getSessionByConnection(channel); + Packet newPacket = new Packet(); + newPacket.setDataType(PackDataType.TEXT); + newPacket.setSender(session); + ITObject requestObject = TObject.newFromJsonData(data); + newPacket.setData(requestObject); + session.setLastReadTime(System.currentTimeMillis()); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + private void readBinaryAction(WebSocketChannel channel,ByteBuffer data) { + Session session = sessionManager.getSessionByConnection(channel); + Packet newPacket = new Packet(); + newPacket.setDataType(PackDataType.BINARY); + boolean compressed = data.get() >0; + byte[] bytes = new byte[data.remaining()]; + data.get(bytes); + if(compressed) { + try { + bytes = Utils.uncompress(bytes); + } catch (IOException e) { + logger.error(e); + return; + } + } + newPacket.setSender(session); + ITObject requestObject = TObject.newFromBinaryData(bytes); + newPacket.setData(requestObject); + session.setLastReadTime(System.currentTimeMillis()); + engine.getProtocolHandler().onPacketRead(newPacket); + } + + + /** + * send packet + */ + public void onDataWrite(Packet packet){ + if (packet.getRecipients().size() > 0) { + packet.setDataType(PackDataType.BINARY); + engine.getProtocolHandler().onPacketWrite(packet); + int protocolCompressionThreshold = TPServer.me().getConfig().protocolCompression; + byte[] binData = ((TObject)packet.getData()).toBinary(); + boolean compression = binData.length > protocolCompressionThreshold; + if(compression) { + try { + binData = Utils.compress(binData); + } catch (IOException e) { + logger.error(e); + return; + } + } + ByteBuffer writeBuffer = ByteBuffer.allocate(1 + binData.length); + writeBuffer.put(compression?(byte)1:(byte)0); + writeBuffer.put(binData); + writeBuffer.flip(); + for (final Session session : packet.getRecipients()) { + session.setLastWriteTime(System.currentTimeMillis()); + final ISocketChannel channel = session.getConnection(); + WebSockets.sendBinary(writeBuffer, (WebSocketChannel)channel.getChannel(), null); + } + } + } + + private void closeAction(WebSocketChannel channel) { + try { + sessionManager.onSocketDisconnected(channel); + } catch (IOException e) { + throw new RuntimeException("WebSocket Disconnected exception!",e); + } + } + + private static final class WSConnectionListener implements WebSocketConnectionCallback{ + private WSListener listener; + private WebSocketService wsService; + + public WSConnectionListener(WebSocketService wsService) { + this.wsService = wsService; + this.listener = new WSListener(wsService); + } + + @Override + public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) { + channel.getReceiveSetter().set(this.listener); + channel.resumeReceives(); + wsService.openAction(channel); + } + + } + + private static final class WSListener extends AbstractReceiveListener{ + private WebSocketService wsService; + + public WSListener(WebSocketService wsService) { + this.wsService = wsService; + } + + @Override + protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) { + wsService.readTextAction(channel, message.getData()); + } + + + protected void onCloseMessage(CloseMessage cm, WebSocketChannel channel) { + wsService.closeAction(channel); + } + + protected void onFullPingMessage(final WebSocketChannel channel, BufferedBinaryMessage message) throws IOException { + super.onFullBinaryMessage(channel, message); + } + + protected void onFullBinaryMessage(final WebSocketChannel channel, BufferedBinaryMessage message) throws IOException { + ByteBuffer[] bufferList= message.getData().getResource(); + for (ByteBuffer tem : bufferList) { + wsService.readBinaryAction(channel, tem); + } + message.getData().free(); + } + + } + + +} diff --git a/taurus-server/taurus-permanent/src/test/java/com/taurus/T1Controller.java b/taurus-server/taurus-permanent/src/test/java/com/taurus/T1Controller.java new file mode 100644 index 0000000..1e9cba6 --- /dev/null +++ b/taurus-server/taurus-permanent/src/test/java/com/taurus/T1Controller.java @@ -0,0 +1,16 @@ +package com.taurus; + +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +public class T1Controller implements IController{ + + @ActionKey("test") + public void test(Session sender,TObject params,int gid) { + System.out.println("t1 test"); + TPServer.me().getController().sendResponse(gid, 0, params, sender); + } +} diff --git a/taurus-server/taurus-permanent/src/test/java/com/taurus/T2Controller.java b/taurus-server/taurus-permanent/src/test/java/com/taurus/T2Controller.java new file mode 100644 index 0000000..82b8e99 --- /dev/null +++ b/taurus-server/taurus-permanent/src/test/java/com/taurus/T2Controller.java @@ -0,0 +1,22 @@ +package com.taurus; + +import com.taurus.core.entity.TObject; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.routes.IController; +import com.taurus.permanent.TPServer; +import com.taurus.permanent.data.Session; + +public class T2Controller implements IController{ + + @ActionKey("test") + public void test(Session sender,TObject params,int gid) { + System.out.println("t1 test"); + TPServer.me().getController().sendResponse(gid, 0, params, sender); + } + + @ActionKey("test1") + public void test1(Session sender,TObject params,int gid) { + System.out.println("t2 test"); + TPServer.me().getController().sendResponse(gid, 1, params, sender); + } +} diff --git a/taurus-server/taurus-permanent/src/test/java/com/taurus/TestExtension.java b/taurus-server/taurus-permanent/src/test/java/com/taurus/TestExtension.java new file mode 100644 index 0000000..2fc031a --- /dev/null +++ b/taurus-server/taurus-permanent/src/test/java/com/taurus/TestExtension.java @@ -0,0 +1,43 @@ +package com.taurus; + +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; + +/** + * + * @version V2.9 + */ +public class TestExtension extends Extension{ + + public TestExtension() { + super(); +// login_cmd_map.put("req_test", true); + } + + @Override + public void configRoute(Routes me) { + me.add("t1", new T1Controller()); + me.add("t2", new T2Controller()); + } + +// @Override +// public void handleEvent(Event event) { +// if( event.getName() == TPEvents.EVENT_SESSION_DISCONNECT){ +// Session session = (Session) event.getParameter(TPEvents.PARAM_SESSION); +// logger.info("session:" + session.isIdle()); +// } +// +// } +// +// @Override +// protected void handlerRequest(Session sender, String cmdName, ITObject params, int gid) { +// // TODO Auto-generated method stub +// params.putInt("ttt", 1); +// sendResponse(gid, 0, params, sender); +// +// //api.disconnect(sender); +// } + + + +} diff --git a/taurus-server/taurus-web/pom.xml b/taurus-server/taurus-web/pom.xml new file mode 100644 index 0000000..09c6e0f --- /dev/null +++ b/taurus-server/taurus-web/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.taurus + taurus-server + 1.0.1 + + jar + taurus-web + 1.0.1 + + + + junit + junit + + + + + com.taurus + taurus-core + + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + + + diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/Controller.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/Controller.java new file mode 100644 index 0000000..f61bb74 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/Controller.java @@ -0,0 +1,133 @@ +package com.taurus.web; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.routes.IController; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +/** + * Controller + * + * + */ +public abstract class Controller implements IController{ + private String actionKey; + private String session; + private String tokens; + private ITObject param; + private HttpServletRequest request; + private HttpServletResponse response; + private volatile boolean isFinish; + protected Logger logger; + + void _init(HttpServletRequest request,HttpServletResponse response,String actionKey,String session, String tokens, ITObject param){ + this.logger = Logger.getLogger(getClass()); + this.request = request; + this.response = response; + this.actionKey = actionKey; + this.session = session; + this.param = param; + this.tokens = tokens; + } + + /** + * get action key. + * @return + */ + public String getActionKey() { + return actionKey; + } + + public String getTokens() { return tokens; } + + /** + * 获取session对象 + * @return + */ + public String getSession() { + return session; + } + + public void setSession(String session) { + this.session = session; + } + + /** + * 获取参数 + * @return + */ + public ITObject getParams() { + return param; + } + + /** + * 动态响应客户端请示 + * @param result 响应结果 0成功 + * @param params 数据参数 + */ + public void sendResponse(int result, ITObject params) { + if(isFinish) { + throw new RuntimeException("This response is finish!"); + } + isFinish = true; + try { + WebUtils.httpResponse(this.response, result, params); + } catch (IOException e) { + logger.error("response client execption!\n",e); + } + } + + + + /** + * 获取客户端Host + * @return + */ + public String getRemoteAddr() { + return getIpAddr(this.request); + } + + private static final String[] HEADERS = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR", + "X-Real-IP" + }; + + private static final String UNKNOWN = "unknown"; + /** + * 判断ip是否为空,空返回true + * @param ip + * @return + */ + private static boolean isEmptyIp(final String ip){ + return (StringUtil.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)); + } + + private static String getIpAddr(HttpServletRequest request) { + String ip = StringUtil.Empty; + for (String header : HEADERS) { + ip = request.getHeader(header); + if(!isEmptyIp(ip)) { + break; + } + } + if(isEmptyIp(ip)){ + ip = request.getRemoteAddr(); + } + return ip; + } +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/JettyServer.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/JettyServer.java new file mode 100644 index 0000000..01d4ba5 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/JettyServer.java @@ -0,0 +1,157 @@ + +package com.taurus.web; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.ServerSocket; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.webapp.WebAppClassLoader; +import org.eclipse.jetty.webapp.WebAppContext; + +import com.taurus.core.util.StringUtil; + + + +/** + * JettyServer is used to config and start jetty web server. + */ +public class JettyServer{ + private static final int DEFAULT_PORT = 80; + private static final String DEFAULT_WEBAPPDIR = "webapp"; + + private String webAppDir; + private int port; + private String context; + private boolean running = false; + private Server server; + private WebAppContext webApp; + + public JettyServer(){ + this(DEFAULT_WEBAPPDIR,DEFAULT_PORT,"/"); + } + + public JettyServer(String webAppDir, int port, String context) { + if (webAppDir == null) { + throw new IllegalStateException("Invalid webAppDir of web server: " + webAppDir); + } + if (port < 0 || port > 65535) { + throw new IllegalArgumentException("Invalid port of web server: " + port); + } + if (StringUtil.isEmpty(context)) { + throw new IllegalStateException("Invalid context of web server: " + context); + } + + this.webAppDir = webAppDir; + this.port = port; + this.context = context; + } + + public void start() { + if (!running) { + try { + running = true; + doStart(); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } + } + + public void stop() { + if (running) { + try {server.stop();} catch (Exception e) {e.printStackTrace();} + running = false; + } + } + + private void doStart() { + if (!available(port)) { + throw new IllegalStateException("port: " + port + " already in use!"); + } + + System.out.println("Starting taurus web server "); + server = new Server(port); + webApp = new WebAppContext(); + webApp.setThrowUnavailableOnStartupException(true); + webApp.setContextPath(context); + webApp.setResourceBase(webAppDir); + webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); + webApp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false"); + + server.setHandler(webApp); + changeClassLoader(webApp); + + + try { + System.out.println("Starting web server on port: " + port); + server.start(); + System.out.println("Starting Complete."); + server.join(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(100); + } + return; + } + + private void changeClassLoader(WebAppContext webApp) { + try { + WebAppClassLoader jfcl = new WebAppClassLoader(webApp); + webApp.setClassLoader(jfcl); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static boolean available(int port) { + if (port <= 0) { + throw new IllegalArgumentException("Invalid start port: " + port); + } + + ServerSocket ss = null; + DatagramSocket ds = null; + try { + ss = new ServerSocket(port); + ss.setReuseAddress(true); + ds = new DatagramSocket(port); + ds.setReuseAddress(true); + return true; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (ds != null) { + ds.close(); + } + + if (ss != null) { + try { + ss.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return false; + } + + + + public static void main(String[] args) { + if (args == null || args.length == 0) { + JettyServer server = new JettyServer(); + server.start(); + return; + } + + if (args.length == 3) { + String webAppDir = args[0]; + int port = Integer.parseInt(args[1]); + String context = args[2]; + JettyServer server = new JettyServer(webAppDir, port, context); + server.start(); + return ; + } + } + +} \ No newline at end of file diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/ServletHealthCheck.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/ServletHealthCheck.java new file mode 100644 index 0000000..c5464a8 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/ServletHealthCheck.java @@ -0,0 +1,23 @@ +package com.taurus.web; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.util.StringUtil; + + +@WebServlet("/health") +public class ServletHealthCheck extends HttpServlet { + + private static final long serialVersionUID = 1L; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().println(StringUtil.Empty); + } + +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/SessionInfo.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/SessionInfo.java new file mode 100644 index 0000000..42ad702 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/SessionInfo.java @@ -0,0 +1,11 @@ +package com.taurus.web; + +/** + * session info + * + * + */ +public class SessionInfo { + public String target; + public String method; +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/StatusServlet.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/StatusServlet.java new file mode 100644 index 0000000..f54a6f3 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/StatusServlet.java @@ -0,0 +1,66 @@ +package com.taurus.web; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.plugin.redis.Cache; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +import redis.clients.jedis.JedisPool; + +@WebServlet("/status") +public class StatusServlet extends HttpServlet{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String str = ""; + String tem = req.getParameter("info"); + boolean is_info = false; + if(StringUtil.isNotEmpty(tem)) { + is_info = Boolean.parseBoolean(tem); + } + int size = TWebServer.me().getConcurrentSize(); + str += "connect-num:"+size + "
"; + if(is_info) { + List concurrentList = TWebServer.me().getConcurrentList(); + List list = null; + synchronized (concurrentList) { + list = new ArrayList<>(concurrentList); + } + int i= 0; + for(SessionInfo info : list) { + i++; + str +=String.format("
[%s] action->%s method->%s
",i, info.target,info.method); + } + } + + ConcurrentHashMap map = Redis.getCacheMap(); + Set> entrySet = map.entrySet(); + for(Entry entry : entrySet) { + JedisPool pool = entry.getValue().getJedisPool(); + str += String.format("
%s
",entry.getKey()); + str += "active-num:"+pool.getNumActive(); + str += "\tidle-num:"+pool.getNumIdle(); + str += "\twait-num:"+pool.getNumWaiters(); + } + str+=""; + + resp.getWriter().write(str); + } +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/TWebServer.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/TWebServer.java new file mode 100644 index 0000000..a8da03b --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/TWebServer.java @@ -0,0 +1,233 @@ +package com.taurus.web; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.PluginService; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.ActionMapping; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; + +/** + * The web server main class. + * + * + * + */ +public class TWebServer { + private static final String _POST = "POST"; + private static final String _Session = "$s"; + private static final String _Version = "$v"; + /** + * The server class instance. + */ + private static TWebServer _instance = null; + private Logger log; + private Extension extension; + private ActionMapping actionMapping; + private ScheduledThreadPoolExecutor timeScheduler; + private int forceVer = 1; + private Routes routes; + private String contextPath; + private String contextRealPath; + /** + * 当前并发数 + */ + private final List concurrentList; + + /** + * get main instance + */ + public static TWebServer me() { + if (_instance == null) { + _instance = new TWebServer(); + } + return _instance; + } + + public TWebServer() { + log = Logger.getLogger(WebFilter.class); + this.routes = new Routes(Routes.CONTROLLER_CLASS) { + public void config() { + } + }; + concurrentList = new ArrayList(); + timeScheduler = new ScheduledThreadPoolExecutor(1); + actionMapping = new ActionMapping(routes); + } + + void init(FilterConfig filterConfig) throws Exception { + String path = filterConfig.getServletContext().getRealPath("/"); + System.setProperty("WORKDIR", path); + PluginService.me().loadConfig(path); + this.contextRealPath = path; + this.contextPath = filterConfig.getServletContext().getContextPath(); + String extensionClass = filterConfig.getInitParameter("main"); + this.extension = instanceExtension(extensionClass); + this.extension.configRoute(routes); + actionMapping.buildActionMapping(); + this.extension.onStart(); + timeScheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + forceVer = extension.readVersion(); + } + }, 5, 5, TimeUnit.SECONDS); + } + + private Extension instanceExtension(String extensionClass) { + if (StringUtil.isEmpty(extensionClass)) { + throw new RuntimeException("Extension class parameter is missing!"); + } + Extension extension = null; + try { + Class exclass = Class.forName(extensionClass); + if (!Extension.class.isAssignableFrom(exclass)) { + throw new RuntimeException("You extension does not implement Extension "); + } + extension = (Extension) exclass.newInstance(); + } catch (IllegalAccessException e) { + throw new RuntimeException("Illegal access while instantiating class: " + extensionClass); + } catch (InstantiationException e) { + throw new RuntimeException("Cannot instantiate class: " + extensionClass); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Class not found: " + extensionClass); + } + return extension; + } + + void handle(String target,HttpServletRequest request,HttpServletResponse response,FilterChain chain) + throws IOException, ServletException { + String method = request.getMethod(); + SessionInfo info = new SessionInfo(); + info.target = target; + info.method = method; + synchronized (concurrentList) { + concurrentList.add(info); + } + Action action =actionMapping.getAction(target); + try { + if (action != null) { + if (!method.equals(_POST)) { + return; + } + + ITObject obj = WebUtils.httpRequest(request); + if (obj == null) { + throw new RuntimeException("data is null!"); + } + if (!obj.containsKey(_Version)) { + WebUtils.httpResponse(response, -1, null); + return; + } + int client_ver = obj.getInt(_Version); + if (client_ver < forceVer) { + WebUtils.httpResponse(response, -1, null); + return; + } + long startTime = System.currentTimeMillis(); + String session = null; + String token = null; + if (obj.containsKey(_Session)) { + String str_session = obj.getString(_Session); + String[] sourceStrArray = str_session.split(","); + if (sourceStrArray.length == 2) + { + session = sourceStrArray[0]; + token = sourceStrArray[1]; + } + else { + session = str_session; + } + } + ITObject params = obj.getTObject(WebUtils._Param); + Controller controller = null; + try { + controller = (Controller)action.getControllerClass().newInstance(); + controller._init(request, response, action.getActionKey(), session, token, params); + + if (action.getInterceptor() != null) { + action.getInterceptor().intercept(action, controller); + } + action.getMethod().invoke(controller); + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof WebException) { + WebException we = (WebException) targetException; + controller.sendResponse(we.getCode(), null); + } else { + controller.sendResponse(500, null); + log.error(targetException); + } + }catch (WebException e) { + controller.sendResponse(e.getCode(), null); + }catch (Exception e) { + if (controller != null) { + controller.sendResponse(500, null); + } + log.error(e); + } + long endTime = System.currentTimeMillis(); + if(!action.getActionKey().equalsIgnoreCase("set_group_heartbeat")) { + log.info("action: "+action + "[" + session+"] time:"+(endTime - startTime)+"ms"); + } + } else { + chain.doFilter(request, response); + } + }finally { + synchronized (concurrentList) { + concurrentList.remove(info); + } + } + } + void destroy() { + if (timeScheduler != null) { + timeScheduler.shutdownNow(); + } + if (extension != null) { + extension.onStop(); + } + PluginService.me().stop(); + synchronized (concurrentList) { + concurrentList.clear(); + } + } + + public int getForceVer() { + return forceVer; + } + + public String getContextPath() { + return contextPath; + } + + public String getContextRealPath() { + return contextRealPath; + } + + public List getConcurrentList(){ + return concurrentList; + } + + public int getConcurrentSize() { + int size = concurrentList.size(); + if(extension!=null) { + size +=extension.getConcurrentSize(); + } + return size; + } +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/WebException.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebException.java new file mode 100644 index 0000000..1a1ec72 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebException.java @@ -0,0 +1,17 @@ +package com.taurus.web; + +public class WebException extends Exception{ + /** + * + */ + private static final long serialVersionUID = 1L; + private int code; + + public WebException(int code) { + this.code = code; + } + + public int getCode() { + return code; + } +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/WebFilter.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebFilter.java new file mode 100644 index 0000000..7cad0e9 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebFilter.java @@ -0,0 +1,72 @@ +package com.taurus.web; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.util.StringUtil; + +/** + * + * main filter class + * + */ +public class WebFilter implements Filter { + private static final String _UTF8 = "UTF-8"; + private static final String _ALLOW_ORIGIN = "Access-Control-Allow-Origin"; + private static final String _ALLOW_ORIGIN_V = "*"; + private int contextPathLength; + + private TWebServer tweb; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + try { + String contextPath = filterConfig.getServletContext().getContextPath(); + contextPathLength = StringUtil.isNotEmpty(contextPath) ? contextPath.length() : 0; + tweb = TWebServer.me(); + tweb.init(filterConfig); + } catch (Exception e) { + e.printStackTrace(); + throw new ServletException(e); + } + } + + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + String target = request.getRequestURI(); + if (StringUtil.isEmpty(target)) { + return; + } + if (contextPathLength != 0) { + target = target.substring(contextPathLength); + } +// // 添加对/config/目录的访问限制 +// if (target.contains("/config/") || target.contains(".") ) { +// response.setStatus(HttpServletResponse.SC_FORBIDDEN); +// response.getWriter().write("Access to config directory is forbidden"); +// return; +// } + request.setCharacterEncoding(_UTF8); + response.setCharacterEncoding(_UTF8); + response.setHeader(_ALLOW_ORIGIN, _ALLOW_ORIGIN_V); + tweb.handle(target, request, response, chain); + } + + @Override + public void destroy() { + tweb.destroy(); + } + +} diff --git a/taurus-server/taurus-web/src/main/java/com/taurus/web/WebUtils.java b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebUtils.java new file mode 100644 index 0000000..b8415d4 --- /dev/null +++ b/taurus-server/taurus-web/src/main/java/com/taurus/web/WebUtils.java @@ -0,0 +1,42 @@ +package com.taurus.web; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Utils; + +/** + * WebUtils + * + * + */ +public class WebUtils{ + static final String _Result = "$r"; + static final String _Param = "$p"; + + + static final ITObject httpRequest(HttpServletRequest request) throws IOException { + InputStream in = request.getInputStream(); + byte[] bytes = Utils.uncompress(in); + ITObject obj = TObject.newFromBinaryData(bytes); + return obj; + } + + final static void httpResponse(HttpServletResponse response, int result, ITObject param) throws IOException { + ITObject tem = TObject.newInstance(); + tem.putInt(_Result, result); + param = param == null ? TObject.newInstance() : param; + tem.putTObject(_Param, param); + byte[] bytes = tem.toBinary(); + OutputStream out = response.getOutputStream(); + Utils.compress(bytes, out); + out.close(); + } + +} diff --git a/taurus-server/taurus-web/src/test/java/com/taurus/Test.java b/taurus-server/taurus-web/src/test/java/com/taurus/Test.java new file mode 100644 index 0000000..790c675 --- /dev/null +++ b/taurus-server/taurus-web/src/test/java/com/taurus/Test.java @@ -0,0 +1,14 @@ +package com.taurus; + +public class Test { + + public static void main(String[] args) { + +// UndertowServer.create(AppConfig.class) +// .addHotSwapClassPrefix("com.abc.") +// .setPort(8000) +// .setDevMode(true) +// .start(); + } + +} diff --git a/web_group/build/local/taurus-core.xml b/web_group/build/local/taurus-core.xml new file mode 100644 index 0000000..2c8c033 --- /dev/null +++ b/web_group/build/local/taurus-core.xml @@ -0,0 +1,100 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 2000 + + 1 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 2000 + + 8 + + 2 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + + + diff --git a/web_group/build/pro/bank_hp.lua b/web_group/build/pro/bank_hp.lua new file mode 100644 index 0000000..d3a02ce --- /dev/null +++ b/web_group/build/pro/bank_hp.lua @@ -0,0 +1,19 @@ +local tag_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local bank_hp = tonumber(redis.call('hget', KEYS[2],KEYS[3])) +bank_hp = not bank_hp and 0 or bank_hp +local hp = tonumber(ARGV[1]) +local opt = tonumber(ARGV[2]) +if opt==0 then + if bank_hp < hp then + return 3 + end + bank_hp = redis.call('hincrBy',KEYS[2],KEYS[3],-hp) + tag_hp = redis.call('hincrBy',KEYS[1],'hp',hp) +else + if tag_hp < hp then + return 4 + end + bank_hp = redis.call('hincrBy',KEYS[2],KEYS[3],hp) + tag_hp = redis.call('hincrBy',KEYS[1],'hp',-hp) +end +return {tag_hp,bank_hp} \ No newline at end of file diff --git a/web_group/build/pro/log4j.properties b/web_group/build/pro/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_group/build/pro/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_group/build/pro/mgr.lua b/web_group/build/pro/mgr.lua new file mode 100644 index 0000000..50b3c69 --- /dev/null +++ b/web_group/build/pro/mgr.lua @@ -0,0 +1,25 @@ +-- redis.call('select',0) +local mgr_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local tag_hp = tonumber(redis.call('hget', KEYS[2],'hp')) + +local ulev = tonumber(ARGV[2]) +local hp = tonumber(ARGV[1]) +if ulev == 3 or ulev == 2 then + if hp > 0 and mgr_hp 0 and reward_hp < hp then + return 3 +else + reward_hp = redis.call('incrBy',KEYS[1],-hp) + tag_hp = redis.call('hincrBy',KEYS[2],'hp',hp) +end +return {reward_hp,tag_hp} \ No newline at end of file diff --git a/web_group/build/pro/taurus-core.xml b/web_group/build/pro/taurus-core.xml new file mode 100644 index 0000000..2c8c033 --- /dev/null +++ b/web_group/build/pro/taurus-core.xml @@ -0,0 +1,100 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 2000 + + 1 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 2000 + + 8 + + 2 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + + + diff --git a/web_group/build/pro/trade.lua b/web_group/build/pro/trade.lua new file mode 100644 index 0000000..c03a438 --- /dev/null +++ b/web_group/build/pro/trade.lua @@ -0,0 +1,12 @@ +local mgr_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local tag_hp = tonumber(redis.call('hget', KEYS[2],'hp')) +mgr_hp = not mgr_hp and 0 or mgr_hp +tag_hp = not tag_hp and 0 or tag_hp +local hp = tonumber(ARGV[1]) +if hp > 0 and mgr_hp 0 and mgr_hp 0 and reward_hp < hp then + return 3 +else + reward_hp = redis.call('incrBy',KEYS[1],-hp) + tag_hp = redis.call('hincrBy',KEYS[2],'hp',hp) +end +return {reward_hp,tag_hp} \ No newline at end of file diff --git a/web_group/build/test/taurus-core.xml b/web_group/build/test/taurus-core.xml new file mode 100644 index 0000000..2c8c033 --- /dev/null +++ b/web_group/build/test/taurus-core.xml @@ -0,0 +1,100 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 2000 + + 1 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 2000 + + 8 + + 2 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + + + diff --git a/web_group/build/test/trade.lua b/web_group/build/test/trade.lua new file mode 100644 index 0000000..c03a438 --- /dev/null +++ b/web_group/build/test/trade.lua @@ -0,0 +1,12 @@ +local mgr_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local tag_hp = tonumber(redis.call('hget', KEYS[2],'hp')) +mgr_hp = not mgr_hp and 0 or mgr_hp +tag_hp = not tag_hp and 0 or tag_hp +local hp = tonumber(ARGV[1]) +if hp > 0 and mgr_hp + 4.0.0 + com.group + web_group + war + 1.0.0 + + UTF-8 + 1.8 + 1.8 + pro + + + + + junit + junit + 3.8.1 + test + + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + org.quartz-scheduler + quartz + 2.2.3 + compile + + + + + + ROOT + + + org.apache.maven.plugins + maven-war-plugin + + 1.8 + 1.8 + UTF-8 + logs/**,config/** + + + config/ + ${project.basedir}/build/${build.type}/ + + + + + + + + diff --git a/web_group/src/main/java/com/group/MainServer.java b/web_group/src/main/java/com/group/MainServer.java new file mode 100644 index 0000000..455dc48 --- /dev/null +++ b/web_group/src/main/java/com/group/MainServer.java @@ -0,0 +1,142 @@ +package com.group; + + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.group.controller.GroupController; +import com.group.controller.GroupLogController; +import com.group.controller.GroupRoomController; +import com.group.job.UpdatePlayRoomJob; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.FileUtil; + +import org.quartz.CronTrigger; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerFactory; +import org.quartz.impl.StdSchedulerFactory; +import redis.clients.jedis.Jedis; + +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + +public class MainServer extends Extension { + private ScheduledThreadPoolExecutor timeScheduler; + + private static final String WEB_CONFIG_KEY = "web_config"; + private static final String FORCE_VER_KEY = "force_ver"; + + public static Map lua_map = new HashMap<>(); + public MainServer() { + super(); + //3秒 +// NetManager.TIMEOUT_TIME =3; + timeScheduler = new ScheduledThreadPoolExecutor(1); + timeScheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + AccountCache.clearData(); + GroupCache.clearData(); + System.gc(); + } + }, 0,600, TimeUnit.SECONDS); + loadLua(); + initJob(); + } + + @Override + public int readVersion() { + int ver = Integer.parseInt(Redis.use("group1_db1").hget(WEB_CONFIG_KEY,FORCE_VER_KEY)); + return ver; + } + + + @Override + public void configRoute(Routes me) { + me.setInterceptor(new WebInterceptor()); + + me.add("group", GroupController.class); + me.add("group/room", GroupRoomController.class); + me.add("group/log",GroupLogController.class); + } + + private static void loadLua() { + String path = System.getProperty("WORKDIR"); + try { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String str = FileUtil.readTxt(path + "/config/mgr.lua"); + lua_map.put("mgr", jedis10.scriptLoad(str)); + str = FileUtil.readTxt(path + "/config/trade.lua"); + lua_map.put("trade", jedis10.scriptLoad(str)); + str = FileUtil.readTxt(path + "/config/take_hp.lua"); + lua_map.put("take_hp", jedis10.scriptLoad(str)); + str = FileUtil.readTxt(path + "/config/bank_hp.lua"); + lua_map.put("bank_hp", jedis10.scriptLoad(str)); + } finally { + jedis10.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void initJob() { + + try { + SchedulerFactory sf = new StdSchedulerFactory(); + Scheduler sched = sf.getScheduler(); + + JobDetail job = newJob(UpdatePlayRoomJob.class).withIdentity("update_play_room", "group").build(); + CronTrigger trigger= newTrigger().withIdentity("update_play_room_trigger", "group").withSchedule(cronSchedule("0/5 * * * * ? ")).build(); + sched.scheduleJob(job, trigger); + + job = newJob(UpdatePlayRoomJob.class).withIdentity("create_play_room", "group").build(); + trigger= newTrigger().withIdentity("create_play_room_trigger", "group").withSchedule(cronSchedule("0/3 * * * * ? ")).build(); + sched.scheduleJob(job, trigger); + + job = newJob(UpdatePlayRoomJob.class).withIdentity("clean_play_score", "group").build(); +// trigger= newTrigger().withIdentity("clean_play_score_trigger", "group").withSchedule(cronSchedule("0 0 0 * * ? ")).build(); + trigger= newTrigger().withIdentity("clean_play_score_trigger", "group").withSchedule(cronSchedule("0 0 0 * * ? ")).build(); + sched.scheduleJob(job, trigger); + + job = newJob(UpdatePlayRoomJob.class).withIdentity("del_room", "group").build(); + trigger= newTrigger().withIdentity("del_room_trigger", "group").withSchedule(cronSchedule("0/2 * * * * ? ")).build(); + sched.scheduleJob(job, trigger); + + sched.start(); + } + catch(Exception e) { + + } + } + + + @Override + public void onStart() { + System.out.println("web group start!"); + } + + @Override + public void onStop() { + if(timeScheduler!=null) { + timeScheduler.shutdownNow(); + } + } + + + + + + + +} diff --git a/web_group/src/main/java/com/group/Protocol.java b/web_group/src/main/java/com/group/Protocol.java new file mode 100644 index 0000000..b3dcd99 --- /dev/null +++ b/web_group/src/main/java/com/group/Protocol.java @@ -0,0 +1,279 @@ +package com.group; + + +public class Protocol { + + + + // --------------------group-------------------------- + + //显示,隐藏 + public static final String SHOW_GROUP = "show_group"; + + /**获取圈子列表*/ + public static final String GET_GROUPS = "get_groups"; + /**获取创建圈子*/ + public static final String CREATE_GROUP = "create_group"; + /**加入圈子*/ + public static final String JOIN_GROUP = "join_group"; + /**删除圈子*/ + public static final String DEL_GROUP = "del_group"; + /**获取申请列表*/ + public static final String GET_GROUP_JOINS = "get_group_joins"; + /**授权加入圈子*/ + public static final String VERIFY_JOIN_GROUP = "verify_join_group"; + /**获取成员列表*/ + public static final String GET_GROUP_MEMBERS = "get_group_members"; + + /** 心跳推送数据 **/ + public static final String GET_MY_MEMBERS = "get_my_members"; + + public static final String GET_MEMBERS_COUNT = "get_members_count"; + + /**获取合伙人列表*/ + public static final String GET_GROUP_PARTNERS = "get_group_partners"; + + + + /**删除成员*/ + public static final String GROUP_KICK = "group_kick"; + + + + + public static final String GET_KICK_LOG = "get_kick_log"; + + /** 邀请加入圈子*/ + public static final String INVITE_GROUP_MEMBER = "invite_group_member"; + /** 获取玩家信息 */ + public static final String GET_PLAYER_INFO = "get_player_info"; + + public static final String CLONE_GROUP = "clone_group"; + + //聊天室 + public static final String GET_CHAT_ROOMS = "get_chat_rooms"; + + /** 获取提取数据信息*/ + public static final String TRADE_TAKE_INFO = "get_take_info"; + /** 提取体力值*/ + public static final String TAKE_HP = "take_hp"; + /** 提取体力值*/ + public static final String GROUP_TAKE_HP = "group_take_hp"; + + public static final String GET_BANK_HP = "get_bank_hp"; + public static final String TAKE_BANK_HP = "take_bank_hp"; + public static final String SAVE_BANK_HP = "save_bake_hp"; + + /** 获取提取日志*/ + public static final String GET_TAKE_LOG = "get_take_log"; + + public static final String GET_BANK_LOG = "get_bank_log"; + + + /** 更新成员体力值*/ + public static final String UPDATE_MEMBER_HP = "update_member_hp"; + public static final String UPDATE_MEMBER_SCORE = "update_member_score"; + public static final String UPDATE_JOIN_SCORE = "update_join_score"; + + /** 充值房卡*/ + public static final String ADD_GROUP_DIAMO = "add_group_diamo"; + + /** 充值房卡*/ + public static final String SET_GROUP_HEARTBEAT = "set_group_heartbeat"; + + /** 进入圈子*/ + public static final String ENTER_GROUP = "enter_group"; + + /** 置顶圈子*/ + public static final String STICK_GROUP = "stick_group"; + + + /** 添加玩法 */ + public static final String ADD_PLAY = "add_play"; + /** 删除玩法 */ + public static final String DEL_PLAY = "del_play"; + /** 更新玩法*/ + public static final String UPDATE_PLAY = "update_play"; + /** 快速加入房间 */ + public static final String GROUP_MATCH_ROOM = "match_room"; + /** 加入房间 */ + public static final String GROUP_JOIN_ROOM = "join_room"; + + + /** + * 玩家进入观众席 + */ + public static final String GAME_JOIN_SPECTATOR= "join_spectator"; + + /** + * 玩家退出观众席 + */ + public static final String GAME_OUT_SPECTATOR= "out_spectator"; + /** 删除房间 */ + public static final String GROUP_DEL_ROOM = "del__room"; + /** 更新圈子配置 */ + public static final String GROUP_UPDATE_INFO = "update_info"; + /** 成员禁止娱乐*/ + public static final String GROUP_BAN_MEMBER = "ban_member"; + /** 成员禁止娱乐*/ + public static final String GROUP_BLACK_MEMBER = "black_member"; + /** 成员禁止娱乐*/ + public static final String GROUP_GET_BLACK_MEMBER = "get_black_member"; + /** 玩法禁止娱乐*/ + public static final String GROUP_BAN_PLAY = "ban_play"; + /** 标识玩法*/ + public static final String GROUP_MARK_PLAY = "mark_play"; + /** 更新成员管理*/ + public static final String GROUP_SET_MEMBER_MGR = "set_member_mgr"; + /** 更新成员管理*/ + public static final String GROUP_SET_PARTNER = "set_partner"; + /** 获取成员上级合伙人列表*/ + public static final String GET_MEMBER_PARENTS = "get_member_parents"; + /** 查询成员*/ + public static final String FIND_MEMBER = "find_member"; + /** 查询成员1*/ + public static final String FIND_MEMBER1 = "find_member1"; + /** 获取管理上下分记录*/ + public static final String GET_HPLOG_MGR = "get_hplog_mgr"; + /** 获取管理上下分记录统计*/ + public static final String GET_HPLOG_MGR_COUNT = "get_hplog_mgr_count"; + /** 获取管理员上下分详细信息*/ + public static final String GET_HPLOG_MGR_INFO = "get_hplog_mgr_info"; + /** 获取玩家体力值详细*/ + public static final String GET_HPLOG_INFO = "get_hplog_info"; + + /** 获取玩家详细体力值*/ + public static final String GET_HPLOG_DETAIL_INFO = "get_hplog_detail_info"; + + /** 获取抽水体力值详细*/ + public static final String GET_HPLOG_PUMP = "get_hplog_pump"; + /** 设置奖励*/ + public static final String GROUP_SET_REWARD = "set_reward"; + /** 设置奖励*/ + public static final String GROUP_SET_XIPAI_REWARD = "set_xipai_reward"; + /** 获取奖励数据*/ + public static final String GROUP_GET_REWARDS = "get_rewards"; + /** 获取奖励日志*/ + public static final String GROUP_GET_REWARD_LOG = "get_reward_log"; + /** 获取奖励统计*/ + public static final String GROUP_GET_REWARD_COUNT = "get_reward_count"; + /** 获取玩法局数统计*/ + public static final String GROUP_GET_PLAY_ROUND_COUNT = "get_play_round_count"; + /** 获取消耗统计*/ + public static final String GROUP_GET_COST_COUNT = "get_cost_count"; + /** 获取局数统计*/ + public static final String GROUP_GET_ROUND_COUNT = "get_round_count"; + /**获得成员统计*/ + public static final String GROUP_GET_MEMBER_STAT = "get_member_stat"; + /**获得合伙人统计*/ + public static final String GROUP_GET_PARTNER_STAT = "get_partner_stat"; + /**查找合伙人统计*/ + public static final String GROUP_FIND_PARTNER_STAT = "find_partner_stat"; + /**获得合伙人统计 成员*/ + public static final String GROUP_GET_PARTNER_STAT_MEMBER = "get_partner_stat_member"; + /**查找合伙人统计 成员*/ + public static final String GROUP_FIND_PARTNER_STAT_MEMBER = "find_partner_stat_member"; + + public static final String GROUP_GET_DIRECT_STAT_MEMBER = "get_direct_stat_member"; + /**获得合伙人统计 玩法*/ + public static final String GROUP_GET_PARTNER_STAT_PLAY = "get_partner_stat_play"; + /** 获取成员排行*/ + public static final String GROUP_GET_MEMBER_RANK_2 = "get_member_rank_2"; + /** 获取成员排行*/ + public static final String GROUP_GET_MEMBER_RANK = "get_member_rank"; + + /** 获取战绩列表*/ + public static final String GROUP_GET_RECORDS = "get_records"; + /** 获取战绩列表(外圈游戏记录模块)*/ + public static final String GROUP_GET_RECORDS_OWNER = "get_records_owner"; + + + /** 阅读战绩列表*/ + public static final String GROUP_READ_RECORDS = "read_records"; + + /** 获取个人亲友圈战绩列表*/ + public static final String GROUP_GET_PERSON_RECORDS = "get_person_records"; + + + /** 根据房间ID查询战绩*/ + public static final String GROUP_FIND_RECORD_ROOM = "find_record_room"; + /** 调配成员*/ + public static final String DISTRIBUTE_MEMBER = "distribute_member"; + + + /** 退出圈子*/ + public static final String EXIT_GROUP = "exit_group"; + + + + /** 获取合伙人[日志]管理列表*/ + public static final String GET_PARTNER_INFOS = "get_partner_data"; + /**搜索合伙人信息*/ + public static final String QUERY_PARTNER_INFOS = "query_partner_data"; + /** 获取合伙人[日志]成员列表*/ + public static final String GET_PARTNER_MEMBERS = "get_partner_members"; + + /** 设置管理员权限*/ + public static final String SET_MGR_PERMISSION = "set_mgr_permission"; + /** 获取禁止同桌列表*/ + public static final String GET_BAN_DESK_LIST = "get_ban_desk_list"; + /** 获取禁止同桌列表*/ + public static final String GET_BAN_DESK_LIST2 = "get_ban_desk_list2"; + /** 设置禁止同桌*/ + public static final String SET_BAN_DESK = "set_ban_desk"; + /** 设置禁止同桌2*/ + public static final String SET_BAN_DESKList = "set_ban_deskList"; + /**获取体力值信息*/ + public static final String GET_HP_COUNT_INFO ="get_hp_count_info"; + /** 获取体力值消耗统计*/ + public static final String GROUP_GET_HPCONSUME_COUNT = "get_hpconsume_count"; + /** 转移合伙人*/ + public static final String MOVE_PARTNER = "move_partner"; + /**获取整线体力值*/ + public static final String GET_HP_TOTAL = "get_hp_total"; + /**更新推广设置*/ + public static final String UPDATE_PROMOTION = "update_promotion"; + /**获取推广设置*/ + public static final String GET_PROMOTION = "get_promotion"; + /**获取邮件列表*/ + public static final String GET_MAIL_LIST = "get_mail_list"; + /**删除所以邮件*/ + public static final String DEL_MAIL_ALL = "del_mail_all"; + + /**设置亲友圈合伙人阀值*/ + public static final String SET_AUTO_SCORE ="set_auto_score"; + + /**幸运号数据*/ + public static final String GET_XINGYUNHAO_INFO ="get_xingyunhao_info"; + + //旁观 + public static final String GROUP_GUEST = "set_group_guest"; + + //充值房卡 + public static final String RECHARGE_DIAMO = "recharge_diamo"; + + //推送在线玩家 + public static final String PUSH_ONLINE_MEMBER = "get_online_member"; + + //消息记录 + public static final String GET_MESSAGE = "get_messages"; + + //请求申请数量 + public static final String REQUEST_APPLY_COUNT = "request_apply_count"; + + //获取圈子详细信息 + public static final String GET_GROUP_DETAIL = "get_groupDetail"; + + + /** + * 更新分数限制天数 + */ + public static final String UPDATE_DAY_SCORE = "update_day_score"; + + /** + * 房卡记录 + */ + public static final String GET_DIAMO_MESSAGE = "get_diamo_messages"; + + +} diff --git a/web_group/src/main/java/com/group/WebInterceptor.java b/web_group/src/main/java/com/group/WebInterceptor.java new file mode 100644 index 0000000..2b6c66f --- /dev/null +++ b/web_group/src/main/java/com/group/WebInterceptor.java @@ -0,0 +1,241 @@ +package com.group; + +import com.data.bean.AccountBean; +import com.data.bean.GroupBean; +import com.data.bean.GroupMemberBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.util.ErrorCode; +import com.group.controller.GroupController; +import com.group.service.GroupRoomService; +import com.taurus.core.entity.ITObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.IController; +import com.taurus.core.routes.Interceptor; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +public class WebInterceptor implements Interceptor{ + /** + * 验证session + */ + public static final int V_SESSION = 1; + /** + * 验证圈子 + */ + public static final int V_GROUP = 2; + /** + * 验证圈主 + */ + public static final int V_GROUP_OWNER = 4; + /** + * 验证合伙人 + */ + public static final int V_GROUP_PARTNER= 8; + /** + * 验证玩法 + */ + public static final int V_GROUP_PLAY= 16; + /** + * 验证管理员 + */ + public static final int V_GROUP_MGR= 32; + /** + * 验证管理员或者合伙人 + */ + public static final int V_GROUP_MGR_OR_PARTNER= 64; + /** + * 检测玩家在不在房间 + */ + public static final int V_GROUP_CHECK_ROOM= 128; + + /** + * 验证圈主或合伙人 + */ + public static final int V_GROUP_OWNER_OR_MGR_OR_PARTNER = 256; + + private final static Logger log; + + static { + log = Logger.getLogger(GroupController.class); + } + +/** + * 拦截器方法,用于在执行动作之前验证会话和令牌的有效性 + * 此方法主要检查用户是否登录、会话是否有效、以及用户在特定组中的权限 + * + * @param action 执行的动作对象,包含动作键等信息 + * @param controller 控制器对象,用于获取会话、令牌和参数等信息 + * @param args 动作的参数列表 + * @throws Exception 如果验证失败或出现错误,则抛出异常 + */ +@Override +public void intercept(Action action, IController controller, Object... args) throws Exception { + // 将控制器对象转换为Controller类型 + Controller ctr = (Controller) controller; + + // 获取动作的验证标志 + int validate = action.getActionKeyObj().validate(); + + // 获取会话和令牌 + String session = ctr.getSession(); + String token = ctr.getTokens(); + + // 检查令牌和会话是否非空 + if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session)) + { + // 从Redis中获取与令牌关联的会话 + String token_session = Redis.use("group1_db0").hget(token, "user"); + // 如果Redis中没有与令牌关联的会话,抛出无会话异常 + if (StringUtil.isEmpty(token_session)) + { + throw new WebException(ErrorCode._NO_SESSION); + } + else { + // 如果与令牌关联的会话与当前会话不一致,抛出无会话异常 + if (!token_session.equals(session)) + { + throw new WebException(ErrorCode._NO_SESSION); + } + } + } + else { + // 如果令牌或会话为空,抛出无会话异常 + throw new WebException(ErrorCode._NO_SESSION); + } + + // 检查是否需要验证会话 + if ((validate&V_SESSION)!=0 ) { + // 如果Redis中不存在当前会话,抛出无会话异常 + if (!Redis.use("group1_db0").exists(session)) { + throw new WebException(ErrorCode._NO_SESSION); + } + // 获取会话的opt值 + String opt = Redis.use("group1_db0").hget(session, "opt"); + // 如果opt值为1,表示后台删除了签名,抛出无会话异常 + if (!StringUtil.isEmpty(opt) && Integer.parseInt(opt) == 1) { + throw new WebException(ErrorCode._NO_SESSION); + } + } + + // 检查是否需要验证组的存在性 + if((validate&V_GROUP)!=0) { + // 获取请求参数 + ITObject reqData = ctr.getParams(); + // 如果参数中没有组ID,抛出组不存在异常 + if(!reqData.containsKey("id")) { + throw new WebException(ErrorCode.GROUP_NO_EXIST); + } + // 获取组ID + int groupId = reqData.getInt("id"); + // 从缓存中获取组信息 + GroupBean gb = GroupCache.getGroup(groupId); + // 如果组信息为空,抛出组不存在异常 + if (gb == null) { + throw new WebException(ErrorCode.GROUP_NO_EXIST); + } + // 如果组服务停止,抛出组服务停止异常 + if (gb.stop == 1) { + throw new WebException(ErrorCode.GROUP_STOP_SERVICE); + } + // 获取账户信息 + AccountBean acc = AccountCache.getAccount(session); + + // 检查是否需要验证组的房间存在性 + if((validate&V_GROUP_CHECK_ROOM)!=0) { + // 检查组是否有房间,如果有,抛出组房间存在异常 + boolean checkRoom = GroupRoomService.checkRoom(groupId, acc.id); + if(checkRoom) { + throw new WebException(ErrorCode.GROUP_EXIST_ROOMS); + } + } + + // 检查是否需要验证用户是组的所有者、管理者或合作伙伴 + boolean v_o_p = (validate&V_GROUP_OWNER_OR_MGR_OR_PARTNER)!=0; + if (v_o_p) + { + // 如果当前用户不是组的所有者,检查其是否为管理者或合作伙伴 + if(gb.owner != acc.id) { + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + if (gmb==null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (gmb.lev >= 3) + { + // 如果用户不是合作伙伴,抛出不是合作伙伴异常 + if(gmb.partnerLev<=0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + } + } + } + else if((validate&V_GROUP_OWNER)!=0) { + // 如果用户不是组的成员,抛出不是成员异常 + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + // 如果需要验证用户是组的所有者,如果不是,抛出不是所有者异常 + if(gb.owner != acc.id) { + if (gmb.lev==3){ + throw new WebException(ErrorCode.GROUP_NOT_OWNER); + } + + } + } + else { + // 如果用户不是组的成员,抛出不是成员异常 + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + if (gmb==null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int count = 0; + boolean v_m_p = (validate&V_GROUP_MGR_OR_PARTNER)!=0; + + // 检查是否需要验证用户是组的合作伙伴 + if((validate&V_GROUP_PARTNER)!=0 || v_m_p) { + // 如果用户不是合作伙伴,根据验证标志决定是否抛出异常 + if(gmb.partnerLev<=0) { + if(v_m_p) { + count ++; + }else { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + } + } + + // 检查是否需要验证用户是组的管理者 + if((validate&V_GROUP_MGR)!=0 || v_m_p) { + // 如果用户是管理者,根据验证标志决定是否抛出异常 + if(gmb.lev == 3) { + if(v_m_p) { + count ++; + }else { + throw new WebException(ErrorCode.GROUP_MGR_EXIST); + } + } + } + + // 如果需要验证用户是管理者或合作伙伴,但用户不符合条件,抛出不是合作伙伴异常 + if(v_m_p && count==0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + } + + // 检查是否需要验证组的播放存在性 + if((validate&V_GROUP_PLAY)!=0) { + // 获取播放ID + int pid = reqData.getInt("pid"); + // 从缓存中获取播放信息 + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + // 如果播放信息为空,抛出播放不存在异常 + if (gpb==null) { + throw new WebException(ErrorCode.GROUP_PLAY_EXIST); + } + } + } +} + +} diff --git a/web_group/src/main/java/com/group/controller/GroupController.java b/web_group/src/main/java/com/group/controller/GroupController.java new file mode 100644 index 0000000..0a8902a --- /dev/null +++ b/web_group/src/main/java/com/group/controller/GroupController.java @@ -0,0 +1,1775 @@ +package com.group.controller; + +import com.data.bean.AccountBean; +import com.data.bean.GroupBean; +import com.data.bean.GroupMemberBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ErrorCode; +import com.group.Protocol; +import com.group.WebInterceptor; +import com.group.service.GroupLogService; +import com.group.service.GroupPublisherService; +import com.group.service.GroupRoomService; +import com.group.service.GroupService; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class GroupController extends Controller { + + private final static Logger log; + + static { + log = Logger.getLogger(GroupController.class); + } + + /** + * 获取圈子列表 + * + * @throws Exception + */ +// @ActionKey(value = Protocol.GET_GROUPS, validate = WebInterceptor.V_SESSION) + @ActionKey(value = Protocol.GET_GROUPS) + public final void getGroups() throws Exception { + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + ITArray list = GroupService.getGroups(acc.id); + ITObject resData = TObject.newInstance(); + resData.putTArray("groups", list); + + sendResponse(0, resData); + } + + // 申请数量 + @ActionKey(value = Protocol.REQUEST_APPLY_COUNT) + public final void groupMemberCount() throws Exception { + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + TArray list = GroupService.groupMemberCounts(acc.id); + ITObject resData = TObject.newInstance(); + resData.putTArray("groups", list); + sendResponse(0, resData); + } + + /** + * 获取玩家列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HP_TOTAL, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getHpTotal() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int tag = reqData.getInt("tagId"); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + ITObject resData = GroupService.getPersonHpTotal(groupId, acc.id, tag); + sendResponse(0, resData); + } + + /** + * 获取玩家列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_GROUP_MEMBERS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getMembers() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); +// boolean minus_only = reqData.getBoolean("minus_only"); +// int type = reqData.getInt("type"); + ITObject resData = GroupService.getMembers(groupId, acc.id, limit, num); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GET_MY_MEMBERS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getMembers_1() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int type = reqData.getInt("type"); // 1-我的成员 2-全部成员 + int online = reqData.getInt("online"); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + + if (tagId == 0) { + tagId = acc.id; + } + + Jedis jedis00 = Redis.use("group1_db0").getJedis(); + try { + String online1 = jedis00.hget("{user}:" + acc.id, "online"); + ITObject resData = GroupService.getMembers_1(groupId, acc.id, tagId, online1, type, limit, num); + sendResponse(0, resData); + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis00.close(); + } + + //////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////// + } + + @ActionKey(value = Protocol.GET_MEMBERS_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getMembersCount() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + //////////////////////////////////////////////////////// + ITObject resData = GroupService.getMemberCount(groupId, acc.id); + sendResponse(0, resData); + + //////////////////////////////////////////////////////// + } + + /** + * 查询成员 + * + * @throws Exception + */ + @ActionKey(value = Protocol.FIND_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void findMember() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int uid = 0; + int groupId = 0; + int tagId = 0; + int tagtype = 0; + String tagName = StringUtil.Empty; + try { + uid = AccountCache.getAccount(session).id; + groupId = reqData.getInt("id"); + tagId = reqData.containsKey("tagId") ? reqData.getInt("tagId") : 0; + tagName = reqData.containsKey("tagName") ? reqData.getUtfString("tagName") : StringUtil.Empty; + tagtype = reqData.containsKey("tagType") ? reqData.getInt("tagType") : 0; + } catch (Exception e) { + sendResponse(0, null); + return; + } + if (tagtype == 1) { + // + Integer parentid = GroupService.getParents(groupId, tagId); + ITObject resData = GroupService.findMember(groupId, parentid, parentid, parentid.toString()); + sendResponse(0, resData); + } else { + ITObject resData = GroupService.findMember(groupId, uid, tagId, tagName); + sendResponse(0, resData); + } + } + + /** + * 查询成员 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.FIND_MEMBER1, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor. + * V_GROUP_MGR_OR_PARTNER) public final void findMember1() throws Exception{ + * ITObject reqData = this.getParams(); int groupId = reqData.getInt("id"); int + * tagId = reqData.getInt("tagId"); ITObject resData = + * GroupService.findMember1(groupId,tagId); sendResponse(0, resData); } + */ + + /** + * 获取合伙人 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.GET_GROUP_PARTNERS, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor. + * V_GROUP_MGR_OR_PARTNER) public final void getPartners() throws Exception { + * ITObject reqData = this.getParams(); int groupId = reqData.getInt("id"); + * String session = this.getSession(); AccountBean acc = + * AccountCache.getAccount(session); int limit = reqData.getInt("limit"); int + * num = reqData.getInt("num"); int qid = reqData.getInt("qid"); ITObject + * resData = GroupService.getPartners(groupId,acc.id,limit,num,qid); + * sendResponse(0, resData); } + */ + + /** + * 获取成员上级合伙人列表 + * + * @throws Exception + */ + /* + * 容易被黑客关注,获取到盟主ID + * + * @ActionKey(value = Protocol.GET_MEMBER_PARENTS, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor. + * V_GROUP_MGR_OR_PARTNER) public final void getMemberParents() throws Exception + * { ITObject reqData = this.getParams(); int groupId = reqData.getInt("id"); + * int tagId = reqData.getInt("tagId"); ITArray list = + * GroupService.getMemberParents(groupId, tagId); ITObject resData = + * TObject.newInstance(); resData.putTArray("parents", list); sendResponse(0, + * resData); } + */ + + /** + * 获取邀请玩家列表 + * + * @throws Exception + */ + + @ActionKey(value = Protocol.GET_GROUP_JOINS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getGroupJoins() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + ITArray array = GroupService.getGroupJoins(groupId); + ITObject resData = new TObject(); + resData.putTArray("joins", array); + sendResponse(ErrorCode._SUCC, resData); + } + + /** + * 删除圈子 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.DEL_GROUP, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor.V_GROUP_OWNER) + * public final void delGroup() throws Exception { String session = + * this.getSession(); ITObject reqData = this.getParams(); int groupId = + * reqData.getInt("id"); AccountBean acc = AccountCache.getAccount(session); + * GroupService.delGroup(groupId,acc.id); this.sendResponse(0, null); } + */ + + /** + * 创建圈子 + * + * @throws Exception + */ + @ActionKey(value = Protocol.CREATE_GROUP, validate = WebInterceptor.V_SESSION) + public final void createGroup() throws Exception { + log.info("创建亲友圈----------------------"); + String session = this.getSession(); + ITObject reqData = this.getParams(); + String name = reqData.getString("name").trim(); + if (StringUtil.isEmpty(name)) { + throw new WebException(ErrorCode._FAILED); + } + name = StringUtil.filterEmoji(name); + if (StringUtil.isEmpty(name)) { + throw new WebException(ErrorCode._FAILED); + } + AccountBean acc = AccountCache.getAccount(session); + int type = reqData.getInt("type"); + int pay_type = reqData.getInt("pay_type"); + int num = 0; + if (reqData.containsKey("num")) { + num = reqData.getInt("num"); + } + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { +// String mng = jedis0.hget(acc.redis_key, "mng"); +// if (StringUtil.isEmpty(mng) || !mng.equals("2")) { +// throw new WebException(ErrorCode._FAILED); +// } + } catch (Exception e) { + log.info("mng error-----------" + e); + } finally { + jedis0.close(); + } + ITObject info = GroupService.createGroup(name, acc.id, type, pay_type, num, acc.nick, acc.portrait); + if (info != null) { + ITObject resData = TObject.newInstance(); + resData.putTObject("info", info); + this.sendResponse(0, resData); + } else { + throw new WebException(ErrorCode._FAILED); + } + } + + /** + * 创建圈子 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.STICK_GROUP, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP) public final void topGroup() + * throws Exception { String session = this.getSession(); ITObject reqData = + * this.getParams(); int groupId = reqData.getInt("id"); boolean top = + * reqData.getBoolean("top"); AccountBean acc = + * AccountCache.getAccount(session); int top_time + * =GroupService.topGroup(groupId, acc.id, top); + * + * ITObject resData = TObject.newInstance(); resData.putInt("top_time", + * top_time); this.sendResponse(0, resData); } + */ + + /** + * 进入圈子 + * + * @throws Exception + */ +// @ActionKey(value = Protocol.ENTER_GROUP) + @ActionKey(value = Protocol.ENTER_GROUP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void enterGroup() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + + int groupId = reqData.getInt("id"); + AccountBean acc = AccountCache.getAccount(session); + ITObject tem = GroupService.enterGroup(groupId, acc.id); + if (tem == null) { + throw new WebException(ErrorCode._FAILED); + } +// ITObject resData = TObject.newInstance(); +// resData.putString("host", tem.getString("host")); +// ITArray arr = GroupService.getPlayList(groupId); +// resData.putTArray("playList", arr); + + this.sendResponse(0, tem); + } + + /** + * 退出圈子 + * + * @throws Exception + */ + + @ActionKey(value = Protocol.EXIT_GROUP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void exitGroup() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + // 传入用户id + AccountBean acc = AccountCache.getAccount(session); + GroupBean gb = GroupCache.getGroup(groupId); + + GroupService.delMember(groupId, gb.owner, acc.id, "exit"); + + this.sendResponse(0, null); + } + + /** + * 创建圈子玩法 + * + * @throws Exception + */ + @ActionKey(value = Protocol.ADD_PLAY, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void addPlay() throws Exception { + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int hpOnOff = reqData.getInt("hpOnOff"); + int groupType = reqData.getInt("gtype"); + if (hpOnOff == 0 && groupType == 2) { + throw new WebException(ErrorCode.GROUP_TYPE2_MUST_HP); + } + int gameId = reqData.getInt("gameId"); + ITObject config = reqData.getTObject("config"); + String name = reqData.getString("name"); + int deskId = reqData.containsKey("deskId") ? reqData.getInt("deskId") : 0; + ITObject hpData = reqData.getTObject("hpData"); + ITObject obj = GroupService.addPlay(groupId, gameId, name, deskId, config, hpData, hpOnOff); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + String gameTypeString = jedis1.hget("game:" + gameId, "gameType"); + obj.putInt("gameType", Integer.parseInt(gameTypeString)); + + } finally { + jedis1.close(); + } + this.sendResponse(0, obj); + + } + + /** + * 创建圈子玩法 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_PLAY, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR | WebInterceptor.V_GROUP_PLAY) + public final void updatePlay() throws Exception { + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int groupType = reqData.getInt("gtype"); + int hpOnOff = reqData.getInt("hpOnOff"); + if (hpOnOff == 0 && groupType == 2) { + throw new WebException(ErrorCode.GROUP_TYPE2_MUST_HP); + } + int pid = reqData.getInt("pid"); + int gameId = reqData.getInt("gameId"); + ITObject config = reqData.getTObject("config"); + String name = reqData.getString("name"); + ITObject hpData = reqData.getTObject("hpData"); + int deskId = reqData.containsKey("deskId") ? reqData.getInt("deskId") : 0; + + GroupService.updatePlay(groupId, pid, gameId, name, deskId, config, hpData, hpOnOff); + int maxPlayers = config.getInt("maxPlayers"); + int maxRound = config.getInt("maxRound"); + + ITObject params = TObject.newInstance(); + params.putInt("maxPlayers", maxPlayers); + params.putInt("maxRound", maxRound); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + String gameTypeString = jedis1.hget("game:" + gameId, "gameType"); + params.putInt("gameType", Integer.parseInt(gameTypeString)); + + } finally { + jedis1.close(); + } + + this.sendResponse(0, params); + } + + /** + * 删除圈子玩法 + * + * @throws Exception + */ + @ActionKey(value = Protocol.DEL_PLAY, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER | WebInterceptor.V_GROUP_PLAY) + public final void delPlay() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + int result = GroupService.delPlay(groupId, pid); + this.sendResponse(result, null); + } + + /** + * 加入圈子 + * + * @throws Exception + */ + + @ActionKey(value = Protocol.JOIN_GROUP, validate = WebInterceptor.V_SESSION) + public final void applyGroup() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + int id = reqData.getInt("id"); + // 申请时成员所申请的备注信息 + String remark = reqData.getString("remark"); +// String remark ="成员"; + // 申请信息状态 + int ReadStatus = 1; + int result = GroupService.applyGroup(id, acc.id, remark, ReadStatus); + sendResponse(result, null); + } + + /** + * 审核加入圈子 + * + * @throws Exception + */ + + @ActionKey(value = Protocol.VERIFY_JOIN_GROUP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void verifyJoinGroup() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + int uid = acc.id; + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + boolean allow = reqData.getBoolean("allow"); + int result = GroupService.verifyJoinGroup(groupId, uid, tagId, allow, acc.nick); + if (result != 0) { + throw new WebException(result); + } + this.sendResponse(0, null); + } + + /** + * 添加成员 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_PLAYER_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getPlayerInfo() throws Exception { + ITObject reqData = this.getParams(); + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(tagId); + if (acc == null) { + sendResponse(ErrorCode._FAILED, null); + return; + } + + ITObject obj = TObject.newInstance(); + obj.putInt("uid", tagId); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + sendResponse(0, obj); + } + + /** + * 添加成员 + * + * @throws Exception + */ + @ActionKey(value = Protocol.INVITE_GROUP_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void addMember() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int result = GroupService.addMember(groupId, acc.id, tagId); + if (result != 0) { + throw new WebException(result); + } + this.sendResponse(0, null); + } + + /** + * 删除成员 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_KICK, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void delMember() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + AccountBean accs = AccountCache.getAccount(tagId); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + String outs = "kick"; + long time = System.currentTimeMillis() / 1000; + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + + GroupService.delMember(groupId, acc.id, tagId, outs); + this.sendResponse(0, null); + } finally { + jedis11.close(); + log.info("关闭db11" + Protocol.GROUP_KICK); + + } + + } + + @ActionKey(value = Protocol.GET_KICK_LOG, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getKickLog() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + + ITArray arr = GroupService.getKickLog(groupId, acc.id, limit, num); + + ITObject rspData = new TObject(); + rspData.putTArray("data", arr); + + this.sendResponse(0, rspData); + + } + + /** + * 禁止娱乐 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_BAN_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void banMember() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + int ban = reqData.getInt("ban"); + int optType = reqData.getInt("opType"); + AccountBean acc = AccountCache.getAccount(session); + GroupService.banMember(groupId, acc.id, tagId, optType, ban); + this.sendResponse(0, null); + } + + /** + * 禁止娱乐 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_BLACK_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void blackMember() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + int ban = reqData.getInt("ban"); + int ban_rate = reqData.getInt("ban_rate"); + int ban_value = reqData.getInt("ban_max_value"); + int optType = reqData.getInt("opType"); + AccountBean acc = AccountCache.getAccount(session); + GroupService.blackMember(groupId, acc.id, tagId, optType, ban, ban_rate, ban_value); + ITObject resData = TObject.newInstance(); + resData.putInt("ban", ban); + resData.putInt("playerid", acc.id); + resData.putInt("groupid", groupId); + resData.putInt("ban_rate", ban_rate); + resData.putInt("ban_max_value", ban_value); + resData.putInt("ban_value", 0); + this.sendResponse(0, resData); + } + + /** + * 禁止娱乐 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_BLACK_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void getBlackMember() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + ITObject resData = TObject.newInstance(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String black_key = jedis10.hget(gm_key, "group_black_key"); + if (StringUtil.isEmpty(black_key)) { + black_key = gm_key; + } + + String black = jedis10.hget(black_key, "black"); + String group_black = jedis10.hget(black_key, "group_black"); + + String black_rate = jedis10.hget(black_key, "group_black_rate"); + if (StringUtil.isEmpty(black_rate)) { + black_rate = "0"; + } + + String black_max_value = jedis10.hget(black_key, "group_black_max_value"); + if (StringUtil.isEmpty(black_max_value)) { + black_max_value = "0"; + } + + String black_value = jedis10.hget(black_key, "group_black_now_value"); + if (StringUtil.isEmpty(black_value)) { + black_value = "0"; + } + + resData.putInt("ban_rate", Integer.parseInt(black_rate)); + resData.putInt("ban_max_value", Integer.parseInt(black_max_value)); + resData.putInt("ban_value", Integer.parseInt(black_value)); + + if (StringUtil.isNotEmpty(black) && black.equals("0")) { + resData.putInt("black", 0); + } else if (StringUtil.isNotEmpty(black) && black.equals("1")) { + resData.putInt("black", 1); + } else if (StringUtil.isNotEmpty(black) && black.equals("2")) { + resData.putInt("black", 2); + } else { + resData.putInt("black", 0); + } + + if (StringUtil.isNotEmpty(group_black) && group_black.equals("0")) { + resData.putInt("group_black", 0); + } else if (StringUtil.isNotEmpty(group_black) && group_black.equals("1")) { + resData.putInt("group_black", 1); + } else if (StringUtil.isNotEmpty(group_black) && group_black.equals("2")) { + resData.putInt("group_black", 2); + } else { + resData.putInt("group_black", 0); + } + } finally { + jedis10.close(); + } + + resData.putInt("playerid", tagId); + resData.putInt("groupid", groupId); + this.sendResponse(0, resData); + } + + /** + * 玩法禁止娱乐 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_BAN_PLAY, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER | WebInterceptor.V_GROUP_PLAY) + public final void banPlay() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + int ban = reqData.getInt("ban"); + GroupService.banPlay(groupId, pid, ban); + this.sendResponse(0, null); + } + + /** + * 标识玩法 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_MARK_PLAY, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER | WebInterceptor.V_GROUP_PLAY) + public final void markPlay() throws Exception { + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + boolean mark = reqData.getBoolean("mark"); + int iMark = mark ? 1 : 0; + + int count = GroupService.getMarkedPlayCount(groupId); + if (iMark == 1) { + if (count >= 5) { + this.sendResponse(1, null); + return; + } + } + + GroupService.markPlay(groupId, pid, iMark); + + this.sendResponse(0, null); + } + + /** + * 更改圈子信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_UPDATE_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void updateGroupInfo() throws Exception { + ITObject reqData = this.getParams(); +// String name = reqData.getString("name").trim(); + String name = reqData.getString("name"); + if (StringUtil.isEmpty(name)) { + throw new WebException(ErrorCode._FAILED); + } + name = StringUtil.filterEmoji(name); + if (StringUtil.isEmpty(name)) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + GroupService.updateGroupInfo(groupId, name, reqData); + String wechatId = reqData.getString("wechatId"); + + if (StringUtil.isEmpty(wechatId) || wechatId == null) { + wechatId = "null"; + } +// boolean ban = reqData.getBoolean("ban"); + String notice = reqData.getString("notice"); + + String names = reqData.getString("name"); +//// boolean ban_ip = reqData.getBoolean("ban_ip"); +//// boolean ban_gps = reqData.getBoolean("ban_gps") +// int dissolve_opt = reqData.getInt("dissolve_opt"); +// int kick_opt = reqData.getInt("kick_opt"); +// int ban_apply = reqData.getInt("ban_apply"); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String keys = "group:" + groupId; + jedis11.hset(keys, "wechatId", wechatId + ""); + jedis11.hset(keys, "notice", notice); + jedis11.hset(keys, "name", names); + + } catch (Exception e) { + log.info("更新圈子信息异常"); + } finally { + jedis11.close(); + log.info("关闭db11" + Protocol.GROUP_UPDATE_INFO); + + } + + // 修改成功 对公告进行推送 + GroupPublisherService.publishNotice(groupId, notice); + + this.sendResponse(0, null); + } + + /** + * 更改圈子信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_SET_MEMBER_MGR, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void updateMgrLev() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + // 1 设置管理员 2 取消管理员 + int opt = reqData.getInt("opt"); + ITObject resData = GroupService.updateMemberMgr(groupId, tagId, opt); + this.sendResponse(0, resData); + } + + /** + * 更改圈子信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_SET_PARTNER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void setParent() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + // 1 设置管理员 2 取消管理员 +// int opt = reqData.getInt("opt"); + ITObject resData = GroupService.setParent(groupId, acc.id, tagId); + this.sendResponse(0, resData); + } + + /** + * 设置玩法奖励 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_SET_REWARD, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void setReward() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + int value = reqData.getInt("value"); + int pid = reqData.getInt("pid"); + int partnerLev = reqData.getInt("partnerLev"); + boolean all = reqData.getBoolean("all"); + int isSingle = 0; + try { + isSingle = reqData.getInt("single"); // 0:all 1:单局 + } catch (Exception e) { + + } + int result = GroupService.setReward(groupId, acc.id, tagId, partnerLev, pid, value, all, isSingle); + this.sendResponse(result, null); + } + + /** + * 设置洗牌玩法奖励 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_SET_XIPAI_REWARD, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void setXiPaiReward() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + int value = reqData.getInt("value"); + int pid = reqData.getInt("pid"); + int partnerLev = reqData.getInt("partnerLev"); + boolean all = reqData.getBoolean("all"); + int isSingle = 0; + try { + isSingle = reqData.getInt("single"); // 0:all 1:单局 + } catch (Exception e) { + + } + int result = GroupService.setXiPaiReward(groupId, acc.id, tagId, partnerLev, pid, value, all, isSingle); + this.sendResponse(result, null); + } + + /** + * 获取玩法奖励列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_REWARDS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getRewards() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); +// if(acc.id == tagId) { +// throw new WebException(ErrorCode._FAILED); +// } + + int groupId = reqData.getInt("id"); + int partnerLev = reqData.getInt("partnerLev"); + ITObject resData = TObject.newInstance(); + GroupService.getRewards(groupId, acc.id, tagId, partnerLev, resData); + + this.sendResponse(0, resData); + ; + } + + /** + * 更新我成员体力值 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_MEMBER_HP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER | WebInterceptor.V_GROUP_CHECK_ROOM) + public final void updateMemberHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int hp = 0; + try { + hp = reqData.getInt("hp"); + } catch (Exception e) { + throw new WebException(ErrorCode._FAILED); + } + if (hp == 0) { + throw new WebException(ErrorCode._FAILED); + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int tag = 0; + if (reqData.getString("tag").length() != 0) { + tag = reqData.getInt("tag"); + } + AccountBean acc = AccountCache.getAccount(session); + try { + // 正在游戏不允许下分操作 + if (hp < 0) { + if (GroupRoomService.checkRoom(groupId, acc.id)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + if (GroupRoomService.checkRoom(groupId, tag)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + } + + String uidKey = GroupMemberCache.genKey(groupId, acc.id); + long uid_hp = Long.parseLong(jedis10.hget(uidKey, "hp")); + if (uid_hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + String tagKey = GroupMemberCache.genKey(groupId, tag); + long tag_hp = Long.parseLong(jedis10.hget(tagKey, "hp")); + if (tag_hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_OTHER_HP_THAN_LIMIET); + } + + if (acc.id != tag) { + if (hp < 0) { + if ((long) uid_hp + (long) Math.abs(hp) > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + if ((long) tag_hp < Math.abs(hp)) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + } else if (hp > 0) { + if ((long) uid_hp < hp) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + + if ((long) tag_hp + (long) Math.abs(hp) > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_OTHER_HP_THAN_LIMIET); + } + } + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, acc.id); + if (mng_bean != null && mng_bean.lev == 1) { + GroupService.updateMemberHp(groupId, acc.id, acc.id, -hp, true, tag); + } + } else { + if (hp < 0) { + if ((long) uid_hp < Math.abs(hp)) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + } else if (hp > 0) { + if ((long) uid_hp + (long) Math.abs(hp) > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + } + } + } catch (Exception e) { + throw e; + } finally { + jedis10.close(); + } + + ITObject resData = GroupService.updateMemberHp(groupId, acc.id, tag, hp, false, 0); + this.sendResponse(0, resData); + } + + /** + * 更新我成员体力值 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_MEMBER_SCORE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER | WebInterceptor.V_GROUP_CHECK_ROOM) + public final void updateMemberScore() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("uid"); + + String tag = reqData.getString("tag"); + AccountBean acc = AccountCache.getAccount(session); + GroupService.updateMemberScore(groupId, acc.id, tag, tagId); + this.sendResponse(0, null); + } + + /** + * 获取聊天室信息 + * + * 该方法用于获取特定群体的聊天室信息,根据用户权限返回不同的数据 使用了@ActionKey注解来指定动作键,用于web服务的路由 + * + * @throws Exception 如果执行过程中发生错误,则抛出异常 + */ + @ActionKey(value = Protocol.GET_CHAT_ROOMS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getChatRooms() throws Exception { + // 获取请求参数 + ITObject reqData = this.getParams(); + // 获取用户会话 + String session = this.getSession(); + + // 根据会话获取用户ID + int uid = AccountCache.getAccount(session).id; + + // 获取群体ID + int groupId = reqData.getInt("id"); + + ITObject resData = GroupLogService.getRecords(uid, groupId); + sendResponse(0, resData); + + } + + /** + * 获取能量包信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.TRADE_TAKE_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER_OR_MGR_OR_PARTNER) + public final void getTakeInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + + AccountBean acc = AccountCache.getAccount(session); + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupService.getTakeInfo(groupId, acc.id, tagId); + this.sendResponse(0, resData); + } + + /** + * 提取体力值 + * + * @throws Exception + */ + @ActionKey(value = Protocol.TAKE_HP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_CHECK_ROOM | WebInterceptor.V_GROUP_OWNER_OR_MGR_OR_PARTNER) + public final void takeHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int hp = reqData.getInt("hp"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupService.takeHp(groupId, acc.id, tagId, hp); + this.sendResponse(0, resData); + } + + /** + * 盟主强行提取体力值 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_TAKE_HP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void groupTakeHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + GroupService.groupTakeHp(groupId, acc.id, tagId); + this.sendResponse(0, null); + } + + @ActionKey(value = Protocol.GET_BANK_HP, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP/* |WebInterceptor.V_GROUP_PARTNER */) + public final void getBankHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupService.getBankInfo(groupId, acc.id, tagId); + this.sendResponse(0, resData); + } + + @ActionKey(value = Protocol.TAKE_BANK_HP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_CHECK_ROOM/* |WebInterceptor.V_GROUP_PARTNER */) + public final void takeBankHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int hp = reqData.getInt("hp"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupService.takeBankHp(groupId, acc.id, tagId, hp); + this.sendResponse(0, resData); + } + + @ActionKey(value = Protocol.SAVE_BANK_HP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_CHECK_ROOM/* |WebInterceptor.V_GROUP_PARTNER */) + public final void saveBankHp() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int hp = reqData.getInt("hp"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupService.saveBankHp(groupId, acc.id, tagId, hp); + this.sendResponse(0, resData); + } + + /** + * 分配成员 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.DISTRIBUTE_MEMBER, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor.V_GROUP_MGR) + * public final void distributeMember() throws Exception { ITObject reqData = + * this.getParams(); int groupId = reqData.getInt("id"); int parId = + * reqData.getInt("parId"); int tagId = reqData.getInt("tagId"); + * GroupService.distributeMember(groupId, parId, tagId); this.sendResponse(0, + * null); } + */ + + /** + * 获取合伙人管理列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_PARTNER_INFOS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getPartnerInfos() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + + int limit = 0; + int num = 0; + + int simpleAll = reqData.getInt("simple_all"); + if (simpleAll == 0) { + limit = reqData.getInt("limit"); + num = reqData.getInt("num"); + } + + boolean diff = false; + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + if (tagId > 0) { + diff = true; + } + } catch (Exception e) { + + } + + AccountBean acc = AccountCache.getAccount(session); + if (tagId == 0) { + tagId = acc.id; + } + + ITObject resData = GroupService.getPartnerInfos(groupId, acc.id, tagId, limit, num, simpleAll, diff); + sendResponse(0, resData); + } + + /** + * 获取合伙人管理列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.QUERY_PARTNER_INFOS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void queryPartnerInfos() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + + int qid = 0; + String tagName = StringUtil.Empty; + try { + qid = reqData.getInt("qid"); + tagName = reqData.getUtfString("tagName"); + } catch (Exception e) { + sendResponse(0, null); + return; + } + + AccountBean acc = AccountCache.getAccount(session); + ITObject resData = GroupService.queryPartnerInfos(groupId, acc.id, qid, tagName); + sendResponse(0, resData); + } + + /** + * 获取合伙人管理列表 + * + * @throws Exception + */ + /* + * @ActionKey(value = Protocol.GET_PARTNER_MEMBERS, validate = + * WebInterceptor.V_SESSION|WebInterceptor.V_GROUP|WebInterceptor. + * V_GROUP_MGR_OR_PARTNER) public final void getPartnerMemebers() throws + * Exception { ITObject reqData = this.getParams(); int groupId = + * reqData.getInt("id"); int tagId = reqData.getInt("tagId"); int limit = + * reqData.getInt("limit"); int num = reqData.getInt("num"); int qid = + * reqData.getInt("qid"); ITObject resData + * =GroupService.getPartnerMemebers(groupId, tagId, limit, num,qid); + * sendResponse(0, resData); } + */ + + /** + * 设置合伙人上下分开关 + * + * @throws Exception + */ + @ActionKey(value = Protocol.SET_MGR_PERMISSION, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void setMgrPermission() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + int permission = reqData.getInt("permission"); + GroupService.setMgrPermission(groupId, tagId, permission); + sendResponse(0, null); + } + + /** + * 获取禁止同桌列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_BAN_DESK_LIST, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getBanDeskList() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int tagId = reqData.getInt("tagId"); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + ITArray arr = GroupService.getBanDeskList(groupId, acc.id, tagId); + ITObject resData = TObject.newInstance(); + resData.putTArray("ban_list", arr); + sendResponse(0, resData); + } + + /** + * 获取禁止同桌列表2 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_BAN_DESK_LIST2, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getBanDeskList2() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + ITArray arr = GroupService.getBanDeskList2(groupId, acc.id); + ITObject resData = TObject.newInstance(); + resData.putTArray("ban_list", arr); + sendResponse(0, resData); + } + + /** + * 设置禁止同桌 + * + * @throws Exception + */ + @ActionKey(value = Protocol.SET_BAN_DESK, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void setBanDesk() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int tagId = reqData.getInt("tagId"); + if (acc.id == tagId) { + throw new WebException(ErrorCode._FAILED); + } + int groupId = reqData.getInt("id"); + ITArray ban_list = reqData.getTArray("ban_list"); + ITArray del_list = reqData.getTArray("del_list"); + + GroupService.setBanDesk(groupId, acc.id, tagId, ban_list, del_list); + sendResponse(0, null); + } + + /** + * 设置禁止同桌2 亲友圈列表中的所有成员互相不能同桌 + * + * @throws Exception + */ + @ActionKey(value = Protocol.SET_BAN_DESKList, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void setBanDeskList() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int tableId = reqData.getInt("tableId"); + int groupId = reqData.getInt("id"); + String tableName = reqData.getString("tableName"); + ITArray table_list = TArray.newInstance(); + try { + table_list = reqData.getTArray("table"); + } catch (Exception e) { + + } + GroupService.setBanDeskList(groupId, acc.id, tableId, tableName, table_list); + sendResponse(0, null); + } + + /** + * 转移合伙人 + * + * @throws Exception + */ + @ActionKey(value = Protocol.MOVE_PARTNER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void movePartner() throws Exception { + ITObject reqData = this.getParams(); + int tagId = reqData.getInt("tagId"); + int parId = reqData.getInt("parId"); + int groupId = reqData.getInt("id"); + ITObject resData = GroupService.movePartner(groupId, parId, tagId); + sendResponse(0, resData); + } + + /** + * 获取邮件列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_MAIL_LIST, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getMailList() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int uid = reqData.getInt("uid"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id != uid) { + throw new WebException(ErrorCode._FAILED); + } + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + ITArray arr = GroupService.getMailList(groupId, uid, limit, num); + ITObject resData = TObject.newInstance(); + resData.putTArray("mail_list", arr); + sendResponse(0, resData); + } + + /** + * 删除所有邮件 + * + * @throws Exception + */ + @ActionKey(value = Protocol.DEL_MAIL_ALL, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void delMailAll() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int uid = reqData.getInt("uid"); + AccountBean acc = AccountCache.getAccount(session); + if (acc.id != uid) { + throw new WebException(ErrorCode._FAILED); + } + GroupService.delMailAll(groupId, uid); + sendResponse(0, null); + } + + /** + * 设置阀值 + */ + @ActionKey(value = Protocol.SET_AUTO_SCORE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void setPartenerAutoScore() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("uid"); + int score = reqData.getInt("score"); + AccountBean acc = AccountCache.getAccount(session); + int result = GroupService.setPartenerAutoScore(groupId, acc.id, tagId, score); + if (result == 0) { + this.sendResponse(-1, null); + } else { + this.sendResponse(0, null); + } + } + + @ActionKey(value = Protocol.GET_XINGYUNHAO_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void getXingyunhaoInfo() throws Exception { + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getXingYunHaoMember(groupId, limit, num, tt, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 更新默认分数 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_JOIN_SCORE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void updateJoinScore() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int playerId = reqData.getInt("playerId"); + int mj_score = reqData.getInt("mj_score"); + int pk_score = reqData.getInt("pk_score"); + AccountBean acc = AccountCache.getAccount(session); + GroupService.updateJoinScore(groupId, acc.id, mj_score, pk_score, playerId); + + this.sendResponse(0, null); + } + + /** + * 充值亲友圈房卡 + * + * @throws Exception + */ + @ActionKey(value = Protocol.ADD_GROUP_DIAMO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void addGroupDiamo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int diamo = reqData.getInt("diamo"); + int playerId = reqData.getInt("playerId"); + AccountBean acc = AccountCache.getAccount(session); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + int playerDiamo = Integer.parseInt(jedis0.hget("{user}:" + playerId, "diamo")); + if (playerDiamo < diamo) { + throw new WebException(ErrorCode.NO_DIAMO); + } + GroupService.addGroupDiamo(groupId, acc.id, diamo, playerId); + } finally { + jedis0.close(); + } + + this.sendResponse(0, null); + } + + /** + * 在线心跳 + * + * @throws Exception + */ + @ActionKey(value = Protocol.SET_GROUP_HEARTBEAT, validate = WebInterceptor.V_SESSION) + public final void setGroupHeartbeat() throws Exception { + ITObject reqData = this.getParams(); + int playerId = reqData.getInt("playerId"); + int id = reqData.getInt("id"); + + GroupService.setGroupHeartbeat(playerId, id); + this.sendResponse(0, null); + } + + @ActionKey(value = Protocol.SHOW_GROUP, validate = WebInterceptor.V_SESSION) + public final void showGroup() throws Exception { + ITObject reqData = this.getParams(); + int isShow = reqData.getInt("isShow"); + int groupId = reqData.getInt("groupId"); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + GroupMemberBean mgn = GroupCache.getMember(groupId, acc.id); + + if (mgn.lev == 3) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + try { + String key = "group:" + groupId; + jedis11.hset(key, "isShow", isShow + ""); + } catch (Exception e) { + log.error("isShow数据没存上addIsShow error", e); + } finally { + jedis11.close(); + log.info("关闭db11" + Protocol.SHOW_GROUP); + + } + sendResponse(0, null); + } + + @ActionKey(value = Protocol.GROUP_GUEST, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void groupGuest() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + int isWatch = reqData.getInt("isWatch"); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + GroupMemberBean mgn = GroupCache.getMember(groupId, acc.id); + if (mgn.lev == 3) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + try { + String key = "group:" + groupId; + jedis11.hset(key, "isWatch", isWatch + ""); + + GroupPublisherService.roomButton(groupId, String.valueOf(isWatch)); + } catch (Exception e) { + log.error("isWatch数据没存上", e); + } finally { + jedis11.close(); + log.info("关闭db11" + Protocol.GROUP_GUEST); + + } + sendResponse(0, null); + } + + @ActionKey(value = Protocol.RECHARGE_DIAMO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void rechargeDiamo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + GroupBean gb = GroupCache.getGroup(groupId); + +// if (acc.id != gb.owner) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } + + int diamo = reqData.getInt("diamo"); + if (diamo <= 0) { + throw new WebException(ErrorCode._FAILED); + } + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + try { + int userDiamo = Integer.parseInt(jedis0.hget("{user}:" + acc.id, "diamo")); + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + int lastDiamo = userDiamo - diamo; + String sql = String.format("update account set diamo=%s where id=%s", lastDiamo, acc.id); + DataBase.use().executeUpdate(sql); + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + groupId, 2, groupDiamo + diamo, diamo, System.currentTimeMillis(), 0, acc.id, gb.name, acc.nick); + DataBase.use().executeUpdate(messagesql); + + jedis0.hset("{user}:" + acc.id, "diamo", lastDiamo + ""); + jedis10.hset("g{" + groupId + "}:diamo", "diamo", groupDiamo + diamo + ""); + +// int userDiamos = Integer.parseInt(Redis.use("group1_db0").hget("{user}:" + acc.id, "diamo")); +// int groupDiamos = Integer.parseInt(Redis.use("group1_db10").hget("g{" + groupId + "}:diamo", "diamo")); + + reqData.putInt("userDiamo", lastDiamo); + reqData.putInt("groupDiamo", groupDiamo + diamo); + + } catch (Exception e) { + log.error("充值数据没存上", e); + } finally { + jedis10.close(); + jedis0.close(); + } + + sendResponse(0, reqData); + + } + + @ActionKey(value = Protocol.PUSH_ONLINE_MEMBER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public void pushOnlineMember() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + GroupPublisherService.updateOnlineUsers(groupId, acc.id); + sendResponse(0, reqData); + } + + @ActionKey(value = Protocol.GET_GROUP_DETAIL, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public void getGroupDetail() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + AccountBean acc = AccountCache.getAccount(session); + ITArray groupDetail = GroupService.getGroupDetail(groupId, acc.id); + TObject resData = TObject.newInstance(); + resData.putTArray("groupDetail", groupDetail); + sendResponse(0, resData); + } + + // 获取消息列表数据 + @ActionKey(value = Protocol.GET_MESSAGE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public void getMessage() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + AccountBean acc = AccountCache.getAccount(session); + + String sql = String.format("SELECT * FROM `message` where group_id =%s ORDER BY `message`.`m_time` ASC", + groupId); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + ITObject resData = TObject.newInstance(); + resData.putTArray("messages", arr); + sendResponse(0, resData); + } + + /** + * 更新分数限制天数 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_DAY_SCORE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void updateDayScore() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int dayType = reqData.getInt("dayType"); + GroupService.updateDayScore(groupId, dayType); + + this.sendResponse(0, null); + } + + /** + * 获取房卡消息列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_DIAMO_MESSAGE, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getDiamoMessage() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + + ITArray list = GroupService.getDiamoMessage(groupId); + ITObject resData = TObject.newInstance(); + resData.putTArray("messages", list); + sendResponse(0, resData); + } + +} \ No newline at end of file diff --git a/web_group/src/main/java/com/group/controller/GroupLogController.java b/web_group/src/main/java/com/group/controller/GroupLogController.java new file mode 100644 index 0000000..5412788 --- /dev/null +++ b/web_group/src/main/java/com/group/controller/GroupLogController.java @@ -0,0 +1,804 @@ +package com.group.controller; + +import com.data.bean.AccountBean; +import com.data.bean.GroupMemberBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.group.Protocol; +import com.group.WebInterceptor; +import com.group.service.GroupLogService; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TDataWrapper; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.web.Controller; +import com.taurus.web.WebException; +import redis.clients.jedis.Jedis; + +import java.util.List; + +public class GroupLogController extends Controller { + + /** + * 获取奖励日志 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_REWARD_LOG, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getRewardLog() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + int tagId = reqData.getInt("tagId"); + AccountBean acc = AccountCache.getAccount(session); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, acc.id); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && acc.id != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(acc.id)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + ITObject resData = GroupLogService.getRewardLog(groupId, tagId, limit, num, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取奖励统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_REWARD_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void getRewardLogCount() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + ITObject resData = GroupLogService.getRewardLogCount(groupId, pid, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取体力值管理统计数据 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_MGR, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getHpLogMgr() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + AccountBean acc = AccountCache.getAccount(session); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + // 类型 type 1上分 2下分 3合伙人上分 4合伙人下分 + int type = reqData.getInt("type"); + int qid = reqData.getInt("qid"); + String tagName = reqData.getUtfString("tagName"); + ITObject resData = GroupLogService.getHpLogMgr(groupId, acc.id, limit, num, type, qid, tagName); + sendResponse(0, resData); + } + + /** + * 获取体力值管理统计数据 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_MGR_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getHpLogMgrCount() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + ITObject resData = GroupLogService.getHpLogMgrCount(groupId); + sendResponse(0, resData); + } + + /** + * 获取体力值管理员详细信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_MGR_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getHpLogMgrInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + int groupId = reqData.getInt("id"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + // 1 管理员 2合伙人 + int type = reqData.getInt("type"); + + ITArray arr = GroupLogService.getHpLogMgrInfo(groupId, acc.id, beginTime, endTime, type); + ITObject resData = TObject.newInstance(); + resData.putTArray("infos", arr); + sendResponse(0, resData); + } + + /** + * 获取玩家体力值详细 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getHpLogInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int tagId = reqData.getInt("tagId"); + // 筛选 + int choose = reqData.getInt("choose"); + AccountBean acc = AccountCache.getAccount(session); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, acc.id); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && acc.id != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(acc.id)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + ITObject resData = GroupLogService.getHpLogInfo(groupId, tagId, limit, num, choose); + sendResponse(0, resData); + } + + /** + * 获取玩家体力值详细 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_DETAIL_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getHpLogDetailInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int groupId = reqData.getInt("id"); + int tagId = reqData.getInt("tagId"); + String roomId = reqData.getUtfString("roomId"); + int time = reqData.getInt("time"); + AccountBean acc = AccountCache.getAccount(session); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, acc.id); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && acc.id != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(acc.id)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + ITObject resData = GroupLogService.getHpLogDetailInfo(groupId, tagId, roomId, time); + sendResponse(0, resData); + } + + /** + * 获取抽水体力值详细 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_HPLOG_PUMP, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getHpLogPumpInfo() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + + ITObject resData = GroupLogService.getHpLogPumpInfo(groupId, limit, num, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取玩法局数统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_MEMBER_RANK, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getMemberRank() throws Exception { + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + + int type = 0; + if (reqData.containsKey("type")) { + try { + type = reqData.getInt("type"); + } catch (Exception e) { + + } + } + ITObject resData = GroupLogService.getMemberRank(groupId, acc.id, pid, type, limit, num, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取玩法局数统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_MEMBER_RANK_2, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getMemberRank2() throws Exception { + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + + int type = 0; + if (reqData.containsKey("type")) { + try { + type = reqData.getInt("type"); + } catch (Exception e) { + + } + } + int limitScore = reqData.getInt("limitScore"); + + int gameId = Integer.parseInt(reqData.getString("gameId")); + ITObject resData = GroupLogService.getMemberRank2(groupId, acc.id, pid, type, limit, num, beginTime, endTime, + limitScore, gameId); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_GET_MEMBER_STAT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getMemberStat() throws Exception { + + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int qid = reqData.getInt("qid"); + int partnerId = reqData.getInt("partner_id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 3) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getMemberStat(groupId, acc.id, qid, partnerId, limit, num, tt, beginTime, + endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_GET_PARTNER_STAT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getPartnerStat() throws Exception { + + ITObject reqData = this.getParams(); + + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + int groupId = reqData.getInt("id"); + + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getPartnerStat(groupId, acc.id, limit, num, tt, beginTime, endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_FIND_PARTNER_STAT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void findPartnerStat() throws Exception { + + ITObject reqData = this.getParams(); + + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + int groupId = reqData.getInt("id"); + + int tagId = reqData.getInt("tagId"); + + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.findPartnerStat(groupId, acc.id, tagId, limit, num, tt, beginTime, endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_GET_PARTNER_STAT_MEMBER, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getPartnerStatMember() throws Exception { + + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int uid = reqData.getInt("uid"); + int rootUid = reqData.getInt("root_uid"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getPartnerStatMember(groupId, uid, rootUid, limit, num, tt, beginTime, + endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_FIND_PARTNER_STAT_MEMBER, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void findPartnerStatMember() throws Exception { + + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int uid = reqData.getInt("uid"); + int rootUid = reqData.getInt("root_uid"); + int tagId = reqData.getInt("tagId"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.findPartnerStatMember(groupId, uid, rootUid, tagId, limit, num, tt, + beginTime, endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_GET_DIRECT_STAT_MEMBER, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getDirectStatMember() throws Exception { + + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int uid = reqData.getInt("uid"); + int rootUid = reqData.getInt("root_uid"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getDirectStatMember(groupId, uid, rootUid, limit, num, tt, beginTime, + endTime); + sendResponse(0, resData); + } + + @ActionKey(value = Protocol.GROUP_GET_PARTNER_STAT_PLAY, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getPartnerStatPlay() throws Exception { + + ITObject reqData = this.getParams(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + int num = reqData.getInt("num"); + int uid = reqData.getInt("uid"); + int parent_id = reqData.getInt("parent_id"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + + ITObject resData = GroupLogService.getPartnerStatPlay(groupId, uid, parent_id, limit, num, tt, beginTime, + endTime); + sendResponse(0, resData); + } + + /** + * 获取消耗统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_COST_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getCostCount() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + int uid = AccountCache.getAccount(session).id; + int groupId = reqData.getInt("id"); + int beginTime = 0; + int endTime = 0; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + beginTime = reqData.getInt("beginTime"); + endTime = reqData.getInt("endTime"); + ITObject resData = TObject.newInstance(); + resData = GroupLogService.getCostCountByGroup(groupId, uid, beginTime, endTime); + String gm_key = "g{" + groupId + "}"; + + String mj_score = jedis10.hget(gm_key + ":score", "mj_score"); + String pk_score = jedis10.hget(gm_key + ":score", "pk_score"); + resData.putInt("mj_score", mj_score == null ? 0 : Integer.parseInt(mj_score)); + resData.putInt("pk_score", pk_score == null ? 0 : Integer.parseInt(pk_score)); + +// 亲友圈开局数:g876129:round:d1756656000 +// 剩余房卡:g{876129}:diamo + sendResponse(0, resData); + + }finally { + jedis10.close(); + } + + } + + /** + * 获取消耗统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_ROUND_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getRoundCount() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + ITArray arr = GroupLogService.getRoundCount(groupId, pid); + ITObject resData = TObject.newInstance(); + resData.putTArray("rounds", arr); + sendResponse(0, resData); + } + + /** + * 获取消耗统计 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_HPCONSUME_COUNT, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getHpConsumeCount() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int tag = reqData.getInt("tagId"); + ITArray arr = GroupLogService.getHpConsumeCount(groupId, tag); + ITObject resData = TObject.newInstance(); + resData.putTArray("list", arr); + sendResponse(0, resData); + } + + /** + * 获取战绩列表 + * + * 该方法用于获取特定群体的战绩记录,可以根据平台、群体ID、记录数量等条件进行查询 主要功能包括参数获取、条件处理、调用服务获取战绩数据以及响应发送 + * + * @throws Exception 方法可能抛出异常,需要调用者处理 + */ + @ActionKey(value = Protocol.GROUP_GET_RECORDS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + ) + public final void getRecords() throws Exception { + // 获取请求参数 + ITObject reqData = this.getParams(); + + // 获取会话 + String session = this.getSession(); + + // 从会话中获取用户ID + int uid = AccountCache.getAccount(session).id; + // 获取平台信息 + String platform = reqData.getString("platform"); + // 获取群体ID + int groupId = reqData.getInt("id"); + // 获取每次查询的记录数量上限 + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + // 查询ID,用于分页或特定查询 + int qid = reqData.getInt("qid"); + // 是否包含成员信息,默认不包含 + int includeMembers = reqData.containsKey("includeMembers") ? reqData.getInt("includeMembers") : 0; + // 时间条件标志 + int tt = -1; + // 开始时间 + int beginTime = 0; + // 结束时间 + int endTime = 0; + // 处理时间条件 + if (reqData.containsKey("tt")) { + tt = reqData.getInt("tt"); + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + } + // 调用服务获取战绩数据 + ITObject resData = GroupLogService.getRecords(platform, groupId, limit, num, qid, uid, includeMembers, tt, + beginTime, endTime); + // 发送响应 + sendResponse(0, resData); + } + + /** + * 获取战绩列表 + * + * 该方法用于获取特定群体的战绩记录,可以根据平台、群体ID、记录数量等条件进行查询 主要功能包括参数获取、条件处理、调用服务获取战绩数据以及响应发送 + * + * @throws Exception 方法可能抛出异常,需要调用者处理 + */ + @ActionKey(value = Protocol.GROUP_GET_RECORDS_OWNER, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void getRecordsOwner() throws Exception { + // 获取请求参数 + ITObject reqData = this.getParams(); + + // 获取会话 + String session = this.getSession(); + + // 从会话中获取用户ID + int uid = AccountCache.getAccount(session).id; + // 获取平台信息 + String platform = reqData.getString("platform"); + // 获取群体ID + int groupId = reqData.getInt("id"); + // 获取每次查询的记录数量上限 + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + // 查询ID,用于分页或特定查询 + int qid = reqData.getInt("qid"); + // 是否包含成员信息,默认不包含 + int includeMembers = reqData.containsKey("includeMembers") ? reqData.getInt("includeMembers") : 0; + // 时间条件标志 + int tt = -1; + // 开始时间 + int beginTime = 0; + // 结束时间 + int endTime = 0; + // 处理时间条件 + if (reqData.containsKey("tt")) { + tt = reqData.getInt("tt"); + if (tt == 0) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + } + // 调用服务获取战绩数据 + ITObject resData = GroupLogService.getRecordsOwner(platform, groupId, limit, num, qid, uid, includeMembers, tt, + beginTime, endTime); + // 发送响应 + sendResponse(0, resData); + } + + + /** + * 阅读战绩列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_READ_RECORDS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void readRecords() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + ITArray militarys = reqData.getTArray("militarys"); + int setRead = reqData.getInt("is_read"); + int tagId = reqData.getInt("tagId"); + GroupLogService.readRecords(militarys, setRead,tagId); + + sendResponse(0, null); + } + + /** + * 获取战绩列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_GET_PERSON_RECORDS, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void getPersonRecords() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + + int uid = AccountCache.getAccount(session).id; + String platform = reqData.getString("platform"); + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int qid = reqData.getInt("qid"); + int tt = reqData.getInt("tt"); + int beginTime = 0; + int endTime = 0; + if (tt == 3) { + beginTime = reqData.getInt("bt"); + endTime = reqData.getInt("et"); + } + ITObject resData = GroupLogService.getPersonRecords(platform, groupId, tt, beginTime, endTime, limit, num, qid, + uid); + sendResponse(0, resData); + } + + /** + * 根据房间ID查询战绩 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_FIND_RECORD_ROOM, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR_OR_PARTNER) + public final void findRecordByRoom() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + + int uid = AccountCache.getAccount(session).id; + String platform = reqData.getString("platform"); + int groupId = reqData.getInt("id"); + String roomid = reqData.getString("roomid"); + ITArray data = GroupLogService.findRecordByRoom(platform, groupId, roomid, uid); + ITObject resData = TObject.newInstance(); + resData.putBoolean("is_rec", data != null && data.size() != 0); + if (data != null) { + resData.putTArray("rec", data); + } + sendResponse(0, resData); + } + + /** + * 获取提取体力值详细 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_TAKE_LOG, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER_OR_MGR_OR_PARTNER) + public final void getHpLogTakeInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupLogService.getHpLogTakeInfo(groupId, acc.id, tagId, limit, num, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取提取体力值详细 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_BANK_LOG, validate = WebInterceptor.V_SESSION + | WebInterceptor.V_GROUP/* |WebInterceptor.V_GROUP_PARTNER */) + public final void getHpLogTakeBankInfo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + + int groupId = reqData.getInt("id"); + int limit = reqData.getInt("limit"); + // 数量 + int num = reqData.getInt("num"); + int beginTime = reqData.getInt("beginTime"); + int endTime = reqData.getInt("endTime"); + AccountBean acc = AccountCache.getAccount(session); + int tagId = 0; + try { + tagId = reqData.getInt("tagId"); + } catch (Exception e) { + + } + if (tagId == 0) { + tagId = acc.id; + } + ITObject resData = GroupLogService.getHpLogTakeBankInfo(groupId, acc.id, tagId, limit, num, beginTime, endTime); + sendResponse(0, resData); + } + + /** + * 获取体力值统计信息 + */ + @ActionKey(value = Protocol.GET_HP_COUNT_INFO, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_MGR) + public final void getHpCountInfo() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + ITObject resData = GroupLogService.getHpCountInfo(groupId); + sendResponse(0, resData); + } +} diff --git a/web_group/src/main/java/com/group/controller/GroupRoomController.java b/web_group/src/main/java/com/group/controller/GroupRoomController.java new file mode 100644 index 0000000..fb74273 --- /dev/null +++ b/web_group/src/main/java/com/group/controller/GroupRoomController.java @@ -0,0 +1,114 @@ +package com.group.controller; + +import com.data.bean.GroupPlayBean; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.group.Protocol; +import com.group.WebInterceptor; +import com.group.service.GroupRoomService; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.web.Controller; +import com.taurus.web.WebException; +import redis.clients.jedis.Jedis; + +import java.util.Map; + +public class GroupRoomController extends Controller { + + /** + * 匹配房间 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_MATCH_ROOM, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void matchRoom() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + int pid = reqData.getInt("pid"); + String platform = reqData.getString("platform"); + String pos = reqData.getString("pos"); + boolean is_null = reqData.containsKey("is_null") ? reqData.getBoolean("is_null") : false; + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + GroupPlayBean playKey = GroupCache.getPlay(groupId, pid); + Map map = jedis11.hgetAll(playKey.redis_key); + ITObject configData = TObject.newFromJsonData(map.get("config")); + int gpsDetection = configData.getInt("GPSDetection"); + + if (gpsDetection > 0 && pos.equals("")) { + this.sendResponse(55, reqData); + } else { + ITObject resData = GroupRoomService.matchRoom(groupId, pid, session, platform, is_null, playKey.gameId); + this.sendResponse(0, resData); + + } + }finally { + jedis11.close(); + + } + + + } + + /** + * 加入房间 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_JOIN_ROOM, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void joinRoom() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String roomid = reqData.getString("room_id"); + String platform = reqData.getString("platform"); + if (reqData.getInt("pid") != null) { + int pid = reqData.getInt("pid"); + GroupPlayBean playKey = GroupCache.getPlay(groupId, pid); + ITObject resData = GroupRoomService.joinRoom(groupId, roomid, session, platform, playKey.gameId); + this.sendResponse(0, resData); + + } else { + ITObject resData = GroupRoomService.reloadJoinRoom(groupId, roomid, session, platform); + this.sendResponse(0, resData); + + } + } + + /** + * 加入房间 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GAME_JOIN_SPECTATOR, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP) + public final void joinRoomSpectator() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String roomid = reqData.getString("room_id"); + String platform = reqData.getString("platform"); + + ITObject resData = GroupRoomService.joinRoomSpectator(groupId, roomid, session, platform); + this.sendResponse(0, resData); + } + + /** + * 获取玩家列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GROUP_DEL_ROOM, validate = WebInterceptor.V_SESSION | WebInterceptor.V_GROUP + | WebInterceptor.V_GROUP_OWNER) + public final void delRoom() throws Exception { + ITObject reqData = this.getParams(); + int groupId = reqData.getInt("id"); + String roomId = reqData.getString("roomId"); + ITObject obj = GroupRoomService.delRoom(groupId, roomId); + this.sendResponse(0, obj); + } +} diff --git a/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java b/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java new file mode 100644 index 0000000..fbbcea2 --- /dev/null +++ b/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java @@ -0,0 +1,889 @@ +package com.group.job; + +import com.data.bean.*; +import com.data.cache.*; +import com.data.util.ErrorCode; +import com.data.util.EventType; +import com.data.util.Utility; +import com.google.protobuf.ByteString; +import com.group.Protocol; +import com.group.service.GroupPublisherService; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.*; +import com.taurus.web.WebException; + +import org.eclipse.jetty.util.log.Log; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.ScanParams; +import redis.clients.jedis.ScanResult; +import com.taurus.core.util.StringUtil; +import java.io.InputStream; +import java.net.URL; +import java.sql.SQLException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.*; + +public class UpdatePlayRoomJob implements Job { + + private Logger logger = Logger.getLogger(UpdatePlayRoomJob.class); + + public static final String CHANNEL_NAME = "mgr_group"; + + private static final String CMD_DEL_ROOM = "del_room"; + private static final String CMD_UPDATE_ROOM = "update_room"; + + public UpdatePlayRoomJob() { +// logger.info("定时器启动-------------------------------------"); + } + + private void cleanPlayScore() { + logger.info("重置所有用户当日积分"); + + String listSql = "select gid,uid from group_hp_log group by gid,uid"; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + + ITArray resultArray = DataBase.use().executeQueryByTArray(listSql); + if (resultArray.size() > 0) { + for (int i = 0; i < resultArray.size(); i++) { + ITObject obj = resultArray.getTObject(i); + int groupId = obj.getInt("gid"); + int uid = obj.getInt("uid"); + + String playerIdKey = "g{" + groupId + "}:" + "m" + uid; + String lost_mj_score = jedis10.hget(playerIdKey, "lost_mj_score") == null ? "0" + : jedis10.hget(playerIdKey, "lost_mj_score"); + jedis10.hset(playerIdKey, "lost_mj_score_before", lost_mj_score); + jedis10.hset(playerIdKey, "lost_mj_score", "0"); + logger.info("重置用户" + playerIdKey + "当日麻将积分:" + lost_mj_score); + String lost_pk_score = jedis10.hget(playerIdKey, "lost_pk_score") == null ? "0" + : jedis10.hget(playerIdKey, "lost_pk_score"); + jedis10.hset(playerIdKey, "lost_pk_score_before", lost_pk_score); + jedis10.hset(playerIdKey, "lost_pk_score", "0"); + logger.info("重置用户" + playerIdKey + " :" + lost_pk_score); + } + } + } catch (Exception e) { + logger.error("重置用户当日积分失败:" + e); + } finally { + jedis10.close(); + } + + } + + private void createPlayRoom(int groupId) throws Exception { + String gp_key = GroupCache.genPidsKey(groupId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + Set pids = jedis11.zrangeByScore(gp_key, 11, 11); + if (pids.size() == 0) { + return; + } + + GroupBean gb = GroupCache.getGroup(groupId); + if (gb == null) { + return; + } + + for (String str : pids) { + int pid = Integer.parseInt(str); + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + if (gpb == null) + continue; + + if (gpb.robot_room <= 0) + continue; + + Set rooms = null; + + int min_value = pid * 10000; + int max_value = pid * 10000 + 9999; + String grooms_key = GroupCache.genRoomsKey(groupId); + rooms = jedis11.zrevrangeByScore(grooms_key, max_value, min_value); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "fake", "status", "round", "id", "times", "players"); + + String fake_json = room_list.get(0); + if (fake_json == null) { + continue; + } + + String status = room_list.get(1); + if (StringUtil.isEmpty(status)) { + continue; + } + + String strRound = room_list.get(2); + if (StringUtil.isEmpty(strRound)) { + continue; + } + int round = Integer.parseInt(strRound); + + String roomId = room_list.get(3); + if (StringUtil.isEmpty(roomId)) { + continue; + } + + if (round == 0) { + roomUpdateEvent(room, groupId, roomId); + round++; + updateRound(room, groupId, roomId, round); + } + } + + if (rooms.size() >= gpb.robot_room || rooms.size() >= 20) { + continue; + } + + String exist = jedis1.get("robot_exist"); + if (StringUtil.isNotEmpty(exist)) { + createGroupRoom(groupId, pid); + } + + } + } finally { + jedis10.close(); + jedis11.close(); + jedis1.close(); + jedis0.close(); + + } + } + + private void updateBlackSpecial(int groupId) { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + Map mapString = jedis1.hgetAll("gods_special"); + if (mapString == null) + return; + + for (Map.Entry entry : mapString.entrySet()) { + String strPlayerId = entry.getKey(); + String strPlayerValue = entry.getValue(); + int playerId = Integer.parseInt(strPlayerId); + GroupMemberBean gmb = GroupCache.getMember(groupId, playerId); + if (gmb == null) + continue; + if (jedis1.sismember("gods", strPlayerId) == false) { + String gm_key = GroupMemberCache.genKey(groupId, playerId); + String black_key = jedis10.hget(gm_key, "group_black_key"); + if (StringUtil.isEmpty(black_key)) { + return; + } + String strblack = jedis10.hget(black_key, "black"); + int black = 0; + if (StringUtil.isNotEmpty(strblack)) { + try { + black = Integer.parseInt(strblack); + if (black == 0) { + jedis1.sadd("gods", strPlayerId); + String StrWhiteValue = jedis1.hget("gods_value", strPlayerId); + if (StringUtil.isEmpty(StrWhiteValue)) { + jedis1.hset("gods_value", strPlayerId, strPlayerValue); + } + } + } catch (NumberFormatException e) { + black = 0; + } + } + } + } + } finally { + jedis1.close(); + jedis10.close(); + } + + } + + private void updatePlayRoom(int groupId) { + String gp_key = GroupCache.genPidsKey(groupId); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + try { + Set pids = jedis11.zrangeByScore(gp_key, 11, 11); + if (pids.size() == 0) { + return; + } + + GroupBean gb = GroupCache.getGroup(groupId); + if (gb == null) { + return; + } + + for (String str : pids) { + int pid = Integer.parseInt(str); + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + if (gpb == null) + continue; + + if (gpb.robot_room <= 0) + continue; + + Set rooms = null; + int min_value = pid * 10000; + int max_value = pid * 10000 + 9999; + String grooms_key = GroupCache.genRoomsKey(groupId); + rooms = jedis11.zrevrangeByScore(grooms_key, max_value, min_value); + long time = System.currentTimeMillis() / 1000; + for (String room : rooms) { + List room_list = jedis10.hmget(room, "fake", "status", "round", "id", "times", "players", + "create_time", "fake_existTime"); + + String fake_json = room_list.get(0); + if (fake_json == null) { + continue; + } + + String status = room_list.get(1); + if (StringUtil.isEmpty(status)) { + continue; + } + + String strRound = room_list.get(2); + if (StringUtil.isEmpty(strRound)) { + continue; + } + int round = Integer.parseInt(strRound); + + String roomId = room_list.get(3); + if (StringUtil.isEmpty(roomId)) { + continue; + } + + String maxStrRound = (room_list.get(4)); + if (StringUtil.isEmpty(maxStrRound)) { + continue; + } + + int maxRound = Integer.parseInt(maxStrRound); + if (round == 0) { + roomUpdateEvent(room, groupId, roomId); + round++; + updateRound(room, groupId, roomId, round); + continue; + } + + Long createTime = Long.parseLong(room_list.get(6)); + Long useTime = time - createTime; + + String str_fake_existTime = room_list.get(7); + int fake_existTime = 30; + if (!StringUtil.isEmpty(str_fake_existTime)) { + fake_existTime = Integer.parseInt(str_fake_existTime); + } + + if (fake_existTime * round >= useTime) { + continue; + } + + boolean exitGame = false; + ITArray players = TArray.newFromJsonData(room_list.get(5)); + if (round >= 1) { + int fake_hp = (int) (Math.random() * 100000); + int rate = (int) (Math.random() * 100); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (i % 2 == 0) { + if (rate < 50) { + jedis10.hincrBy("fake_" + player_id, "fake_hp", fake_hp); + } else { + jedis10.hincrBy("fake_" + player_id, "fake_hp", -fake_hp); + } + } else { + if (rate < 50) { + jedis10.hincrBy("fake_" + player_id, "fake_hp", -fake_hp); + } else { + jedis10.hincrBy("fake_" + player_id, "fake_hp", fake_hp); + } + } + String fakeHp = jedis10.hget("fake_" + player_id, "fake_hp"); + if (!StringUtil.isEmpty(fakeHp)) { + long curFakeHp = Long.parseLong(fakeHp); + if (curFakeHp <= 1000) { + curFakeHp = (long) (Math.random() * 10000000); + jedis10.hset("fake_" + player_id, "fake_hp", Long.toString(curFakeHp)); + exitGame = true; + break; + } + } + } + } + + round++; + + if (round > maxRound || exitGame) { + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + jedis1.srem("used_robot", Integer.toString(player_id)); + jedis1.sadd("free_robot", Integer.toString(player_id)); + } + GroupPublisherService.delRoomEvt(groupId, roomId); + jedis1.zrem(grooms_key, room); + jedis0.hset(room, "status", 3 + ""); + jedis0.hincrBy(room, "cache_ver", 1); + jedis0.expire(room, 20); + logger.error( + "del robot room:" + roomId + " player:" + room_list.get(5) + " fake_json:" + fake_json); + continue; + } + updateRound(room, groupId, roomId, round); + } + + } + } finally { + jedis10.close(); + jedis1.close(); + jedis11.close(); + jedis0.close(); + + } + } + + /** 解散时间 */ + private static final String[] DISMISS_TIME = { "30", "60", "90", "180" }; + /** 踢出时间 */ + private static final String[] KICK_TIME = { "30", "60", "120", "180" }; + + private String createGroupRoom(int groupId, int pid) throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + if (gpb == null) { + throw new WebException(ErrorCode.GROUP_PLAY_EXIST); + } + + int gameId = gpb.gameId; + GameBean gb = GameCache.getGame(gameId); + + String grooms_key = GroupCache.genRoomsKey(groupId); + GroupBean group = GroupCache.getGroup(groupId); + ITObject configData = TObject.newFromJsonData(gpb.config); + int maxPlayers = gpb.maxPlayers; + + int opt = configData.getInt("opt"); + String owner_session = AccountCache.genKey(group.owner); + + int dissolve_opt = group.dissolve_opt; + int kick_opt = group.kick_opt; + + String newRoomId = jedis1.rpop("free_room"); + jedis1.lpush("free_room", newRoomId); + String room_key = "room:" + newRoomId; + + long time = System.currentTimeMillis() / 1000; + Map roomMap = new HashMap(); + /** + * 玩家列表Seat映射 + */ + + roomMap.put("id", newRoomId); + roomMap.put("owner", owner_session); + roomMap.put("AA", "0"); + roomMap.put("agent", "1"); + roomMap.put("group", groupId + ""); + roomMap.put("gpid", pid + ""); + roomMap.put("payer", group.owner + ""); + roomMap.put("maxPlayers", maxPlayers + ""); + roomMap.put("times", gb.opt.get(opt) + ""); + roomMap.put("opt", opt + ""); + roomMap.put("status", "0"); + roomMap.put("fake", "1"); + int fake_existTime = (int) ((Math.random() + 0.5) * 40); + roomMap.put("fake_existTime", fake_existTime + ""); + + roomMap.put("hpOnOff", gpb.hpOnOff + ""); + roomMap.put("rewardType", gpb.rewardType + ""); + roomMap.put("rewardValueType", gpb.rewardValueType + ""); + roomMap.put("xipai_rewardType", gpb.xipai_rewardType + ""); + roomMap.put("xipai_rewardValueType", gpb.xipai_rewardValueType + ""); + roomMap.put("dismiss_time", DISMISS_TIME[dissolve_opt - 1]); + roomMap.put("kick_time", KICK_TIME[kick_opt - 1]); + roomMap.put("hp_times", gpb.hp_times + ""); + if (gpb.hpOnOff == 1) { + ITObject hpObj = TObject.newFromJsonData(gpb.hpConfig); + if (hpObj.getInt("limitInRoom") != null) { + roomMap.put("limitInRoom", hpObj.getInt("limitInRoom") + ""); + } + configData.putTObject("hpData", hpObj); + } + + configData.del("opt"); + configData.del("AA"); + roomMap.put("options", configData.toJson()); + roomMap.put("game", gameId + ""); + roomMap.put("open", "1"); + roomMap.put("round", "0"); + roomMap.put("create_time", time + ""); + roomMap.put("cache_ver", "1"); + + String exist = jedis1.get("robot_exist"); + if (StringUtil.isNotEmpty(exist)) { + jedis0.hmset(room_key, roomMap); + + /** + * pid open status 剩余空位 11 1 1 00 + */ + jedis11.zadd(grooms_key, pid * 10000 + 1101, room_key); + GroupPublisherService.addRoomEvt(groupId, newRoomId); + updateRedisMap(groupId, newRoomId, room_key, roomMap, maxPlayers); + return room_key; + } + return null; + } finally { + jedis0.close(); + jedis1.close(); + jedis11.close(); + + } + } + + /** + * 更新redis回合 + */ + private void updateRound(String roomKey, int groupId, String roomid, int round) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + jedis0.hset(roomKey, "round", Integer.toString(round)); + jedis0.close(); + roomUpdateEvent(roomKey, groupId, roomid); + } + + /** + * list to TArray + * + * @param list + * @return + */ + public static final ITArray toTArray(List list) { + ITArray result = new TArray(); + for (Integer card : list) { + result.addInt(card); + } + return result; + } + + /** + * 更新房间redis数据 + */ + public void updateRedisMap(int groupId, String roomId, String roomKey, Map redis_room_map, + int maxPlayers) { + Map playerMapBySeat = new HashMap(); + for (int i = 1; i <= maxPlayers; i++) { + playerMapBySeat.put(i, getRobot(maxPlayers)); + } + + Iterator> it = playerMapBySeat.entrySet().iterator(); + List seat_list = new ArrayList<>(); + List player_list = new ArrayList<>(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + seat_list.add(entry.getKey()); + player_list.add(entry.getValue()); + } + redis_room_map.put("players", toTArray(player_list).toJson()); + redis_room_map.put("seats", toTArray(seat_list).toJson()); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + jedis0.hmset(roomKey, redis_room_map); + jedis0.close(); + updateRound(roomKey, groupId, roomId, 0); + } + + /** + * 玩家加入房间刷新总服圈子缓存 + */ + public void roomUpdateEvent(String roomKey, int groupId, String roomid) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + jedis0.hincrBy(roomKey, "cache_ver", 1); + updateRoomEvt(groupId, roomid); + jedis0.close(); + } + + /** + * 更新房间事件 + * + * @param groupId + * @param roomid + */ + public void updateRoomEvt(int groupId, String roomid) { + if (groupId == 0) + return; + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putUtfString("roomid", roomid); + data.putUtfString("cmd", CMD_UPDATE_ROOM); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + + } + + @Override + public void execute(JobExecutionContext context) { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + JobKey jobKey = context.getJobDetail().getKey(); + if (jobKey.getName().equals("update_play_room")) { + Set robotGroup = jedis1.smembers("robot_group"); + for (String strGroupId : robotGroup) { + updatePlayRoom(Integer.parseInt(strGroupId)); + updateBlackSpecial(Integer.parseInt(strGroupId)); + } + } else if (jobKey.getName().equals("create_play_room")) { + // logger.info("执行成功" + jobKey.getName()); + Set robotGroup = jedis1.smembers("robot_group"); + for (String strGroupId : robotGroup) { + try { + createPlayRoom(Integer.parseInt(strGroupId)); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } else if (jobKey.getName().equals("clean_play_score")) { + cleanPlayScore(); + } else if (jobKey.getName().equals("del_room")) { + delRoom(); + } + jedis1.close(); + } + + private void delRoom() { +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// Set roomKeys = jedis0.keys("room:*"); +// try { +// for (String roomKey : roomKeys) { +// long time = Long.parseLong(jedis0.hget(roomKey, "create_time")); +// +// if (jedis0.hget(roomKey, "players") == null && time - 3000 > System.currentTimeMillis() / 1000) { +// jedis0.del(roomKey); +// } +// String players = jedis0.hget(roomKey, "players"); +// if (players.length() == 0 && time - 3000 > System.currentTimeMillis() / 1000) { +// logger.info("删除房间:" + roomKey); +// +// jedis0.del(roomKey); +// } +// +// } +// +// } finally { +// jedis0.close(); +// } + } + + public int getRobot(int maxPlayers) { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + long freeRobotNum = jedis1.scard("free_robot"); + if (freeRobotNum < maxPlayers) { + long useRobotNum = jedis1.scard("used_robot"); + if (useRobotNum >= 100) { + logger.warn("robot not enough, cur used robot " + useRobotNum); + } + try { + createRobot(); + freeRobotNum = jedis1.scard("free_robot"); + if (freeRobotNum < maxPlayers) { + logger.error("create robot failed............"); + return 0; + } + + } catch (Exception e) { + logger.error(e); + } + } + + try { + while (freeRobotNum > 0) { + String strRobotId = jedis1.spop("free_robot"); + freeRobotNum = jedis1.scard("free_robot"); + if (StringUtil.isEmpty(strRobotId)) { + createRobot(); + continue; + } else { + AccountBean acc_bean = AccountCache.getAccount(Integer.parseInt(strRobotId)); + if (acc_bean != null) { + URL url = null; + try { + url = new URL(acc_bean.portrait); + InputStream in = url.openStream(); + String jsonStr = inputStreamToString(in); + String md5 = MD5.getInstance().getHash(jsonStr); + if (md5.equals("787d66f3fdfa8df70795629c62a3a850") + || md5.equals("f1fce77813a0fc9660c76d523813bb59") + || md5.equals("d629ac346299c2640dfb6e8fd4232646") + || md5.equals("1e76068afc60d7dcff851936b3c2b24b")) { + url = null; + } + } catch (Exception e1) { + url = null; + } + if (url == null) { + logger.error("robot head error, this robot:" + strRobotId + " will not use"); + continue; + } + } else { + continue; + } + } + + jedis1.sadd("used_robot", strRobotId); + int robotId = Integer.parseInt(strRobotId); + String fakeHp = jedis10.hget("fake_" + strRobotId, "fake_hp"); + if (StringUtil.isEmpty(fakeHp)) { + int fake_hp = (int) (Math.random() * 10000000); + jedis10.hset("fake_" + strRobotId, "fake_hp", Integer.toString(fake_hp)); + } + return robotId; + } + } catch (Exception e) { + logger.error(e); + } + jedis1.close(); + jedis10.close(); + return 0; + } + + /** + * 登录 + * + * @throws Exception + */ + public final void createRobot() throws Exception { + int num = 100; + int mng = 9999; + + String listSql = "select * from old_account"; + ITArray resultArray = DataBase.use().executeQueryByTArray(listSql); + ArrayList nameList = new ArrayList<>(); + ArrayList headList = new ArrayList<>(); + for (int i = 0; i < resultArray.size(); i++) { + ITObject userData = resultArray.getTObject(i); + String nick = userData.getUtfString("nick"); + nameList.add(nick); + String head = userData.getUtfString("portrait"); + headList.add(head); + } + + Math.random(); + Collections.shuffle(nameList); + Collections.shuffle(headList); + + for (int i = 0; i < num; i++) { + String sql = ""; + int accountid = create_register(mng, "xx123456xx", nameList, headList); + AccountBean acc_bean = AccountCache.getAccount(accountid); + if (acc_bean == null) { + sql = String.format("SELECT * FROM account WHERE id ='%d'", accountid); + + ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql); + if (resultArray2.size() == 0) { + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = resultArray2.getTObject(0); + UpdateUserData(userData, accountid); + + acc_bean = AccountCache.getAccount(accountid); + } + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + jedis1.sadd("free_robot", Integer.toString(acc_bean.id)); + int fake_hp = (int) (Math.random() * 10000000); + jedis10.hset("fake_" + acc_bean.id, "fake_hp", Integer.toString(fake_hp)); + jedis1.close(); + jedis10.close(); + } + } + + /** + * + * @return + * @throws Exception + */ + private final int UpdateUserData(ITObject reqData, long id) throws Exception { + ITObject userData = TObject.newInstance(); + userData.putInt("id", (int) id); + + userData.putUtfString("acc", reqData.getUtfString("acc")); + userData.putUtfString("portrait", reqData.getUtfString("portrait")); + userData.putUtfString("nick", reqData.getUtfString("nick")); + int sex = reqData.getInt("sex"); + if (sex == 0) { + sex = 1; + reqData.putInt("sex", sex); + } + userData.putInt("sex", sex); + + userData.putInt("mng", 0); + userData.putInt("type", 0); + if (reqData.containsKey("diamo")) { + userData.putInt("diamo", reqData.getInt("diamo")); + } + + userData.putInt("invitation", 1); + updateSession(userData, (int) id); + return (int) id; + } + + private static String updateSession(ITObject userData, int id) { + String session = AccountCache.genKey(id); + Map map = new HashMap(); + Utils.objectToMap(userData, map); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hmset(session, map); + BaseCache.updateCacheVer(jedis0, session); + } finally { + jedis0.close(); + } + + return session; + } + + /** + * + * @description: 将输入流转换成字符串 + * @author: Jeff + * @date: 2019年12月15日 + * @param inputStream 输入流 + * @return + */ + private static String inputStreamToString(InputStream inputStream) { + StringBuffer buffer = new StringBuffer(); + InputStreamReader inputStreamReader; + try { + inputStreamReader = new InputStreamReader(inputStream, "utf-8"); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + String str = null; + while ((str = bufferedReader.readLine()) != null) { + buffer.append(str); + } + // 释放资源 + bufferedReader.close(); + inputStreamReader.close(); + inputStream.close(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return buffer.toString(); + } + + private final int create_register(int mng, String password, ArrayList nickList, ArrayList headList) + throws Exception { + int count = 0; + long id = 0; + ArrayList list = new ArrayList<>(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + for (int i = 0; i < 10; i++) { + String strId = jedis1.rpop("free_account"); + if (StringUtil.isEmpty(strId)) { + break; + } + list.add(strId); + } + + Collections.shuffle(list); + + do { + id = Long.parseLong(list.remove(0)); + String sql = "SELECT id FROM account WHERE id =" + id; + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + if (resultArray.size() == 0) { + break; + } + } while (count++ <= 10); + + for (int i = 0; i < list.size(); i++) { + jedis1.lpush("free_account", list.get(i)); + } + + if (id == 0) { + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = TObject.newInstance(); + userData.putInt("id", (int) id); + + userData.putUtfString("acc", "" + id); + userData.putUtfString("portrait", ""); + while (headList.size() > 0) { + String head = null; + try { + head = headList.remove(0); + URL url = new URL(head); + InputStream in = url.openStream(); + String jsonStr = inputStreamToString(in); + String md5 = MD5.getInstance().getHash(jsonStr); + if (md5.equals("787d66f3fdfa8df70795629c62a3a850") || md5.equals("f1fce77813a0fc9660c76d523813bb59") + || md5.equals("d629ac346299c2640dfb6e8fd4232646") + || md5.equals("1e76068afc60d7dcff851936b3c2b24b")) { + head = null; + } + } catch (Exception e1) { + head = null; + } + if (head != null) { + userData.putUtfString("portrait", head); // 头像 + break; + } + } + + String nick = ""; + if (nickList.size() > 0) { + nick = nickList.remove(0); + } + nick = nick.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", " "); + userData.putUtfString("nick", nick); + int sex = 1; + if (sex == 0) { + sex = 1; + } + userData.putInt("sex", sex); + userData.putInt("diamo", 0); + userData.putInt("mng", 0); + userData.putInt("regTime", mng); + userData.putInt("type", 0); + userData.putUtfString("password", Utils.getMD5Hash(password)); + long reg_time = System.currentTimeMillis() / 1000; + userData.putLong("reg_time", reg_time); + int result = DataBase.use().insert("account", userData); + if (result == -1) { + throw new WebException(ErrorCode._FAILED); + } + userData.putInt("invitation", 1); + String session = updateSession(userData, (int) id); + jedis1.close(); + return (int) id; + } +} diff --git a/web_group/src/main/java/com/group/service/GroupLogService.java b/web_group/src/main/java/com/group/service/GroupLogService.java new file mode 100644 index 0000000..17d1dc3 --- /dev/null +++ b/web_group/src/main/java/com/group/service/GroupLogService.java @@ -0,0 +1,2722 @@ +package com.group.service; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.data.bean.AccountBean; +import com.data.bean.GroupBean; +import com.data.bean.GroupMemberBean; +import com.data.cache.AccountCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ConsumeCode; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class GroupLogService { + + private static final Logger log = Logger.getLogger(GroupLogService.class); + // 体力值变化 + private static final int CHOOSE_CHAGE = 1; + // 操作上分 + private static final int CHOOSE_UPPER = 2; + // 操作下分 + private static final int CHOOSE_SUB = 4; + // 抽水 + private static final int CHOOSE_PUMP = 8; + // 奖励 + private static final int CHOOSE_RWARD = 16; + // 转账 + private static final int CHOOSE_TRADE = 32; + // 提取 + private static final int CHOOSE_TAKE_REWARD = 64; + // 洗牌 + private static final int CHOOSE_XIPAI = 128; + /** + * 上下分记录类型 + */ + private static final int[] MGRLOG_TYPE = { ConsumeCode.HP_MGR_UPPER, ConsumeCode.HP_MGR_SUB, + ConsumeCode.HP_PARTNER_UPPER, ConsumeCode.HP_PARTNER_SUB }; + + /** + * 获取成员排行 + * + * @param groupId + * @param pid + * @param limit + * @param num + * @param beginTime + * @param endTime + * @return + * @throws Exception + */ + public static final ITObject getMemberRank(int groupId, int uid, int pid, int type, int limit, int num, + int beginTime, int endTime) throws Exception { + ITObject obj1 = TObject.newInstance(); + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + int mgn_partner = mng_bean.partnerLev; + int mgn_lev = mng_bean.lev; +// if (mgn_lev == 1 && mgn_partner == 0) { + String sql = String.format( + "SELECT uid,SUM(win) AS win,SUM(round) as round,SUM(score) as score FROM group_member_log WHERE groupId = %s ", + groupId); + if (pid > 0) { + sql = sql + " AND pid =" + pid; + } + + if (type == 0) { + sql = sql + String.format(" AND time >=%s AND time <%s GROUP BY uid ORDER BY round DESC limit %s,%s", + beginTime, endTime, limit, num); + } else if (type == 1) { + sql = sql + String.format(" AND time >=%s AND time <%s GROUP BY uid ORDER BY score DESC limit %s,%s", + beginTime, endTime, limit, num); + } + + ITArray arr = DataBase.use().executeQueryByTArray(sql); + log.info("战绩记录-----" + sql); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + } + obj1.putTArray("ranks", arr); + String sql2 = String.format( + "select count(uid) as num from group_member_log where groupId = %s and round > 0 and time >=%s AND time <%s ", + groupId, beginTime, endTime); + + int allActiveNum = 0; + ITArray arr2 = DataBase.use().executeQueryByTArray(sql2); + if (arr2.size() > 0) { + ITObject obj = arr2.getTObject(0); + allActiveNum = obj.getLong("num").intValue(); + } + obj1.putInt("allActiveNum", allActiveNum); +// } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + obj1.putInt("pk_score", Integer.parseInt(jedis11.hget("group:" + groupId, "pk_score"))); + obj1.putInt("mj_score", Integer.parseInt(jedis11.hget("group:" + groupId, "mj_score"))); + obj1.putInt("limit", limit); + jedis11.close(); + return obj1; + } + + /** + * 获取成员排行 + * + * @param groupId + * @param pid + * @param limit + * @param num + * @param beginTime + * @param endTime + * @return + * @throws Exception + */ + public static final ITObject getMemberRank2(int groupId, int uid, int pid, int type, int limit, int num, + int beginTime, int endTime, int limitScore, int gameId) throws Exception { + ITObject obj1 = TObject.newInstance(); + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + String orderBySql = ""; + if (limitScore == 0) { + orderBySql = "order by score desc"; + } else { + orderBySql = "order by score asc"; + } + String gameIdSql = ""; + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + try { + List gamePids = new ArrayList(); + Set gameIds = new HashSet(); + + if (gameId == 0) { + String gpids_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gpids_key, 10, 99999); + String key = "g{" + groupId + "}:play:"; + for (String tem : pids) { + String gkey = key + tem; + String gameKey = "game:" + jedis11.hget(gkey, "gameId"); + if (jedis1.hget(gameKey, "gameType") != null) { + int gameType = Integer.parseInt(jedis1.hget(gameKey, "gameType")); + if (gameType == 2) { + gameIds.add(jedis11.hget(gkey, "gameId")); + gamePids.add(tem); + + } + + } + } +// gameIds+=")"; + + if (gamePids.size() > 0) { + gameIdSql = "and pid in(" + gamePids.toString().replace("[", "").replace("]", "") + ")"; + } else { + gameIdSql = "and pid =0"; + + } + } else if (gameId == 1) { + String gpids_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gpids_key, 10, 99999); + String key = "g{" + groupId + "}:play:"; + for (String tem : pids) { + String gkey = key + tem; + String gameKey = "game:" + jedis11.hget(gkey, "gameId"); + if (jedis1.hget(gameKey, "gameType") != null) { + int gameType = Integer.parseInt(jedis1.hget(gameKey, "gameType")); + if (gameType == 1) { + gameIds.add(jedis11.hget(gkey, "gameId")); + gamePids.add(tem); + + } + + } + } +// gameIds+=")"; + + if (gamePids.size() > 0) { + gameIdSql = "and pid in(" + gamePids.toString().replace("[", "").replace("]", "") + ")"; + } else { + gameIdSql = "and pid =0"; + } + } else { + String gpids_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gpids_key, 10, 99999); + String key = "g{" + groupId + "}:play:"; + for (String tem : pids) { + String gkey = key + tem; + String gameKey = "game:" + gameId; + if (jedis1.hget(gameKey, "gameType") != null && jedis11.hget(gkey, "gameId") != null) { + if (gameId == Integer.parseInt(jedis11.hget(gkey, "gameId"))) { + gameIds.add(jedis11.hget(gkey, "gameId")); + + gamePids.add(tem); + } + } + } +// gameIds+=")"; + + if (gamePids.size() > 0) { + gameIdSql = "and pid in(" + gamePids.toString().replace("[", "").replace("]", "") + ")"; + } else { + gameIdSql = "and pid =0"; + } + } + log.info("gamePids:" + gamePids); + log.info("gameIds:" + gameIds); + +// log.info("gameIdSql:" + gameIdSql); + + int mgn_partner = mng_bean.partnerLev; + int mgn_lev = mng_bean.lev; + String sql = String.format( + "SELECT uid,ifnull(sum(hp),0) score,count(id) round, COUNT(CASE WHEN hp > 0 THEN 1 END) AS win FROM group_hp_log WHERE gid = %s ", + groupId); +// String sql = String.format( +// "SELECT uid,SUM(win) AS win,SUM(round) as round,SUM(score) as score FROM group_member_log WHERE groupId = %s ", +// groupId); + +// if (pid > 0) { +// sql = sql + " AND pid =" + pid; +// } + sql = sql + gameIdSql; +// log.info("sql:" + sql); + + if (type == 0) { + sql = sql + String.format(" AND time >=%s AND time <%s GROUP BY uid " + orderBySql + " limit %s,%s", + beginTime, endTime, limit, num); +// ," + orderBySql + " + } else if (type == 1) { + sql = sql + String.format(" AND time >=%s AND time <%s GROUP BY uid " + orderBySql + " limit %s,%s", + beginTime, endTime, limit, num); + } + log.info("sql:" + sql); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + // 构造完整的SQL查询语句 + String readsql = String.format( + "select rec_key from room_rec_log where uid=%s AND time >=%s AND time <%s and gid = %s", acc.id, + beginTime, endTime, groupId); + + // 执行SQL查询,获取战绩记录的列表 + ITArray list = DataBase.use().executeQueryByTArray(readsql); +// log.info("已读战绩记录-----" + readsql); +// log.info("已读战绩记录list-----" + list.size()); + Double readScore = new Double(0); + + // 如果查询到战绩记录,则进一步获取详细的战绩信息 + if (list.size() > 0) { + for (int j = 0; j < list.size(); ++j) { + ITObject tem = list.getTObject(j); + String rec_key = tem.getString("rec_key"); + // 根据战绩记录的key获取详细的战绩信息,并添加到战绩列表中 +// log.info("rec_key:"+rec_key); + ITObject readobj = Utility.getMilitaryList(jedis5, rec_key, ""); +// log.info("rec_key--" + "---uid:" + acc.id + "------" + readobj); + + if (readobj == null ) { + continue; + } + if (readobj.getString("is_read_" + acc.id) == null ) { + continue; + } + if(readobj.getString("is_read_" + acc.id).equals("0")) { + continue; + } + readobj.putString("is_read", readobj.getString("is_read_" + acc.id)); + + ITArray players = TArray.newFromJsonData(readobj.getString("totalScore")); + String game_id = readobj.getString("game_id"); + + for (int k = 0; k < players.size(); k++) { + ITObject player = players.getTObject(k); + int playerId = player.getInt("accId"); + + if (acc.id != playerId) { + continue; + } + for (String item : gameIds) { + if (game_id.equals(item)) { + log.info("game_id--" + gameId + "--------score:" + player.getInt("score")); + readScore += player.getInt("score"); + } + } + +// log.info(acc.id+"-----"+playerId); + +// log.info(acc.id+"-readScore-----"+readScore); + + } + } + + obj.putDouble("score", obj.getDouble("score") - readScore); + } + } + + obj1.putTArray("ranks", arr); + String sql2 = String.format( + "select count(uid) as num from group_member_log where groupId = %s and round > 0 and time >=%s AND time <%s ", + groupId, beginTime, endTime); + + int allActiveNum = 0; + ITArray arr2 = DataBase.use().executeQueryByTArray(sql2); + if (arr2.size() > 0) { + ITObject obj = arr2.getTObject(0); + allActiveNum = obj.getLong("num").intValue(); + } + obj1.putInt("allActiveNum", allActiveNum); + + obj1.putInt("pk_score", Integer.parseInt(jedis10.hget("g{" + groupId + "}:score", "pk_score"))); + obj1.putInt("mj_score", Integer.parseInt(jedis10.hget("g{" + groupId + "}:score", "mj_score"))); + obj1.putInt("limit", limit); + }finally { + jedis10.close(); + jedis11.close(); + jedis5.close(); + jedis1.close(); + + } + + + return obj1; + } + + /** + * 获取战绩列表 + * + * @param platform + * @param groupId + * @param limit + * @param num + * @return + */ + public static ITObject getPersonRecords(String platform, int groupId, int timeType, int beginTime, int endTime, + int limit, int num, int qid, int uid) throws Exception { + String qid_sql = StringUtil.Empty; + qid_sql = "and uid=" + qid; + + ITArray militaryList = TArray.newInstance(); + + ITObject obj1 = TObject.newInstance(); + if (timeType == 0) { + + beginTime = DateUtils.getBeginDay(); + endTime = DateUtils.getBeginDay() + 3600 * 24; + } else if (timeType == 1) { + + beginTime = DateUtils.getBeginDay() - 3600 * 24; + endTime = DateUtils.getBeginDay(); + } else if (timeType == 2) { + + beginTime = DateUtils.getBeginDay() - 3600 * 48; + endTime = DateUtils.getBeginDay() - 3600 * 24; + } + + int total = 0; + int consume = 0; + + String where = String.format("gid=%s and time>=%s and time<=%s", groupId, beginTime, endTime); + if (limit == 0) { + + String count_sql = String.format("SELECT count(*) AS total FROM room_rec_log where %s %s", where, qid_sql); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + total = obj.getLong("total").intValue(); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + String key = String.format("g%s:m%s:consume_hp", groupId, uid); + if (timeType >= 0 && timeType <= 2) { + + String hp_key = String.format("%s:d%s", key, beginTime); + String r_str = jedis9.get(hp_key); + int r_num = 0; + if (StringUtil.isNotEmpty(r_str)) { + r_num = Integer.parseInt(r_str); + } + consume = r_num; + } else { + int timeBegin = beginTime; + while (timeBegin <= endTime) { + + String hp_key = String.format("%s:d%s", key, timeBegin); + String r_str = jedis9.get(hp_key); + int r_num = 0; + if (StringUtil.isNotEmpty(r_str)) { + r_num = Integer.parseInt(r_str); + } + consume += r_num; + timeBegin += 86400; + } + } + + getMemberData(jedis9, uid, obj1, groupId, 0, beginTime, endTime, false, false); + } finally { + jedis9.close(); + } + } + + String sql = String.format( + "select rec_key from room_rec_log where %s %s GROUP BY roomid ORDER BY time desc limit %s,%s", where, + qid_sql, limit, num); + ITArray list = DataBase.use().executeQueryByTArray(sql); + + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, platform); + if (obj == null) { + continue; + } + militaryList.addTObject(obj); + } + } finally { + jedis5.close(); + } + } + + obj1.putTArray("records", militaryList); + obj1.putInt("limit", limit); + obj1.putInt("total", total); + obj1.putInt("consume", consume); + return obj1; + } + + public static ITObject getPartnerStatPlay(int groupId, int uid, int parent_id, int limit, int num, int timeType, + int beginTime, int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gp_key, 10, 11); + ITArray arr = TArray.newInstance(); + try { + for (String pid : pids) { + + ITObject objp = TObject.newInstance(); + + objp.putInt("pid", Integer.parseInt(pid)); + + if (timeType == 0) { + + String key = String.format("g{%s}:m%s:valid_round:p%s", groupId, uid, pid); + int round = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("round", round); + + key = String.format("g%s:hp_cost:m%s:p%s", groupId, uid, pid); + int pump = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("pump", pump); + + key = String.format("g{%s}:m%s:p%s:reward_log", groupId, uid, pid); + int award = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("award", award); + } else if (timeType == 1) { + + String curMonth = ":m" + DateUtils.getBeginMonth(); + + String key = String.format("g{%s}:m%s:valid_round:p%s%s", groupId, uid, pid, curMonth); + int round = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("round", round); + + key = String.format("g%s:hp_cost:m%s:p%s%s", groupId, uid, pid, curMonth); + int pump = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("pump", pump); + + key = String.format("g{%s}:m%s:p%s:reward_log%s", groupId, uid, pid, curMonth); + int award = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("award", award); + } else if (timeType == 2) { + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + + String key = String.format("g{%s}:m%s:valid_round:p%s%s", groupId, uid, pid, curMonth); + int round = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("round", round); + + key = String.format("g%s:hp_cost:m%s:p%s%s", groupId, uid, pid, curMonth); + int pump = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("pump", pump); + + key = String.format("g{%s}:m%s:p%s:reward_log%s", groupId, uid, pid, curMonth); + int award = _getCountValue(jedis9, key, beginTime, endTime); + objp.putInt("award", award); + } + arr.addTObject(objp); + } + } finally { + jedis9.close(); + jedis11.close(); + } + + obj.putTArray("members", arr); + obj.putInt("limit", limit); + + return obj; + } + + public static ITObject getDirectStatMember(int groupId, int uid, int rootUid, int limit, int num, int timeType, + int beginTime, int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + + String limitSql = String.format("limit %s,%s", limit, num); + String sql = String.format( + "SELECT uid, partnerLev" + " FROM group_member" + + " WHERE groupId = %s and ((parentId=%s and partnerLev = 0) or uid = %s) GROUP BY uid %s", + groupId, uid, uid, limitSql); + + ITArray temp = TArray.newInstance(); + + ITArray list = DataBase.use().executeQueryByTArray(sql); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + if (objLine.containsKey("uid")) { + + int tagUid = objLine.getInt("uid"); + + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + // int newBeginTime = beginTime - 86400*30; + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, false, false); + + if (timeType == 0) { + { + String tmpKey = String.format("g{%s}:m%s:", groupId, tagUid); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + objLine.putInt("reward_tongji", reward_hp); + } + + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getCountValue(jedis9, key, beginTime, endTime); + objLine.putInt("reward_hp", (int) reward_hp); + } else if (timeType == 1) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 2) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } + temp.addTObject(objLine); + } + } + } finally { + jedis9.close(); + } + + obj.putTArray("members", temp); + obj.putInt("limit", limit); + + return obj; + } + + public static ITObject getXingYunHaoMember(int groupId, int limit, int num, int timeType, int beginTime, + int endTime) throws Exception { + ITObject obj = TObject.newInstance(); + + String limitSql = String.format("limit %s,%s", limit, num); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + String strGodsList = null; + Set godsList = jedis1.smembers("gods"); + Map mapString = jedis1.hgetAll("gods_special"); + for (Map.Entry entry : mapString.entrySet()) { + String strPlayerId = entry.getKey(); + godsList.remove(strPlayerId); + } + + List allList = new ArrayList(); + allList.addAll(godsList); + for (String mem : godsList) { + if (strGodsList == null) { + strGodsList = mem; + } else { + strGodsList += "," + mem; + } + } + + String sql = String.format( + "SELECT uid, partnerLev" + " FROM group_member" + " WHERE groupId = %s and uid in (%s) GROUP BY uid %s", + groupId, strGodsList, limitSql); + + ITArray temp = TArray.newInstance(); + int allTotalWin = 0; + ITArray list = DataBase.use().executeQueryByTArray(sql); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + if (objLine.containsKey("uid")) { + + int tagUid = objLine.getInt("uid"); + + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, false, false); + + temp.addTObject(objLine); + } + } + + for (String user : allList) { + String key = String.format("g{%s}:m%s:", groupId, user); + int total_win = _getCountValue(jedis9, key + "total_win_self", beginTime, endTime); + allTotalWin += total_win; + } + } finally { + jedis9.close(); + } + + obj.putTArray("members", temp); + obj.putInt("limit", limit); + obj.putLong("all_total_win", allTotalWin); + + return obj; + } + + public static ITObject getPartnerStatMember(int groupId, int uid, int rootUid, int limit, int num, int timeType, + int beginTime, int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + + String limitSql = String.format("limit %s,%s", limit, num); + + String sql = String.format( + "SELECT uid, partnerLev" + " FROM group_member" + + " WHERE groupId = %s and (parentId=%s or uid = %s) and partnerLev > 0 GROUP BY uid %s", + groupId, uid, uid, limitSql); + + ITArray temp = TArray.newInstance(); + + ITArray list = DataBase.use().executeQueryByTArray(sql); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + if (objLine.containsKey("uid")) { + + int tagUid = objLine.getInt("uid"); + + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + if (tagUid != uid) { + // int newBeginTime = beginTime - 86400 * 30; + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, false, true); + } else { + // int newBeginTime = beginTime - 86400 * 30; + // getMemberData(jedis9,tagUid,objLine,groupId,timeType, + // beginTime,endTime,false,true); + getDirectMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime); + } + + if (tagUid == uid) { + + if (timeType == 0) { + { + String tmpKey = String.format("g{%s}:m%s:", groupId, tagUid); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + objLine.putInt("reward_tongji", reward_hp); + } + + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getCountValue(jedis9, key, beginTime, endTime); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 1) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginMonth(); + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 2) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } + } else { + if (timeType == 0) { + { + long reward_hp_total = 0; + List listParent = Utility.getChildParentList(groupId, tagUid, true); + for (Integer parId : listParent) { + String tmpKey = String.format("g{%s}:m%s:", groupId, parId); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + reward_hp_total += reward_hp; + } + objLine.putInt("reward_tongji", (int) reward_hp_total); + } + + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getCountValue(jedis9, key, beginTime, endTime); + objLine.putInt("reward_hp", (int) reward_hp); + } else if (timeType == 1) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 2) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } + } + + temp.addTObject(objLine); + } + } + } finally { + jedis9.close(); + } + + obj.putTArray("members", temp); + obj.putInt("limit", limit); + + return obj; + } + + public static ITObject findPartnerStatMember(int groupId, int uid, int rootUid, int tagId, int limit, int num, + int timeType, int beginTime, int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + + String limitSql = String.format("limit %s,%s", limit, num); + + String sql = String.format("SELECT uid, partnerLev" + " FROM group_member" + + " WHERE groupId = %s and (parentId=%s or uid = %s) and partnerLev > 0 and uid=%s GROUP BY uid %s", + groupId, uid, uid, tagId, limitSql); + + ITArray temp = TArray.newInstance(); + + ITArray list = DataBase.use().executeQueryByTArray(sql); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + if (objLine.containsKey("uid")) { + + int tagUid = objLine.getInt("uid"); + + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + if (tagUid != uid) { + // int newBeginTime = beginTime - 86400 * 30; + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, false, true); + } else { + // int newBeginTime = beginTime - 86400 * 30; + // getMemberData(jedis9,tagUid,objLine,groupId,timeType, + // beginTime,endTime,false,true); + getDirectMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime); + } + + if (tagUid == uid) { + + if (timeType == 0) { + { + String tmpKey = String.format("g{%s}:m%s:", groupId, tagUid); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + objLine.putInt("reward_tongji", reward_hp); + } + + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getCountValue(jedis9, key, beginTime, endTime); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 1) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginMonth(); + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 2) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + String key = String.format("g{%s}:m%s:d_reward", groupId, tagUid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } + } else { + if (timeType == 0) { + { + long reward_hp_total = 0; + List listParent = Utility.getChildParentList(groupId, tagUid, true); + for (Integer parId : listParent) { + String tmpKey = String.format("g{%s}:m%s:", groupId, parId); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + reward_hp_total += reward_hp; + } + objLine.putInt("reward_tongji", (int) reward_hp_total); + } + + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getCountValue(jedis9, key, beginTime, endTime); + objLine.putInt("reward_hp", (int) reward_hp); + } else if (timeType == 1) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } else if (timeType == 2) { + { + String key = String.format("g{%s}:m%s:", groupId, tagUid); + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + + objLine.putInt("reward_tongji", reward_hp); + } + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + String key = String.format("g{%s}:m%s:reward_log_to:par%s", groupId, tagUid, uid); + int reward_hp = _getValue(jedis9, key + curMonth); + objLine.putInt("reward_hp", reward_hp); + } + } + + temp.addTObject(objLine); + } + } + } finally { + jedis9.close(); + } + + obj.putTArray("members", temp); + obj.putInt("limit", limit); + + return obj; + } + + public static ITObject getPartnerStat(int groupId, int uid, int limit, int num, int timeType, int beginTime, + int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + int lev = gmb.lev; + boolean mgr = lev < 3; + ITArray list = null; + String limitSql = String.format("limit %s,%s", limit, num); + if (mgr) { + + String sql = String.format("SELECT A.uid,A.partnerLev, A.autoscore," + + "(SELECT COUNT(uid) FROM group_member B where B.groupId = %s AND B.parentId = A.uid) AS total " + + "FROM group_member AS A" + " where A.groupId= %s and A.partnerLev=1 %s", groupId, groupId, + limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } else { + + String sql = String.format( + "SELECT A.uid,A.partnerLev, A.autoscore, (SELECT COUNT(uid) FROM group_member B where B.groupId = %s AND B.parentId = A.uid) AS total " + + "FROM group_member AS A" + + " where A.groupId= %s and (A.parentId=%s or A.uid=%s) AND A.partnerLev >0 %s", + groupId, groupId, uid, uid, limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + int tagUid = objLine.getInt("uid"); + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, true, true); + } + } finally { + jedis9.close(); + jedis10.close(); + } + + obj.putTArray("members", list); + obj.putInt("limit", limit); + + return obj; + } + + public static ITObject findPartnerStat(int groupId, int uid, int tagId, int limit, int num, int timeType, + int beginTime, int endTime) throws Exception { + + ITObject obj = TObject.newInstance(); + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + int lev = gmb.lev; + boolean mgr = lev < 3; + ITArray list = null; + String limitSql = String.format("limit %s,%s", limit, num); + if (mgr) { + + String sql = String.format("SELECT A.uid,A.partnerLev, A.autoscore," + + "(SELECT COUNT(uid) FROM group_member B where B.groupId = %s AND B.parentId = A.uid) AS total " + + "FROM group_member AS A" + " where A.groupId= %s and A.uid=%s %s", groupId, groupId, tagId, + limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } else { + if (uid != tagId) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } finally { + jedis10.close(); + } + + } + + String sql = String.format( + "SELECT A.uid,A.partnerLev, A.autoscore, (SELECT COUNT(uid) FROM group_member B where B.groupId = %s AND B.parentId = A.uid) AS total " + + "FROM group_member AS A" + " where A.groupId= %s AND A.uid=%s %s", + groupId, groupId, tagId, limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + try { + + for (int i = 0; i < list.size(); ++i) { + + ITObject objLine = list.getTObject(i); + int tagUid = objLine.getInt("uid"); + AccountBean acc = AccountCache.getAccount(tagUid); + objLine.putString("nick", acc.nick); + + getMemberData(jedis9, tagUid, objLine, groupId, timeType, beginTime, endTime, true, true); + } + } finally { + jedis9.close(); + jedis10.close(); + } + + obj.putTArray("members", list); + obj.putInt("limit", limit); + + return obj; + } + + public static void getMemberData(Jedis jedis9, int uid, ITObject param, int groupId, int timeType, int beginTime, + int endTime, boolean rewardHP, boolean total) { + + String key = String.format("g{%s}:m%s:", groupId, uid); + String self = total ? "" : "_self"; + if (timeType == 0) { + + if (rewardHP) { +// int reward_hp = _getCountValue(jedis9,key + "reward_log",beginTime,endTime); +// param.putInt("reward_hp", reward_hp); + + // 包含下级合伙人 + long reward_hp_total = 0; + List listParent = Utility.getChildParentList(groupId, uid, true); + for (Integer parId : listParent) { + String tmpKey = String.format("g{%s}:m%s:", groupId, parId); + int reward_hp = _getCountValue(jedis9, tmpKey + "reward_log", beginTime, endTime); + reward_hp_total += reward_hp; + } + param.putLong("reward_hp", reward_hp_total); + } + + int valid_round = _getCountValue(jedis9, key + "valid_round" + self, beginTime, endTime); + param.putInt("valid_round", valid_round); + + int total_round = _getCountValue(jedis9, key + "round_log" + self, beginTime, endTime); + param.putInt("total_round", total_round); + + int total_win = _getCountValue(jedis9, key + "total_win" + self, beginTime, endTime); + param.putInt("total_win", total_win); + } else if (timeType == 1) { + + String curMonth = ":m" + DateUtils.getBeginMonth(); + + if (rewardHP) { + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + param.putInt("reward_hp", reward_hp); + } + + int valid_round = _getValue(jedis9, key + "valid_round" + self + curMonth); + param.putInt("valid_round", valid_round); + + int total_round = _getValue(jedis9, key + "round_log" + self + curMonth); + param.putInt("total_round", total_round); + + int total_win = _getValue(jedis9, key + "total_win" + self + curMonth); + param.putInt("total_win", total_win); + } else if (timeType == 2) { + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + + if (rewardHP) { + int reward_hp = _getValue(jedis9, key + "reward_log" + curMonth); + param.putInt("reward_hp", reward_hp); + } + + int valid_round = _getValue(jedis9, key + "valid_round" + self + curMonth); + param.putInt("valid_round", valid_round); + + int total_round = _getValue(jedis9, key + "round_log" + self + curMonth); + param.putInt("total_round", total_round); + + int total_win = _getValue(jedis9, key + "total_win" + self + curMonth); + param.putInt("total_win", total_win); + } + } + + private static void getDirectMemberData(Jedis jedis9, int uid, ITObject param, int groupId, int timeType, + int beginTime, int endTime) { + + String key = String.format("g{%s}:m%s:", groupId, uid); + + if (timeType == 0) { + + int valid_round = _getCountValue(jedis9, key + "d_valid_round", beginTime, endTime); + param.putInt("valid_round", valid_round); + + int total_round = _getCountValue(jedis9, key + "d_round_log", beginTime, endTime); + param.putInt("total_round", total_round); + + int total_win = _getCountValue(jedis9, key + "d_total_win", beginTime, endTime); + param.putInt("total_win", total_win); + } else if (timeType == 1) { + + String curMonth = ":m" + DateUtils.getBeginMonth(); + + int valid_round = _getValue(jedis9, key + "d_valid_round" + curMonth); + param.putInt("valid_round", valid_round); + + int total_round = _getValue(jedis9, key + "d_round_log" + curMonth); + param.putInt("total_round", total_round); + + int total_win = _getValue(jedis9, key + "d_total_win" + curMonth); + param.putInt("total_win", total_win); + } else if (timeType == 2) { + + String curMonth = ":m" + DateUtils.getBeginLastMonth(); + + int valid_round = _getValue(jedis9, key + "d_valid_round" + curMonth); + param.putInt("valid_round", valid_round); + + int total_round = _getValue(jedis9, key + "d_round_log" + curMonth); + param.putInt("total_round", total_round); + + int total_win = _getValue(jedis9, key + "d_total_win" + curMonth); + param.putInt("total_win", total_win); + } + } + + /** + * 获取战绩列表 + * + * @param + * @param groupId + * @param limit + * @param num + * @return + */ + public static ITObject getMemberStat(int groupId, int uid, int qid, int partnerId, int limit, int num, int timeType, + int beginTime, int endTime) throws Exception { + + ITObject obj1 = TObject.newInstance(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + + String qid_sql = StringUtil.Empty; + if (qid > 0) { + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + int mgn_partner = mng_bean.partnerLev; + int mgn_lev = mng_bean.lev; + if (mgn_lev == 3 && mgn_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + if (mgn_lev == 3) { + List par_list = Utility.getMemberParents(jedis10, groupId, qid, false); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + + } + + qid_sql = " AND A.uid=" + qid; + } else if (partnerId > 0) { + + String ugm_key = GroupMemberCache.genKey(groupId, partnerId); + String lev = jedis10.hget(ugm_key, "lev"); + boolean mgr = StringUtil.isNotEmpty(lev) && Integer.parseInt(lev) < 3; + + String p = Utility.getChildParentSql(groupId, partnerId, true); + if (mgr) { + p = p + ",0"; + } + + qid_sql = String.format(" AND (A.parentId in(%s) or A.uid = %s)", p, partnerId); + } + + if (timeType == 0) { + + beginTime = DateUtils.getBeginDay(); + endTime = DateUtils.getEndDay(); + } else if (timeType == 1) { + + beginTime = DateUtils.getBeginDay() - 3600 * 24; + endTime = DateUtils.getBeginDay(); + } else if (timeType == 2) { + + beginTime = DateUtils.getBeginDay() - 3600 * 48; + endTime = DateUtils.getBeginDay() - 3600 * 24; + } + + String sql = String.format( + "SELECT IFNULL(SUM(B.win), 0) AS win,IFNULL(SUM(B.round), 0) AS round,IFNULL(SUM(B.score), 0) AS score,A.uid,A.hp,A.lev,A.partnerLev " + + "FROM group_member AS A " + + "LEFT JOIN group_member_log AS B ON A.groupId = B.groupId and A.uid = B.uid AND B.time >=%s AND B.time <%s " + + "WHERE A.groupId = %s %s " + "GROUP BY A.uid " + "ORDER BY round DESC " + "limit %s,%s", + beginTime, endTime, groupId, qid_sql, limit, num); + + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (arr.size() > 0) { + for (int i = 0; i < arr.size(); ++i) { + + ITObject obj = arr.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + if (acc != null) { + obj.putString("nick", acc.nick); + } else { + obj.putString("nick", StringUtil.Empty); + } + } + + } + obj1.putTArray("members", arr); + obj1.putInt("limit", limit); + jedis9.close(); + jedis10.close(); + return obj1; + } + + /** + * 获取战绩列表 + * + * @param platform 平台标识 + * @param groupId 组ID + * @param limit 查询的起始记录编号 + * @param num 查询的记录数量 + * @param qid 查询的用户ID,用于筛选特定用户的战绩 + * @param uid 当前用户ID,用于权限校验 + * @param includeMembers 是否包括成员的战绩,0为只查询个人,1为包括成员 + * @param timeType 时间类型,用于筛选战绩的时间范围 + * @param beginTime 开始时间戳 + * @param endTime 结束时间戳 + * @return 返回包含战绩列表和查询参数的ITObject对象 + */ + public static ITObject getRecords(String platform, int groupId, int limit, int num, int qid, int uid, + int includeMembers, int timeType, int beginTime, int endTime) throws Exception { + + // 初始化查询标志和权限标志 + boolean find = true; + boolean mgr = true; + boolean tagIsPartner = false; + + // 获取Redis连接 + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + GroupMemberBean mng = GroupCache.getMember(groupId, uid); + try { + + // 获取当前用户在组中的成员信息 + int _lev = mng.lev; + // 根据用户级别判断是否具有管理权限 + mgr = _lev < 3; + + // 如果指定了查询的用户ID,则进行权限和关系校验 +// if (qid > 0) { +// +// // 获取指定查询用户在组中的成员信息 +// GroupMemberBean tag = GroupCache.getMember(groupId, qid); +// if (tag != null) { +// int parentId = tag.parentId; +// // 如果当前用户没有管理权限,则进一步校验与查询用户的关系 +// if (!mgr) { +// if (parentId == 0) { +// // 如果查询用户没有上级,则不允许查询 +// find = true; +// } else { +// // 如果查询用户是合伙人,则标记为true +// if (tag.partnerLev > 0) { +// tagIsPartner = true; +// } +// // 获取查询用户的上级列表,并校验当前用户是否在其中 +// List par_list = Utility.getMemberParents(jedis10, groupId, +// includeMembers == 0 ? parentId : qid, true); +// if (par_list == null || !par_list.contains(uid)) { +// +// // 如果当前用户不在查询用户的上级列表中,则不允许查询 +// find = false; +// } +// } +// } +// } else { +// // 如果指定的查询用户不存在,则不允许查询 +// find = false; +// } +// } + } finally { + // 关闭Redis连接 + jedis10.close(); + } + + // 初始化战绩列表数组 + ITArray militaryList = TArray.newInstance(); + GroupBean groupBean = GroupCache.getGroup(groupId); + + if (find) { + + // 构造SQL查询的where条件 + String where = StringUtil.Empty; + if (timeType == 0) { + + // 根据指定的时间范围构造where条件 + where = String.format("gid=%s and time>=%s and time<=%s and uid = %s", groupId, beginTime, endTime, + qid); + } else if (timeType == 1) { + + // 根据本月的开始时间构造where条件 + beginTime = DateUtils.getBeginMonth(); + where = String.format("gid=%s and time>=%s and uid = %s", groupId, beginTime, qid); + } else if (timeType == 2) { + + // 根据上月的时间范围构造where条件 + beginTime = DateUtils.getBeginLastMonth(); + endTime = DateUtils.getBeginMonth(); + where = String.format("gid=%s and time>=%s and time<=%s and uid = %s", groupId, beginTime, endTime, + qid); + } else { + // 根据最近一天的时间范围构造where条件 + beginTime = DateUtils.getBeginDay() - 259200; + endTime = DateUtils.getEndDay(); + where = String.format("gid=%s and time>=%s and time<=%s and uid = %s", groupId, beginTime, endTime, + qid); + } +// // 如果是群主则查看所有成员战绩 +// if (groupBean.owner == qid && uid == groupBean.owner) { +// beginTime = DateUtils.getBeginDay() - 259200; +// endTime = DateUtils.getEndDay(); +// where = String.format("gid=%s and time>=%s and time<=%s ", groupId, beginTime, endTime); +// } + + // 构造完整的SQL查询语句 + String sql = String.format( + "select rec_key from room_rec_log where %s GROUP BY roomid ORDER BY time desc limit %s,%s", where, + limit, num); + + // 执行SQL查询,获取战绩记录的列表 + ITArray list = DataBase.use().executeQueryByTArray(sql); + log.info("看sql语句:" + sql); + + // 如果查询到战绩记录,则进一步获取详细的战绩信息 + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + // 根据战绩记录的key获取详细的战绩信息,并添加到战绩列表中 + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, platform); + if (obj == null) { + continue; + } +// obj.putString("is_read", obj.getString("is_read_"+acc.id)); + + militaryList.addTObject(obj); + } + } finally { + // 关闭Redis连接 + jedis5.close(); + } + } + } + + // 构造返回对象,包含战绩列表和查询参数 + ITObject obj1 = TObject.newInstance(); + obj1.putTArray("records", militaryList); + obj1.putInt("limit", limit); +// log.info("返回数据看看看看看看看看:"+obj1); + return obj1; + } + + /** + * 获取战绩列表 + * + * @param platform 平台标识 + * @param groupId 组ID + * @param limit 查询的起始记录编号 + * @param num 查询的记录数量 + * @param qid 查询的用户ID,用于筛选特定用户的战绩 + * @param uid 当前用户ID,用于权限校验 + * @param includeMembers 是否包括成员的战绩,0为只查询个人,1为包括成员 + * @param timeType 时间类型,用于筛选战绩的时间范围 + * @param beginTime 开始时间戳 + * @param endTime 结束时间戳 + * @return 返回包含战绩列表和查询参数的ITObject对象 + */ + public static ITObject getRecordsOwner(String platform, int groupId, int limit, int num, int qid, int uid, + int includeMembers, int timeType, int beginTime, int endTime) throws Exception { + + // 初始化查询标志和权限标志 + boolean find = true; + boolean mgr = true; + boolean tagIsPartner = false; + + // 获取Redis连接 + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + GroupMemberBean mng = GroupCache.getMember(groupId, uid); + try { + + // 获取当前用户在组中的成员信息 + int _lev = mng.lev; + // 根据用户级别判断是否具有管理权限 + mgr = _lev < 3; + + // 如果指定了查询的用户ID,则进行权限和关系校验 + if (qid > 0) { + + // 获取指定查询用户在组中的成员信息 + GroupMemberBean tag = GroupCache.getMember(groupId, qid); + if (tag != null) { + int parentId = tag.parentId; + // 如果当前用户没有管理权限,则进一步校验与查询用户的关系 + if (!mgr) { + if (parentId == 0) { + // 如果查询用户没有上级,则不允许查询 + find = true; + } else { + // 如果查询用户是合伙人,则标记为true + if (tag.partnerLev > 0) { + tagIsPartner = true; + } + // 获取查询用户的上级列表,并校验当前用户是否在其中 + List par_list = Utility.getMemberParents(jedis10, groupId, + includeMembers == 0 ? parentId : qid, true); + if (par_list == null || !par_list.contains(uid)) { + + // 如果当前用户不在查询用户的上级列表中,则不允许查询 + find = false; + } + } + } + } else { + // 如果指定的查询用户不存在,则不允许查询 + find = false; + } + } + } finally { + // 关闭Redis连接 + jedis10.close(); + } + + // 初始化战绩列表数组 + ITArray militaryList = TArray.newInstance(); + + if (find) { + + // 构造SQL查询的where条件 + String where = StringUtil.Empty; + if (timeType == 0) { + + // 根据指定的时间范围构造where条件 + where = String.format("gid=%s and time>=%s and time<=%s ", groupId, beginTime, endTime); + } else if (timeType == 1) { + + // 根据本月的开始时间构造where条件 + beginTime = DateUtils.getBeginMonth(); + where = String.format("gid=%s and time>=%s ", groupId, beginTime); + } else if (timeType == 2) { + + // 根据上月的时间范围构造where条件 + beginTime = DateUtils.getBeginLastMonth(); + endTime = DateUtils.getBeginMonth(); + where = String.format("gid=%s and time>=%s and time<=%s ", groupId, beginTime, endTime); + } else { + // 根据最近一天的时间范围构造where条件 + beginTime = DateUtils.getBeginDay() - 259200; + endTime = DateUtils.getEndDay(); + where = String.format("gid=%s and time>=%s and time<=%s ", groupId, beginTime, endTime); + } + // 构造完整的SQL查询语句 + String sql = String.format( + "select rec_key from room_rec_log where %s GROUP BY roomid ORDER BY time desc limit %s,%s", where, + limit, num); + + // 执行SQL查询,获取战绩记录的列表 + ITArray list = DataBase.use().executeQueryByTArray(sql); + log.info("看sql语句:" + sql); + + // 如果查询到战绩记录,则进一步获取详细的战绩信息 + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + // 根据战绩记录的key获取详细的战绩信息,并添加到战绩列表中 + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, platform); + if (obj == null) { + continue; + } +// obj.putString("is_read", obj.getString("is_read_"+acc.id)); + + militaryList.addTObject(obj); + } + } finally { + // 关闭Redis连接 + jedis5.close(); + } + } + } + + // 构造返回对象,包含战绩列表和查询参数 + ITObject obj1 = TObject.newInstance(); + obj1.putTArray("records", militaryList); + obj1.putInt("limit", limit); +// log.info("返回数据看看看看看看看看:"+obj1); + return obj1; + } + + /** + * 聊天室 + * + * @param uid + * @param groupId + * @return + * @throws WebException + */ + public static ITObject getRecords(int uid, int groupId) throws WebException { + ITArray list = TArray.newInstance(); + + // 获取成员信息 + GroupMemberBean mgn = GroupCache.getMember(groupId, uid); + log.info("mgn数据:" + mgn); + if (mgn == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + // 根据lev判断权限 + if (mgn.lev == 1 || mgn.lev == 2) { + // 构建最终的SQL查询语句 + String sql = String.format("SELECT rec_key FROM room_rec_log WHERE gid =%s", groupId); + // 执行SQL查询,获取结果集 + try { + list = DataBase.use().executeQueryByTArray(sql); + // 如果查询到战绩记录,则进一步获取详细的战绩信息 + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i <= list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + log.info("rec_key数据: " + rec_key); + if (rec_key == null) { + break; + } + // 根据战绩记录的key获取详细的战绩信息,并添加到战绩列表中 + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, ""); + if (obj == null) { + continue; + } + list.addTObject(obj); + log.info("obj数据1: " + obj); + } + } finally { + // 关闭Redis连接 + jedis5.close(); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + } else if (mgn.lev == 3) { + + // 仅查询当前群组且用户在线期间的战绩 + String sql = String.format("SELECT rec_key FROM room_rec_log WHERE gid =%s AND time >= %s", groupId, + mgn.last_time); + + try { + list = DataBase.use().executeQueryByTArray(sql); + } catch (SQLException e) { + e.printStackTrace(); + } + log.info("数据: list长度:" + list.size()); + // 如果查询到战绩记录,则进一步获取详细的战绩信息 + if (list.size() > 0) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i <= list.size(); ++i) { + ITObject tem = list.getTObject(i); + String rec_key = tem.getString("rec_key"); + if (rec_key == null) { + break; + } + // 根据战绩记录的key获取详细的战绩信息,并添加到战绩列表中 + ITObject obj = Utility.getMilitaryList(jedis5, rec_key, ""); + if (obj == null) { + continue; + } + + list.addTObject(obj); + log.info("obj数据2: " + obj); + + } + } finally { + // 关闭Redis连接 + jedis5.close(); + } + } + } else { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + // 创建一个新的ITObject对象,用于存储军事列表数据 + ITObject obj1 = TObject.newInstance(); + // 将军事列表数据添加到ITObject对象中 + obj1.putTArray("list", list); + // 返回包含军事列表数据的ITObject对象 + return obj1; + } + + /** + * 根据房间ID查询战绩 + * + * @param platform + * @param groupId + * @param roomid + * @return + */ + public static ITArray findRecordByRoom(String platform, int groupId, String roomid, int uid) throws Exception { + if (StringUtil.isNotEmpty(roomid)) { + if (roomid.length() != 6) { + return null; + } + } + boolean find = false; + int time3last = DateUtils.getBeginDay() - 259200; + String sql = String.format("select rec_key,uid from room_rec_log where gid=%s and roomid='%s' and time>=%s", + groupId, roomid, time3last); + ITArray list = DataBase.use().executeQueryByTArray(sql); + if (list.size() == 0) + return null; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean mng = GroupCache.getMember(groupId, uid); + int _lev = mng.lev; + boolean mgr = _lev < 3; + if (!mgr) { + for (int i = 0; i < list.size(); ++i) { + ITObject obj = list.getTObject(i); + int id = obj.getInt("uid"); + if (id == uid) { + find = true; + break; + } + GroupMemberBean tag = GroupCache.getMember(groupId, id); + if (tag == null) + continue; + int par = tag.parentId; + if (par == 0) + continue; + List par_list = Utility.getMemberParents(jedis10, groupId, par, true); + if (par_list != null && par_list.contains(uid)) { + find = true; + break; + } + } + } else { + find = true; + } + } finally { + jedis10.close(); + } + if (!find) + return null; + + ITArray militaryList = TArray.newInstance(); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for (int i = 0; i < list.size(); i++) { + String rec_key = list.getTObject(i).getString("rec_key"); + ITObject data = Utility.getMilitaryList(jedis5, rec_key, platform); + boolean flag = true; + for (int j = 0; j < militaryList.size(); j++) { + ITObject temp = militaryList.getTObject(j); + String temp_create_time = temp.getString("create_time"); + String create_time = data.getString("create_time"); + String temp_rec_key = temp.getString("military_id"); + + if (temp_rec_key.equals(rec_key) && create_time.equals(temp_create_time)) { + flag = false; + break; + } + } + + if (flag) { + militaryList.addTObject(data); + } + } + + return militaryList; + } finally { + jedis5.close(); + } + } + + /** + * + * @param groupId + * @param uid + * @param limit + * @param num + * @param type 1上分 2下分 3合伙人上分 4合伙人下分 + * @return + * @throws Exception + */ + public static final ITObject getHpLogMgr(int groupId, int uid, int limit, int num, int type, int qid, + String tagName) throws Exception { + GroupMemberBean mng = GroupCache.getMember(groupId, uid); + int beginDay = DateUtils.getBeginDay(); + int beginTime = beginDay - 9 * 24 * 3600; + if (mng.lev >= 3) { + beginTime = beginDay - 2 * 24 * 3600; + } + + long endTime = DateUtils.getEndDay(); + + int reason = MGRLOG_TYPE[type - 1]; + String mgr_sql = StringUtil.Empty; + String qid_sql = StringUtil.Empty; + + ITArray arr = null; + + if (type > 2) { + + mgr_sql = "and A.mgr_id=" + uid; + + if (StringUtil.isNotEmpty(tagName) || qid > 0) { + + if (qid > 0) { + + qid_sql = "and A.uid=" + qid; + + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format( + "SELECT uid,mgr_id,hp,cur_hp,time FROM group_hp_log as A %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + arr = DataBase.use().executeQueryByTArray(sql); + } + + if (StringUtil.isNotEmpty(tagName)) { + + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format("SELECT A.uid,A.mgr_id,A.hp,A.cur_hp,A.time " + "FROM group_hp_log as A " + + "RIGHT JOIN account as B " + "ON A.uid = B.id and B.nick like '%%%s%%' " + + "%s ORDER BY time desc " + "limit %s,%s", tagName, where_sql, limit, num); + + ITArray temp = DataBase.use().executeQueryByTArray(sql); + if (temp.size() > 0) { + if (arr == null) { + arr = temp; + } else { + + for (int i = 0; i < temp.size(); i++) { + ITObject mo = temp.getTObject(i); + if (qid > 0 && mo.getInt("uid") == qid) { + continue; + } + arr.addTObject(temp.getTObject(i)); + } + } + } + } + } else { + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format( + "SELECT uid,mgr_id,hp,cur_hp,time FROM group_hp_log as A %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + arr = DataBase.use().executeQueryByTArray(sql); + } + } else { + + if (StringUtil.isNotEmpty(tagName) || qid > 0) { + + if (qid > 0) { + qid_sql = "and (A.uid=" + qid; + qid_sql += " or A.mgr_id=" + qid + ")"; + + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format( + "SELECT uid,mgr_id,hp,cur_hp,time FROM group_hp_log as A %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + arr = DataBase.use().executeQueryByTArray(sql); + } + + if (StringUtil.isNotEmpty(tagName)) { + + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format("SELECT A.uid,A.mgr_id,A.hp,A.cur_hp,A.time " + "FROM group_hp_log as A " + + "RIGHT JOIN account as B " + + "ON (A.uid = B.id OR A.mgr_id = B.id) and B.nick like '%%%s%%' " + + "%s ORDER BY time desc " + "limit %s,%s", tagName, where_sql, limit, num); + + ITArray temp = DataBase.use().executeQueryByTArray(sql); + if (temp.size() > 0) { + if (arr == null) { + arr = temp; + } else { + + for (int i = 0; i < temp.size(); i++) { + + ITObject mo = temp.getTObject(i); + if (qid > 0 && mo.getInt("uid") == qid) { + continue; + } + arr.addTObject(temp.getTObject(i)); + } + } + } + + } + } else { + + String where_sql = String.format( + "WHERE A.gid = %s " + "and A.reason = %s " + "and A.time>=%s " + "and A.time <=%s %s %s", + groupId, reason, beginTime, endTime, mgr_sql, qid_sql); + + String sql = String.format( + "SELECT uid,mgr_id,hp,cur_hp,time FROM group_hp_log as A %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + arr = DataBase.use().executeQueryByTArray(sql); + } + + } + + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + + if (arr != null) { + + for (int i = 0; i < arr.size(); ++i) { + + ITObject obj = arr.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + obj.putString("t_nick", acc.nick); + acc = AccountCache.getAccount(obj.getInt("mgr_id")); + obj.putString("m_nick", acc.nick); + } + resData.putTArray("hp_logs", arr); + } + + return resData; + } + + /** + * 获取体力值管理统计数据 + * + * @param groupId + * @return + * @throws Exception + */ + public static final ITObject getHpLogMgrCount(int groupId) throws Exception { + int beginTime = DateUtils.getBeginDay() - 9 * 24 * 3600; + long upper_count = 0; + long sub_count = 0; + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String str = null; + for (int i = 0; i < 10; ++i) { + String hp_mgr_upper_key = String.format("g%s:hp_mgr:upper:d%s", groupId, beginTime); + String hp_mgr_sub_key = String.format("g%s:hp_mgr:sub:d%s", groupId, beginTime); + str = jedis9.get(hp_mgr_upper_key); + if (StringUtil.isNotEmpty(str)) { + upper_count += Long.parseLong(str); + } + str = jedis9.get(hp_mgr_sub_key); + if (StringUtil.isNotEmpty(str)) { + sub_count += Long.parseLong(str); + } + beginTime += 24 * 3600; + } + String hp_cost_key = String.format("g%s:hp_cost:d%s", groupId, DateUtils.getBeginDay()); + long hp_cost_count = 0; + str = jedis9.get(hp_cost_key); + if (StringUtil.isNotEmpty(str)) { + hp_cost_count += Long.parseLong(str); + } + + hp_cost_key = String.format("g%s:hp_cost:d%s", groupId, DateUtils.getBeginLastday()); + long last_hp_cost_count = 0; + str = jedis9.get(hp_cost_key); + if (StringUtil.isNotEmpty(str)) { + last_hp_cost_count += Long.parseLong(str); + } + ITObject resData = TObject.newInstance(); + resData.putLong("hp_cost", hp_cost_count); + resData.putLong("last_hp_cost", last_hp_cost_count); + resData.putLong("hp_upper", upper_count); + resData.putLong("hp_sub", sub_count); + return resData; + } finally { + jedis9.close(); + } + } + + /** + * 获取体力值管理员详细信息 + * + * @param jedis9 + * @param groupId + * @param uid + * @param beginTime + * @param endTime + * @param mgr + * @return + */ + private static final ITObject _getHpLogMgrInfo(Jedis jedis9, int groupId, int uid, int beginTime, int endTime, + boolean mgr) { + long upper_count = 0; + long sub_count = 0; + AccountBean acc = AccountCache.getAccount(uid); + String str = null; + int tem = beginTime; + int tem_day = (endTime - beginTime) / 86400; + String hp_key = mgr ? "hp_mgr" : "hp_par"; + for (int k = 0; k < tem_day; ++k) { + String hp_mgr_upper_key = String.format("g%s:%s:upper:u%s:d%s", groupId, hp_key, uid, tem); + String hp_mgr_sub_key = String.format("g%s:%s:sub:u%s:d%s", groupId, hp_key, uid, tem); + str = jedis9.get(hp_mgr_upper_key); + if (StringUtil.isNotEmpty(str)) { + upper_count += Long.parseLong(str); + } + str = jedis9.get(hp_mgr_sub_key); + if (StringUtil.isNotEmpty(str)) { + sub_count += Long.parseLong(str); + } + + tem += 86400; + } + ITObject info = TObject.newInstance(); + info.putLong("hp_upper", upper_count); + info.putLong("hp_sub", sub_count); + info.putString("nick", acc.nick); + if (mgr) { + String gm_key = "gm_" + groupId + "_" + uid; + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String lev_str = jedis10.hget(gm_key, "lev"); + info.putInt("lev", StringUtil.isEmpty(lev_str) ? 2 : Integer.parseInt(lev_str)); + } + return info; + } + + /** + * 获取体力值管理员详细信息 + * + * @param groupId + * @param uid 操作人 + * @param beginTime + * @param endTime + * @param type 1 管理员 2合伙人 + * @return + * @throws Exception + */ + public static final ITArray getHpLogMgrInfo(int groupId, int uid, int beginTime, int endTime, int type) + throws Exception { + if (type == 1) { + String sql = String.format("SELECT uid FROM group_member WHERE groupId =%s AND lev <3", groupId); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + ITArray list = TArray.newInstance(); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + ITObject info = _getHpLogMgrInfo(jedis9, groupId, obj.getInt("uid"), beginTime, endTime, type == 1); + list.addTObject(info); + } + + return list; + } finally { + jedis9.close(); + } + } else { + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + ITArray list = TArray.newInstance(); + ITObject info = _getHpLogMgrInfo(jedis9, groupId, uid, beginTime, endTime, type == 1); + list.addTObject(info); + return list; + } finally { + jedis9.close(); + } + } + + } + + /** + * 体力值抽水记录 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @param choose + * @return + */ + public static final ITObject getHpLogPumpInfo(int groupId, int limit, int num, int beginTime, int endTime) + throws Exception { + String where_sql = String.format("WHERE gid = %s and reason = %s and time>=%s and time <=%s", groupId, + ConsumeCode.HP_PUMP, beginTime, endTime); + + String sql = String.format("SELECT uid,hp,roomid,pid,time FROM group_hp_log %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + int uid = obj.getInt("uid"); + AccountBean acc = AccountCache.getAccount(uid); + obj.putString("nick", acc.nick); + } + int hp_cost = 0; + int hp_reward = 0; + int count = 0; + int valid_count = 0; + + if (limit == 0) { + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String hp_cost_key = String.format("g%s:hp_cost", groupId); + String hp_reward_key = String.format("g%s:hp_reward", groupId); + String total_round = String.format("g%s:round", groupId); + String valid_round = String.format("g%s:valid_room", groupId); + + hp_cost = _getCountValue(jedis9, hp_cost_key, beginTime, endTime); + hp_reward = _getCountValue(jedis9, hp_reward_key, beginTime, endTime); + count = _getCountValue(jedis9, total_round, beginTime, endTime); + valid_count = _getCountValue(jedis9, valid_round, beginTime, endTime); + + } finally { + jedis9.close(); + } + } + + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + resData.putTArray("hp_logs", arr); + resData.putInt("pump", hp_cost); + resData.putInt("gains", hp_cost - hp_reward); + resData.putInt("count", count); + resData.putInt("valid_count", valid_count); + + return resData; + } + + /** + * 体力值详情 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @param choose + * @return + */ + public static final ITObject getHpLogInfo(int groupId, int tagId, int limit, int num, int choose) throws Exception { + String reason_sql = StringUtil.Empty; + if ((choose & CHOOSE_UPPER) != 0) { + reason_sql += ConsumeCode.HP_MGR_UPPER + "," + ConsumeCode.HP_PARTNER_UPPER + ","; + reason_sql += ConsumeCode.HP_MGR_SUB + "," + ConsumeCode.HP_PARTNER_SUB + ","; + } + if ((choose & CHOOSE_SUB) != 0) { + reason_sql += ConsumeCode.HP_MGR_SUB + "," + ConsumeCode.HP_PARTNER_SUB + ","; + } + if ((choose & CHOOSE_PUMP) != 0) { + reason_sql += ConsumeCode.HP_PUMP + ","; + } + if ((choose & CHOOSE_RWARD) != 0) { + reason_sql += ConsumeCode.HP_PARTNER_REWARD + ","; + } + if ((choose & CHOOSE_CHAGE) != 0) { + reason_sql += ConsumeCode.HP_PUMP_TOTAL + ","; + } + if ((choose & CHOOSE_TRADE) != 0) { + reason_sql += ConsumeCode.HP_TRADE + ","; + } + if ((choose & CHOOSE_TAKE_REWARD) != 0) { + reason_sql += ConsumeCode.HP_TAKE_REWARD + ","; + } + if ((choose & CHOOSE_XIPAI) != 0) { + reason_sql += ConsumeCode.HP_PARTNER_XIPAI_REWARD + ","; + } + if (StringUtil.isNotEmpty(reason_sql)) { + reason_sql = reason_sql.substring(0, reason_sql.length() - 1); + } else { + reason_sql = "0"; + } + + int time = DateUtils.getBeginDay() - 2 * 24 * 3600; + + String where_sql = String.format("WHERE gid = %s and uid =%s and reason in(%s) and time > %s", groupId, tagId, + reason_sql, time); + String sql = String.format("SELECT mgr_id,hp,reason,cur_hp,time,info,roomid " + "FROM group_hp_log %s " + + "ORDER BY time desc " + "limit %s,%s", where_sql, limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + int mgr_id = obj.getInt("mgr_id"); + if (mgr_id > 0) { + AccountBean acc = AccountCache.getAccount(obj.getInt("mgr_id")); + obj.putString("m_nick", acc.nick); + } + } + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + resData.putTArray("hp_logs", arr); + return resData; + } + + /** + * 体力值详情 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @param choose + * @return + */ + public static final ITObject getHpLogDetailInfo(int groupId, int tagId, String roomId, int time) throws Exception { + String reason_sql = StringUtil.Empty; + reason_sql += ConsumeCode.HP_CLEARING + ","; + reason_sql += ConsumeCode.HP_PUMP + ","; + reason_sql += ConsumeCode.HP_XIPAI_PUMP + ","; + if (StringUtil.isNotEmpty(reason_sql)) { + reason_sql = reason_sql.substring(0, reason_sql.length() - 1); + } else { + reason_sql = "0"; + } + + String where_sql = String.format( + "WHERE gid = %s and uid =%s and reason in(%s) and roomId ='%s' and time >= %s and time <= %s", groupId, + tagId, reason_sql, roomId, time - 7200, time + 3600); + String sql = String.format( + "SELECT mgr_id,hp,reason,cur_hp,time,info,roomid " + "FROM group_hp_log %s " + "ORDER BY time desc", + where_sql); + try { + ITArray arr = DataBase.use().executeQueryByTArray(sql); + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + int mgr_id = obj.getInt("mgr_id"); + if (mgr_id > 0) { + AccountBean acc = AccountCache.getAccount(obj.getInt("mgr_id")); + obj.putString("m_nick", acc.nick); + } + } + ITObject resData = TObject.newInstance(); + resData.putTArray("hp_logs", arr); + return resData; + } catch (Exception e) { + log.info("sql error:" + sql); + log.error(e); + } + + ITObject resData = TObject.newInstance(); + return resData; + } + + private static final int _getCountValue(Jedis jedis9, String key, int beginTime, int endTime) { + String str = null; + int tem = beginTime; + int tem_day = (endTime - beginTime) / 86400; + int count = 0; + for (int k = 0; k < tem_day; ++k) { + String tem_key = String.format("%s:d%s", key, tem); + str = jedis9.get(tem_key); + if (StringUtil.isNotEmpty(str)) { + count += Integer.parseInt(str); + } + tem += 86400; + } + return count; + } + + private static final int _getValue(Jedis jedis9, String key) { + + int count = 0; + String str = jedis9.get(key); + if (StringUtil.isNotEmpty(str)) { + count = Integer.parseInt(str); + } + return count; + } + + /** + * 获取奖励日志 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @param beginTime + * @param endTime + * @return + * @throws Exception + */ + public static final ITObject getRewardLog(int groupId, int tagId, int limit, int num, int beginTime, int endTime) + throws Exception { + String where_sql = String.format( + "WHERE gid = %s and (reason = %s or reason = %s ) and time>=%s and time <=%s and uid=%s and hp != 0", + groupId, ConsumeCode.HP_PARTNER_REWARD, ConsumeCode.HP_PARTNER_XIPAI_REWARD, beginTime, endTime, tagId); + int total_num = 0; + int total_hp = 0; + if (limit == 0) { + String count_sql = String.format( + "SELECT IFNULL(SUM(round),0) AS num,IFNULL(SUM(hp),0) AS total_hp FROM group_hp_log %s", where_sql); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + total_num = obj.getDouble("num").intValue(); + total_hp = obj.getDouble("total_hp").intValue(); + } + } + + String sql = String.format( + "SELECT hp,pid,roomid,time,round,reason,info FROM group_hp_log %s ORDER BY time desc limit %s,%s", + where_sql, limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + resData.putTArray("reward_logs", arr); + resData.putInt("total_num", total_num); + resData.putInt("total_hp", total_hp); + return resData; + } + + /** + * 奖励统计 + * + * @param groupId + * @param pid + * @param beginTime + * @param endTime + * @return + */ + public static final ITObject getRewardLogCount(int groupId, int pid, int beginTime, int endTime) { + String p_key = pid > 0 ? (":p" + pid) : StringUtil.Empty; + String valid_key = String.format("g%s:valid_room%s", groupId, p_key); + String round_key = String.format("g%s:round%s", groupId, p_key); + String hp_cost_key = String.format("g%s:hp_cost%s", groupId, p_key); + String hp_reward_key = String.format("g%s:hp_reward%s", groupId, p_key); + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + int v_round = _getCountValue(jedis9, valid_key, beginTime, endTime); + int round = _getCountValue(jedis9, round_key, beginTime, endTime); + int hp_cost = _getCountValue(jedis9, hp_cost_key, beginTime, endTime); + int hp_reward = _getCountValue(jedis9, hp_reward_key, beginTime, endTime); + ITObject resData = TObject.newInstance(); + resData.putInt("v_round", v_round); + resData.putInt("round", round); + resData.putInt("hp_cost", hp_cost); + resData.putInt("gains", hp_cost - hp_reward); + return resData; + } finally { + jedis9.close(); + } + + } + + /** + * 体力值提取记录 + * + * @param groupId + * @param tagid + * @param limit + * @param num + * @param beginTime + * @param endTime + * @return + * @throws Exception + */ + public static final ITObject getHpLogTakeInfo(int groupId, int uid, int tagId, int limit, int num, int beginTime, + int endTime) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + String where_sql = String.format("WHERE gid = %s and uid=%s and reason = %s and time>=%s and time <=%s", + groupId, tagId, ConsumeCode.HP_TAKE_REWARD, beginTime, endTime); + + String sql = String.format("SELECT hp,time FROM group_hp_log %s ORDER BY time desc limit %s,%s", where_sql, + limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + resData.putTArray("hp_logs", arr); + return resData; + } + + public static final ITObject getHpLogTakeBankInfo(int groupId, int uid, int tagId, int limit, int num, + int beginTime, int endTime) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + String where_sql = String.format( + "WHERE gid = %s and uid=%s and (reason = %s or reason = %s) and time>=%s and time <=%s", groupId, tagId, + ConsumeCode.HP_TAKE_BANK, ConsumeCode.HP_SAVE_BANK, beginTime, endTime); + + String sql = String.format("SELECT hp,time FROM group_hp_log %s ORDER BY time desc limit %s,%s", where_sql, + limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + ITObject resData = TObject.newInstance(); + resData.putInt("limit", limit); + resData.putTArray("hp_logs", arr); + return resData; + } + + /** + * 获取消耗统计 + * + * @param groupId + * @return + */ + public static final ITObject getCostCountByGroup(int groupId, int uid, int beginTime, int endTime) { + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + ITObject obj = TObject.newInstance(); + try { + + String valid_key = String.format("g%s:valid_room", groupId); + obj.putInt("valid", _getCountValue(jedis9, valid_key, beginTime, endTime) * 100); +// g{876129}:valid_diamo:d1756742400 + Long win_count = 0L; + Long round = 0L; + int diamoCost = 0; + String diamo_cost_key = String.format("g{%s}:valid_diamo:d%s", groupId, beginTime); + log.info("diamo_cost_key:" + diamo_cost_key); + diamoCost = jedis9.get(diamo_cost_key) == null ? 0 : Integer.parseInt(jedis9.get(diamo_cost_key)); + + String sql = String.format("SELECT COUNT(DISTINCT roomid) as uidCount FROM group_hp_log WHERE gid='%s'" + + " AND hp>0 and time>=%d and time<=%d ", groupId, beginTime, endTime); + log.info("win_count_sql:" + sql); + ITArray list = DataBase.use().executeQueryByTArray(sql); + if (list.size() > 0) { + ITObject winCount = list.getTObject(0); + win_count += winCount.getLong("uidCount"); + } + + String totalRoundsql = String + .format("SELECT COUNT(DISTINCT roomid) as uidCount FROM group_hp_log WHERE gid='%s'" + + " and time>=%d and time<=%d ", groupId, beginTime, endTime); + log.info("win_count_sql:" + sql); + ITArray totalRoundlist = DataBase.use().executeQueryByTArray(totalRoundsql); + if (totalRoundlist.size() > 0) { + ITObject totalRound = totalRoundlist.getTObject(0); + round += totalRound.getLong("uidCount"); + } + + // 剩余房卡 + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo") == null ? "0" + : jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + + obj.putInt("diamo", groupDiamo); + obj.putInt("diamo_cost", diamoCost); + + obj.putLong("win_count", win_count); + obj.putLong("round", round); + String dayType = jedis10.hget("g{" + groupId + "}:daysave", "daysave"); + obj.putInt("dayType", dayType == null ? 1 : Integer.parseInt(dayType)); + + } catch (SQLException e) { + e.printStackTrace(); + } finally { + jedis9.close(); + jedis10.close(); + } + return obj; + } + + /** + * 获取消耗统计 + * + * @param groupId + * @return + */ + public static final ITArray getCostCount(int groupId, int uid, int beginTime, int endTime) { + String gp_key = GroupCache.genPidsKey(groupId); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + + Set pids = jedis11.zrangeByScore(gp_key, 10, 11); + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + ITArray arr = TArray.newInstance(); + try { + if (uid_bean.lev < 3) { + for (String pid : pids) { + + ITObject obj = TObject.newInstance(); + + String round_key = String.format("g%s:round:p%s", groupId, pid); + obj.putInt("round", _getCountValue(jedis9, round_key, beginTime, endTime) * 100); + + String valid_key = String.format("g%s:valid_room:p%s", groupId, pid); + obj.putInt("valid", _getCountValue(jedis9, valid_key, beginTime, endTime) * 100); + + String no_valid_key = String.format("g%s:no_valid_room:p%s", groupId, pid); + obj.putInt("no_valid", _getCountValue(jedis9, no_valid_key, beginTime, endTime) * 100); + + String diamo_cost_key = String.format("g%s:diamo_cost:p%s", groupId, pid); + obj.putInt("diamo_cost", _getCountValue(jedis9, diamo_cost_key, beginTime, endTime) * 100); + + obj.putInt("pid", Integer.parseInt(pid)); + + arr.addTObject(obj); + } + } else { + for (String pid : pids) { + + ITObject obj = TObject.newInstance(); + String round_key = String.format("g{%s}:m%s:all_count:p%s", groupId, uid, pid); + int all_round = _getCountValue(jedis9, round_key, beginTime, endTime); + obj.putInt("round", all_round); + + String valid_key = String.format("g{%s}:m%s:valid_round2:p%s", groupId, uid, pid); + int valid = _getCountValue(jedis9, valid_key, beginTime, endTime); + obj.putInt("valid", valid); + + int no_valid_key = all_round - valid; + obj.putInt("no_valid", no_valid_key); + + String diamo_cost_key = String.format("g{%s}:m%s:valid_diamo:p%s", groupId, uid, pid); + obj.putInt("diamo_cost", _getCountValue(jedis9, diamo_cost_key, beginTime, endTime) * 100); + + obj.putInt("pid", Integer.parseInt(pid)); + + arr.addTObject(obj); + } + } + } finally { + jedis9.close(); + jedis11.close(); + } + return arr; + } + + /** + * 获取局数统计 + * + * @param groupId + * @return + */ + public static final ITArray getRoundCount(int groupId, int pid) { + int bengin = DateUtils.getBeginDay() - 29 * 86400; + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + ITArray arr = TArray.newInstance(); + try { + String p_key = pid > 0 ? (":p" + pid) : StringUtil.Empty; + for (int i = 0; i < 30; ++i) { + String round_key = String.format("g%s:round%s:d%s", groupId, p_key, bengin); + String r_str = jedis9.get(round_key); + ITObject obj = TObject.newInstance(); + obj.putInt("time", bengin); + int r_num = 0; + if (StringUtil.isNotEmpty(r_str)) { + r_num = Integer.parseInt(r_str); + } + obj.putInt("num", r_num); + arr.addTObject(obj); + bengin += 86400; + } + } finally { + jedis9.close(); + } + return arr; + } + + /** + * 获取体力值消耗统计 + * + * @param groupId + * @return + */ + public static final ITArray getHpConsumeCount(int groupId, int uid) { + int bengin = DateUtils.getBeginDay() - 2 * 86400; + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + ITArray arr = TArray.newInstance(); + try { + String key = String.format("g%s:m%s:consume_hp", groupId, uid); + for (int i = 0; i < 3; ++i) { + String hp_key = String.format("%s:d%s", key, bengin); + String r_str = jedis9.get(hp_key); + ITObject obj = TObject.newInstance(); + obj.putInt("time", bengin); + int r_num = 0; + if (StringUtil.isNotEmpty(r_str)) { + r_num = Integer.parseInt(r_str); + } + obj.putInt("num", r_num); + arr.addTObject(obj); + bengin += 86400; + } + } finally { + jedis9.close(); + } + return arr; + } + + /** + * 获取体力值统计信息 + * + * @param groupId + * @return + * @throws Exception + */ + public static final ITObject getHpCountInfo(int groupId) throws Exception { + String sql = String.format("SELECT uid FROM group_member WHERE groupId=%s" + " AND partnerLev >0", groupId); + ITArray list = DataBase.use().executeQueryByTArray(sql); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int _t_hp = 0; + try { + for (int i = 0; i < list.size(); ++i) { + ITObject obj = list.getTObject(i); + int parentId = obj.getInt("uid"); + String key = String.format("g{%s}:m%s:reward_hp", groupId, parentId); + String r_hp = jedis10.get(key); + if (StringUtil.isNotEmpty(r_hp)) { + _t_hp += Integer.parseInt(r_hp); + } + } + } finally { + jedis10.close(); + } + String where = String.format("FROM group_member WHERE groupId = %s", groupId); + String count_sql = String.format("SELECT (SELECT IFNULL(SUM(hp),0) %s AND hp >0) t_hp1," + + " (SELECT IFNULL(SUM(ABS(hp)),0) %s AND hp <0) t_hp2", where, where); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + ITObject obj1 = TObject.newInstance(); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + obj1.putLong("hp_num1", obj.getDouble("t_hp1").longValue()); + obj1.putLong("hp_num2", obj.getDouble("t_hp2").longValue()); + } else { + obj1.putLong("hp_num1", 0); + obj1.putLong("hp_num2", 0); + } + obj1.putLong("hp_num3", _t_hp); + return obj1; + } + + public static void readRecords(ITArray militarys, int setRead, int tagId) { + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + for (int i = 0; i < militarys.size(); i++) { + String military = militarys.getString(i); + jedis5.hset(military, "is_read_" + tagId, setRead + ""); + + String groupId = jedis5.hget(military, "groupId"); + String gameId = jedis5.hget(military, "game_id"); + String gameTypeString = jedis1.hget("game:" + gameId, "gameType"); + int gameType = Integer.parseInt(gameTypeString); + String totalScore = jedis5.hget(military, "totalScore"); + int readTime = Integer.parseInt(jedis5.hget(military, "create_time")); + + ITArray players = TArray.newFromJsonData(totalScore); + for (int j = 0; j < players.size(); j++) { + ITObject player = players.getTObject(j); + int playerId = player.getInt("accId"); + + if (tagId != playerId) { + continue; + } + int score = player.getInt("score"); + String playerIdKey = "g{" + groupId + "}:" + "m" + playerId; + String lost_mj_score = jedis10.hget(playerIdKey, "lost_mj_score") == null ? "0" + : jedis10.hget(playerIdKey, "lost_mj_score"); + String lost_pk_score = jedis10.hget(playerIdKey, "lost_pk_score") == null ? "0" + : jedis10.hget(playerIdKey, "lost_pk_score"); + String lost_mj_score_before = jedis10.hget(playerIdKey, "lost_mj_score_before") == null ? "0" + : jedis10.hget(playerIdKey, "lost_mj_score_before"); + String lost_pk_score_before = jedis10.hget(playerIdKey, "lost_pk_score_before") == null ? "0" + : jedis10.hget(playerIdKey, "lost_pk_score_before"); + + if (gameType == 2) { + log.info("阅读扑克:" + gameType); + log.info("阅读扑克:" + lost_pk_score); + log.info("阅读扑克:" + score); + + // 如果是0则代表将分数设置为未读,扣除分数 + if (setRead == 0) { + // 检查是今天还是昨天的战绩 + if (readTime < DateUtils.getBeginDay()) { + jedis10.hset(playerIdKey, "lost_pk_score_before", + Integer.parseInt(lost_pk_score_before) + score + ""); + } else { + jedis10.hset(playerIdKey, "lost_pk_score", + Integer.parseInt(lost_pk_score) + score + ""); + } + } else { + if (readTime < DateUtils.getBeginDay()) { + jedis10.hset(playerIdKey, "lost_pk_score_before", + Integer.parseInt(lost_pk_score_before) - score + ""); + } else { + jedis10.hset(playerIdKey, "lost_pk_score", + Integer.parseInt(lost_pk_score) - score + ""); + } + } + + } else if (gameType == 1) { + log.info("阅读麻将:" + gameType); + log.info("阅读麻将:" + lost_mj_score); + log.info("阅读麻将:" + score); + + // 如果是0则代表将分数设置为未读,扣除分数 + if (setRead == 0) { + if (readTime < DateUtils.getBeginDay()) { + jedis10.hset(playerIdKey, "lost_mj_score_before", + Integer.parseInt(lost_mj_score_before) + score + ""); + + } else { + jedis10.hset(playerIdKey, "lost_mj_score", + Integer.parseInt(lost_mj_score) + score + ""); + } + } else { + if (readTime < DateUtils.getBeginDay()) { + jedis10.hset(playerIdKey, "lost_mj_score_before", + Integer.parseInt(lost_mj_score_before) - score + ""); + + } else { + jedis10.hset(playerIdKey, "lost_mj_score", + Integer.parseInt(lost_mj_score) - score + ""); + } + + } + + } + + } + } + } finally { + jedis10.close(); + jedis1.close(); + jedis5.close(); + } + + } +} diff --git a/web_group/src/main/java/com/group/service/GroupPublisherService.java b/web_group/src/main/java/com/group/service/GroupPublisherService.java new file mode 100644 index 0000000..559c21e --- /dev/null +++ b/web_group/src/main/java/com/group/service/GroupPublisherService.java @@ -0,0 +1,328 @@ +package com.group.service; + +import com.group.controller.GroupController; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; +import jdk.nashorn.internal.objects.Global; +import redis.clients.jedis.Jedis; + +public class GroupPublisherService { + + private final static Logger log; + + static { + log = Logger.getLogger(GroupController.class); + } + + public static final String CHANNEL_NAME = "mgr_group"; + + private static final String CMD_ADD_ROOM = "add_room"; + private static final String CMD_DEL_ROOM = "del_room"; + private static final String CMD_DEL_PLAY = "del_play"; + private static final String CMD_ADD_PLAY = "add_play"; + private static final String CMD_UPDATE_PLAY = "update_play"; + private static final String CMD_DEL_GROUP = "del_group"; + private static final String CMD_UPDATE_GROUP = "update_group"; + + private static final String CMD_UPDATE_JOINS = "update_joins"; + private static final String CMD_UPDATE_MAIL_TIP = "update_mail_tip"; + + // 拒接申请推送 + public static final String CMD_REFUSE_ENTER_GROUP = "family_refuse"; + + // 申请进入亲友圈允许 前端刷新申请数量 + public static final String CMD_ALLOW_ENTER_GROUP = "family_reflash"; + + // 退出亲友圈推送 + public static final String CMD_QUIT_GROUP = "quit_group"; + + // 申请成功加入亲友全友圈推送 + public static final String CMD_APPLY_SUCCESS = "apply_success"; + + // 在线用户推送 + public static final String CMD_ONLINE_USERS = "online_users"; + + // 禁止娱乐 + public static final String CMD_BAN_PLAY = "ban_play"; + + // 聊天室按钮 + public static final String CMD_ROOM_BUTTON = "room_button"; + + // 修改公告 + public static final String CMD_UPDATE_NOTICE = "update_notice"; + + public static void addRoomEvt(int groupId, String roomid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("roomid", roomid); + data.putString("cmd", CMD_ADD_ROOM); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + public static void roomButton(int groupId, String isWatch) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("isWatch", isWatch); + data.putString("cmd", CMD_ROOM_BUTTON); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void delRoomEvt(int groupId, String roomid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("roomid", roomid); + data.putString("cmd", CMD_DEL_ROOM); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + public static void delPlayEvt(int groupId, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("pid", pid); + data.putString("cmd", CMD_DEL_PLAY); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void addPlayEvt(int groupId, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("pid", pid); + data.putString("cmd", CMD_ADD_PLAY); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void publishNotice(int groupId, String notice) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("notice", notice); + data.putString("cmd", CMD_UPDATE_NOTICE); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + + } + + public static void updatePlayEvt(int groupId, int pid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("pid", pid); + data.putString("cmd", CMD_UPDATE_PLAY); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void delGroupEvt(int groupId) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("cmd", CMD_DEL_GROUP); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void updateGroupEvt(int groupId, String name, boolean ban, String notice, int option, int showNum) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putString("cmd", CMD_UPDATE_GROUP); + data.putString("name", name); + data.putBoolean("ban", ban); + data.putString("notice", notice); + data.putInt("option", option); + data.putInt("show_num", showNum); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + public static void updateJoinsEvt(int groupId, int joins, String remark, int ReadStatus, String nick, + String portrait, String reg_time, String id) { + log.info("进入updateJoinsEvt----------参数:" + joins + "--------" + remark + "--------" + ReadStatus); + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("joins", joins); + data.putString("remark", remark); + data.putInt("read_status", ReadStatus); + data.putString("nick", nick); + data.putString("portrait", portrait); + data.putString("reg_time", reg_time); + data.putString("uid", id); + data.putString("cmd", CMD_UPDATE_JOINS); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + // 允许 + public static void familyReflash(int groupId, int joins, String remark, int ReadStatus, int tagId, boolean allow) { + log.info("familyReflash----------参数:" + joins + "--------" + remark + "--------" + ReadStatus); + ITObject data = TObject.newInstance(); + data.putBoolean("allow", allow); + data.putInt("tag_id", tagId); + data.putInt("gid", groupId); + data.putInt("joins", joins); + data.putString("remark", remark); + data.putInt("read_status", ReadStatus); + data.putString("cmd", CMD_ALLOW_ENTER_GROUP); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + public static void joinFamily(int groupId, int joins, String remark, int ReadStatus, int tagId, boolean allow, + ITObject users, String name) { + log.info("joinFamily----------参数:" + joins + "--------" + remark + "--------" + ReadStatus); + ITObject data = TObject.newInstance(); + data.putBoolean("allow", allow); + data.putInt("tag_id", tagId); + data.putInt("gid", groupId); + data.putInt("joins", joins); + data.putString("remark", remark); + data.putInt("read_status", ReadStatus); + data.putTObject("users", users); + data.putString("name", name); + data.putString("cmd", CMD_APPLY_SUCCESS); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + public static void updateMailTipEvt(int groupId, int uid) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("uid", uid); + data.putString("cmd", CMD_UPDATE_MAIL_TIP); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + // 拒绝 + public static void familyRefuse(int groupId, int uid, int joins) { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("uid", uid); + data.putInt("joins", joins); + data.putString("cmd", CMD_REFUSE_ENTER_GROUP); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.publish(CHANNEL_NAME, data.toJson()); + jedis11.close(); + } + + // 禁止娱乐 + public static void banPlay(int groupId, int uid, int ban) throws Exception { + log.info("banPlay pid:" + uid + " ban:" + ban); + TObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("uid", uid); + data.putInt("ban", ban); + data.putString("cmd", CMD_BAN_PLAY); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + public static void quitGroup(int groupId, int tagId, String outs, String nick) { + log.info("退出圈子----------参数:" + groupId + "--------"); + + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("tagId", tagId); + data.putString("outs", outs); + data.putString("name", nick); + data.putString("cmd", CMD_QUIT_GROUP); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + jedis.publish(CHANNEL_NAME, data.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jedis.close(); + } + } + + /** + * 1 hp 2 等级 3 合伙人等级 + * + * @param groupId + * @param uid + * @param type + * @param value + */ + public static void updateMemberEvt(int groupId, int uid, int type, int value) { +// if (type == 1) { +// return; +// } +// ITObject data = TObject.newInstance(); +// data.putInt("gid", groupId); +// data.putInt("uid", uid); +// data.putInt("type", type); +// data.putInt("value", value); +// data.putString("cmd", CMD_UPDATE_MEMBER); +// Redis.use("group1_db11").publish(CHANNEL_NAME, data.toJson()); + } + + // 推送在线用户 + public static void updateOnlineUsers(int groupId, int uid) { +//// log.info("推送在线用户-----"+groupId+"-------"+uid); + Jedis jedis = Redis.use("group1_db11").getJedis(); + try { + ITObject data = TObject.newInstance(); + data.putInt("gid", groupId); + data.putInt("uid", uid); + data.putString("cmd", CMD_ONLINE_USERS); + jedis.publish(CHANNEL_NAME, data.toJson()); + }finally { + if (jedis != null) { + jedis.close(); // 确保连接返回到连接池 + } + } + } + +} diff --git a/web_group/src/main/java/com/group/service/GroupRoomService.java b/web_group/src/main/java/com/group/service/GroupRoomService.java new file mode 100644 index 0000000..fae265a --- /dev/null +++ b/web_group/src/main/java/com/group/service/GroupRoomService.java @@ -0,0 +1,1596 @@ +package com.group.service; + +import java.util.*; + +import com.data.bean.*; +import com.data.cache.AccountCache; +import com.data.cache.BaseCache; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.ErrorCode; +import com.data.util.EventType; +import com.data.util.Utility; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class GroupRoomService { + private static final Logger log = Logger.getLogger(GroupRoomService.class); + + /** 解散时间 */ + private static final String[] DISMISS_TIME = { "30", "60", "90", "180" }; + /** 踢出时间 */ + private static final String[] KICK_TIME = { "30", "60", "120", "180" }; + + private static final String _getSvr(Jedis jedis0, GameBean gb) { + String svr = null; + Set gamesvrs = gb.svr_list; + Integer conns = null; + for (String str : gamesvrs) { + String currConns = jedis0.hget(str, "conns"); + if (conns == null && currConns != null + || (conns != null && currConns != null && Integer.parseInt(currConns) < conns)) { + conns = Integer.parseInt(currConns); + svr = str; + } + } + return svr; + } + + // 创建房间 + private final static String createGroupRoom(String session, int groupId, int pid, int tagId) throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + try { + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + if (gpb == null) { + throw new WebException(ErrorCode.GROUP_PLAY_EXIST); + } + + int gameId = gpb.gameId; + GameBean gb = GameCache.getGame(gameId); + String svr = _getSvr(jedis0, gb); + if (svr == null) { + log.error("createGroupRoom gameId:" + gameId + " svr:" + svr); + throw new WebException(ErrorCode.NO_SERVICE); + } + + String grooms_key = GroupCache.genRoomsKey(groupId); + GroupBean group = GroupCache.getGroup(groupId); + ITObject configData = TObject.newFromJsonData(gpb.config); + int maxPlayers = gpb.maxPlayers; + + int opt = configData.getInt("opt"); + + String owner_session = AccountCache.genKey(group.owner); + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + if (pay == null) { + log.warn("pay no set!"); + throw new WebException(ErrorCode._FAILED); + } + + // g{373014}:diamo + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo") == null ? "0" + : jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + + if (pay > 0) { + if (groupDiamo - pay < 0) { + log.error("createGroupRoom groupId:" + groupId + " pid:" + pid + " group.owner:" + group.owner + + " no diamo"); + throw new WebException(ErrorCode.NO_DIAMO); + } + log.info("预扣房卡" + pay); + jedis10.hset("g{" + groupId + "}:diamo", "diamo", (groupDiamo - pay) + ""); + // 保存预扣房卡消息 + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + groupId, 0, groupDiamo+pay, pay, System.currentTimeMillis(), 0,0,gb.name,""); + DataBase.use().executeUpdate(messagesql); + + } + String ban = jedis10.hget("g{" + groupId + "}:m" + tagId, "ban"); + + if (StringUtil.isNotEmpty(ban) && ban.equals("1")) { + throw new WebException(ErrorCode.GROUP_MEMBER_BAN); + } + +// if (pay > 0) { +// ArrayList result_list = Utility.payDiamo(jedis0, owner_session, pay); +// if (result_list == null) { +// throw new WebException(ErrorCode._FAILED); +// } +// long result = result_list.get(0); +// if (result != 0) { +// log.error("createGroupRoom groupId:" + groupId + " pid:" + pid + " group.owner:" + group.owner +// + " no diamo"); +// throw new WebException(ErrorCode.NO_DIAMO); +// } +// long cur_diamo = result_list.get(1); +// Utility.payDiamo(EventType.REDIS_EVENT_GROUP_ROOM, group.owner, gameId, pay, (int) cur_diamo, groupId, +// pid); +// } + + int dissolve_opt = group.dissolve_opt; + int kick_opt = group.kick_opt; + + String newRoomId = Redis.use("group1_db1").rpop("free_room"); + Redis.use("group1_db1").lpush("free_room", newRoomId); + String room_key = "room:" + newRoomId; + + long time = System.currentTimeMillis() / 1000; + Map roomMap = new HashMap(); + roomMap.put("id", newRoomId); + roomMap.put("owner", owner_session); + roomMap.put("svr", svr); + roomMap.put("AA", "0"); + roomMap.put("pay", pay + ""); + roomMap.put("agent", "1"); + roomMap.put("group", groupId + ""); + roomMap.put("gpid", pid + ""); + String playingGroupIdKey = "g{" + groupId + "}:play:" + pid; + String pname = jedis11.hget(playingGroupIdKey, "name"); + roomMap.put("gpname", pname + ""); + + roomMap.put("payer", group.owner + ""); + roomMap.put("maxPlayers", maxPlayers + ""); + roomMap.put("times", gb.opt.get(opt) + ""); + roomMap.put("opt", opt + ""); + roomMap.put("status", "0"); + roomMap.put("hpOnOff", gpb.hpOnOff + ""); + roomMap.put("rewardType", gpb.rewardType + ""); + roomMap.put("rewardValueType", gpb.rewardValueType + ""); + roomMap.put("xipai_rewardType", gpb.xipai_rewardType + ""); + roomMap.put("xipai_rewardValueType", gpb.xipai_rewardValueType + ""); + roomMap.put("dismiss_time", DISMISS_TIME[dissolve_opt - 1]); + roomMap.put("kick_time", KICK_TIME[kick_opt - 1]); + roomMap.put("hp_times", gpb.hp_times + ""); + roomMap.put("BanChat", gpb.BanChat + ""); + roomMap.put("BanMissile", gpb.BanMissile + ""); + if (gpb.hpOnOff == 1) { + ITObject hpObj = TObject.newFromJsonData(gpb.hpConfig); + if (hpObj.getInt("limitInRoom") != null) { + roomMap.put("limitInRoom", hpObj.getInt("limitInRoom") + ""); + } + configData.putTObject("hpData", hpObj); + } + + configData.del("opt"); + configData.del("AA"); + roomMap.put("options", configData.toJson()); + roomMap.put("game", gameId + ""); + roomMap.put("open", "1"); + roomMap.put("round", "0"); + roomMap.put("create_time", time + ""); + roomMap.put("cache_ver", "1"); + jedis0.hmset(room_key, roomMap); + + /** + * pid open status 剩余空位 11 1 1 00 + */ + + String fake = jedis0.hget(room_key, "fake"); + if (StringUtil.isNotEmpty(fake)) { + log.info("create room:" + newRoomId + " session:" + session + " fake:" + fake + " pay:" + pay + + " players:" + jedis0.hget(room_key, "players")); + jedis0.hset(room_key, "status", 3 + ""); + jedis0.hincrBy(room_key, "cache_ver", 1); + jedis0.expire(room_key, 20); + } else { + jedis11.zadd(grooms_key, pid * 10000 + 1101, room_key); + GroupPublisherService.addRoomEvt(groupId, newRoomId); + } + return room_key; + } finally { + jedis0.close(); + jedis11.close(); + jedis10.close(); + } + + } + + /** + * 检测成员在不在房间里 + * + * @param groupId + * @param + * @return + */ + public static final boolean checkRoom(int groupId, int uid) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + String session = AccountCache.genKey(uid); + String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, uid); + if (StringUtil.isNotEmpty(oldRoom)) { + return true; + } + } finally { + jedis0.close(); + } + return false; + } + + public static final boolean checkRoom(String room_key, Jedis jedis0) { + RedisLock lock = new RedisLock(room_key, jedis0); + lock.lock(); + try { + String status = jedis0.hget(room_key, "status"); + if (StringUtil.isEmpty(status) || status.equals("2")) { + return false; + } + return true; + } finally { + lock.unlock(false); + } + } + + public static final boolean checkFakeRoom(String room_key, Jedis jedis0) { + RedisLock lock = new RedisLock(room_key, jedis0); + lock.lock(); + try { + String fake = jedis0.hget(room_key, "fake"); + if (!StringUtil.isEmpty(fake)) { + return true; + } + return false; + } finally { + lock.unlock(false); + } + } + + private static final ITObject publicJoinRoom(int groupId, String session, String room_key, String platform) + throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + List x_room_list = jedis0.hmget(room_key, "fake"); + String fake_json = x_room_list.get(0); + if (fake_json != null) { + log.error("session:" + session + " public join room:" + room_key + " fail, fake != null"); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + + RedisLock lock = null; + try { + String finalRoom = room_key; + + boolean enter_old = false; + int uid = AccountCache.getAccount(session).id; + String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, uid); + if (StringUtil.isNotEmpty(oldRoom)) { + String group = jedis0.hget(oldRoom, "group"); + if (StringUtil.isEmpty(group) || Integer.parseInt(group) != groupId) { + throw new WebException(ErrorCode.GROUP_NOT_CURGROUP_ROOM); + } + enter_old = true; + finalRoom = oldRoom; + } + + lock = new RedisLock(session, jedis0); + lock.lock(); + List room_list = jedis0.hmget(finalRoom, "hpOnOff", "hp_times", "limitInRoom", "status", "open", + "svr", "game", "gpid", "group", "maxPlayers", "AA", "opt", "players", "BanChat", "BanMissile"); + String status = room_list.get(3); + if (StringUtil.isEmpty(status)) { + throw new WebException(ErrorCode.GROUP_ROOM_DEL); + } + int _status = Integer.parseInt(status); + + if (_status == 2 || _status == 3) { + Utility.delRoomBySession(jedis0, session, finalRoom); + throw new WebException(ErrorCode.GROUP_ROOM_DEL); + } + + String gm_key = GroupMemberCache.genKey(groupId, uid); + int hp_times = 1; + String group = room_list.get(8); + if (StringUtil.isNotEmpty(group)) { + String hp_times_str = room_list.get(1); + hp_times = Integer.parseInt(group) > 0 ? Integer.parseInt(hp_times_str) : 1; + } + int gameId = Integer.parseInt(room_list.get(6)); + int hpOnOff = Integer.parseInt(room_list.get(0)); + int BanMissile = Integer.parseInt(room_list.get(14)); + int BanChat = Integer.parseInt(room_list.get(13)); + GameBean gb = GameCache.getGame(gameId); + String svr = room_list.get(5); + if (svr == null || !jedis0.exists(svr)) { + svr = _getSvr(jedis0, gb); + } + if (svr == null) { + log.error("publicJoinRoom room_key:" + room_key + " gm_key:" + gm_key + " svr:" + svr); + throw new WebException(ErrorCode.NO_SERVICE); + } + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + List list = jedis10.hmget(gm_key, "ban", "hp"); + String ban = list.get(0); + if (StringUtil.isNotEmpty(ban) && ban.equals("1")) { + throw new WebException(ErrorCode.GROUP_MEMBER_BAN); + } + + jedis0.hset(finalRoom, "svr", svr); + + int gpid = Integer.parseInt(room_list.get(7)); + GroupBean group_bean = GroupCache.getGroup(groupId); + if (!enter_old) { + int _maxPlayers = Integer.parseInt(room_list.get(9)); + String _players = room_list.get(12); + if (StringUtil.isNotEmpty(_players)) { + ITArray arr = TArray.newFromJsonData(_players); + if (arr.size() >= _maxPlayers) { + boolean flag = true; + for (int i = 0; i < arr.size(); i++) { + int player_id = arr.getInt(i); + if (player_id == uid) { + flag = false; + } + } + + if (flag) { + log.info("publicJoinRoom enter group fail, room full:" + gm_key + " room_key:" + room_key); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + } + } + + String open = room_list.get(4); + if ((StringUtil.isEmpty(open) || open.equals("0"))) { + log.info("publicJoinRoom enter group fail, room open close:" + gm_key + " room_key:" + room_key); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + int AA = Integer.parseInt(room_list.get(10)); + if (AA == 1) { + int maxPlayers = Integer.parseInt(room_list.get(9)); + int opt = Integer.parseInt(room_list.get(11)); + + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + if (pay == null) { + log.warn("pay no set!"); + throw new WebException(ErrorCode._FAILED); + } + pay = (int) Math.ceil((double) pay / maxPlayers); + int result = Utility.checkRoomDiamo(jedis0, session, pay); + if (result != 0) { + log.error("publicJoinRoom groupId:" + groupId + " no diamo"); + throw new WebException(result); + } + } + + if (group_bean.ban == 1) { + throw new WebException(ErrorCode.GROUP_BAN); + } + GroupPlayBean gpb = GroupCache.getPlay(groupId, gpid); + if (gpb == null || gpb.ban == 1) { + throw new WebException(ErrorCode.GROUP_BAN_PLAY); + } + +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + RedisLock lock2 = new RedisLock(gm_key, jedis10); + try { + lock2.lock(); +// List list = jedis10.hmget(gm_key, "ban", "hp"); +// String ban = list.get(0); +// if (StringUtil.isNotEmpty(ban) && ban.equals("1")) { +// throw new WebException(ErrorCode.GROUP_MEMBER_BAN); +// } + + String ban_key = "ban{" + groupId + "}:" + uid; + Set ban_set = jedis11.smembers(ban_key); + if (ban_set.size() > 0) { + String players = room_list.get(12); + if (StringUtil.isNotEmpty(players)) { + ITArray arr = TArray.newFromJsonData(players); + for (int i = 0; i < arr.size(); ++i) { + String tem = arr.getInt(i) + ""; + if (ban_set.contains(tem)) { + throw new WebException(ErrorCode.GROUP_BAN_DESK); + } + } + } + } + + Set desks_list = jedis11.keys("g{" + groupId + "}:desks:*"); + for (String deskId : desks_list) { + String desk_key = deskId; + if (desk_key.equals(String.format("g{%d}:desks:name", groupId))) { + continue; + } + Set ban_set_list = jedis11.smembers(desk_key); + String players = room_list.get(12); + if (StringUtil.isNotEmpty(players)) { + ITArray arr = TArray.newFromJsonData(players); + if (ban_set_list.contains(String.format("%d", uid))) { + for (int i = 0; i < arr.size(); ++i) { + String tem = arr.getInt(i) + ""; + if (ban_set_list.contains(tem)) { + throw new WebException(ErrorCode.GROUP_BAN_DESK); + } + } + } + } + } + + long uid_hp = Long.parseLong(jedis10.hget(gm_key, "hp")); + + if (uid_hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } +// if (uid_hp <= 0) +// { +// throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); +// } +// String gameId = room_list.get(6); + +// String default_mj_score = jedis10.hget("g{" + groupId + "}:score", "mj_score"); +// String default_pk_score = jedis10.hget("g{" + groupId + "}:score", "pk_score"); +// List game_list = Redis.use("group1_db1").hmget("game:" + gameId, "gameType"); +// GroupMemberBean mgn = GroupCache.getMember(groupId, uid); +// String gameType = game_list.get(0); +// +//// if (mgn.lev == 1) { +// long mj_score = Long +// .parseLong(jedis10.hget(gm_key + ":score", "mj_score") == null ? default_mj_score +// : jedis10.hget(gm_key + ":score", "mj_score")); +// long pk_score = Long +// .parseLong(jedis10.hget(gm_key + ":score", "pk_score") == null ? default_pk_score +// : jedis10.hget(gm_key + ":score", "pk_score")); +// long lost_mj_score = Long.parseLong(jedis10.hget(gm_key, "lost_mj_score") == null ? "0" +// : jedis10.hget(gm_key, "lost_mj_score")); +// long lost_pk_score = Long.parseLong(jedis10.hget(gm_key, "lost_pk_score") == null ? "0" +// : jedis10.hget(gm_key, "lost_pk_score")); +// +// int dayType = jedis10.hget("g{" + groupId + "}:daysave", "daysave") == null ? 0 +// : Integer.parseInt(jedis10.hget("g{" + groupId + "}:daysave", "daysave")); +// +// if (dayType == 2) { +// lost_mj_score += Long.parseLong(jedis10.hget(gm_key, "lost_mj_score_before") == null ? "0" +// : jedis10.hget(gm_key, "lost_mj_score_before")); +// lost_pk_score += Long.parseLong(jedis10.hget(gm_key, "lost_pk_score_before") == null ? "0" +// : jedis10.hget(gm_key, "lost_pk_score_before")); +// } +// +// log.info("lost_mj_score:" + lost_mj_score); +// log.info("mj_score:" + mj_score); +// +// if (mj_score != 0 && lost_mj_score != 0 && lost_mj_score < mj_score +// && gameType.equalsIgnoreCase("1")) { +// throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); +// } +// +// if (pk_score != 0 && lost_pk_score != 0 && lost_pk_score >= pk_score +// && gameType.equalsIgnoreCase("2")) { +// throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); +// } +// } + + if (hpOnOff == 1) { + String hp = list.get(1); + String limitInRoom = room_list.get(2); + if (Long.parseLong(hp) > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + boolean pass = Redis.use("group1_db1").sismember("pass_games", gameId + ""); + if (!pass && StringUtil.isNotEmpty(limitInRoom)) { + if (Integer.parseInt(hp) < Integer.parseInt(limitInRoom)) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + } + } + jedis0.hset(session, "room", finalRoom); + + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + + List t_list = Utility.getMemberParents(jedis10, groupId, uid, true); + if (t_list != null) { + // 奖励还是佣金? + ITArray list1 = TArray.newInstance(); + String p_reward_key = GroupCache.genRewardKey(groupId, gpid); + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, gpid); + for (Integer par : t_list) { + Double val = jedis10.zscore(p_reward_key, par.toString()); + int r = 0; + if (val != null) { + r = val.intValue(); + } + int x = 0; + Double xipai_val = jedis10.zscore(p_xipai_reward_key, par.toString()); + if (xipai_val != null) { + x = xipai_val.intValue(); + } + if (r > 0 || x > 0) { + ITObject obj = TObject.newInstance(); + obj.putInt("p", par); + if (r > 0) { + obj.putInt("r", r); + } + if (x > 0) { + obj.putInt("x", x); + } + list1.addTObject(obj); + } + } + jedis0.hset(finalRoom, "prs_" + uid, list1.toJson()); + } + } finally { + lock2.unlock(); + jedis11.close(); + } + } + + ITObject resData = TObject.newInstance(); + resData.putString("room_id", finalRoom.replace("room:", "")); + resData.putInt("hp_times", hp_times); + ITObject gameObj = gb.getTObject(); + resData.putTObject("game_info", gameObj); + resData.putInt("status", _status); + List server_ip = jedis0.hmget(svr, "ip", "port", "intranet"); + // resData.putString("server_ip", server_ip.get(0)); + resData.putString("server_ip", server_ip.get(2)); + resData.putString("server_port", server_ip.get(1)); + resData.putInt("groupId", groupId); + resData.putInt("pid", gpid); + resData.putInt("hpOnOff", hpOnOff); + resData.putBoolean("ban_chat1", group_bean.ban_chat1); + resData.putBoolean("ban_chat2", group_bean.ban_chat2); + resData.putInt("BanChat", BanChat); + resData.putInt("BanMissile", BanMissile); + + String lev_str = Redis.use("group1_db10").hget(gm_key, "lev"); + int lev = 3; + if (StringUtil.isNotEmpty(lev_str)) { + lev = Integer.parseInt(lev_str); + } + resData.putInt("lev", lev); + return resData; + } finally { + if (lock != null) + lock.unlock(false); + jedis0.close(); + } + } + + /** + * 加入房间(观战) + * + * @param groupId + * @param roomid + * @param session + * @param platform + * @return + * @throws Exception + */ + public static ITObject joinRoomSpectator(int groupId, String roomid, String session, String platform) + throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + String grooms_key = GroupCache.genRoomsKey(groupId); + String room_key = "room:" + roomid; + Long tem = jedis11.zrank(grooms_key, room_key); + if (tem == null) { + throw new WebException(ErrorCode.NO_ROOM_NUM); + } + +// List room_list = Redis.use("group1_db0").hmget(room_key, "fake"); +// String fake_json = room_list.get(0); +// if (fake_json != null) { +// throw new WebException(ErrorCode.ROOM_CLOSE); +// } +// AccountBean acc = AccountCache.getAccount(session); +// List s_list = Redis.use("group1_db0").hmget(session, "regTime"); +// String robotInfo = s_list.get(0); +// if (StringUtil.isNotEmpty(robotInfo) && robotInfo.equals("9999")) { +// log.error("robot:" + acc.id + " match room error"); +// throw new WebException(ErrorCode.ROOM_CLOSE); +// } +// int uid = AccountCache.getAccount(session).id; +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// List t_list = Utility.getMemberParents(jedis10, groupId, uid, true); +// jedis10.close(); + +// if (t_list != null) { +// // 判断阀值 +// for (Integer par : t_list) { +// // get aoto_score +// String gm_par_key = GroupMemberCache.genKey(groupId, par); +// String autoscore1 = Redis.use("group1_db10").hget(gm_par_key, "autoscore"); +// Integer autoscore = 0; +// if (!StringUtil.isEmpty(autoscore1)) { +// autoscore = Integer.parseInt(autoscore1); +// } +// +// if (autoscore > 0) { +// ITObject totalHp = GroupService.getHpTotal(groupId, par, 30); +// Long hp = totalHp.getLong("hp"); +// if (hp < autoscore) { +// throw new WebException(ErrorCode.GROUP_PARTNER_HP_NOT_ENOUGH); +// } +// } +// } +// } + +// boolean xingyuhao = false; +// if (Redis.use("group1_db1").sismember("gods", Integer.toString(uid))) { +// xingyuhao = true; +// } + +// if (xingyuhao) { +// boolean isSpecialGods = false; +// { +// String specail = Redis.use("group1_db1").hget("gods_special", Integer.toString(uid)); +// if (StringUtil.isNotEmpty(specail)) { +// isSpecialGods = true; +// } +// } +// +// { +// List player_list = Redis.use("group1_db0").hmget(room_key, "players"); +// +// String players_json = player_list.get(0); +// if (StringUtil.isNotEmpty(players_json)) { +// ITArray players = TArray.newFromJsonData(players_json); +// for (int i = 0; i < players.size(); i++) { +// int player_id = players.getInt(i); +// if (player_id == uid) +// continue; +// +// if (Redis.use("group1_db1").sismember("gods", Integer.toString(player_id))) { +// boolean isPlayerSpecialGods = false; +// String specail = Redis.use("group1_db1").hget("gods_special", Integer.toString(player_id)); +// if (StringUtil.isNotEmpty(specail)) { +// isPlayerSpecialGods = true; +// } +// +// if (!isSpecialGods && isPlayerSpecialGods) { +// +// } else { +// if (isSpecialGods && isPlayerSpecialGods) { +// +// } else { +// log.error("xingyun:" + acc.id + " can't join rooms:" + room_key +// + " xingyun playerId:" + player_id); +// throw new WebException(ErrorCode.GROUP_BAN_DESK); +// } +// } +// } +// } +// } +// } +// } + + try { + + jedis0.hset(session, "spectator_room", room_key); +// List room_list = jedis0.hmget(room_key, "hpOnOff", "hp_times", "limitInRoom", "status", "open", +// "svr", "game", "gpid", "group", "maxPlayers", "AA", "opt", "players"); + String tag_key = "room:" + roomid; + +// GameBean gb = GameCache.getGame(room_list.get(6)); + String svr = jedis0.hget(tag_key, "svr"); + ITObject resData = TObject.newInstance(); +// ITObject gameObj = gb.getTObject(); +// resData.putTObject("game_info", gameObj); + List server_ip = jedis0.hmget(svr, "ip", "port", "intranet"); + // resData.putString("server_ip", server_ip.get(0)); + resData.putString("server_ip", server_ip.get(2)); + resData.putString("server_port", server_ip.get(1)); + resData.putInt("groupId", groupId); +// resData.putInt("pid", Integer.parseInt(room_list.get(7))); + return resData; + } finally { + jedis0.close(); + jedis11.close(); + } + } + + /** + * 加入房间 + * + * @param groupId + * @param roomid + * @param session + * @param platform + * @return + * @throws Exception + */ + public static ITObject joinRoom(int groupId, String roomid, String session, String platform, int gameId) + throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + String grooms_key = GroupCache.genRoomsKey(groupId); + String room_key = "room:" + roomid; + Long tem = jedis11.zrank(grooms_key, room_key); + if (tem == null) { + throw new WebException(ErrorCode.NO_ROOM_NUM); + } + + List room_list = jedis0.hmget(room_key, "fake"); + String fake_json = room_list.get(0); + if (fake_json != null) { + throw new WebException(ErrorCode.ROOM_CLOSE); + } + AccountBean acc = AccountCache.getAccount(session); + List s_list = jedis0.hmget(session, "regTime"); + String robotInfo = s_list.get(0); + if (StringUtil.isNotEmpty(robotInfo) && robotInfo.equals("9999")) { + log.error("robot:" + acc.id + " match room error"); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + int uid = AccountCache.getAccount(session).id; + List t_list = Utility.getMemberParents(jedis10, groupId, uid, true); +// jedis10.close(); + + if (t_list != null) { + // 判断阀值 + for (Integer par : t_list) { + // get aoto_score + String gm_par_key = GroupMemberCache.genKey(groupId, par); + String autoscore1 = jedis10.hget(gm_par_key, "autoscore"); + Integer autoscore = 0; + if (!StringUtil.isEmpty(autoscore1)) { + autoscore = Integer.parseInt(autoscore1); + } + + if (autoscore > 0) { + ITObject totalHp = GroupService.getHpTotal(groupId, par, 30); + Long hp = totalHp.getLong("hp"); + if (hp < autoscore) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_NOT_ENOUGH); + } + } + } + } + + boolean xingyuhao = false; + if (jedis1.sismember("gods", Integer.toString(uid))) { + xingyuhao = true; + } + + if (xingyuhao) { + boolean isSpecialGods = false; + { + String specail = jedis1.hget("gods_special", Integer.toString(uid)); + if (StringUtil.isNotEmpty(specail)) { + isSpecialGods = true; + } + } + + { + List player_list = jedis0.hmget(room_key, "players"); + + String players_json = player_list.get(0); + if (StringUtil.isNotEmpty(players_json)) { + ITArray players = TArray.newFromJsonData(players_json); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (player_id == uid) + continue; + + if (jedis1.sismember("gods", Integer.toString(player_id))) { + boolean isPlayerSpecialGods = false; + String specail = jedis1.hget("gods_special", Integer.toString(player_id)); + if (StringUtil.isNotEmpty(specail)) { + isPlayerSpecialGods = true; + } + + if (!isSpecialGods && isPlayerSpecialGods) { + + } else { + if (isSpecialGods && isPlayerSpecialGods) { + + } else { + log.error("xingyun:" + acc.id + " can't join rooms:" + room_key + + " xingyun playerId:" + player_id); + throw new WebException(ErrorCode.GROUP_BAN_DESK); + } + } + } + } + } + } + } + + try { + String gm_key = GroupMemberCache.genKey(groupId, uid); + String default_mj_score = jedis10.hget("g{" + groupId + "}:score", "mj_score"); + String default_pk_score = jedis10.hget("g{" + groupId + "}:score", "pk_score"); + log.info("default_pk_score:" + default_pk_score); + log.info("default_mj_score:" + default_pk_score); + + List game_list = jedis1.hmget("game:" + gameId, "gameType"); + String gameType = game_list.get(0); + // 个人限制 +// String selfScoreKey = "g{" + groupId + "}:m"+uid; + log.info("gm_key:" + gm_key); + + long mjSocreSelf = jedis10.hget(gm_key, "mj_score") == null ? 0 + : Long.parseLong(jedis10.hget(gm_key, "mj_score")); + long pkSocreSelf = jedis10.hget(gm_key, "pk_score") == null ? 0 + : Long.parseLong(jedis10.hget(gm_key, "pk_score")); + log.info("mjSocreSelf:" + mjSocreSelf); + log.info("pkSocreSelf:" + pkSocreSelf); + + long mj_score = 0 - (mjSocreSelf == 0 ? (default_mj_score == null ? 0 : Long.parseLong(default_mj_score)) + : mjSocreSelf); + long pk_score = 0 - (pkSocreSelf == 0 ? (default_pk_score == null ? 0 : Long.parseLong(default_pk_score)) + : pkSocreSelf); + log.info("mj_score:" + mj_score); + log.info("pk_score:" + pk_score); + + long lost_mj_score = Long.parseLong( + jedis10.hget(gm_key, "lost_mj_score") == null ? "0" : jedis10.hget(gm_key, "lost_mj_score")); + long lost_pk_score = Long.parseLong( + jedis10.hget(gm_key, "lost_pk_score") == null ? "0" : jedis10.hget(gm_key, "lost_pk_score")); + + int dayType = jedis10.hget("g{" + groupId + "}:daysave", "daysave") == null ? 0 + : Integer.parseInt(jedis10.hget("g{" + groupId + "}:daysave", "daysave")); + + if (dayType == 2) { + lost_mj_score += Long.parseLong(jedis10.hget(gm_key, "lost_mj_score_before") == null ? "0" + : jedis10.hget(gm_key, "lost_mj_score_before")); + lost_pk_score += Long.parseLong(jedis10.hget(gm_key, "lost_pk_score_before") == null ? "0" + : jedis10.hget(gm_key, "lost_pk_score_before")); + } + + if (mj_score != 0 && lost_mj_score != 0 && lost_mj_score < mj_score && gameType.equalsIgnoreCase("1")) { + log.info("lost_mj_score:" + lost_mj_score); + log.info("mj_score:" + mj_score); + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + log.info("pk_score:" + pk_score); + log.info("lost_pk_score:" + lost_pk_score); + + if (pk_score != 0 && lost_pk_score != 0 && lost_pk_score < pk_score && gameType.equalsIgnoreCase("2")) { + log.info("lost_pk_score:" + lost_pk_score); + log.info("lost_pk_score:" + pk_score); + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + ITObject resData = publicJoinRoom(groupId, session, room_key, platform); + jedis11.zremrangeByScore(grooms_key, 0, 0); + return resData; + } catch (WebException e) { + if (e.getCode() == ErrorCode.GROUP_ROOM_DEL || e.getCode() == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room_key); + } + throw e; + } finally { + jedis11.close(); + jedis10.close(); + jedis0.close(); + jedis1.close(); + + } + } + + /** + * 加入房间 + * + * @param groupId + * @param roomid + * @param session + * @param platform + * @return + * @throws Exception + */ + public static ITObject reloadJoinRoom(int groupId, String roomid, String session, String platform) + throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + String grooms_key = GroupCache.genRoomsKey(groupId); + String room_key = "room:" + roomid; + Long tem = jedis11.zrank(grooms_key, room_key); + if (tem == null) { + throw new WebException(ErrorCode.NO_ROOM_NUM); + } + + List room_list = jedis0.hmget(room_key, "fake"); + String fake_json = room_list.get(0); + if (fake_json != null) { + throw new WebException(ErrorCode.ROOM_CLOSE); + } + AccountBean acc = AccountCache.getAccount(session); + List s_list = jedis0.hmget(session, "regTime"); + String robotInfo = s_list.get(0); + if (StringUtil.isNotEmpty(robotInfo) && robotInfo.equals("9999")) { + log.error("robot:" + acc.id + " match room error"); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + int uid = AccountCache.getAccount(session).id; + List t_list = Utility.getMemberParents(jedis10, groupId, uid, true); + jedis10.close(); + + if (t_list != null) { + // 判断阀值 + for (Integer par : t_list) { + // get aoto_score + String gm_par_key = GroupMemberCache.genKey(groupId, par); + String autoscore1 = jedis10.hget(gm_par_key, "autoscore"); + Integer autoscore = 0; + if (!StringUtil.isEmpty(autoscore1)) { + autoscore = Integer.parseInt(autoscore1); + } + + if (autoscore > 0) { + ITObject totalHp = GroupService.getHpTotal(groupId, par, 30); + Long hp = totalHp.getLong("hp"); + if (hp < autoscore) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_NOT_ENOUGH); + } + } + } + } + + boolean xingyuhao = false; + if (jedis1.sismember("gods", Integer.toString(uid))) { + xingyuhao = true; + } + + if (xingyuhao) { + boolean isSpecialGods = false; + { + String specail = jedis1.hget("gods_special", Integer.toString(uid)); + if (StringUtil.isNotEmpty(specail)) { + isSpecialGods = true; + } + } + + { + List player_list = jedis0.hmget(room_key, "players"); + + String players_json = player_list.get(0); + if (StringUtil.isNotEmpty(players_json)) { + ITArray players = TArray.newFromJsonData(players_json); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (player_id == uid) + continue; + + if (jedis1.sismember("gods", Integer.toString(player_id))) { + boolean isPlayerSpecialGods = false; + String specail = jedis1.hget("gods_special", Integer.toString(player_id)); + if (StringUtil.isNotEmpty(specail)) { + isPlayerSpecialGods = true; + } + + if (!isSpecialGods && isPlayerSpecialGods) { + + } else { + if (isSpecialGods && isPlayerSpecialGods) { + + } else { + log.error("xingyun:" + acc.id + " can't join rooms:" + room_key + + " xingyun playerId:" + player_id); + throw new WebException(ErrorCode.GROUP_BAN_DESK); + } + } + } + } + } + } + } + + try { + ITObject resData = publicJoinRoom(groupId, session, room_key, platform); + jedis11.zremrangeByScore(grooms_key, 0, 0); + return resData; + } catch (WebException e) { + if (e.getCode() == ErrorCode.GROUP_ROOM_DEL || e.getCode() == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room_key); + } + throw e; + } finally { + jedis1.close(); + jedis10.close(); + jedis11.close(); + jedis0.close(); + } + } + + /** + * 匹配房间 + * + * @param groupId + * @param pid + * @param session + * @param platform + * @return + * @throws Exception + */ + public static ITObject matchRoom(int groupId, int pid, String session, String platform, boolean is_null, int gameId) + throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + int min_value = pid * 10000 + 1101; + int max_value = pid * 10000 + (is_null ? 1101 : 9999); + String grooms_key = GroupCache.genRoomsKey(groupId); + ITObject resData = null; + Set rooms = null; + rooms = jedis11.zrevrangeByScore(grooms_key, max_value, min_value); + Set delRooms = new HashSet(); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "fake"); + + String fake_json = room_list.get(0); + if (fake_json == null) { + continue; + } + + delRooms.add(room); + } + rooms.removeAll(delRooms); + + boolean isWhite = false; + boolean isBlack = false; + boolean xingyuhao = false; + AccountBean acc = AccountCache.getAccount(session); + List s_list = jedis0.hmget(session, "regTime"); + String robotInfo = s_list.get(0); + if (StringUtil.isNotEmpty(robotInfo) && robotInfo.equals("9999")) { + log.error("robot:" + acc.id + " match room error"); + throw new WebException(ErrorCode.ROOM_CLOSE); + } + int uid = acc.id; + log.info("match room创建用户id-------------:" + uid); + List t_list = Utility.getMemberParents(jedis10, groupId, uid, true); + String gm_keyx = GroupMemberCache.genKey(groupId, uid); + String blackx = jedis10.hget(gm_keyx, "black"); + if (StringUtil.isNotEmpty(blackx) && blackx.equals("2")) { + isWhite = true; + } + if (StringUtil.isNotEmpty(blackx) && blackx.equals("1")) { + isBlack = true; + } + + if (t_list != null) { + // 判断阀值 + for (Integer par : t_list) { + // get aoto_score + String gm_par_key = GroupMemberCache.genKey(groupId, par); + String autoscore1 = jedis10.hget(gm_par_key, "autoscore"); + Integer autoscore = 0; + if (!StringUtil.isEmpty(autoscore1)) { + autoscore = Integer.parseInt(autoscore1); + } + + if (autoscore > 0) { + ITObject totalHp = GroupService.getHpTotal(groupId, par, 30); + Long hp = totalHp.getLong("hp"); + if (hp < autoscore) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_NOT_ENOUGH); + } + } + } + } + + if (jedis1.sismember("gods", Integer.toString(uid))) { + xingyuhao = true; + } + + if (xingyuhao) { + List blackRooms = new ArrayList<>(); + List whiteRooms = new ArrayList<>(); + List genralRooms = new ArrayList<>(); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "players"); + + String players_json = room_list.get(0); + if (players_json == null) { + continue; + } + + ITArray players = TArray.newFromJsonData(players_json); + + boolean hasblack = false; + boolean haswhite = false; + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (player_id == uid) + continue; + if (jedis1.sismember("gods", Integer.toString(player_id))) { + haswhite = true; + } + String gm_key = GroupMemberCache.genKey(groupId, player_id); + String black = jedis10.hget(gm_key, "black"); + if (StringUtil.isNotEmpty(black) && black.equals("2")) { + haswhite = true; + } + if (StringUtil.isNotEmpty(black) && black.equals("1")) { + hasblack = true; + } + } + + if (haswhite) { + whiteRooms.add(room); + } + if (hasblack) { + blackRooms.add(room); + } + if (haswhite == false && hasblack == false) { + genralRooms.add(room); + } + } + + if (blackRooms.size() == 0) { + blackRooms.addAll(genralRooms); + // if (blackRooms.size() == 0) + // { + // blackRooms.addAll(whiteRooms); + // } + } + + if (blackRooms.size() > 0) { + Collections.shuffle(blackRooms); + + for (String room : blackRooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } + } else if (isWhite) { + List blackRooms = new ArrayList<>(); + List whiteRooms = new ArrayList<>(); + List genralRooms = new ArrayList<>(); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "players"); + + String players_json = room_list.get(0); + if (players_json == null) { + continue; + } + + ITArray players = TArray.newFromJsonData(players_json); + + boolean hasblack = false; + boolean haswhite = false; + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (jedis1.sismember("gods", Integer.toString(player_id))) { + haswhite = true; + } + String gm_key = GroupMemberCache.genKey(groupId, player_id); + String black = jedis10.hget(gm_key, "black"); + if (StringUtil.isNotEmpty(black) && black.equals("2")) { + haswhite = true; + } + if (StringUtil.isNotEmpty(black) && black.equals("1")) { + hasblack = true; + } + } + + if (haswhite) { + whiteRooms.add(room); + } + if (hasblack) { + blackRooms.add(room); + } + if (hasblack == false && haswhite == false) { + genralRooms.add(room); + } + } + + if (blackRooms.size() == 0) { + blackRooms.addAll(genralRooms); + if (blackRooms.size() == 0) { + blackRooms.addAll(whiteRooms); + } + } + + if (blackRooms.size() > 0) { + Collections.shuffle(blackRooms); + + for (String room : blackRooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } else { + for (String room : rooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } + } else if (isBlack) { + List blackRooms = new ArrayList<>(); + List whiteRooms = new ArrayList<>(); + List genralRooms = new ArrayList<>(); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "players"); + + String players_json = room_list.get(0); + if (players_json == null) { + continue; + } + + ITArray players = TArray.newFromJsonData(players_json); + + boolean hasblack = false; + boolean haswhite = false; + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (jedis1.sismember("gods", Integer.toString(player_id))) { + haswhite = true; + } + String gm_key = GroupMemberCache.genKey(groupId, player_id); + String black = jedis10.hget(gm_key, "black"); + if (StringUtil.isNotEmpty(black) && black.equals("1")) { + hasblack = true; + } + if (StringUtil.isNotEmpty(black) && black.equals("2")) { + haswhite = true; + } + } + + if (haswhite) { + whiteRooms.add(room); + } + if (hasblack) { + blackRooms.add(room); + } + if (haswhite == false && hasblack == false) { + genralRooms.add(room); + } + } + + if (whiteRooms.size() == 0) { + whiteRooms.addAll(genralRooms); + if (whiteRooms.size() == 0) { + whiteRooms.addAll(blackRooms); + } + } + + if (whiteRooms.size() > 0) { + Collections.shuffle(whiteRooms); + + for (String room : whiteRooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } else { + for (String room : rooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } + } else { + List blackRooms = new ArrayList<>(); + List whiteRooms = new ArrayList<>(); + List genralRooms = new ArrayList<>(); + for (String room : rooms) { + List room_list = jedis0.hmget(room, "players"); + + String players_json = room_list.get(0); + if (players_json == null) { + continue; + } + + ITArray players = TArray.newFromJsonData(players_json); + + boolean hasblack = false; + boolean haswhite = false; + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + if (jedis1.sismember("gods", Integer.toString(player_id))) { + haswhite = true; + } + String gm_key = GroupMemberCache.genKey(groupId, player_id); + String black = jedis10.hget(gm_key, "black"); + if (StringUtil.isNotEmpty(black) && black.equals("1")) { + hasblack = true; + } + if (StringUtil.isNotEmpty(black) && black.equals("2")) { + haswhite = true; + } + } + + if (haswhite) { + whiteRooms.add(room); + } + if (hasblack) { + blackRooms.add(room); + } + if (hasblack == false && haswhite == false) { + genralRooms.add(room); + } + } + + if (genralRooms.size() == 0) { + genralRooms.addAll(blackRooms); + if (genralRooms.size() == 0) { + genralRooms.addAll(whiteRooms); + } + } + + if (genralRooms.size() > 0) { + Collections.shuffle(genralRooms); + + for (String room : genralRooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } else { + for (String room : rooms) { + try { + resData = publicJoinRoom(groupId, session, room, platform); + break; + } catch (WebException e) { + int code = e.getCode(); + if (code == ErrorCode.GROUP_ROOM_DEL || code == ErrorCode.NO_ROOM_NUM) { + jedis11.zrem(grooms_key, room); + } else if (code == ErrorCode.NO_SERVICE || code == ErrorCode.GROUP_BAN + || code == ErrorCode.GROUP_LIMIT_NO_HP || code == ErrorCode.GROUP_MEMBER_BAN + || code == ErrorCode.GROUP_BAN_PLAY) { + throw e; + } + } + } + } + } + + if (resData == null) { + + String gm_key = GroupMemberCache.genKey(groupId, uid); + String default_mj_score = jedis10.hget("g{" + groupId + "}:score", "mj_score"); + String default_pk_score = jedis10.hget("g{" + groupId + "}:score", "pk_score"); + log.info("default_pk_score:" + default_pk_score); + log.info("default_mj_score:" + default_pk_score); + + List game_list = jedis1.hmget("game:" + gameId, "gameType"); + String gameType = game_list.get(0); + // 个人限制 + long mjSocreSelf = jedis10.hget(gm_key, "mj_score") == null ? 0 + : Long.parseLong(jedis10.hget(gm_key, "mj_score")); + long pkSocreSelf = jedis10.hget(gm_key, "pk_score") == null ? 0 + : Long.parseLong(jedis10.hget(gm_key, "pk_score")); + log.info("mjSocreSelf:" + mjSocreSelf); + log.info("pkSocreSelf:" + pkSocreSelf); + + long mj_score = 0 - (mjSocreSelf == 0 ? (default_mj_score == null ? 0 : Long.parseLong(default_mj_score)) + : mjSocreSelf); + long pk_score = 0 - (pkSocreSelf == 0 ? (default_pk_score == null ? 0 : Long.parseLong(default_pk_score)) + : pkSocreSelf); + log.info("mj_score:" + mj_score); + log.info("pk_score:" + pk_score); + + long lost_mj_score = Long.parseLong( + jedis10.hget(gm_key, "lost_mj_score") == null ? "0" : jedis10.hget(gm_key, "lost_mj_score")); + long lost_pk_score = Long.parseLong( + jedis10.hget(gm_key, "lost_pk_score") == null ? "0" : jedis10.hget(gm_key, "lost_pk_score")); + + int dayType = jedis10.hget("g{" + groupId + "}:daysave", "daysave") == null ? 0 + : Integer.parseInt(jedis10.hget("g{" + groupId + "}:daysave", "daysave")); + + if (dayType == 2) { + lost_mj_score += Long.parseLong(jedis10.hget(gm_key, "lost_mj_score_before") == null ? "0" + : jedis10.hget(gm_key, "lost_mj_score_before")); + lost_pk_score += Long.parseLong(jedis10.hget(gm_key, "lost_pk_score_before") == null ? "0" + : jedis10.hget(gm_key, "lost_pk_score_before")); + } + + if (mj_score != 0 && lost_mj_score != 0 && lost_mj_score < mj_score && gameType.equalsIgnoreCase("1")) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + log.info("lost_pk_score:" + lost_pk_score); + log.info("lost_mj_score:" + lost_mj_score); + + if (pk_score != 0 && lost_pk_score != 0 && lost_pk_score < pk_score && gameType.equalsIgnoreCase("2")) { + throw new WebException(ErrorCode.GROUP_LIMIT_NO_HP); + } + + String key = createGroupRoom(session, groupId, pid, uid); + resData = publicJoinRoom(groupId, session, key, platform); + } + jedis11.zremrangeByScore(grooms_key, 0, 0); + jedis0.close(); + jedis1.close(); + jedis10.close(); + jedis11.close(); + return resData; + } + + /** + * 删除房间 + * + * @param groupId + * @param roomId + * @return + * @throws Exception + */ + public static final ITObject delRoom(int groupId, String roomId) throws Exception { + + String tag_key = "room:" + roomId; + Jedis jedis0 = Redis.use("group1_db0").getJedis(); +// String svr = StringUtil.Empty; + + RedisLock lock = new RedisLock(tag_key, jedis0); + try { + lock.lock(); + List list = jedis0.hmget(tag_key, "AA", "payer", "pay", "group", "game", "status", "gpid", "fake", + "players", "round", "times"); + String status = list.get(5); + if (StringUtil.isEmpty(status)) { + throw new WebException(ErrorCode.NO_ROOM_NUM); + } + int _status = Integer.parseInt(status); + if (_status == 2 || _status == 3) { + throw new WebException(ErrorCode.GROUP_ROOM_DEL); + } + String group = list.get(3); + int _gid = 0; + if (StringUtil.isNotEmpty(group)) { + _gid = Integer.parseInt(group); + } + + String strGpid = list.get(6); + int _gpid = 0; + if (StringUtil.isNotEmpty(strGpid)) { + _gpid = Integer.parseInt(strGpid); + } + if (_gid != groupId) { + throw new WebException(ErrorCode.GROUP_NOT_CURGROUP_ROOM); + } + String strFake = list.get(7); + if (_status == 0) { + if (strFake == null) { + int gameId = Integer.parseInt(list.get(4)); + boolean pay_AA = Integer.parseInt(list.get(0)) == 1; + if (!pay_AA) { + int payer = Integer.parseInt(list.get(1)); + int pay = Integer.parseInt(list.get(2)); + log.info("返回房卡-----------------------"); + Utility.payDiamo(EventType.REDIS_EVENT_BACK_PAY, payer, gameId, pay, groupId, _gpid); + } + } + } + // 游戏中需要返回部分房卡 + log.info("当前状态-----------------------"+_status); + + if (_status == 1) { + if (strFake == null) { + int gameId = Integer.parseInt(list.get(4)); + boolean pay_AA = Integer.parseInt(list.get(0)) == 1; + if (!pay_AA) { + int payer = Integer.parseInt(list.get(1)); + int pay = Integer.parseInt(list.get(2)); + int round = Integer.parseInt(list.get(9)); + int maxRound = Integer.parseInt(list.get(10)); + Utility.payDiamo(EventType.REDIS_EVENT_BACK_PAY, payer, gameId, pay, groupId, _gpid); + +// double payDiamo = Math.ceil((double) pay / maxRound * round); +// int backDiamo = (pay - (int) payDiamo); +// log.info("返回部分房卡-----------------------"); +// //记录日志 +// int diamo = Integer.parseInt(Redis.use("group1_db0").hget("{user}:"+payer, "diamo")); +// String sql = String.format( +// "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state)" +// + " values(%s,%s,%s,%s,%s,%s)", +// 0, 1, diamo, backDiamo, System.currentTimeMillis(), 0); +// +// DataBase.use().executeUpdate(sql); + + } + } + + } + if (strFake != null) { + try { + ITArray players = TArray.newFromJsonData(list.get(8)); + for (int i = 0; i < players.size(); i++) { + int player_id = players.getInt(i); + Redis.use("group1_db1").srem("used_robot", Integer.toString(player_id)); + // Redis.use("group1_db1").sadd("free_robot", Integer.toString(player_id)); + + } + } catch (Exception e) { + + } + } + jedis0.hset(tag_key, "status", "2"); + BaseCache.updateCacheVer(jedis0, tag_key); + GroupPublisherService.delRoomEvt(groupId, roomId); +// svr = jedis0.hget(tag_key, "svr"); +// +// List server_ip = Redis.use("group1_db0").hmget(svr, "ip", "port"); +// String ip = server_ip.get(0); +// if(StringUtil.isEmpty(ip)) { +// throw new WebException(ErrorCode.NO_SERVICE); +// } +// String port =server_ip.get(1); + ITObject obj = TObject.newInstance(); +// obj.putString("ip", ip); +// obj.putInt("port", Integer.parseInt(port)); + + return obj; + } finally { + lock.unlock(); + } + + } +} diff --git a/web_group/src/main/java/com/group/service/GroupService.java b/web_group/src/main/java/com/group/service/GroupService.java new file mode 100644 index 0000000..17bc964 --- /dev/null +++ b/web_group/src/main/java/com/group/service/GroupService.java @@ -0,0 +1,5908 @@ +package com.group.service; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.sql.SQLException; +import java.util.*; + +import com.data.bean.AccountBean; +import com.data.bean.GameBean; +import com.data.bean.GroupBean; +import com.data.bean.GroupMemberBean; +import com.data.bean.GroupPlayBean; +import com.data.cache.AccountCache; +import com.data.cache.BaseCache; +import com.data.cache.GameCache; +import com.data.cache.GroupCache; +import com.data.cache.GroupMemberCache; +import com.data.util.CountUtil; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.group.MainServer; +import com.taurus.core.entity.*; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.WebException; + +import jdk.nashorn.internal.objects.Global; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.Pipeline; + +public class GroupService { + private final static Logger log; + + static { + log = Logger.getLogger(GroupService.class); + } + /** 普通圈子3000 */ + public static final int TYPE_1_NUM = 3000000; + /** 大联盟20000 */ + public static final int TYPE_2_NUM = 3000000; + + /** 删除玩家 */ + public static final int PERMISSION_DEL_MEMBER = 1; + /** 添加玩家 */ + public static final int PERMISSION_ADD_MEMBER = 2; + /** 增减体力值 */ + public static final int PERMISSION_HP_OPT = 4; + /** 禁止娱乐 */ + public static final int PERMISSION_BAN = 8; + /** 禁止同桌 */ + public static final int PERMISSION_BAN_DESKMATE = 16; + + private static ITObject getGroupData(int uid, int groupId, Jedis jedis11, Jedis jedis10, Jedis jedis0) { + GroupBean gb = GroupCache.getGroup(groupId); + String key = GroupCache.genGroupsKey(uid); + String joins_key = GroupCache.genJoinsKey(groupId); + + if (gb == null) + return null; + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + + if (gmb == null) { + return null; + } +// GroupPublisherService.updateOnlineUsers(groupId,uid); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + + ITObject obj = TObject.newInstance(); + obj.putInt("id", groupId); + obj.putString("name", gb.name); + int owner = gb.owner; + if (gmb.lev == 1) { + obj.putInt("owner", owner); + } else { + obj.putInt("owner", 0); + } + obj.putInt("type", gb.type); + + try { + if (uid == gb.owner) { + jedis1.sadd("robot_group", Integer.toString(groupId)); + } + jedis0.hset("{user}:" + uid, "setHome", "enter"); + obj.putBoolean("ban", Boolean.parseBoolean(jedis11.hget("group:" + groupId, "ban"))); + // 获取jedis11中的isShow数据 + obj.putInt("isShow", Integer.parseInt(jedis11.hget("group:" + groupId, "isShow"))); + obj.putBoolean("ban_chat1", Boolean.parseBoolean(jedis11.hget("group:" + groupId, "ban_chat1"))); + obj.putBoolean("ban_chat2", Boolean.parseBoolean(jedis11.hget("group:" + groupId, "ban_chat2"))); + + obj.putInt("messageCount", Integer.parseInt(jedis11.hget("group:" + groupId, "messageCount"))); + obj.putInt("userDiamo", Integer.parseInt(jedis0.hget("{user}:" + uid, "diamo"))); + obj.putInt("groupDiamo", Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo"))); +// log.info("数据111:"+Redis.use("group1_db11").hget( "group:"+groupId, "wechatId")); + obj.putInt("pk_score", Integer.parseInt(jedis11.hget("group:" + groupId, "pk_score"))); + obj.putInt("mj_score", Integer.parseInt(jedis11.hget("group:" + groupId, "mj_score"))); + obj.putString("notice", jedis11.hget("group:" + groupId, "notice")); + obj.putString("wechatId", jedis11.hget("group:" + groupId, "wechatId")); + obj.putInt("isOpenChatRoom", jedis11.hget("group:" + groupId, "isOpenChatRoom") == null ? 0 + : Integer.parseInt(jedis11.hget("group:" + groupId, "isOpenChatRoom"))); + String isShowBeginRoomkey = "g{" + groupId + "}:isShowBeginRoom"; + + obj.putInt("isShowBeginRoom", jedis11.hget(isShowBeginRoomkey, "isOpenChatRoom") == null ? 0 + : Integer.parseInt(jedis11.hget(isShowBeginRoomkey, "isOpenChatRoom"))); + + if (gmb.lev < 3) { + jedis11.zadd(key, 0, groupId + ""); + String joins_keys = GroupCache.genJoinsKey(groupId); + int joins = jedis11.scard(joins_keys).intValue(); + if (joins != 0) { + obj.putInt("joins", joins); + } else { + obj.putInt("joins", 0); + } + } else { + obj.putInt("joins", 0); + } + +// if (gmb.lev == 3){ +// +// } + + } catch (Exception e) { +// obj.putInt("pk_score",0); +// obj.putInt("mj_score",0); + obj.putInt("isOpenChatRoom", 1); + log.error("get_group数据报错--------------", e); + } + obj.putInt("isWatch", Integer.parseInt(jedis11.hget("group:" + groupId, "isWatch"))); + obj.putInt("member_num", gb.gms); + obj.putInt("option", gb.option); + obj.putInt("show_num", gb.show_num); + String grooms_key = GroupCache.genRoomsKey(groupId); + Set rooms = jedis11.zrangeByScore(grooms_key, 100000, 2000000); + obj.putInt("room_num", rooms.size()); + obj.putInt("top_time", gmb.top_time); + AccountBean acc = AccountCache.getAccount(owner); + if (acc != null) { + obj.putString("o_nick", acc.nick); + obj.putString("o_portrait", acc.portrait); + } else { + obj.putString("o_nick", StringUtil.Empty); + obj.putString("o_portrait", StringUtil.Empty); + } + // Redis.use("group1_db1").hset("alllook",uid+"","1"); + try { + String fp = jedis1.hget("alllook", uid + ""); + if (fp != null) { + obj.putInt("lev", 1); + } else { + obj.putInt("lev", gmb.lev); + } + } catch (Exception e) { + log.error("get_group数据报错--------------", e); + } finally { + jedis1.close(); + } + + return obj; + } + + /** + * 获取圈子列表 + * + * @param uid + * @return + * @throws Exception + */ + public static final ITArray getGroups(int uid) throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + ITArray list = TArray.newInstance(); + try { + + String key = GroupCache.genGroupsKey(uid); + Set groups = jedis11.zrevrange(key, 0, -1); + log.info("圈子id-------" + groups); + for (String tem : groups) { + ITObject obj = getGroupData(uid, Integer.parseInt(tem), jedis11, jedis10, jedis0); + if (obj == null) { + jedis11.zrem(key, tem); + continue; + } + list.addTObject(obj); + } + + } catch (Exception e) { + log.error("getGroups error", e); + } finally { + jedis11.close(); + } + return list; + + } + + public static final TArray groupMemberCounts(int uid) throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// Jedis jedis0 = Redis.use("group1_db0").getJedis(); + TObject redpointnum = TObject.newInstance(); + try { + + String key = GroupCache.genGroupsKey(uid); + Set groups = jedis11.zrevrange(key, 0, -1); + for (String tem : groups) { + String joins_key = GroupCache.genJoinsKey(Integer.parseInt(tem)); + int joins = jedis11.scard(joins_key).intValue(); + redpointnum.putInt("redpointnum", joins); + redpointnum.putString("groupIds", tem); + } + } catch (Exception e) { + log.error("getGroups error", e); + } finally { + jedis11.close(); + + } + TArray list = TArray.newInstance(); + list.addTObject(redpointnum); + return list; + + } + + /** + * 获取圈子预览 + * + * @param uid + * @return + * @throws Exception + */ + public static final ITObject getPreview(int uid) throws Exception { + String key = GroupCache.genGroupsKey(uid); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + Set groups = jedis11.zrevrange(key, 0, -1); + ITObject obj = TObject.newInstance(); + for (String tem : groups) { + int groupId = Integer.parseInt(tem); + + GroupBean gb = GroupCache.getGroup(groupId); + if (gb == null) { + continue; + } + obj.putInt("id", gb.id); + obj.putString("name", gb.name); + obj.putInt("type", gb.type); + obj.putInt("member_num", gb.gms); + String grooms_key = GroupCache.genRoomsKey(groupId); + Set rooms = jedis11.zrangeByScore(grooms_key, 100000, 1000000); + obj.putInt("room_num", rooms.size()); + obj.putBoolean("is_group", true); + return obj; + } + obj.putBoolean("is_group", false); + return obj; + } finally { + jedis11.close(); + } + + } + + private static final Map groupToRedis(String groupId, String name, int owner, int type, + int pay_type) { + Map redis_map = new HashMap<>(); + redis_map.put("id", groupId); + redis_map.put("name", name); + redis_map.put("owner", owner + ""); + redis_map.put("type", type + ""); + redis_map.put("pay_type", pay_type + ""); + redis_map.put("opt", "1"); + redis_map.put("ban", "0"); + redis_map.put("dissolve_opt", "1"); + redis_map.put("kick_opt", "1"); + redis_map.put("ban_apply", "0"); + redis_map.put("create_time", System.currentTimeMillis() / 1000 + ""); + redis_map.put("gms", "1"); + redis_map.put("option", "0"); + return redis_map; + } + + private static final Map memberToRedis(String groupId, int uid, int lev, int partnerLev, + int parentId, long time, String remark) { + Map redis_map = new HashMap<>(); + redis_map.put("groupId", groupId); + redis_map.put("uid", uid + ""); + redis_map.put("lev", lev + ""); + redis_map.put("opt", "1"); + redis_map.put("hp", "0"); + redis_map.put("ban", "0"); + redis_map.put("join_time", time + ""); + redis_map.put("top_time", "0"); + redis_map.put("partnerLev", partnerLev + ""); + redis_map.put("parentId", parentId + ""); + redis_map.put("hp_opt", "1"); + redis_map.put("permission", "0"); + redis_map.put("remark", remark); + redis_map.put("tag", remark); +// redis_map.put("lost_mj_score", 0 + ""); +// redis_map.put("lost_mj_score_before", 0 + ""); +// redis_map.put("lost_pk_score", 0 + ""); +// redis_map.put("lost_pk_score_before", 0 + ""); + redis_map.put("messageCount", 0 + ""); + + return redis_map; + } + + private static final Map payToRedis(int groupId, int pid, int gameId, String name, int deskId, + String config, String hpData, int hpOnOff, int hp_times, int reward, int rewardType, int rewardValueType, + int xipai_reward, int xipai_rewardType, int xipai_rewardValueType, int robot_room, int cChat, + int cMisslie) { + Map redis_map = new HashMap<>(); + redis_map.put("groupId", groupId + ""); + redis_map.put("id", pid + ""); + redis_map.put("name", name); + redis_map.put("deskId", deskId + ""); + redis_map.put("gameId", gameId + ""); + redis_map.put("config", config); + redis_map.put("hpData", hpData); + redis_map.put("hpOnOff", hpOnOff + ""); + redis_map.put("reward", reward + ""); + redis_map.put("rewardType", rewardType + ""); + redis_map.put("rewardValueType", rewardValueType + ""); + redis_map.put("xipai_reward", xipai_reward + ""); + redis_map.put("xipai_rewardType", xipai_rewardType + ""); + redis_map.put("xipai_rewardValueType", xipai_rewardValueType + ""); + redis_map.put("hp_times", hp_times + ""); + redis_map.put("ban", "0"); + redis_map.put("robot_room", robot_room + ""); + redis_map.put("BanMissile", cChat + ""); + redis_map.put("BanMissile", cMisslie + ""); + + return redis_map; + } + +// /** 战绩更新后广播 */ +// private static void broadcastRecordsUpdate(int groupId, ITObject newRecord) { +// ITObject broadcastMsg = TObject.newInstance(); +// broadcastMsg.putString("protocol", "GET_CHAT_ROOMS"); // 使用指定协议号 +// broadcastMsg.putTObject("record", newRecord); +// // 调用group_mgr的广播接口(需根据实际`group_mgr`实现调整) +// GroupMgr.broadcastToGroup(groupId, broadcastMsg); +// } + +// private static final String DEF_PROMOTION_DATA = "[{\"num\":0,\"val\":0}]"; + + /** + * 创建圈子 + * + * @param name + * @param owner + * @param type 1普通圈子 2大联盟 + * @param pay_type 1 房主支付 2AA支付 + * @return + * @throws Exception + */ + public static final ITObject createGroup(String name, int owner, int type, int pay_type, int num, String userName, + String portrait) throws Exception { + log.info("进入方法createGroup name----------------:" + name + " owner:" + owner + " type:" + type + " pay_type:" + + pay_type + " num:" + num); + + String groupId = null; + String ownersql = String.format("SELECT id FROM groups WHERE owner=%s", owner); + ITArray arr = DataBase.use().executeQueryByTArray(ownersql); + if (arr.size() > 5) { + throw new WebException(ErrorCode.GROUP_TYPE2_ONLY_1); + } + + for (int i = 0; i < 999999; i++) { + int id = (int) (Math.random() * 900000) + 100000; + log.info("new groupId:" + id); + String groupIdsql = String.format("SELECT id FROM groups WHERE id=%s", id); + ITArray groupArr = DataBase.use().executeQueryByTArray(groupIdsql); + if (groupArr.size() == 0) { + groupId = id + ""; + break; + } + } + +// try { +// if (num > 0) { +// groupId = num + ""; +// if (!jedis1.sismember("lh_ids", groupId)) { +// throw new WebException(ErrorCode.GROUP_NO_EXIST); +// } +// } else { +// groupId = jedis1.rpop("free_group"); +// if (jedis1.sismember("lh_ids", groupId)) { +// throw new WebException(ErrorCode._FAILED); +// } +// } +// +// String sql = String.format("SELECT id FROM groups WHERE owner=%s", owner); +// ITArray arr = DataBase.use().executeQueryByTArray(sql); +// if (arr.size() > 5) { +// if (num <= 0) { +// jedis1.lpush("free_group", groupId); +// } +// throw new WebException(ErrorCode.GROUP_TYPE2_ONLY_1); +// } +// +// } finally { +// jedis1.close(); +// } + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + int gid = Integer.parseInt(groupId); + String key = GroupCache.genKey(Integer.parseInt(groupId)); + String remark_key = GroupCache.genRemarkKey(Integer.parseInt(groupId)); + RedisLock lock = null; + try { + lock = new RedisLock(key, jedis11); + lock.lock(); + + String sql = String.format("{call sp_create_group(%s,'%s',%s,%s,%s)}", groupId, name, owner, type, + pay_type); + Utility.evtdb(gid, 2, sql); + + Map redis_map = groupToRedis(groupId, name, owner, type, pay_type); + jedis11.hmset(key, redis_map); + jedis11.hset(key, "isShow", 1 + ""); + + // 聊天室默认关闭 + jedis11.hset(key, "isOpenChatRoom", 1 + ""); + jedis11.hset("g{" + groupId + "}:isShowBeginRoom", "isShowBeginRoom", "0"); + + jedis11.hset(key, "mj_score", 0 + ""); + jedis11.hset(key, "pk_score", 0 + ""); + jedis11.hset(key, "wechatId", ""); + jedis11.hset(key, "isWatch", 1 + ""); + jedis11.hset(key, "notice", ""); + jedis11.hset(key, "messageCount", 0 + ""); + BaseCache.updateCacheVer(jedis11, key); + long time = System.currentTimeMillis() / 1000; + + redis_map = memberToRedis(groupId, owner, 1, 0, 0, time, "群主"); + + String groupIdKey = "g{" + groupId + "}:diamo"; + String groupIdKeys = "g{" + groupId + "}:onlines"; + String gm_key = GroupMemberCache.genKey(Integer.parseInt(groupId), owner); + jedis10.hset(groupIdKey, "diamo", "0"); + + String messageSql = String.format( + "INSERT INTO `message`(`id`, `group_name`, `group_id`, `tag_id`, `tag_name`, `user_name`, `user_id`, `m_time`, `m_state`, `m_portrait`) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", + 0, name, groupId, 0, "无", userName, owner, time, 2, portrait); + DataBase.use().executeUpdate(messageSql); + + jedis10.hset(groupIdKeys, String.valueOf(owner), "online"); + jedis10.hset(gm_key + ":score", "mj_score", "0"); + jedis10.hset(gm_key + ":score", "pk_score", "0"); + + jedis10.hset("g{" + groupId + "}:score", "mj_score", "0"); + jedis10.hset("g{" + groupId + "}:score", "pk_score", "0"); + jedis10.hmset(gm_key, redis_map); + BaseCache.updateCacheVer(jedis10, gm_key); + + ITObject info = TObject.newInstance(); + info.putInt("id", gid); + info.putString("name", name); + String gpids_key = GroupCache.genPidsKey(gid); + Pipeline pipeline = jedis11.pipelined(); + pipeline.del(gpids_key); + for (int i = 10; i < 210; ++i) { + pipeline.zadd(gpids_key, time, i + ""); + time++; + } + pipeline.sync(); + + String gs_key = GroupCache.genGroupsKey(owner); + jedis11.zadd(gs_key, 0, groupId); + + return info; + + } catch (Exception ex) { +// Redis.use("group1_db1").lpush("free_group", groupId); + if (ex instanceof WebException) { + throw ex; + } else { + log.error(ex); + } + + } finally { + if (lock != null) { + lock.unlock(); + } +// jedis10.close(); +// if(jedis11!=null) { +// jedis11.close(); +// } +// if(jedis10!=null) { +// jedis10.close(); +// } + + } + return null; + } + + /** + * 删除圈子 + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static final void delGroup(int groupId, int uid) throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String key = GroupCache.genKey(groupId); + + RedisLock lock = new RedisLock(key, jedis11); + try { + lock.lock(); + String opt = jedis11.hget(key, "opt"); + if (StringUtil.isEmpty(opt) || Integer.parseInt(opt) != 1) { + throw new WebException(ErrorCode.GROUP_NO_EXIST); + } + String grooms_key = GroupCache.genRoomsKey(groupId); + jedis11.zremrangeByScore(grooms_key, 0, 0); + Set rooms = jedis11.zrangeByScore(grooms_key, 100000, 1000000); + if (rooms.size() > 0) { + throw new WebException(ErrorCode.GROUP_EXIST_ROOMS); + } + + jedis11.hset(key, "opt", "2"); + GroupPublisherService.delGroupEvt(groupId); + jedis11.expire(key, 30); + String gpids_key = GroupCache.genPidsKey(groupId); + String gs_key = GroupCache.genGroupsKey(uid); + jedis11.del(gpids_key); + jedis11.zrem(gs_key, groupId + ""); + Set play_list = jedis11.keys("g{" + groupId + "}:*"); + Pipeline pipeline = jedis11.pipelined(); + for (String p_key : play_list) { + pipeline.expire(p_key, 30); + } + pipeline.sync(); + Set members = jedis10.keys("g{" + groupId + "}:*"); + pipeline = jedis10.pipelined(); + for (String m_key : members) { + pipeline.expire(m_key, 30); + } + pipeline.sync(); + + String sql = String.format("{call sp_del_group(%s)}", groupId); + Utility.evtdb(groupId, 2, sql); + } finally { + lock.unlock(); + jedis10.close(); + } + } + + /** + * 退出圈子 + * + * @param groupId + * @param uid + * @throws Exception + */ + public static final void exitGroup(int groupId, int uid) throws Exception { + GroupBean gb = GroupCache.getGroup(groupId); + log.info("exitGroup groupId哈哈哈哈哈进来了:" + groupId + " uid:" + uid); + if (gb.exit_opt == 1) { + throw new WebException(ErrorCode.GROUP_TYPE2_NOT_EXIT); + } + + if ((gb.option & 2) == 0) { + throw new WebException(ErrorCode.GROUP_TYPE2_NOT_EXIT); + } + delMember(groupId, gb.owner, uid, "exit"); + } + + /** + * 申请加入牌友圈 + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static final int applyGroup(int groupId, int uid, String remark, int ReadStatus) throws Exception { + String joins_key = GroupCache.genJoinsKey(groupId); + + // 备注,已读未读状态redis key + String remark_key = GroupCache.genRemarkKey(groupId); + String ReadStatus_key = GroupCache.genReadStatusKey(groupId); + String time_key = "g{" + groupId + "}:gtime"; + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + RedisLock lock = new RedisLock(joins_key, jedis11); + try { + lock.lock(); + GroupBean gb = GroupCache.getGroup(groupId); + if (gb == null) { + throw new WebException(ErrorCode.GROUP_NO_EXIST); + } + if (gb.ban_apply == 2) { + return ErrorCode.GROUP_BAN_APPLY; + } + int type = gb.type; + int gms = gb.gms; + if (type == 1 && gms >= TYPE_1_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + if (type == 2 && gms >= TYPE_2_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + String tag_key = GroupMemberCache.genKey(groupId, uid); + String member_opt = Redis.use("group1_db10").hget(tag_key, "opt"); + if (StringUtil.isNotEmpty(member_opt) && member_opt.equals("1")) { + return ErrorCode.GROUP_MEMBER_EXIST; + } + if (jedis11.sismember(joins_key, uid + "")) { + return ErrorCode.GROUP_JOIN_EXIST; + } + jedis11.sadd(joins_key, uid + ""); + + // 存储备注,已读未读状态数据 + jedis11.hset(remark_key, uid + "", remark); + jedis11.hset(ReadStatus_key, uid + "", ReadStatus + ""); +// Integer expireTimeInSeconds = 5 * 24 * 60 * 60; // 5天 +// jedis11.expire(remark_key+uid+"",expireTimeInSeconds); +// jedis11.expire(ReadStatus_key+uid+"", expireTimeInSeconds); + int joins = jedis11.scard(joins_key).intValue(); + + // 创建时间 + long time = System.currentTimeMillis(); + jedis11.hset(time_key, uid + "", time + ""); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + String getUser_key = "{user}:" + uid; + try { + String nick = jedis0.hget(getUser_key, "nick"); + String portrait = jedis0.hget(getUser_key, "portrait"); + String id = jedis0.hget(getUser_key, "id"); + log.info("昵称:" + nick + "头像:" + portrait + "id:" + id); + GroupPublisherService.updateJoinsEvt(groupId, joins, remark, ReadStatus, nick, portrait, + String.valueOf(time), id); + } catch (Exception e) { + log.error(e); + } finally { + jedis0.close(); + } + log.info("退出来---------------"); + } finally { + lock.unlock(); + } + + return 0; + } + + /** + * 验证加入牌友圈 + * + * @param groupId + * @param uid + * @param tagId + * @param allow + * @return + * @throws Exception + */ + public static final int verifyJoinGroup(int groupId, int uid, int tagId, boolean allow, String userName) + throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + String member_key = GroupMemberCache.genKey(groupId, tagId); + String remark_key = GroupCache.genRemarkKey(groupId); + + String ReadStatus_key = GroupCache.genReadStatusKey(groupId); + RedisLock lock1 = new RedisLock(member_key, jedis10); + String joins_key = GroupCache.genJoinsKey(groupId); + RedisLock lock = new RedisLock(joins_key, jedis11); + try { + lock.lock(); + lock1.lock(); + long len = jedis11.srem(joins_key, tagId + ""); + + String remark = jedis11.hget(remark_key, tagId + ""); + String ReadStatus = jedis11.hget(ReadStatus_key, tagId + ""); + + String member_opt = jedis10.hget(member_key, "opt"); + + if (StringUtil.isNotEmpty(member_opt) && member_opt.equals("1")) { + return ErrorCode.GROUP_MEMBER_EXIST; + } + String g_key = GroupCache.genKey(groupId); + List list = jedis11.hmget(g_key, "type", "gms"); + int type = Integer.parseInt(list.get(0)); + int gms = Integer.parseInt(list.get(1)); + if (type == 1 && gms >= TYPE_1_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + if (type == 2 && gms >= TYPE_2_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + if (len > 0 && allow) { + String onlineGroupIdKey = "g{" + groupId + "}:onlines"; + long time = System.currentTimeMillis() / 1000; + // 判断是否曾今进入过亲友圈 + + String isinsql = String.format("select * from group_member where groupId=%s and uid=%s", groupId, + tagId); + ITArray isinlist = DataBase.use().executeQueryByTArray(isinsql); + if (isinlist.size() > 0) { + String updateSql = String.format("update group_member set is_delete=0 WHERE uid=%s and groupId =%s", + tagId, groupId); + DataBase.use().executeUpdate(updateSql); + } else { + String sql = String.format( + "INSERT INTO group_member(uid,groupId,join_time,parentId) VALUES(%s,%s,%s,%s)", tagId, + groupId, time, 0); + Utility.evtdb(groupId, 1, sql); + + } + + Map redis_map = memberToRedis(groupId + "", tagId, 3, 0, 0, time, remark); + jedis10.hmset(member_key, redis_map); + BaseCache.updateCacheVer(jedis10, member_key); + jedis10.hset(onlineGroupIdKey, tagId + "", "online"); + GroupCache.updateCacheVer(jedis11, onlineGroupIdKey); + jedis11.hincrBy(g_key, "gms", 1); + BaseCache.updateCacheVer(jedis11, g_key); + String key = GroupCache.genGroupsKey(tagId); + jedis11.zadd(key, 0, groupId + ""); + int joins = jedis11.scard(joins_key).intValue(); + String name = jedis11.hget("group:" + groupId, "name"); + + // 刷新jedis10 + + // reflashType =="changeJoins" 允许拒绝之后前端修改申请的信息 数量刷新 allow :区分允许还是拒绝 + GroupPublisherService.familyReflash(groupId, joins, remark, Integer.parseInt(ReadStatus), tagId, allow); + + // reflashType =="joinFamily" 成功加入亲友圈 + ITObject users = GroupService.getUsers(groupId, tagId); + + log.info("用户数据:------" + users); + GroupPublisherService.joinFamily(groupId, joins, remark, Integer.parseInt(ReadStatus), tagId, allow, + users, name); + + String messageSql = String.format( + "INSERT INTO `message`(`id`, `group_name`, `group_id`, `tag_id`, `tag_name`, `user_name`, `user_id`, `m_time`, `m_state`, `m_portrait`) VALUES " + + "('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", + 0, name, groupId, tagId, users.getString("nick"), userName, uid, time, 0, + users.getString("portrait")); + DataBase.use().executeUpdate(messageSql); + } + + if (len > 0 && !allow) { + String onlineGroupIdKey = "g{" + groupId + "}:onlines"; + long time = System.currentTimeMillis() / 1000; + String sql = String.format( + "INSERT INTO group_member(uid,groupId,join_time,parentId) VALUES(%s,%s,%s,%s)", tagId, groupId, + time, 0); + Utility.evtdb(groupId, 1, sql); + Map redis_map = memberToRedis(groupId + "", tagId, 3, 0, 0, time, remark); + jedis10.hmset(member_key, redis_map); + BaseCache.updateCacheVer(jedis10, member_key); + jedis10.hset(onlineGroupIdKey, tagId + "", "online"); + GroupCache.updateCacheVer(jedis11, onlineGroupIdKey); + jedis11.hincrBy(g_key, "gms", 1); + BaseCache.updateCacheVer(jedis11, g_key); + + String key = GroupCache.genGroupsKey(tagId); + jedis11.zadd(key, 0, groupId + ""); + int joins = jedis11.scard(joins_key).intValue(); + + // reflashType =="changeJoins" 允许拒绝之后前端修改申请的信息 数量刷新 allow :区分允许还是拒绝 + GroupPublisherService.familyReflash(groupId, joins, remark, Integer.parseInt(ReadStatus), tagId, allow); +// GroupPublisherService.familyRefuse(groupId, tagId,joins); + + GroupService.delMembers(groupId, uid, tagId, "exit"); + + } + return 0; + } finally { + lock.unlock(); + lock1.unlock(); + } + + } + + private static String getSvr(Jedis jedis11) { + Set svr_list = jedis11.zrange("mgr_group", 0, -1); + if (svr_list.size() > 0) { + for (String str : svr_list) { + if (jedis11.exists(str)) { + return str; + } + } + } + return null; + } + + /** + * 进入圈子 + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static final ITObject enterGroup(int groupId, int uid) throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + String svr = getSvr(jedis11); + if (StringUtil.isEmpty(svr)) { + log.error("enterGroup fail groupId:" + groupId + " svr:" + svr + " uid:" + uid); + throw new WebException(ErrorCode.NO_SERVICE); + } + String group_key = GroupCache.genKey(groupId); + + String host = jedis11.hget(svr, "host"); + ITObject data = TObject.newInstance(); + data.putString("host", host); + String notice = jedis11.hget(group_key, "notice"); + data.putString("notice", StringUtil.isEmpty(notice) ? StringUtil.Empty : notice); + String hide_action = jedis11.hget(group_key, "hide_action"); + data.putInt("hide_action", StringUtil.isEmpty(hide_action) ? 0 : Integer.parseInt(hide_action)); + return data; + } finally { + jedis11.close(); + } + } + + /** + * 获得玩家信息 + * + * @param + * @return + * @throws Exception + */ + public static final ITObject getPlayerInfo(int uid) throws Exception { + AccountBean acc = AccountCache.getAccount(uid); + if (acc == null) { + return null; + } + + ITObject obj = TObject.newInstance(); + obj.putInt("uid", uid); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + return obj; + } + + /** + * 添加成员 + * + * @param groupId + * @param uid + * @param tagId + * @return + * @throws Exception + */ + public static final int addMember(int groupId, int uid, int tagId) throws Exception { + log.info("addMember uid:" + uid + " tagId:" + tagId); + GroupBean gb = GroupCache.getGroup(groupId); + String g_key = gb.redis_key; + int type = gb.type; + int gms = gb.gms; + if (type == 1 && gms >= TYPE_1_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + if (type == 2 && gms >= TYPE_2_NUM) { + return ErrorCode.GROUP_MEMBER_IS_FULL; + } + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(tag_key, jedis10); + RedisLock lock1 = null; + try { + lock.lock(); + String session_key = AccountCache.genKey(tagId); + List s_list = Redis.use("group1_db0").hmget(session_key, "id", "invitation"); + if (StringUtil.isEmpty(s_list.get(0))) { + return ErrorCode._FAILED; + } + int invitation = 0; + if (StringUtil.isNotEmpty(s_list.get(1))) { + invitation = Integer.parseInt(s_list.get(1)); + } + if (invitation == 0) { + return ErrorCode.GROUP_CLOSE_INVITATION; + } + String mng_key = GroupMemberCache.genKey(groupId, uid); + lock1 = new RedisLock(mng_key, jedis10); + lock1.lock(); + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + return ErrorCode.GROUP_NOT_MEMBER; + } + + int mgn_lev = mng_bean.lev; + int mgn_partnerLev = mng_bean.partnerLev; + if (mgn_lev == 3 && mgn_partnerLev == 0) { + return ErrorCode.GROUP_NOT_PARTNER; + } + if (mgn_lev == 2) { + if ((mng_bean.permission & PERMISSION_ADD_MEMBER) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + String member_opt = jedis10.hget(tag_key, "opt"); + boolean exits = StringUtil.isNotEmpty(member_opt) && member_opt.equals("1"); + if (exits) { + return ErrorCode.GROUP_MEMBER_EXIST; + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + String remark_key = GroupCache.genRemarkKey(groupId); + String ReadStatus_key = GroupCache.genReadStatusKey(groupId); + String remark = jedis11.hget(remark_key, tagId + ""); + String ReadStatus = jedis11.hget(ReadStatus_key, tagId + ""); + if (!exits) { + String joins_key = GroupCache.genJoinsKey(groupId); + + log.info("addMember joins_key:" + joins_key); + if (jedis11.sismember(joins_key, tagId + "")) { + jedis11.srem(joins_key, tagId + ""); + int joins = jedis11.scard(joins_key).intValue(); + log.info("addMember joins:" + joins); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + String getUser_key = "{user}:" + tagId; + String time_key = "g{" + groupId + "}:gtime"; + try { + String nick = jedis0.hget(getUser_key, "nick"); + String portrait = jedis0.hget(getUser_key, "portrait"); + String reg_time = jedis11.hget(time_key, tagId + ""); + String id = jedis0.hget(getUser_key, "id"); + GroupPublisherService.updateJoinsEvt(groupId, joins, remark, Integer.parseInt(ReadStatus), nick, + portrait, reg_time, id); + } catch (Exception e) { + log.error(e); + } finally { + jedis0.close(); + } + } + } + + try { + int mgn_uid = mgn_lev == 3 ? uid : 0; + String sql = String.format("{call sp_add_member(%s,%s,%s)}", groupId, mgn_uid, tagId); + log.info("addMember addsql:" + sql); + Utility.evtdb(groupId, 2, sql); + + long time = System.currentTimeMillis() / 1000; + log.info("addMember time:" + time); + Map redis_map = memberToRedis(groupId + "", tagId, 3, 0, mgn_uid, time, remark); + jedis10.hmset(tag_key, redis_map); + BaseCache.updateCacheVer(jedis10, tag_key); + jedis11.hincrBy(g_key, "gms", 1); + BaseCache.updateCacheVer(jedis11, g_key); + String key = GroupCache.genGroupsKey(tagId); + jedis11.zadd(key, 0, groupId + ""); + String group_ban = jedis10.hget(mng_key, "group_ban"); + if (!StringUtil.isEmpty(group_ban) && Integer.parseInt(group_ban) == 1) { + sql = String.format("update group_member set ban = %s where uid = %s AND groupId = %s", group_ban, + tagId, groupId); + Utility.evtdb(groupId, 1, sql); + jedis10.hset(tag_key, "ban", group_ban); + jedis10.hset(tag_key, "group_ban", group_ban); + BaseCache.updateCacheVer(jedis10, tag_key); + } + } finally { + jedis11.close(); + } + return 0; + } finally { + log.info("lock1 time:" + lock1); + if (lock1 != null) { + lock1.unlock(false); + } + log.info("lock time:" + lock); + lock.unlock(); + } + } + +// /** +// * 设置麻将跟扑克限制分数 +// * +// * @param groupId +// * @param uid +// * @param tagId +// * @return +// * @throws Exception +// */ +// public static final void setScore(int groupId, int uid, int tagId, int mjScore, int pkScore) throws Exception { +// log.info("setScore uid:" + uid + " mjScore:" + mjScore + " pkScore:" + pkScore); +// String sql = String.format( +// "update group_member set mjScore = %s,pkScore=%s " + "WHERE uid = %s and groupId = %s", mjScore, +// pkScore,uid, groupId); +// Utility.evtdb(groupId, 1, sql); +// +// } +// +// /** +// * 查询麻将跟扑克限制分数 +// * +// * @param groupId +// * @param uid +// * @param tagId +// * @return +// * @throws Exception +// */ +// public static final void getScore(int groupId, int uid, int tagId, int mjScore, int pkScore) throws Exception { +// log.info("setScore uid:" + uid + " mjScore:" + mjScore + " pkScore:" + pkScore); +// String sql = String.format( +// "select mj_score,pkScore from group_member where groupId = %s and uid = %s", +// groupId, child_list2, tmpTagId); +// +// ITArray tmplist = DataBase.use().executeQueryByTArray(sql); +// +// +// } + + /** + * 设置合伙人 + * + * @param groupId + * @param uid + * @param tagId + * @return + * @throws Exception + */ + public static final ITObject setParent(int groupId, int uid, int tagId) throws Exception { + log.info("setParent uid:" + uid + " tagId:" + tagId); + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(tag_key, jedis10); + RedisLock lock1 = null; + try { + lock.lock(); + GroupMemberBean tag_bean = GroupCache.getMember(groupId, tagId); + if (tag_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + String mng_key = GroupMemberCache.genKey(groupId, uid); + lock1 = new RedisLock(mng_key, jedis10); + lock1.lock(); + GroupMemberBean mng = GroupCache.getMember(groupId, uid); + if (mng == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int mgn_lev = mng.lev; + int mgn_partner = mng.partnerLev; + if (mgn_lev == 3 && mgn_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + int member_lev = tag_bean.lev; + if (member_lev < 3) { + throw new WebException(ErrorCode.GROUP_TAG_ISMGR); + } + int member_partner = tag_bean.partnerLev; + if (member_partner > 0) { + throw new WebException(ErrorCode.GROUP_ALREADY_PARTNER); + } + int member_parentId = tag_bean.parentId; + if (member_parentId > 0 && uid != member_parentId) { + throw new WebException(ErrorCode.GROUP_MEMBER_EXIST_PARTENER); + } + GroupBean gb = GroupCache.getGroup(groupId); + int tag_partner_lev = 1; + int parent = uid; + if (mgn_lev < 3) { + parent = gb.owner; + } else { + tag_partner_lev = (mgn_partner + 1); + } + + String sql = String.format( + "update group_member set parentId = %s,partnerLev=%s " + "WHERE uid = %s and groupId = %s", parent, + tag_partner_lev, tagId, groupId); + Utility.evtdb(groupId, 1, sql); + GroupPublisherService.updateMemberEvt(groupId, tagId, 3, tag_partner_lev); + jedis10.hset(tag_key, "parentId", parent + ""); + jedis10.hset(tag_key, "partnerLev", tag_partner_lev + ""); + BaseCache.updateCacheVer(jedis10, tag_key); + if (mgn_lev == 3) { + List list = Utility.getMemberParents(jedis10, groupId, uid, true); + for (Integer par : list) { + String pl_key = GroupCache.genParListKey(groupId, par); + jedis10.sadd(pl_key, tagId + ""); + } + } + // int member_hp = Integer.parseInt(jedis10.hget(tag_key, "hp")); + // String ph_key = String.format("g{%s}:par_hp:%s", groupId,tagId); + // jedis10.incrBy(ph_key, member_hp); + ITObject resData = TObject.newInstance(); + resData.putInt("parentId", parent); + resData.putInt("partnerLev", tag_partner_lev); + + return resData; + + } finally { + if (lock1 != null) { + lock1.unlock(false); + } + lock.unlock(); + + } + } + + /** + * 设置备注值 + * + * @param groupId + * @param uid + * @param tag + * @param tagId + * @return + * @throws Exception + */ + public static final void updateMemberScore(int groupId, int uid, String tag, int tagId) throws Exception { + log.info("updateMemberScore uid:" + uid + " tag:" + tag + " tagId:" + tagId); +// GroupMemberBean tag_bean = GroupCache.getMember(groupId, tagId); +// if (tag_bean == null) { +// throw new WebException(ErrorCode.GROUP_NOT_MEMBER); +// } + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, tagId); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { +// if (mng_bean.lev >= 3) { +// List par_list = Utility.getMemberParents(jedis10, groupId, tagId, false); +// if (par_list == null || !par_list.contains(uid)) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// } + + jedis10.hset(mng_bean.redis_key, "tag", tag); + BaseCache.updateCacheVer(jedis10, GroupMemberCache.genKey(groupId, tagId)); + } finally { + jedis10.close(); + } + } + + /** + * 设置体力值 + * + * @param groupId + * @param uid + * @param tagId + * @param hp + * @return + * @throws Exception + */ + public static final ITObject updateMemberHp(int groupId, int uid, int tagId, int hp, boolean self, int otherId) + throws Exception { + + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(tag_key, jedis10); + try { + lock.lock(); + GroupMemberBean tag_bean = GroupCache.getMember(groupId, tagId); + if (tag_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + // 正在游戏不允许下分操作 + if (hp < 0) { + if (GroupRoomService.checkRoom(groupId, uid)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + if (GroupRoomService.checkRoom(groupId, tagId)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + } + + if (hp > 0) { + int pre_hp = Integer.parseInt(jedis10.hget(tag_key, "hp")); + + if ((long) pre_hp + (long) hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode._FAILED); + } + } + + int mgn_partner = mng_bean.partnerLev; + int mgn_lev = mng_bean.lev; + if (tag_bean.lev == 1) { + if (uid != tagId) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } else if (tag_bean.lev == 2) { + if (mgn_lev != 1) { + if (uid != tagId) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } + + if (mgn_lev == 3 && mgn_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + if (mgn_lev == 2) { + if ((mng_bean.permission & PERMISSION_HP_OPT) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + if (self == false && mgn_lev != 1 && uid == tagId) { + throw new WebException(ErrorCode._FAILED); + } + + if (mgn_lev == 3) { + if (!self) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, false); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } else { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } + String lua = MainServer.lua_map.get("mgr"); + Object obj = jedis10.evalsha(lua, Arrays.asList(mng_bean.redis_key, tag_key), + Arrays.asList(hp + "", mgn_lev + "")); + if (obj == null) { + throw new WebException(ErrorCode._FAILED); + } + if (obj instanceof Long) { + Long code = (Long) obj; + if (code == 3) { + throw new WebException(ErrorCode.GROUP_TAG_MGR_HP); + } else if (code == 4) { + throw new WebException(ErrorCode.GROUP_TAG_NO_HP); + } + } else { + ArrayList arr = (ArrayList) obj; + ITObject resData = TObject.newInstance(); + int mhp = arr.get(0).intValue(); + int thp = arr.get(1).intValue(); + resData.putInt("mhp", (int) mhp); + resData.putInt("hp", (int) thp); + + String sql = String.format("{call sp_update_hp_mgr2(%s,%s,%s,%s,%s,%s,%s,%s)}", groupId, uid, hp, mhp, + thp, tagId, mgn_lev, otherId); + Utility.evtdb(groupId, 2, sql); + + if (!self) + log.info("updateMemberHp uid:" + uid + " tagId:" + tagId + " hp:" + hp / 1000); + + // ------------------------邮件 ------------------- + ITObject mail_data = TObject.newInstance(); + mail_data.putInt("mgr_id", uid); + AccountBean acc = AccountCache.getAccount(uid); + mail_data.putString("nick", acc.nick); + mail_data.putString("headurl", acc.portrait); + mail_data.putInt("hp", hp); + mail_data.putInt("type", 1); + int time = (int) (System.currentTimeMillis() / 1000); + mail_data.putInt("time", time); + String mail_key = GroupCache.genMailKey(groupId, tagId); + jedis10.zadd(mail_key, time, mail_data.toJson()); + String mail_tip_key = GroupCache.genMailTipKey(groupId); + jedis10.zadd(mail_tip_key, 1, tagId + ""); + GroupPublisherService.updateMailTipEvt(groupId, tagId); + // ----------------------------------------------- + + String c_tem = hp > 0 ? "upper" : "sub"; + if (mgn_lev < 3) { + String hp_mgr_key = String.format("g%s:hp_mgr:%s", groupId, c_tem); + String hp_mgr_id_key = String.format("g%s:hp_mgr:%s:u%s", groupId, c_tem, uid); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + hp = Math.abs(hp); + CountUtil.countLogByDay(hp_mgr_key, hp, jedis9); + CountUtil.countLogByDay(hp_mgr_id_key, hp, jedis9); + } finally { + jedis9.close(); + } + } else { + String hp_par_id_key = String.format("g%s:hp_par:%s:u%s", groupId, c_tem, uid); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + hp = Math.abs(hp); + CountUtil.countLogByDay(hp_par_id_key, hp, jedis9); + } finally { + jedis9.close(); + } + } + return resData; + } + return null; + } finally { + lock.unlock(); + + } + } + + /** + * 获取奖励数据 + * + * @param groupId + * @param uid + * @return + */ + public static final ITObject getTakeInfo(int groupId, int uid, int tagId) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + String rhp_key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = Redis.use("group1_db10").get(rhp_key); + int _r_hp = 0; + if (StringUtil.isNotEmpty(r_hp)) { + _r_hp = Integer.parseInt(r_hp); + } + + long day_rewad = 0; + long day_rewad_1 = 0; + long day_rewad_2 = 0; +// int all_day_reward = 0; + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String key = String.format("g%s:hp_reward:m%s", groupId, tagId); + day_rewad = CountUtil.getCountLogByDay(key, jedis9); + String day_key_1 = key + ":d" + (DateUtils.getBeginDay() - 3600 * 24); + day_rewad_1 = CountUtil.getCountLog(day_key_1, 0, jedis9); + String day_key_2 = key + ":d" + (DateUtils.getBeginDay() - 3600 * 48); + day_rewad_2 = CountUtil.getCountLog(day_key_2, 0, jedis9); + } finally { + jedis9.close(); + } + ITObject resData = TObject.newInstance(); + resData.putLong("total_hp", _r_hp); + // resData.putInt("bank_hp", _b_hp); + resData.putLong("day_rewad", day_rewad); + resData.putLong("day_rewad_1", day_rewad_1); + resData.putLong("day_rewad_2", day_rewad_2); + return resData; + } + + public static final ITObject getBankInfo(int groupId, int uid, int tagId) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + String mng_key = GroupMemberCache.genKey(groupId, tagId); + // String rhp_key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + // String r_hp = Redis.use("group1_db10").get(rhp_key); + String r_hp = Redis.use("group1_db10").hget(mng_key, "hp"); + long _r_hp = 0; + if (StringUtil.isNotEmpty(r_hp)) { + _r_hp = Long.parseLong(r_hp); + } + String b_hp = Redis.use("group1_db10").hget(mng_key, "bank_hp"); + long _b_hp = 0; + if (StringUtil.isNotEmpty(b_hp)) { + _b_hp = Long.parseLong(b_hp); + } + + int day_rewad = 0; + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + String key = String.format("g%s:hp_reward:m%s", groupId, tagId); + day_rewad = CountUtil.getCountLogByDay(key, jedis9); + } finally { + jedis9.close(); + } + ITObject resData = TObject.newInstance(); + resData.putLong("total_hp", _r_hp); + resData.putLong("bank_hp", _b_hp); + // resData.putInt("day_rewad", day_rewad); + return resData; + } + + /** + * 提取体力值 + * + * @param groupId + * @param uid + * @param hp + * @return + * @throws Exception + */ + public static final ITObject takeHp(int groupId, int uid, int tagId, long hp) throws Exception { + log.info("takeHp uid:" + uid + " tagId:" + tagId + " hp:" + hp / 1000); + if (hp <= 0) { + throw new WebException(ErrorCode._FAILED); + } + + if (hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + String mng_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(mng_key, jedis10); + try { + lock.lock(); + + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, tagId); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + String key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = jedis10.get(key); + if (StringUtil.isEmpty(r_hp)) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + if (Long.parseLong(r_hp) < hp) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + long tag_hp = Long.parseLong(jedis10.hget(mng_key, "hp")); + if (tag_hp + hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + if (GroupRoomService.checkRoom(groupId, tagId)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + + String lua = MainServer.lua_map.get("take_hp"); + Object obj = jedis10.evalsha(lua, Arrays.asList(key, mng_key), Arrays.asList((int) hp + "")); + if (obj == null) { + throw new WebException(ErrorCode._FAILED); + } + if (obj instanceof Long) { + Long code = (Long) obj; + if (code == 3) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + } else { + ArrayList arr = (ArrayList) obj; + int _r_hp = arr.get(0).intValue(); + int mhp = arr.get(1).intValue(); + String sql = String.format("{call sp_take_reward_hp(%s,%s,%s,%s)}", groupId, tagId, (int) hp, mhp); + Utility.evtdb(groupId, 2, sql); + sql = String.format("update group_member set reward_hp = %s where uid = %s AND groupId = %s", _r_hp, + tagId, groupId); + Utility.evtdb(groupId, 1, sql); + ITObject resData = TObject.newInstance(); + resData.putInt("hp", mhp); + resData.putLong("r_hp", _r_hp); + return resData; + } + return null; + } finally { + lock.unlock(); + + } + } + + /** + * 提取体力值 + * + * @param groupId + * @param uid + * @param + * @return + * @throws Exception + */ + public static final void groupTakeHp(int groupId, int uid, int tagId) throws Exception { + log.info("groupTakeHp uid:" + uid + " tagId:" + tagId); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + String opt1 = jedis10.hget(gm_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev != 1) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } finally { + lock1.unlock(false); + } + + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (gmb.partnerLev > 0) { + isPartner = true; + } + + String sql; + if (isPartner) { + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + String key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = jedis10.get(key); + if (!StringUtil.isEmpty(r_hp)) { + try { + long allRewardHp = Long.parseLong(r_hp); + GroupService.takeHp(groupId, uid, tagId, allRewardHp); + } catch (Exception e) { + + } + } + + String tag_gm_key = GroupMemberCache.genKey(groupId, tagId); + String b_hp = jedis10.hget(tag_gm_key, "bank_hp"); + if (!StringUtil.isEmpty(b_hp)) { + try { + long allBankHp = Long.parseLong(b_hp); + GroupService.takeBankHp(groupId, uid, tagId, allBankHp); + } catch (Exception e) { + + } + } + + while (!arrayList.isEmpty()) { + ArrayList arrayListTemp = new ArrayList<>(); + arrayListTemp.addAll(arrayList); + arrayList.clear(); + + for (int i = 0; i < arrayListTemp.size(); ++i) { + int tmpTagId = arrayListTemp.get(i); + String child_list2 = Utility.getChildParentSql(groupId, tmpTagId, true); + + sql = String.format( + "select uid from group_member where groupId = %s and (parentId in(%s) or uid = %s)", + groupId, child_list2, tmpTagId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + + if (hashSet.contains(childId)) + continue; + + String child_key = String.format("g{%s}:m%s:reward_hp", groupId, childId); + String child_hp = jedis10.get(child_key); + if (!StringUtil.isEmpty(child_hp)) { + try { + long allRewardHp = Long.parseLong(child_hp); + GroupService.takeHp(groupId, uid, childId, allRewardHp); + } catch (Exception e) { + + } + } + + String child_tag_gm_key = GroupMemberCache.genKey(groupId, childId); + String child_b_hp = jedis10.hget(child_tag_gm_key, "bank_hp"); + if (!StringUtil.isEmpty(child_b_hp)) { + try { + long allBankHp = Long.parseLong(child_b_hp); + GroupService.takeBankHp(groupId, uid, childId, allBankHp); + } catch (Exception e) { + + } + } + + hashSet.add(childId); + arrayList.add(childId); + } + } + } + } + } else { + String key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = jedis10.get(key); + if (!StringUtil.isEmpty(r_hp)) { + try { + long allRewardHp = Long.parseLong(r_hp); + GroupService.takeHp(groupId, uid, tagId, allRewardHp); + } catch (Exception e) { + + } + } + + String tag_gm_key = GroupMemberCache.genKey(groupId, tagId); + String b_hp = jedis10.hget(tag_gm_key, "bank_hp"); + if (!StringUtil.isEmpty(b_hp)) { + try { + long allBankHp = Long.parseLong(b_hp); + GroupService.takeBankHp(groupId, uid, tagId, allBankHp); + } catch (Exception e) { + + } + } + } + } finally { + lock.unlock(); + } + } + + public static final ITObject takeBankHp(int groupId, int uid, int tagId, long hp) throws Exception { + log.info("takeBankHp uid:" + uid + " tagId:" + tagId + " hp:" + hp / 1000); + if (hp <= 0) { + throw new WebException(ErrorCode._FAILED); + } + if (hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + String mng_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(mng_key, jedis10); + try { + lock.lock(); + + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, tagId); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + String r_hp = jedis10.hget(mng_key, "bank_hp"); + if (StringUtil.isEmpty(r_hp)) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + if (Long.parseLong(r_hp) < hp) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + long tag_hp = Long.parseLong(jedis10.hget(mng_key, "hp")); + if (tag_hp + hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + if (GroupRoomService.checkRoom(groupId, tagId)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + + String lua = MainServer.lua_map.get("bank_hp"); + Object obj = jedis10.evalsha(lua, Arrays.asList(mng_key, mng_key, "bank_hp"), + Arrays.asList((int) hp + "", "0")); + if (obj == null) { + throw new WebException(ErrorCode._FAILED); + } + if (obj instanceof Long) { + Long code = (Long) obj; + if (code == 3) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + } else { + ArrayList arr = (ArrayList) obj; + int mhp = arr.get(0).intValue(); + int b_hp = arr.get(1).intValue(); + String sql = String.format("{call sp_bank_hp(%s,%s,%s,%s)}", groupId, tagId, -(int) hp, mhp); + Utility.evtdb(groupId, 2, sql); + sql = String.format("update group_member set bank_hp = %s where uid = %s AND groupId = %s", b_hp, tagId, + groupId); + Utility.evtdb(groupId, 1, sql); + ITObject resData = TObject.newInstance(); + resData.putInt("hp", mhp); + resData.putLong("b_hp", b_hp); + return resData; + } + return null; + } finally { + lock.unlock(); + } + } + + public static final ITObject saveBankHp(int groupId, int uid, int tagId, long hp) throws Exception { + log.info("saveBankHp uid:" + uid + " tagId:" + tagId + " hp:" + hp / 1000); + if (hp <= 0) { + throw new WebException(ErrorCode._FAILED); + } + if (hp > Integer.MAX_VALUE) { + throw new WebException(ErrorCode.GROUP_PARTNER_HP_THAN_LIMIET); + } + + String mng_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(mng_key, jedis10); + try { + lock.lock(); + + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + GroupMemberBean mng_bean = GroupCache.getMember(groupId, tagId); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + String cur_hp = jedis10.hget(mng_key, "hp"); + if (StringUtil.isEmpty(cur_hp)) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + if (Long.parseLong(cur_hp) < hp) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + + if (GroupRoomService.checkRoom(groupId, tagId)) { + throw new WebException(ErrorCode.GROUP_DONOT_SUB_HP); + } + + String lua = MainServer.lua_map.get("bank_hp"); + Object obj = jedis10.evalsha(lua, Arrays.asList(mng_key, mng_key, "bank_hp"), Arrays.asList(hp + "", "1")); + if (obj == null) { + throw new WebException(ErrorCode._FAILED); + } + if (obj instanceof Long) { + Long code = (Long) obj; + if (code == 3) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_HP); + } + } else { + ArrayList arr = (ArrayList) obj; + long mhp = arr.get(0).longValue(); + long b_hp = arr.get(1).longValue(); + String sql = String.format("{call sp_bank_hp(%s,%s,%s,%s)}", groupId, tagId, hp, mhp); + Utility.evtdb(groupId, 2, sql); + + sql = String.format("update group_member set bank_hp = %s where uid = %s AND groupId = %s", b_hp, tagId, + groupId); + Utility.evtdb(groupId, 1, sql); + + ITObject resData = TObject.newInstance(); + resData.putLong("hp", mhp); + resData.putLong("b_hp", b_hp); + return resData; + } + return null; + } finally { + lock.unlock(); + } + } + + /** + * 删除成员 + * + * @param groupId + * @param uid + * @param tagId + * @return + * @throws Exception + */ + public static final void delMember(int groupId, int uid, int tagId, String outs) throws Exception { + log.info("delMember uid:" + uid + " tagId" + tagId); + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + GroupBean gb = GroupCache.getGroup(groupId); + + int dellev = 3; + RedisLock lock = null; + try { + lock = new RedisLock(tag_key, jedis10); + lock.lock(); + GroupMemberBean tag_bean = GroupCache.getMember(groupId, tagId); + if (tag_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + dellev = tag_bean.lev; + + GroupMemberBean mgn = GroupCache.getMember(groupId, uid); + + if (mgn == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int mgn_lev = mgn.lev; + int mgn_partner = mgn.partnerLev; + if (mgn_lev == 3 && mgn_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + // 暂时删掉,可能2级没有权限 +// if (mgn_lev == 2) { +// if ((mgn.permission & PERMISSION_DEL_MEMBER) == 0) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// } + + long hp = Long.parseLong(jedis10.hget(tag_key, "hp")); +// if (hp != 0) { +// throw new WebException(ErrorCode.GROUP_HP_NOT_0); +// } + +// int tag_lev = tag_bean.lev; +// if (mgn_lev < 3 && tag_lev <= mgn_lev) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// if (mgn_lev == 3 && mgn_partner > 0) { +// +// GroupBean gb = GroupCache.getGroup(groupId); +// if ((gb.option & 1) == 0) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// +// int parentId = tag_bean.parentId; +// if (uid != parentId) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// } + + boolean checkRoom = GroupRoomService.checkRoom(groupId, tagId); + + if (checkRoom) { + log.info("在房间内,不可删除---------------------"); + throw new WebException(ErrorCode.GROUP_MEMBER_ROOM_EXIST); + } + + int tag_partner = tag_bean.partnerLev; + String rhp_key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = jedis10.get(rhp_key); + if (StringUtil.isNotEmpty(r_hp) && Long.parseLong(r_hp) > 0) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_TAKE); + } + + String b_hp = jedis10.hget(tag_key, "bank_hp"); + if (StringUtil.isNotEmpty(b_hp) && Long.parseLong(b_hp) > 0) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_TAKE); + } + + String sql = String.format("select count(1) count from group_member where groupId =%s and parentId=%s ", + groupId, tagId); + ITArray resultList = DataBase.use().executeQueryByTArray(sql); + long count = resultList.getTObject(0).getLong("count"); + if (count > 0) { + throw new WebException(ErrorCode.GROUP_PARTNER_MEMBERS); + } + + List list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (list != null) { + for (Integer par : list) { + if (tag_partner > 0) { + String pl_key = GroupCache.genParListKey(groupId, par); + if (par == tagId) { + jedis10.del(pl_key); + } else { + jedis10.srem(pl_key, tagId + ""); + } + } + String mlk = GroupCache.genMemberListKey(groupId, par); + if (par == tagId) { + jedis10.del(mlk); + } else { + jedis10.srem(mlk, tagId + ""); + } + + } + } + + jedis10.hset(tag_key, "opt", "2"); + BaseCache.updateCacheVer(jedis10, tag_key); + jedis10.expire(rhp_key, 10); + + AccountBean acc = AccountCache.getAccount(tagId); + GroupPublisherService.quitGroup(groupId, tagId, outs, acc.nick); + + String g_key = GroupCache.genKey(groupId); + jedis11.hincrBy(g_key, "gms", -1); + BaseCache.updateCacheVer(jedis11, g_key); +// String key = GroupCache.genGroupsKey(tagId); +// jedis11.zrem(key, groupId + ""); + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gp_key, 10, 11); + for (String pid : pids) { + String p_reward_key = GroupCache.genRewardKey(groupId, Integer.parseInt(pid)); + jedis10.zrem(p_reward_key, tagId + ""); + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, Integer.parseInt(pid)); + jedis10.zrem(p_xipai_reward_key, tagId + ""); + } + String getSizeSql = String.format("select * from groups where id=%s", groupId); + ITArray getSize = DataBase.use().executeQueryByTArray(getSizeSql); + AccountBean accs = AccountCache.getAccount(uid); + String name = jedis11.hget("group:" + groupId, "name"); + if (tag_bean.lev == 1 && getSize.size() <= 5) { + // 当前时间 + long time = System.currentTimeMillis() / 1000; + String delSql1 = String.format("DELETE FROM groups WHERE owner=%s and id=%s", uid, groupId); + DataBase.use().executeUpdate(delSql1); + jedis11.del(g_key); + String selSql = String.format("select uid from group_member where groupId =%s", groupId); + ITArray resultLists2 = DataBase.use().executeQueryByTArray(selSql); + jedis10.del("Keys", "g{" + groupId + "}"); + for (int i = 0; i < resultLists2.size(); ++i) { + ITObject tem = resultLists2.getTObject(i); + int uids = tem.getInt("uid"); + + String delSql = String.format("update group_member set is_delete=1 WHERE uid=%s and groupId =%s", + uids, groupId); + + DataBase.use().executeUpdate(delSql); + // 推送给所有人 kick + GroupPublisherService.quitGroup(groupId, uids, "kick", name); + + } + // 退回房卡 + log.info("退回房卡给到:" + uid); + int userDiamo = Integer.parseInt(jedis0.hget("{user}:" + uid, "diamo")); + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + int lastDiamo = userDiamo + groupDiamo; + jedis10.hset("g{" + groupId + "}:diamo", "diamo", "0"); + jedis0.hset("{user}:" + uid, "diamo", lastDiamo + ""); + String diamosql = String.format("update account set diamo=%s where id=%s", lastDiamo, uid); + + DataBase.use().executeUpdate(diamosql); + + String messagesql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + groupId, 1, lastDiamo, groupDiamo, System.currentTimeMillis(), 0, uid, gb.name, acc.nick); + DataBase.use().executeUpdate(messagesql); + + + } else { + long time = System.currentTimeMillis() / 1000; + if (outs.equals("exit")) { + String messageSql = String.format( + "INSERT INTO `message`(`id`, `group_name`, `group_id`, `tag_id`, `tag_name`, `user_name`, `user_id`, `m_time`, `m_state`, `m_portrait`) VALUES " + + "('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", + 0, name, groupId, 0, "无", acc.nick, acc.id, time, 1, acc.portrait); + DataBase.use().executeUpdate(messageSql); + } + if (outs.equals("kick")) { + String messageSql = String.format( + "INSERT INTO `message`(`id`, `group_name`, `group_id`, `tag_id`, `tag_name`, `user_name`, `user_id`, `m_time`, `m_state`, `m_portrait`) VALUES " + + "('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", + 0, name, groupId, tagId, accs.nick, acc.nick, acc.id, time, 3, acc.portrait); + DataBase.use().executeUpdate(messageSql); + } + + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines"; + String delGroupUserKey = "g{" + groupId + "}:m" + tagId; + jedis10.hdel(groupIdKey, tagId + ""); + jedis10.hdel(groupIdKeys, tagId + ""); + + String delSql = String.format("update group_member set is_delete=1 WHERE uid=%s and groupId =%s", + tagId, groupId); + + int resultLists = DataBase.use().executeUpdate(delSql); + + } + +// sql = String.format("{call sp_del_member(%s,%s)}", groupId, tagId); +// Utility.evtdb(groupId, 2, sql); + + delMemberLog(groupId, uid, tagId, dellev); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (lock != null) { + lock.unlock(); + } +// jedis0.close(); +// jedis11.close(); +// if (jedis10 != null) { +// jedis10.close(); +// } + + } + } + + // 拒绝清理数据 + public static final void delMembers(int groupId, int uid, int tagId, String outs) throws Exception { + log.info("delMember uid:" + uid + " tagId" + tagId); + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + + int dellev = 3; + RedisLock lock = null; + try { + lock = new RedisLock(tag_key, jedis10); + lock.lock(); + GroupMemberBean tag_bean = GroupCache.getMember(groupId, tagId); + if (tag_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + dellev = tag_bean.lev; + + GroupMemberBean mgn = GroupCache.getMember(groupId, uid); + + if (mgn == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int mgn_lev = mgn.lev; + int mgn_partner = mgn.partnerLev; + if (mgn_lev == 3 && mgn_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + // 暂时删掉,可能2级没有权限 +// if (mgn_lev == 2) { +// if ((mgn.permission & PERMISSION_DEL_MEMBER) == 0) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// } + + long hp = Long.parseLong(jedis10.hget(tag_key, "hp")); +// if (hp != 0) { +// throw new WebException(ErrorCode.GROUP_HP_NOT_0); +// } + +// int tag_lev = tag_bean.lev; +// if (mgn_lev < 3 && tag_lev <= mgn_lev) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// if (mgn_lev == 3 && mgn_partner > 0) { +// +// GroupBean gb = GroupCache.getGroup(groupId); +// if ((gb.option & 1) == 0) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// +// int parentId = tag_bean.parentId; +// if (uid != parentId) { +// throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); +// } +// } + + boolean checkRoom = GroupRoomService.checkRoom(groupId, tagId); + if (checkRoom) { + throw new WebException(ErrorCode.GROUP_MEMBER_ROOM_EXIST); + } + int tag_partner = tag_bean.partnerLev; + String rhp_key = String.format("g{%s}:m%s:reward_hp", groupId, tagId); + String r_hp = jedis10.get(rhp_key); + if (StringUtil.isNotEmpty(r_hp) && Long.parseLong(r_hp) > 0) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_TAKE); + } + + String b_hp = jedis10.hget(tag_key, "bank_hp"); + if (StringUtil.isNotEmpty(b_hp) && Long.parseLong(b_hp) > 0) { + throw new WebException(ErrorCode.GROUP_REWARD_NO_TAKE); + } + + String sql = String.format("select count(1) count from group_member where groupId =%s and parentId=%s ", + groupId, tagId); + ITArray resultList = DataBase.use().executeQueryByTArray(sql); + long count = resultList.getTObject(0).getLong("count"); + if (count > 0) { + throw new WebException(ErrorCode.GROUP_PARTNER_MEMBERS); + } + + List list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (list != null) { + for (Integer par : list) { + if (tag_partner > 0) { + String pl_key = GroupCache.genParListKey(groupId, par); + if (par == tagId) { + jedis10.del(pl_key); + } else { + jedis10.srem(pl_key, tagId + ""); + } + } + String mlk = GroupCache.genMemberListKey(groupId, par); + if (par == tagId) { + jedis10.del(mlk); + } else { + jedis10.srem(mlk, tagId + ""); + } + } + } + + jedis10.hset(tag_key, "opt", "2"); + BaseCache.updateCacheVer(jedis10, tag_key); + jedis10.expire(rhp_key, 10); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + String g_key = GroupCache.genKey(groupId); + jedis11.hincrBy(g_key, "gms", -1); + BaseCache.updateCacheVer(jedis11, g_key); + String key = GroupCache.genGroupsKey(tagId); + jedis11.zrem(key, groupId + ""); + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gp_key, 10, 11); + for (String pid : pids) { + String p_reward_key = GroupCache.genRewardKey(groupId, Integer.parseInt(pid)); + jedis10.zrem(p_reward_key, tagId + ""); + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, Integer.parseInt(pid)); + jedis10.zrem(p_xipai_reward_key, tagId + ""); + } + String getSizeSql = String.format("select * from groups where id=%s", groupId); + ITArray getSize = DataBase.use().executeQueryByTArray(getSizeSql); + if (tag_bean.lev == 1 && getSize.size() <= 5) { + log.info("等级:" + mgn_lev); + String delSql1 = String.format("DELETE FROM groups WHERE owner=%s and id=%s", uid, groupId); + int resultLists = DataBase.use().executeUpdate(delSql1); + log.info("delMemberLog 2222222222:" + g_key); + jedis11.del(g_key); + String selSql = String.format("select uid from group_member where groupId =%s", groupId); + ITArray resultLists2 = DataBase.use().executeQueryByTArray(selSql); + jedis10.del("Keys", "g{" + groupId + "}"); + for (int i = 0; i < resultLists2.size(); ++i) { + ITObject tem = resultLists2.getTObject(i); + int uids = tem.getInt("uid"); + log.info("用户id:" + uids); + String delSql = String.format( + "update group_member set is_delete=1 WHERE uid=%s and groupId =%s", uids, groupId); + int resultLists1 = DataBase.use().executeUpdate(delSql); + } + } else { +// AccountBean acc = AccountCache.getAccount(tagId); +// GroupPublisherService.quitGroup(groupId, tagId,outs,acc.nick); + + String sqls = String.format("update group_member set is_delete=1 WHERE uid=%s and groupId =%s", + tagId, groupId); + int resultLists = DataBase.use().executeUpdate(sqls); + String groupIdKey = "g{" + groupId + "}:onlines"; + String groupIdKeys = "g{" + groupId + "}:offlines "; + String delGroupUserKey = "g{" + groupId + "}:m" + tagId; + try { + jedis10.hdel(groupIdKey, tagId + ""); + jedis10.hdel(groupIdKeys, tagId + ""); + jedis10.del(delGroupUserKey); + log.info("退出-----圈子"); + } catch (Exception e) { + log.error("亲友圈在线离线用户信息清除失败" + e); + } + + } + } finally { + jedis11.close(); + } +// sql = String.format("{call sp_del_member(%s,%s)}", groupId, tagId); +// Utility.evtdb(groupId, 2, sql); + + delMemberLog(groupId, uid, tagId, dellev); + + } finally { + if (lock != null) { + lock.unlock(); + } + } + } + + public static final void delMemberLog(int groupId, int uid, int tagId, int lev) throws Exception { + AccountBean acc = AccountCache.getAccount(uid); + int opid = acc.id; + String opnick = acc.nick; + + AccountBean delacc = AccountCache.getAccount(tagId); + int delid = delacc.id; + String delnick = delacc.nick; + String delPortrait = delacc.portrait; + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + ITObject obj = new TObject(); + try { + GroupLogService.getMemberData(jedis9, delid, obj, groupId, 1, 0, 0, true, true); + + int total_round = obj.getInt("total_round"); + long curTimee = System.currentTimeMillis() / 1000; + + // GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, delid); + String groupName = "队员"; + // if (mgr_gmb != null) { + if (lev < 3) { + groupName = "队长"; + } else { + groupName = "队员"; + } + // } + + ITObject userData = TObject.newInstance(); + userData.putInt("id", delid); + userData.putUtfString("nick", delnick); + userData.putInt("round", total_round); + userData.putUtfString("group", groupName); + userData.putInt("opid", opid); + userData.putUtfString("opnick", opnick); + userData.putLong("deltime", curTimee); + userData.putUtfString("portrait", delPortrait); + + String str = userData.toJson(); + + String gm_key = "kicklog_" + groupId + "_" + uid; + jedis9.lpush(gm_key, str); + + } finally { + jedis9.close(); + } + + } + + public static final ITArray getKickLog(int groupId, int id, int limit, int num) throws Exception { + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + ITArray kickLogList = TArray.newInstance(); + + try { + String gm_key = "kicklog_" + groupId + "_" + id; + List logs = jedis9.lrange(gm_key, limit, limit + num); + + int i = 0; + + for (String _log : logs) { + ITObject kickLog = TObject.newFromJsonData(_log); + kickLogList.addTObject(kickLog); + + } + } finally { + jedis9.close(); + } + + return kickLogList; + } + + /** + * 申请加入列表 + * + * @param groupId + * @return + * @throws Exception + */ + public static final ITArray getGroupJoins(int groupId) throws Exception { + String joins_key = GroupCache.genJoinsKey(groupId); + String remark_key = GroupCache.genRemarkKey(groupId); + String time_key = "g{" + groupId + "}:gtime"; + Set uids = Redis.use("group1_db11").smembers(joins_key); + ITArray array = TArray.newInstance(); + for (String tem : uids) { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + AccountBean acc = AccountCache.getAccount(Integer.parseInt(tem)); + ITObject obj = TObject.newInstance(); + obj.putInt("id", acc.id); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + array.addTObject(obj); + String hget = jedis11.hget(remark_key, acc.id + ""); + String time = jedis11.hget(time_key, acc.id + ""); + obj.putString("tag", hget); + obj.putString("time", time); + } catch (Exception e) { + log.info("数据异常" + e); + } finally { + jedis11.close(); + } + + } + return array; + } + + /** + * 获取整线体力值 + * + * @param groupId + * @param + * @return + * @throws Exception + */ + public static final ITObject getPersonHpTotal(int groupId, int uid, int tagId) throws Exception { + String mng_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(mng_key, jedis10); + try { + lock.lock(); + + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + return getHpTotal(groupId, tagId, 30); + } finally { + lock.unlock(); + } + } + + /** + * 获取整线体力值 + * + * @param groupId + * @param + * @return + * @throws Exception + */ + public static final ITObject getHpTotal(int groupId, int uid, int cacheTime) throws Exception { + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + if (gmb.partnerLev == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + return getAllHpCache(groupId, uid, cacheTime); + /* + * long allHp = 0; long allOtherHp = 0; HashSet childrenList = + * getMemberAllChildren(groupId, uid); for(Integer tagId : childrenList) { + * String gm_key1 = GroupMemberCache.genKey(groupId, tagId); String strHp = + * Redis.use("group1_db10").hget(gm_key1, "hp"); if + * (StringUtil.isNotEmpty(strHp)) { try { allHp += Integer.parseInt(strHp); } + * catch (Exception e) { } } + * + * String temKey = String.format("g{%s}:m%s:reward_hp", groupId, tagId); String + * strtempValue = Redis.use("group1_db10").get(temKey); if + * (StringUtil.isNotEmpty(strtempValue)) { try { allOtherHp += + * Integer.parseInt(strtempValue); } catch (Exception e) { } } + * + * String mng_key = GroupMemberCache.genKey(groupId, tagId); String r_hp = + * Redis.use("group1_db10").hget(mng_key, "bank_hp"); if + * (StringUtil.isNotEmpty(r_hp)) { try { allOtherHp += Integer.parseInt(r_hp); } + * catch (Exception e) { } } } + * + * ITObject obj1 = TObject.newInstance(); obj1.putLong("hp", allHp + + * allOtherHp); obj1.putLong("total_member", childrenList.size()); return obj1; + */ + } + + /** + * 获取成员列表 + * + * @param groupId + * @param uid + * @param limit + * @param num + * @param + * @param + * @return + * @throws Exception + */ + public static final ITObject getMembers(int groupId, int uid, int limit, int num) throws Exception { + ITObject obj1 = TObject.newInstance(); + + String sql = "SELECT uid,hp,join_time,lev,parentId,partnerLev,ban "; + // String order_sql = "ORDER BY hp DESC,join_time ASC"; + String order_sql = "ORDER BY lev ASC, join_time DESC"; + + GroupBean gb = GroupCache.getGroup(groupId); + + GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, uid); + + boolean mgr = mgr_gmb.lev < 3; + + String where = "FROM group_member WHERE groupId = " + groupId; + String count_where = where; + if (!mgr) { +// String p = Utility.getChildParentSql(groupId, uid, true); + if (limit > 0) { + limit = limit - 1; + } + count_where += String.format(" AND (parentId=%s or uid=%s)", uid, uid); + where += String.format(" and partnerLev=0 AND parentId=%s", uid, uid); + } + String limit_sql = String.format("limit %s,%s", limit, num); + sql = String.format("%s %s %s %s", sql, where, order_sql, limit_sql); + if (limit == 0) { + String count_sql = String.format("SELECT (SELECT COUNT(1) %s) num,(SELECT IFNULL(SUM(hp),0) %s) t_hp1", + count_where, count_where); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + obj1.putLong("member_num", obj.getLong("num")); + obj1.putLong("hp_num1", obj.getDouble("t_hp1").longValue()); + obj1.putLong("hp_num2", 0); + } else { + obj1.putLong("member_num", 0); + obj1.putLong("hp_num1", 0); + obj1.putLong("hp_num2", 0); + } + } + + ITArray arr = TArray.newInstance(); + if (!mgr && limit == 0) { + ITObject obj = TObject.newInstance(); + obj.putInt("uid", uid); + obj.putInt("join_time", mgr_gmb.join_time); + obj.putInt("last_time", mgr_gmb.last_time); + obj.putInt("permission", mgr_gmb.permission); + obj.putInt("parentId", mgr_gmb.parentId); + AccountBean acc = AccountCache.getAccount(uid); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + + if (mgr_gmb.parentId > 0) { + AccountBean parent_acc = AccountCache.getAccount(mgr_gmb.parentId); + if (parent_acc != null) { + obj.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", mgr_gmb.parentId); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + obj.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + obj.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + obj.putString("parentId_nick", StringUtil.Empty); + } + + obj.putInt("partnerLev", mgr_gmb.partnerLev); + obj.putInt("ban", mgr_gmb.ban); + + obj.putInt("lev", 3); + + String ugm_key = GroupMemberCache.genKey(groupId, uid); + String hp = Redis.use("group1_db10").hget(ugm_key, "hp"); + obj.putLong("hp", Long.parseLong(hp)); + + arr.addTObject(obj); + } + ITArray arr1 = DataBase.use().executeQueryByTArray(sql); + if (arr1.size() > 0) { + for (int i = 0; i < arr1.size(); ++i) { + ITObject obj = arr1.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + if (acc != null) { + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + } else { + obj.putString("nick", StringUtil.Empty); + obj.putString("portrait", StringUtil.Empty); + } + + if (obj.getInt("parentId") > 0) { + AccountBean parent_acc = AccountCache.getAccount(obj.getInt("parentId")); + if (parent_acc != null) { + obj.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", obj.getInt("parentId")); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + obj.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + obj.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + if (mgr_gmb.lev == 1 && uid != obj.getInt("uid")) { + AccountBean uid_acc = AccountCache.getAccount(uid); + obj.putInt("parentId", uid); + obj.putString("parentId_nick", uid_acc.nick); + } else { + obj.putString("parentId_nick", StringUtil.Empty); + } + } + if (acc == null) { + continue; + } + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + if (gmb == null) { + arr1.del(i); + i--; + continue; + } + obj.putInt("last_time", gmb.last_time); + obj.putInt("permission", gmb.permission); + obj.putInt("score", gmb.score); + + String ugm_key = GroupMemberCache.genKey(groupId, acc.id); + String group_ban = Redis.use("group1_db10").hget(ugm_key, "group_ban"); + if (!StringUtil.isEmpty(group_ban) && Integer.parseInt(group_ban) == 1) { + obj.putInt("group_ban", 1); + } else { + obj.putInt("group_ban", 0); + } + + arr.addTObject(obj); + } + } + obj1.putTArray("members", arr); + obj1.putInt("limit", limit); + return obj1; + } + + /** + * 获取合伙人所有下级成员 + * + * @param groupId + * @param + * @return + */ + public static HashSet getMemberAllChildren(int groupId, int tagId) { + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (gmb.partnerLev > 0) { + isPartner = true; + } + + String sql; + if (isPartner) { + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + while (!arrayList.isEmpty()) { + ArrayList arrayListTemp = new ArrayList<>(); + arrayListTemp.addAll(arrayList); + arrayList.clear(); + + for (int i = 0; i < arrayListTemp.size(); ++i) { + int tmpTagId = arrayListTemp.get(i); + String child_list2 = Utility.getChildParentSql(groupId, tmpTagId, true); + + sql = String.format( + "select uid from group_member where groupId = %s and (parentId in(%s) or uid = %s)", + groupId, child_list2, tmpTagId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + + if (hashSet.contains(childId)) + continue; + + hashSet.add(childId); + arrayList.add(childId); + } + } + } + } + } + } catch (Exception e) { + + } finally { + lock.unlock(); + } + + return hashSet; + } + + public static String getMemberAllChildren2(int groupId, int tagId) { + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + String list = ""; + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (gmb.partnerLev > 0) { + isPartner = true; + } + + String sql; + if (isPartner) { + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + while (!arrayList.isEmpty()) { + ArrayList arrayListTemp = new ArrayList<>(); + arrayListTemp.addAll(arrayList); + arrayList.clear(); + + for (int i = 0; i < arrayListTemp.size(); ++i) { + int tmpTagId = arrayListTemp.get(i); + String child_list2 = Utility.getChildParentSql(groupId, tmpTagId, true); + + sql = String.format( + "select uid,partnerLev from group_member where groupId = %s and (parentId in(%s) or uid = %s)", + groupId, child_list2, tmpTagId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + int partnerLev = tem.getInt("partnerLev"); + + if (hashSet.contains(childId)) + continue; + + hashSet.add(childId); + + if (partnerLev > 0) + arrayList.add(childId); + } + } + } + } + } + } catch (Exception e) { + + } finally { + } + + list += "" + tagId; + hashSet.remove(tagId); + for (Integer iid : hashSet) { + list += "," + iid; + } + return list; + } + + public static String getMemberAllChildren3(int groupId, int tagId) { + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + String list = ""; + try { + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (gmb.partnerLev > 0) { + isPartner = true; + } + + String sql = ""; + if (isPartner) { + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + while (!arrayList.isEmpty()) { + String strParentId = "" + arrayList.get(0); + for (int i = 1; i < arrayList.size(); i++) { + strParentId += "," + arrayList.get(i); + } + arrayList.clear(); + + sql = String.format( + "select uid,partnerLev from group_member where groupId = %s and (parentId in(%s))", groupId, + strParentId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + int partnerLev = tem.getInt("partnerLev"); + + if (hashSet.contains(childId)) + continue; + + hashSet.add(childId); + + if (partnerLev > 0) + arrayList.add(childId); + } + } + } + } + } catch (Exception e) { + + } finally { + } + + list += "" + tagId; + hashSet.remove(tagId); + for (Integer iid : hashSet) { + list += "," + iid; + } + return list; + } + + /** + * 获取成员列表 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @param + * @param type 1 多到少 2少到多 + * @return + * @throws Exception + */ + public static final ITObject getMembers_1(int groupId, int uid, int tagId, String online, int type, int limit, + int num) throws Exception { + log.info("获取成员------" + groupId + "-------" + uid + "------" + tagId + "------" + type); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10.close(); + } + + ITObject obj1 = TObject.newInstance(); + ITArray arr = TArray.newInstance(); + String sqlGetUserId = String.format("SELECT owner FROM `groups` where id=%s", groupId); + ITArray array = DataBase.use().executeQueryByTArray(sqlGetUserId); + for (int i = 0; i < array.size(); i++) { + ITObject obj = array.getTObject(i); + int owner = obj.getInt("owner"); + + GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, owner); + ITObject objs = TObject.newInstance(); + objs.putInt("uid", owner); + objs.putInt("join_time", mgr_gmb.join_time); + objs.putInt("last_time", mgr_gmb.last_time); + objs.putInt("permission", mgr_gmb.permission); + objs.putInt("parentId", mgr_gmb.parentId); + AccountBean acc = AccountCache.getAccount(owner); + + String nick = URLDecoder.decode(acc.nick, StandardCharsets.UTF_8.name()); + objs.putString("nick", nick); + objs.putString("portrait", acc.portrait); + + objs.putString("playing", online); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + String onlines = jedis0.hget("{user}:" + owner + "_online", "online"); + int onlineStatus = 0; // 默认离线状态 + if (onlines != null && !onlines.isEmpty()) { + try { + onlineStatus = Integer.parseInt(onlines); + } catch (NumberFormatException e) { + log.error("Failed to parse online status for user: " + tagId, e); + } + } + obj.putInt("online", onlineStatus); + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis0.close(); + } + + if (mgr_gmb.parentId > 0) { + AccountBean parent_acc = AccountCache.getAccount(mgr_gmb.parentId); + if (parent_acc != null) { + objs.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", mgr_gmb.parentId); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + objs.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + objs.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + objs.putString("parentId_nick", StringUtil.Empty); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + int endtime = DateUtils.getBeginDay() + 86400; + int begintime = endtime - 86400 * 30; + GroupLogService.getMemberData(jedis9, acc.id, objs, groupId, 0, begintime, endtime, false, false); + } finally { + jedis9.close(); + } + + objs.putInt("partnerLev", mgr_gmb.partnerLev); + objs.putInt("ban", mgr_gmb.ban); + + objs.putInt("lev", mgr_gmb.lev); + + String ugm_key = GroupMemberCache.genKey(groupId, owner); + Jedis jedis10s = Redis.use("group1_db10").getJedis(); + try { + String hp = jedis10s.hget(ugm_key, "hp"); + objs.putLong("hp", Long.parseLong(hp)); + String tag = jedis10s.hget(ugm_key, "tag"); + objs.putString("tag", tag); + arr.addTObject(objs); + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis10s.close(); + } + } + + String sql = "SELECT uid,hp,join_time,lev,parentId,partnerLev,ban "; + String order_sql = "ORDER BY hp DESC,join_time ASC"; + + GroupBean gb = GroupCache.getGroup(groupId); + + GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, tagId); + + boolean mgr = mgr_gmb.lev < 3; + + String where = "FROM group_member WHERE is_delete=0 and groupId = " + groupId; + long allOtherHp = 0; + long allNum = 0; + if (!mgr) { +// String p = Utility.getChildParentSql(groupId, uid, true); +// if (limit > 0) { +// limit = limit - 1; +// } + where += String.format(" AND parentId=%s", tagId); + } else { + if (type == 1) { + GroupBean groupBean = GroupCache.getGroup(groupId); + + where += String.format(" AND (parentId=%s OR parentId = 0)", groupBean.owner); + } + } +// where= String.format("FROM group_member WHERE 1=1"); + where = String.format("FROM group_member WHERE is_delete=0 and groupId = " + groupId); +// where = "FROM group_member WHERE groupId = " + groupId; + String limit_sql = String.format("limit %s,%s", limit, num); + sql = String.format("%s %s %s %s", sql, where, order_sql, limit_sql); + + if (limit == 0) { + ITObject obj = TObject.newInstance(); + obj.putInt("uid", tagId); + obj.putInt("join_time", mgr_gmb.join_time); + obj.putInt("last_time", mgr_gmb.last_time); + obj.putInt("permission", mgr_gmb.permission); + obj.putInt("parentId", mgr_gmb.parentId); + AccountBean acc = AccountCache.getAccount(tagId); + + String nick = URLDecoder.decode(acc.nick, StandardCharsets.UTF_8.name()); + obj.putString("nick", nick); + obj.putString("portrait", acc.portrait); + + Jedis jedis00 = Redis.use("group1_db0").getJedis(); + try { + if (jedis00.hget("{user}:" + acc.id + "_online", "online") != null) { + String online1 = jedis00.hget("{user}:" + acc.id, "online"); + String onlines = jedis00.hget("{user}:" + acc.id + "_online", "online"); + obj.putInt("online", Integer.parseInt(onlines)); + + } else { + + } + + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis00.close(); + } + + obj.putString("playing", online); + + if (mgr_gmb.parentId > 0) { + AccountBean parent_acc = AccountCache.getAccount(mgr_gmb.parentId); + if (parent_acc != null) { + obj.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", mgr_gmb.parentId); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + obj.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + obj.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + obj.putString("parentId_nick", StringUtil.Empty); + } + + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + int endtime = DateUtils.getBeginDay() + 86400; + int begintime = endtime - 86400 * 30; + GroupLogService.getMemberData(jedis9, acc.id, obj, groupId, 0, begintime, endtime, false, false); + } finally { + jedis9.close(); + } + + obj.putInt("partnerLev", mgr_gmb.partnerLev); + obj.putInt("ban", mgr_gmb.ban); + + obj.putInt("lev", mgr_gmb.lev); + + String ugm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10s = Redis.use("group1_db10").getJedis(); + try { + String hp = jedis10s.hget(ugm_key, "hp"); + obj.putLong("hp", Long.parseLong(hp)); + String tag = jedis10s.hget(ugm_key, "tag"); + obj.putString("tag", tag); + arr.addTObject(obj); + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis10s.close(); + } + + } + ITArray arr1 = DataBase.use().executeQueryByTArray(sql); + if (arr1.size() > 0) { + for (int i = 0; i < arr1.size(); ++i) { + ITObject obj = arr1.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + + Jedis jedis00 = Redis.use("group1_db0").getJedis(); + try { + String online1 = jedis00.hget("{user}:" + acc.id, "online"); + String onlines = jedis00.hget("{user}:" + acc.id + "_online", "online"); + + int onlineStatus = 0; // 默认离线状态 + if (onlines != null && !onlines.isEmpty()) { + try { + onlineStatus = Integer.parseInt(onlines); + } catch (NumberFormatException e) { + log.error("Failed to parse online status for user: " + tagId, e); + } + } + obj.putInt("online", onlineStatus); + obj.putString("playing", online1); + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis00.close(); + } + + if (acc == null) { + continue; + } + if (limit == 0 && acc.id == tagId) { + continue; + } + if (acc != null) { + String nick = URLDecoder.decode(acc.nick, StandardCharsets.UTF_8.name()); + obj.putString("nick", nick); + obj.putString("portrait", acc.portrait); + } else { + obj.putString("nick", StringUtil.Empty); + obj.putString("portrait", StringUtil.Empty); + } + + if (obj.getInt("parentId") > 0) { + AccountBean parent_acc = AccountCache.getAccount(obj.getInt("parentId")); + if (parent_acc != null) { + obj.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", obj.getInt("parentId")); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + obj.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + obj.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + if (mgr_gmb.lev < 3) { + if (obj.getInt("lev") <= 2 && tagId != obj.getInt("uid")) { + AccountBean uid_acc = AccountCache.getAccount(tagId); + obj.putInt("parentId", tagId); + obj.putString("parentId_nick", uid_acc.nick); + + log.info("litte mgr uid:" + obj.getInt("uid")); + } else if (obj.getInt("lev") == 3 && tagId != obj.getInt("uid")) { + AccountBean uid_acc = AccountCache.getAccount(tagId); + obj.putInt("parentId", tagId); + obj.putString("parentId_nick", uid_acc.nick); + + log.info("aa litte mgr uid:" + obj.getInt("uid")); + } + } + } + + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + if (gmb != null) { + obj.putInt("last_time", gmb.last_time); + obj.putInt("permission", gmb.permission); + obj.putInt("score", gmb.score); + } +// if (gmb == null) { +// arr1.del(i); +// i--; +// log.info("数据--------" +i); +// continue; +// } + + String ugm_key = GroupMemberCache.genKey(groupId, acc.id); + String group_ban = Redis.use("group1_db10").hget(ugm_key, "group_ban"); + if (!StringUtil.isEmpty(group_ban) && Integer.parseInt(group_ban) == 1) { + obj.putInt("group_ban", 1); + } else { + obj.putInt("group_ban", 0); + } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { +// String isOnline = jedis0.hget("{user}:" + acc.id + "_online", "online"); +// obj.putInt("online", isOnline == null ? 0 : 1); + int endtime = DateUtils.getBeginDay() + 86400; + int begintime = endtime - 86400 * 30; + GroupLogService.getMemberData(jedis9, acc.id, obj, groupId, 0, begintime, endtime, false, false); + } finally { + jedis0.close(); + jedis9.close(); + } + String tag = Redis.use("group1_db10").hget(ugm_key, "tag"); +// String remark = Redis.use("group1_db10").hget(ugm_key, "tag"); + obj.putString("tag", tag); +// obj.putString("remark", remark); + + arr.addTObject(obj); + } + } + + // log.info("arr = "+ arr); + obj1.putLong("otherHp", allOtherHp); + obj1.putLong("member_num", 0); + obj1.putLong("hp_num1", 0); + obj1.putLong("hp_num2", 0); + obj1.putTArray("members", arr); + obj1.putInt("limit", limit); + log.info("sql语句------" + sql); + return obj1; + } + + // 成功加入圈子获取成员信息 + public static final ITObject getUsers(int groupId, int tagId) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + String ugm_key = GroupMemberCache.genKey(groupId, tagId); + + ITArray arr = TArray.newInstance(); + GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, tagId); + ITObject obj = TObject.newInstance(); + try { + + AccountBean acc = AccountCache.getAccount(tagId); + obj.putInt("uid", tagId); + obj.putInt("join_time", mgr_gmb.join_time); + obj.putInt("last_time", mgr_gmb.last_time); + obj.putInt("permission", mgr_gmb.permission); + + String owner = jedis11.hget("group:" + groupId, "owner"); + + obj.putInt("parentId", Integer.parseInt(owner)); + + obj.putInt("partnerLev", mgr_gmb.partnerLev); + obj.putInt("ban", mgr_gmb.ban); + + obj.putInt("lev", mgr_gmb.lev); + + String nick = URLDecoder.decode(acc.nick, StandardCharsets.UTF_8.name()); + obj.putString("nick", nick); + obj.putString("portrait", acc.portrait); + + String onlines = jedis0.hget("{user}:" + tagId + "_online", "online"); + obj.putInt("online", Integer.parseInt(onlines)); + +// if (mgr_gmb.parentId > 0) { + AccountBean parent_acc = AccountCache.getAccount(mgr_gmb.parentId); + if (parent_acc != null) { + obj.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", mgr_gmb.parentId); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + obj.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + obj.putString("parentId_nick", userData.getUtfString("nick")); + } + } + + String hp = jedis10.hget(ugm_key, "hp"); + obj.putLong("hp", Long.parseLong(hp)); + String tag = jedis10.hget(ugm_key, "tag"); + obj.putString("tag", tag); + + obj.putInt("group_ban", 0); + int endtime = DateUtils.getBeginDay() + 86400; + int begintime = endtime - 86400 * 30; + GroupLogService.getMemberData(jedis9, acc.id, obj, groupId, 0, begintime, endtime, false, false); + + } catch (Exception e) { + log.error("getUsers error", e); + } finally { + jedis0.close(); + jedis10.close(); + jedis9.close(); + jedis11.close(); + } + return obj; + } + + public static final ITObject getAllHpCache(int groupId, int uid, int cache_time) throws Exception { + String gm_key = GroupMemberCache.genKey(groupId, uid); + String all_temp_hp_key = gm_key + ":all_temp_hp"; + String all_temp_member_key = gm_key + ":all_temp_total_member"; + String all_temp_hp = Redis.use("group1_db10").get(all_temp_hp_key); + String all_temp_member = Redis.use("group1_db10").get(all_temp_member_key); + ITObject obj1 = TObject.newInstance(); + if (all_temp_hp == null || StringUtil.isEmpty(all_temp_hp) || all_temp_member == null + || StringUtil.isEmpty(all_temp_member)) { + obj1.putLong("hp", 0); + obj1.putLong("total_member", 0); + + /* + * String child_sql = + * String.format("{? = call selectPartnerChildHpByParentId(%s,%s)}", uid, + * groupId); String child_key = + * String.format("selectPartnerChildHpByParentId(%s,%s)", uid, groupId); ITArray + * temparr = new TArray(); try { temparr = DataBase.use().executeCall(child_sql, + * true); }catch (Exception e) { e.printStackTrace(); } + * + * if (temparr.size() > 0) { TDataWrapper data = temparr.get(0); TObject map = + * (TObject)data.getObject(); String key_value = map.getString(child_key); + * String[] split = key_value.split(","); if (split.length == 2) { long _allHp = + * Long.parseLong(split[0]); long _allNum = Long.parseLong(split[1]); + * + * obj1.putLong("hp", _allHp); obj1.putLong("total_member", _allNum); + * + * Redis.use("group1_db10").set(all_temp_hp_key, ""+_allHp); + * Redis.use("group1_db10").expire(all_temp_hp_key, cache_time); + * Redis.use("group1_db10").set(all_temp_member_key, ""+_allNum); + * Redis.use("group1_db10").expire(all_temp_member_key, cache_time); } } + */ + String sql = "SELECT uid "; + String where = "FROM group_member WHERE groupId = " + groupId; + String count_where = where; + String childSql = getMemberAllChildren3(groupId, uid); + count_where = String.format(" %s and uid in (%s)", where, childSql); + String count_sql = String.format( + "SELECT (SELECT COUNT(1) %s) num,(SELECT IFNULL(SUM(hp+bank_hp+reward_hp),0) %s) t_hp1", + count_where, count_where); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + + long _allHp = obj.getDouble("t_hp1").longValue(); + long _allNum = obj.getLong("num"); + + obj1.putLong("hp", _allHp); + obj1.putLong("total_member", _allNum); + + Redis.use("group1_db10").set(all_temp_hp_key, "" + _allHp); + Redis.use("group1_db10").expire(all_temp_hp_key, cache_time); + Redis.use("group1_db10").set(all_temp_member_key, "" + _allNum); + Redis.use("group1_db10").expire(all_temp_member_key, cache_time); + } else { + obj1.putLong("hp", 0); + obj1.putLong("total_member", 0); + } + } else { + obj1.putLong("hp", Long.parseLong(all_temp_hp)); + obj1.putLong("total_member", Long.parseLong(all_temp_member)); + } + + return obj1; + } + + /** + * 获取成员列表 + * + * @param groupId + * @param uid + * @param + * @param + * @param + * @param + * @return + * @throws Exception + */ + public static final ITObject getMemberCount(int groupId, int uid) throws Exception { + ITObject obj1 = TObject.newInstance(); + + String sql = "SELECT uid "; + + GroupMemberBean mgr_gmb = GroupCache.getMember(groupId, uid); + + boolean mgr = mgr_gmb.lev < 3; + + String where = "FROM group_member WHERE groupId = " + groupId; + String count_where = where; + long allOtherHp = 0; + long allHp = 0; + if (!mgr) { + obj1.putLong("member_num", 0); + obj1.putLong("hp_num1", 0); + obj1.putLong("hp_num2", 0); + + ITObject obj2 = getAllHpCache(groupId, uid, 30); + obj1.putLong("member_num", obj2.getLong("total_member")); + obj1.putLong("hp_num1", obj2.getLong("hp")); + obj1.putLong("hp_num2", 0); + + /* + * HashSet childrenList = getMemberAllChildren(groupId, uid); + * for(Integer tagId : childrenList) { String gm_key1 = + * GroupMemberCache.genKey(groupId, tagId); String strHp = + * Redis.use("group1_db10").hget(gm_key1, "hp"); if + * (StringUtil.isNotEmpty(strHp)) { try { allHp += Integer.parseInt(strHp); } + * catch (Exception e) { } } + * + * String temKey = String.format("g{%s}:m%s:reward_hp", groupId, tagId); String + * strtempValue = Redis.use("group1_db10").get(temKey); if + * (StringUtil.isNotEmpty(strtempValue)) { try { allOtherHp += + * Integer.parseInt(strtempValue); } catch (Exception e) { } } + * + * String mng_key = GroupMemberCache.genKey(groupId, tagId); String r_hp = + * Redis.use("group1_db10").hget(mng_key, "bank_hp"); if + * (StringUtil.isNotEmpty(r_hp)) { try { allOtherHp += Integer.parseInt(r_hp); } + * catch (Exception e) { } } } obj1.putLong("member_num", childrenList.size()); + * obj1.putLong("hp_num1", allHp); obj1.putLong("hp_num2", 0); + */ + } else { + /* + * sql = String.format("%s %s", sql, where); String count_sql = String. + * format("SELECT (SELECT COUNT(1) %s) num,(SELECT IFNULL(SUM(hp+reward_hp+bank_hp),0) %s) t_hp1" + * , count_where, count_where); ITArray arr = + * DataBase.use().executeQueryByTArray(count_sql); if (arr.size() > 0) { + * ITObject obj = arr.getTObject(0); allHp = obj.getDouble("t_hp1").longValue(); + * obj1.putLong("member_num", obj.getLong("num")); obj1.putLong("hp_num1", + * obj.getDouble("t_hp1").longValue()); obj1.putLong("hp_num2", 0); } else { + * obj1.putLong("member_num", 0); obj1.putLong("hp_num1", 0); + * obj1.putLong("hp_num2", 0); } + */ + sql = String.format("%s %s", sql, where); + String count_sql = String.format( + "SELECT (SELECT COUNT(1) %s) num,(SELECT IFNULL(SUM(hp+bank_hp+reward_hp),0) %s) t_hp1", + count_where, count_where); + ITArray arr = DataBase.use().executeQueryByTArray(count_sql); + if (arr.size() > 0) { + ITObject obj = arr.getTObject(0); + allHp = obj.getDouble("t_hp1").longValue(); + obj1.putLong("member_num", obj.getLong("num")); + obj1.putLong("hp_num1", obj.getDouble("t_hp1").longValue()); + obj1.putLong("hp_num2", 0); + } else { + obj1.putLong("member_num", 0); + obj1.putLong("hp_num1", 0); + obj1.putLong("hp_num2", 0); + } + /* + * ITArray arr1 = DataBase.use().executeQueryByTArray(sql); if (arr1.size() > 0) + * { for (int i = 0; i < arr1.size(); ++i) { ITObject obj = arr1.getTObject(i); + * int tagId = obj.getInt("uid"); + * + * String temKey = String.format("g{%s}:m%s:reward_hp", groupId, tagId); String + * strtempValue = Redis.use("group1_db10").get(temKey); if + * (StringUtil.isNotEmpty(strtempValue)) { try { allOtherHp += + * Integer.parseInt(strtempValue); } catch (Exception e) { } } + * + * + * String mng_key = GroupMemberCache.genKey(groupId, tagId); String r_hp = + * Redis.use("group1_db10").hget(mng_key, "bank_hp"); if + * (StringUtil.isNotEmpty(r_hp)) { try { allOtherHp += Integer.parseInt(r_hp); } + * catch (Exception e) { } } } } + */ + } + + // log.info("arr = "+ arr); + + obj1.putLong("otherHp", allOtherHp); + + if (mgr_gmb.lev == 1) { + log.info("otherHp = " + allOtherHp); + log.info("allHp = " + allHp); + } + + return obj1; + } + + /** + * 查询成员 + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static final ITObject findMember(int groupId, int uid, int queryId, String tagName) throws Exception { + + ITObject obj = TObject.newInstance(); + ITArray array = TArray.newInstance(); + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + List memberParents = Utility.getMemberParents(jedis10, groupId, queryId, true); + + String ugm_key = GroupMemberCache.genKey(groupId, uid); + String lev = jedis10.hget(ugm_key, "lev"); + int _lev = StringUtil.isNotEmpty(lev) ? Integer.parseInt(lev) : 3; + + String gm_key = GroupMemberCache.genKey(groupId, queryId); + Map map = null; + + while (queryId > 0) { + + map = jedis10.hgetAll(gm_key); + if (map.size() == 0 || Integer.parseInt(map.get("opt")) == 2) { + break; + } + + int parentId = Integer.parseInt(map.get("parentId")); + if (_lev == 3) { + + if (parentId == 0) { + break; + } + + if (!memberParents.contains(uid)) { + break; + } + } + + ITObject temp = TObject.newInstance(); + temp.putInt("uid", queryId); + temp.putLong("hp", Long.parseLong(map.get("hp"))); + temp.putInt("join_time", Integer.parseInt(map.get("join_time"))); + temp.putInt("lev", Integer.parseInt(map.get("lev"))); + temp.putInt("parentId", Integer.parseInt(map.get("parentId"))); + temp.putString("tag", map.get("tag")); + if (Integer.parseInt(map.get("parentId")) > 0) { + AccountBean parent_acc = AccountCache.getAccount(Integer.parseInt(map.get("parentId"))); + if (parent_acc != null) { + temp.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", + Integer.parseInt(map.get("parentId"))); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + temp.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + temp.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + if (_lev == 1 && uid != queryId) { + AccountBean uid_acc = AccountCache.getAccount(uid); + temp.putInt("parentId", uid); + temp.putString("parentId_nick", uid_acc.nick); + } else { + temp.putString("parentId_nick", StringUtil.Empty); + } + } + + temp.putInt("partnerLev", Integer.parseInt(map.get("partnerLev"))); + temp.putInt("ban", Integer.parseInt(map.get("ban"))); + + String group_ban = Redis.use("group1_db10").hget(gm_key, "group_ban"); + if (!StringUtil.isEmpty(group_ban) && Integer.parseInt(group_ban) == 1) { + temp.putInt("group_ban", 1); + } else { + temp.putInt("group_ban", 0); + } + AccountBean acc = AccountCache.getAccount(queryId); + temp.putString("nick", acc.nick); + temp.putString("portrait", acc.portrait); + String last_time = map.get("last_time"); + temp.putInt("last_time", StringUtil.isNotEmpty(last_time) ? Integer.parseInt(last_time) : 0); + String permission = map.get("permission"); + temp.putInt("permission", StringUtil.isNotEmpty(permission) ? Integer.parseInt(permission) : 0); + // 获取成员的限制分数 + temp.putInt("mj_score", map.get("mj_score") == null ? 0 : Integer.parseInt(map.get("mj_score"))); + temp.putInt("pk_score", map.get("pk_score") == null ? 0 : Integer.parseInt(map.get("pk_score"))); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + int endtime = DateUtils.getBeginDay() + 86400; + int begintime = endtime - 86400 * 30; + GroupLogService.getMemberData(jedis9, acc.id, temp, groupId, 0, begintime, endtime, false, false); + } finally { + jedis9.close(); + } + + array.addTObject(temp); + break; + } + + if (StringUtil.isNotEmpty(tagName)) { + + String sql = String.format("select id from account as a " + "right join group_member as b " + + "on a.id = b.uid and b.groupId =%s " + "where nick like '%%%s%%'", groupId, tagName); + + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (arr.size() > 0) { + + for (int i = 0; i < arr.size(); i++) { + + int tag = arr.getTObject(i).getInt("id"); + + if (queryId > 0 && tag == queryId) { + continue; + } + + gm_key = GroupMemberCache.genKey(groupId, tag); + + map = jedis10.hgetAll(gm_key); + if (map.size() == 0 || Integer.parseInt(map.get("opt")) == 2) { + continue; + } + + int parentId = Integer.parseInt(map.get("parentId")); + if (_lev == 3) { + + if (parentId == 0) { + continue; + } + + if (parentId != uid) { + continue; + } + } + + ITObject temp = TObject.newInstance(); + temp.putInt("uid", tag); + temp.putInt("hp", Integer.parseInt(map.get("hp"))); + temp.putInt("join_time", Integer.parseInt(map.get("join_time"))); + temp.putInt("lev", Integer.parseInt(map.get("lev"))); + temp.putInt("parentId", Integer.parseInt(map.get("parentId"))); + if (Integer.parseInt(map.get("parentId")) > 0) { + AccountBean parent_acc = AccountCache.getAccount(Integer.parseInt(map.get("parentId"))); + if (parent_acc != null) { + temp.putString("parentId_nick", parent_acc.nick); + } else { + String sql2 = String.format("SELECT nick FROM account WHERE id ='%d'", + Integer.parseInt(map.get("parentId"))); + ITArray resultArray = DataBase.use().executeQueryByTArray(sql2); + if (resultArray.size() == 0) { + temp.putString("parentId_nick", StringUtil.Empty); + } else { + ITObject userData = resultArray.getTObject(0); + temp.putString("parentId_nick", userData.getUtfString("nick")); + } + } + } else { + if (_lev == 1 && uid != tag) { + AccountBean uid_acc = AccountCache.getAccount(uid); + temp.putInt("parentId", uid); + temp.putString("parentId_nick", uid_acc.nick); + } else { + temp.putString("parentId_nick", StringUtil.Empty); + } + } + + temp.putInt("partnerLev", Integer.parseInt(map.get("partnerLev"))); + temp.putInt("ban", Integer.parseInt(map.get("ban"))); + AccountBean acc = AccountCache.getAccount(tag); + temp.putString("nick", acc.nick); + temp.putString("portrait", acc.portrait); + String last_time = map.get("last_time"); + temp.putInt("last_time", StringUtil.isNotEmpty(last_time) ? Integer.parseInt(last_time) : 0); + String permission = map.get("permission"); + temp.putInt("permission", StringUtil.isNotEmpty(permission) ? Integer.parseInt(permission) : 0); + + array.addTObject(temp); + } + } + } + } finally { + jedis10.close(); + } + + obj.putTArray("members", array); + return obj; + } + + /** + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static final ITObject findMember1(int groupId, int uid) throws Exception { + String gm_key = GroupMemberCache.genKey(groupId, uid); + Map map = Redis.use("group1_db10").hgetAll(gm_key); + if (map.size() == 0 || Integer.parseInt(map.get("opt")) == 2) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + ITObject obj = TObject.newInstance(); + obj.putInt("uid", uid); + obj.putLong("hp", Long.parseLong(map.get("hp"))); + AccountBean acc = AccountCache.getAccount(uid); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + return obj; + } + + /** + * 获取成员上级列表 + * + * @param groupId + * @param uid + * @return + */ + public static final ITArray getMemberParents(int groupId, int uid) { + ITArray list = TArray.newInstance(); + List t_list = Utility.getMemberParents(groupId, uid); + if (t_list != null) { + for (Integer n : t_list) { + list.addInt(n); + } + } + return list; + } + + /** + * + * @param groupId + * @param uid + * @return + */ + public static final int getParents(int groupId, int uid) { + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + if (gmb == null) { + return 0; + } + return gmb.parentId; + } + + /** + * 获取合伙人列表 + * + * @param groupId + * @param + * @return + * @throws Exception + */ + public static final ITObject getPartners(int groupId, int uid, int limit, int num, int qid) throws Exception { + ITObject obj1 = TObject.newInstance(); + String qid_sql = StringUtil.Empty; + GroupMemberBean gmb = GroupCache.getMember(groupId, uid); + boolean self = qid == 0 || qid == uid; + ITArray arr1 = TArray.newInstance(); + if (self && gmb.lev == 3 && limit == 0) { + ITObject obj = TObject.newInstance(); + obj.putInt("uid", uid); + AccountBean acc = AccountCache.getAccount(uid); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + obj.putInt("partnerLev", gmb.partnerLev); + arr1.addTObject(obj); + } + if (qid != uid) { + if (qid > 0) { + qid_sql = "AND uid=" + qid; + } + String sql = String.format( + "SELECT uid,partnerLev FROM group_member where groupId =%s and parentId=%s %s and partnerLev>0 limit %s,%s", + groupId, uid, qid_sql, limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (arr.size() > 0) { + for (int i = 0; i < arr.size(); ++i) { + ITObject obj = arr.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + arr1.addTObject(obj); + } + } + } + + obj1.putTArray("members", arr1); + obj1.putInt("limit", limit); + return obj1; + } + + /** + * 获取指定合伙人奖励数据 + * + * @param groupId + * @param parentId + * @param tagId + * @param partnerLev + * @return + */ + public static final void getRewards(int groupId, int parentId, int tagId, int partnerLev, ITObject resData) { + + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = Redis.use("group1_db11").zrangeByScore(gp_key, 11, 11); + if (pids.size() == 0) { + return; + } + + boolean isShowXiPai = false; + GroupBean gb = GroupCache.getGroup(groupId); + if (gb != null) { + if (gb.owner == parentId) { + isShowXiPai = true; + } + } + + ITArray arr = TArray.newInstance(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, parentId); + if (uid_bean == null) { + return; + } + + if (uid_bean.lev >= 3 && parentId != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(parentId)) { + return; + } + } + + for (String str : pids) { + int pid = Integer.parseInt(str); + GroupPlayBean gpb = GroupCache.getPlay(groupId, pid); + if (gpb == null) + continue; + + int cur_value = 0; + int max_value = 0; + + int xipai_cur_value = 0; + int xipai_max_value = 0; + + String p_reward_key = GroupCache.genRewardKey(groupId, pid); + Double tem = jedis10.zscore(p_reward_key, tagId + ""); + cur_value = tem == null ? 0 : tem.intValue(); + if (partnerLev == 1) { + max_value = gpb.reward; + } else { + tem = jedis10.zscore(p_reward_key, parentId + ""); + max_value = tem == null ? 0 : tem.intValue(); + } + + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, pid); + Double xipai_tem = jedis10.zscore(p_xipai_reward_key, tagId + ""); + xipai_cur_value = xipai_tem == null ? 0 : xipai_tem.intValue(); + if (partnerLev == 1) { + xipai_max_value = gpb.xipai_reward; + } else { + xipai_tem = jedis10.zscore(p_xipai_reward_key, parentId + ""); + xipai_max_value = xipai_tem == null ? 0 : xipai_tem.intValue(); + if (gpb.xipai_rewardValueType == 1 && xipai_max_value > 99) { + xipai_max_value = 100; + } + } + + if (isShowXiPai == false) { + Double parent_xipai_tem = jedis10.zscore(p_xipai_reward_key, parentId + ""); + int parent_xipai_cur_value = parent_xipai_tem == null ? 0 : parent_xipai_tem.intValue(); + if (parent_xipai_cur_value > 0) { + isShowXiPai = true; + } + } + + ITObject obj = TObject.newInstance(); + obj.putInt("pid", pid); + obj.putInt("rewardType", gpb.rewardType); + obj.putInt("xipai_rewardType", gpb.xipai_rewardType); + obj.putInt("cur_value", cur_value); + obj.putInt("max_value", max_value); + obj.putInt("xipai_cur_value", xipai_cur_value); + obj.putInt("xipai_max_value", xipai_max_value); + obj.putInt("rewardValueType", gpb.rewardValueType); + obj.putInt("xipai_rewardValueType", gpb.xipai_rewardValueType); + arr.addTObject(obj); + } + } finally { + jedis10.close(); + } + + resData.putTArray("rewards", arr); + resData.putBoolean("showxipai", isShowXiPai); + } + + /** + * + * @param groupId + */ + public static final int setReward(int groupId, int parentId, int tagId, int partnerLev, int pid, int value, + boolean all, int isSingle) throws Exception { + log.info("setReward parentId:" + parentId + " tagId:" + tagId + " pid:" + pid + " value:" + value + " all:" + + all + " isSingle:" + isSingle); + + GroupPlayBean gpbm = GroupCache.getPlay(groupId, pid); + if (gpbm == null) { + throw new WebException(ErrorCode.GROUP_PLAY_EXIST); + } + + ITObject hpObj = TObject.newFromJsonData(gpbm.hpConfig); + int maxRound = 0; + if (hpObj.getInt("maxRound") != null) { + maxRound = hpObj.getInt("maxRound"); + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock("group_play_award_lock", jedis10); + lock.lock(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, parentId); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && parentId != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(parentId)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + String p_reward_key = GroupCache.genRewardKey(groupId, pid); + int p_reward = 0; + + if (partnerLev == 1) { + p_reward = gpbm.reward; + } else { + Double tem = jedis10.zscore(p_reward_key, parentId + ""); + p_reward = tem == null ? 0 : tem.intValue(); + } + + if (value > p_reward) { + return ErrorCode._FAILED; + } + + int tagOldReward = 0; + int diff = 0; + Double tem = jedis10.zscore(p_reward_key, tagId + ""); + tagOldReward = tem == null ? 0 : tem.intValue(); + if (value < tagOldReward) { + diff = tagOldReward - value; + } + + if (!all) { + + jedis10.zadd(p_reward_key, value, tagId + ""); + + if (diff > 0) { + + List listParent = Utility.getChildParentList(groupId, tagId, false); + for (Integer parId : listParent) { + + Double temPar = jedis10.zscore(p_reward_key, parId + ""); + p_reward = temPar == null ? 0 : temPar.intValue(); + + int newValue = 0; + if (p_reward > diff) { + + newValue = p_reward - diff; + } + jedis10.zadd(p_reward_key, newValue, parId + ""); + } + } + } else { + + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = Redis.use("group1_db11").zrangeByScore(gp_key, 11, 11); + if (pids.size() > 0) { + + for (String strPid : pids) { + + p_reward_key = GroupCache.genRewardKey(groupId, Integer.parseInt(strPid)); + GroupPlayBean gpb = GroupCache.getPlay(groupId, Integer.parseInt(strPid)); + + if (isSingle > 0) { + ITObject hpObjTemp = TObject.newFromJsonData(gpb.hpConfig); + int tempMaxRound = 0; + if (hpObjTemp.getInt("maxRound") != null) { + tempMaxRound = hpObjTemp.getInt("maxRound"); + } + + if ((maxRound == 1 && tempMaxRound != 1) || (maxRound != 1 && tempMaxRound == 1)) { + continue; + } + } + + if (gpb.rewardValueType == gpbm.rewardValueType) { + + int p_reward_max = 0; + if (partnerLev == 1) { + p_reward_max = gpb.reward; + } else { + tem = jedis10.zscore(p_reward_key, parentId + ""); + p_reward_max = tem == null ? 0 : tem.intValue(); + } + + if (p_reward_max < value) { + return ErrorCode._FAILED; + } + } + + } + + for (String strPid : pids) { + tagOldReward = 0; + diff = 0; + GroupPlayBean gpb = GroupCache.getPlay(groupId, Integer.parseInt(strPid)); + + if (isSingle > 0) { + ITObject hpObjTemp = TObject.newFromJsonData(gpb.hpConfig); + int tempMaxRound = 0; + if (hpObjTemp.getInt("maxRound") != null) { + tempMaxRound = hpObjTemp.getInt("maxRound"); + } + + if ((maxRound == 1 && tempMaxRound != 1) || (maxRound != 1 && tempMaxRound == 1)) { + continue; + } + } + + if (gpb.rewardValueType == gpbm.rewardValueType) { + + p_reward_key = GroupCache.genRewardKey(groupId, Integer.parseInt(strPid)); + tem = jedis10.zscore(p_reward_key, tagId + ""); + tagOldReward = tem == null ? 0 : tem.intValue(); + if (value < tagOldReward) { + diff = tagOldReward - value; + } + jedis10.zadd(p_reward_key, value, tagId + ""); + + if (diff > 0) { + + List listParent = Utility.getChildParentList(groupId, tagId, false); + for (Integer parId : listParent) { + + Double temPar = jedis10.zscore(p_reward_key, parId + ""); + p_reward = temPar == null ? 0 : temPar.intValue(); + + int newValue = 0; + if (p_reward > diff) { + + newValue = p_reward - diff; + } + jedis10.zadd(p_reward_key, newValue, parId + ""); + } + } + + } + } + + } + } + } finally { + lock.unlock(); + } + + return 0; + } + + /** + * + * @param groupId + */ + public static final int setXiPaiReward(int groupId, int parentId, int tagId, int partnerLev, int pid, int value, + boolean all, int isSingle) throws Exception { + + log.info("setXiPaiReward parentId:" + parentId + " tagId:" + tagId + " pid:" + pid + " value:" + value + " all:" + + all + " isSingle:" + isSingle); + + GroupPlayBean gpbm = GroupCache.getPlay(groupId, pid); + if (gpbm == null) { + throw new WebException(ErrorCode.GROUP_PLAY_EXIST); + } + + ITObject hpObj = TObject.newFromJsonData(gpbm.hpConfig); + int maxRound = 0; + if (hpObj.getInt("maxRound") != null) { + maxRound = hpObj.getInt("maxRound"); + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock("group_play_award_lock", jedis10); + lock.lock(); + try { + + GroupMemberBean uid_bean = GroupCache.getMember(groupId, parentId); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3 && parentId != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(parentId)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + + String p_reward_key = GroupCache.genXiPaiRewardKey(groupId, pid); + int p_reward = 0; + + if (partnerLev == 1) { + p_reward = gpbm.xipai_reward; + } else { + Double tem = jedis10.zscore(p_reward_key, parentId + ""); + p_reward = tem == null ? 0 : tem.intValue(); + } + + if (value > p_reward) { + return ErrorCode._FAILED; + } + + int tagOldReward = 0; + int diff = 0; + Double tem = jedis10.zscore(p_reward_key, tagId + ""); + tagOldReward = tem == null ? 0 : tem.intValue(); + if (value < tagOldReward) { + diff = tagOldReward - value; + } + + if (!all) { + + jedis10.zadd(p_reward_key, value, tagId + ""); + + if (diff > 0) { + + List listParent = Utility.getChildParentList(groupId, tagId, false); + for (Integer parId : listParent) { + + Double temPar = jedis10.zscore(p_reward_key, parId + ""); + p_reward = temPar == null ? 0 : temPar.intValue(); + + int newValue = 0; + if (p_reward > diff) { + + newValue = p_reward - diff; + } + jedis10.zadd(p_reward_key, newValue, parId + ""); + } + } + } else { + + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = Redis.use("group1_db11").zrangeByScore(gp_key, 11, 11); + if (pids.size() > 0) { + + for (String strPid : pids) { + + p_reward_key = GroupCache.genXiPaiRewardKey(groupId, Integer.parseInt(strPid)); + GroupPlayBean gpb = GroupCache.getPlay(groupId, Integer.parseInt(strPid)); + + if (isSingle > 0) { + ITObject hpObjTemp = TObject.newFromJsonData(gpb.hpConfig); + int tempMaxRound = 0; + if (hpObjTemp.getInt("maxRound") != null) { + tempMaxRound = hpObjTemp.getInt("maxRound"); + } + + if ((maxRound == 1 && tempMaxRound != 1) || (maxRound != 1 && tempMaxRound == 1)) { + continue; + } + } + + if (gpb.xipai_rewardValueType == gpbm.xipai_rewardValueType) { + + int p_reward_max = 0; + if (partnerLev == 1) { + p_reward_max = gpb.xipai_reward; + } else { + tem = jedis10.zscore(p_reward_key, parentId + ""); + p_reward_max = tem == null ? 0 : tem.intValue(); + } + + if (p_reward_max < value) { + return ErrorCode._FAILED; + } + } + + } + + for (String strPid : pids) { + tagOldReward = 0; + diff = 0; + + GroupPlayBean gpb = GroupCache.getPlay(groupId, Integer.parseInt(strPid)); + if (isSingle > 0) { + ITObject hpObjTemp = TObject.newFromJsonData(gpb.hpConfig); + int tempMaxRound = 0; + if (hpObjTemp.getInt("maxRound") != null) { + tempMaxRound = hpObjTemp.getInt("maxRound"); + } + + if ((maxRound == 1 && tempMaxRound != 1) || (maxRound != 1 && tempMaxRound == 1)) { + continue; + } + } + + if (gpb.xipai_rewardValueType == gpbm.xipai_rewardValueType) { + + p_reward_key = GroupCache.genXiPaiRewardKey(groupId, Integer.parseInt(strPid)); + tem = jedis10.zscore(p_reward_key, tagId + ""); + tagOldReward = tem == null ? 0 : tem.intValue(); + if (value < tagOldReward) { + diff = tagOldReward - value; + } + + jedis10.zadd(p_reward_key, value, tagId + ""); + + if (diff > 0) { + + List listParent = Utility.getChildParentList(groupId, tagId, false); + for (Integer parId : listParent) { + + Double temPar = jedis10.zscore(p_reward_key, parId + ""); + p_reward = temPar == null ? 0 : temPar.intValue(); + + int newValue = 0; + if (p_reward > diff) { + + newValue = p_reward - diff; + } + jedis10.zadd(p_reward_key, newValue, parId + ""); + } + } + + } + } + } + } + } finally { + lock.unlock(); + } + + return 0; + } + + /** + * 置顶圈子 + * + * @param groupId + * @param uid + * @param top + * @throws Exception + */ + public static final int topGroup(int groupId, int uid, boolean top) throws Exception { + String group_key = GroupCache.genKey(groupId); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + RedisLock lock = new RedisLock(group_key, jedis11); + try { + String opt1 = jedis11.hget(group_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NO_EXIST); + } + long time = top ? System.currentTimeMillis() / 1000 : 0; + jedis11.zadd(GroupCache.genGroupsKey(uid), time, groupId + ""); + String gm_key = GroupMemberCache.genKey(groupId, uid); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + jedis10.hset(gm_key, "top_time", time + ""); + BaseCache.updateCacheVer(jedis10, gm_key); + } finally { + jedis10.close(); + } + + return (int) time; + } finally { + lock.unlock(); + } + } + + /** + * 更新圈子信息 + * + * @param groupId + * @param name + * @param reqData + * @throws Exception + */ + public static final void updateGroupInfo(int groupId, String name, ITObject reqData) throws Exception { + log.info("updateGroupInfo name靠靠靠靠靠靠靠噢噢噢噢:" + name + " reqData:" + reqData.toString()); + boolean ban = reqData.getBoolean("ban"); + String notice = reqData.getString("notice"); + int dissolve_opt = reqData.getInt("dissolve_opt"); + int kick_opt = reqData.getInt("kick_opt"); + int ban_apply = reqData.getInt("ban_apply"); + boolean ban_chat1 = reqData.getBoolean("ban_chat1"); + boolean ban_chat2 = reqData.getBoolean("ban_chat2"); + int option = reqData.getInt("option"); + int showNum = reqData.getInt("show_num"); + // int exit_opt = reqData.getInt("exit_opt"); + int exit_opt = 0; + String _ban = (ban ? 1 : 0) + StringUtil.Empty; + String sql = String.format("update groups set name='%s' where id = %s", name, groupId); + Utility.evtdb(groupId, 1, sql); + Map map = new HashMap(); + map.put("name", name); + map.put("notice", name); + map.put("ban", _ban); + map.put("dissolve_opt", dissolve_opt + ""); + map.put("kick_opt", kick_opt + ""); +// map.put("notice", notice); + map.put("ban_apply", ban_apply + ""); + map.put("ban_chat1", ban_chat1 + ""); + map.put("ban_chat2", ban_chat2 + ""); + map.put("exit_opt", exit_opt + ""); + map.put("option", option + ""); + map.put("show_num", showNum + ""); +// map.put("wechatId", wechatId); + String key = GroupCache.genKey(groupId); + log.info("1111111:" + map); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + try { + jedis11.hmset(key, map); + BaseCache.updateCacheVer(jedis11, key); + } finally { + jedis11.close(); + } + + GroupPublisherService.updateGroupEvt(groupId, name, ban, notice, option, showNum); + } + + /** + * 成员禁止娱乐 + * + * @param groupId + * @throws Exception + */ + public static final void banMember(int groupId, int uid, int tagId, int optType, int ban) throws Exception { + log.info("禁止娱乐-----"); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + String opt1 = jedis10.hget(gm_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } else if (mgn_lev >= 3) { + if (uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + // log.info("uid:" + uid + " ban_member:" + tagId + " par_list:" + par_list); + } + } + + String group_ban = jedis10.hget(mng_key, "group_ban"); + if (!StringUtil.isEmpty(group_ban) && Integer.parseInt(group_ban) == 1) { + throw new WebException(ErrorCode.GROUP_MEMBER_BAN); + } + } finally { + lock1.unlock(false); + } + + log.info("uid:" + uid + " ban_member:" + tagId + " optType:" + optType + " ban:" + ban); + + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (optType == 2 && gmb.partnerLev > 0) { + isPartner = true; + } + + String sql; + String _ban = ban + ""; + if (isPartner) { + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + gm_key = GroupMemberCache.genKey(groupId, tagId); + jedis10.hset(gm_key, "ban", _ban); + jedis10.hset(gm_key, "group_ban", _ban); + BaseCache.updateCacheVer(jedis10, gm_key); + + while (!arrayList.isEmpty()) { + ArrayList arrayListTemp = new ArrayList<>(); + arrayListTemp.addAll(arrayList); + arrayList.clear(); + + for (int i = 0; i < arrayListTemp.size(); ++i) { + int tmpTagId = arrayListTemp.get(i); + String child_list2 = Utility.getChildParentSql(groupId, tmpTagId, true); + + sql = String.format( + "update group_member set ban = %s where groupId = %s and (parentId in(%s) or uid = %s)", + _ban, groupId, child_list2, tmpTagId); + Utility.evtdb(groupId, 1, sql); + + sql = String.format( + "select uid from group_member where groupId = %s and (parentId in(%s) or uid = %s)", + groupId, child_list2, tmpTagId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + + if (hashSet.contains(childId)) + continue; + + gm_key = GroupMemberCache.genKey(groupId, childId); + jedis10.hset(gm_key, "ban", _ban); + jedis10.hset(gm_key, "group_ban", _ban); + BaseCache.updateCacheVer(jedis10, gm_key); + + hashSet.add(childId); + arrayList.add(childId); + } + } + } + } + + GroupPublisherService.banPlay(groupId, tagId, ban); + + } else { + + sql = String.format("update group_member set ban = %s where uid = %s AND groupId = %s", _ban, tagId, + groupId); + Utility.evtdb(groupId, 1, sql); + jedis10.hset(gm_key, "ban", _ban); + BaseCache.updateCacheVer(jedis10, gm_key); + + GroupPublisherService.banPlay(groupId, tagId, ban); + + } + } finally { + lock.unlock(); + } + } + + /** + * 成员禁止娱乐 + * + * @param groupId + * @throws Exception + */ + public static final void blackMember(int groupId, int uid, int tagId, int optType, int ban, int ban_rate, + int ban_value) throws Exception { + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + String opt1 = jedis10.hget(gm_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev != 1) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } finally { + lock1.unlock(false); + } + + boolean isPartner = false; + GroupMemberBean gmb = GroupCache.getMember(groupId, tagId); + if (optType == 2 && gmb.partnerLev > 0) { + isPartner = true; + } + + if (ban != 0) { + if (Redis.use("group1_db1").sismember("gods", Integer.toString(tagId))) { + String specail = Redis.use("group1_db1").hget("gods_special", Integer.toString(tagId)); + if (StringUtil.isEmpty(specail)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } else { + log.info("set gods tagId:" + tagId + " to ban " + ban + " srem gods"); + // Redis.use("group1_db1").srem("gods", Integer.toString(tagId)); + } + } + } + + String sql; + String _ban = ban + ""; + if (ban == 1) { + try { + ban_rate = Integer.parseInt(Redis.use("group1_db1").hget("black_rate", "black")); + } catch (Exception e) { + } + } else if (ban == 2) { + try { + ban_rate = Integer.parseInt(Redis.use("group1_db1").hget("black_rate", "white")); + } catch (Exception e) { + } + } + + log.info("uid:" + uid + " black_member:" + tagId + " ban:" + ban + " ban_rate:" + ban_rate + " ban_value:" + + ban_value); + + if (isPartner) { + HashSet hashSet = new HashSet<>(); + hashSet.add(tagId); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(tagId); + + gm_key = GroupMemberCache.genKey(groupId, tagId); + jedis10.hset(gm_key, "black", _ban); + jedis10.hset(gm_key, "group_black", _ban); + String _ban_rate = ban_rate + ""; + jedis10.hset(gm_key, "group_black_rate", _ban_rate); + jedis10.hset(gm_key, "group_black_key", gm_key); + String _ban_value = ban_value + ""; + jedis10.hset(gm_key, "group_black_max_value", _ban_value); + jedis10.hset(gm_key, "group_black_now_value", "0"); + BaseCache.updateCacheVer(jedis10, gm_key); + + while (!arrayList.isEmpty()) { + ArrayList arrayListTemp = new ArrayList<>(); + arrayListTemp.addAll(arrayList); + arrayList.clear(); + + for (int i = 0; i < arrayListTemp.size(); ++i) { + int tmpTagId = arrayListTemp.get(i); + String child_list2 = Utility.getChildParentSql(groupId, tmpTagId, true); + + sql = String.format( + "select uid from group_member where groupId = %s and (parentId in(%s) or uid = %s)", + groupId, child_list2, tmpTagId); + + ITArray tmplist = DataBase.use().executeQueryByTArray(sql); + if (tmplist.size() > 0) { + for (int j = 0; j < tmplist.size(); ++j) { + + ITObject tem = tmplist.getTObject(j); + int childId = tem.getInt("uid"); + + if (hashSet.contains(childId)) + continue; + + if (!Redis.use("group1_db1").sismember("gods", Integer.toString(childId))) { + gm_key = GroupMemberCache.genKey(groupId, childId); + jedis10.hset(gm_key, "group_black_key", GroupMemberCache.genKey(groupId, tagId)); + BaseCache.updateCacheVer(jedis10, gm_key); + } else { + String specail = Redis.use("group1_db1").hget("gods_special", + Integer.toString(childId)); + if (StringUtil.isEmpty(specail)) { + + } else { + // Redis.use("group1_db1").srem("gods", Integer.toString(childId)); + log.info("set gods childId:" + childId + " to ban " + ban + " srem gods"); + gm_key = GroupMemberCache.genKey(groupId, childId); + jedis10.hset(gm_key, "group_black_key", + GroupMemberCache.genKey(groupId, tagId)); + BaseCache.updateCacheVer(jedis10, gm_key); + } + } + + hashSet.add(childId); + arrayList.add(childId); + } + } + } + } + } else { + + jedis10.hset(gm_key, "group_black_key", GroupMemberCache.genKey(groupId, tagId)); + BaseCache.updateCacheVer(jedis10, gm_key); + } + } finally { + lock.unlock(); + } + } + + /** + * 玩法禁止娱乐 + * + * @param groupId + * @throws Exception + */ + public static final void banPlay(int groupId, int pid, int ban) throws Exception { + log.info("banPlay pid:" + pid + " ban:" + ban); + String p_key = GroupCache.genPlayKey(groupId, pid); + String _ban = ban + ""; + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + jedis11.hset(p_key, "ban", _ban); + jedis11.hincrBy(p_key, "cache_ver", 1); + jedis11.close(); + } + + /** + * 标识玩法 + * + * @param groupId + * @throws Exception + */ + public static final void markPlay(int groupId, int pid, int mark) throws Exception { + String p_key = GroupCache.genPlayKey(groupId, pid); + String _mark = mark + ""; + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + jedis11.hset(p_key, "mark", _mark); + jedis11.hincrBy(p_key, "cache_ver", 1); + jedis11.close(); + } + + public static final int getMarkedPlayCount(int groupId) throws Exception { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int count = 0; + try { + String gpids_key = GroupCache.genPidsKey(groupId); + Set pids = jedis11.zrangeByScore(gpids_key, 10, 11); + String key = "g{" + groupId + "}:play:"; + + for (String tem : pids) { + String gp_key = key + tem; + + String str = Redis.use("group1_db11").hget(gp_key, "mark"); + if (str != null) { + int val = Integer.parseInt(str); + if (val == 1) { + count++; + } + } + } + } finally { + jedis11.close(); + } + + return count; + } + + /** + * 更新成员管理 + * + * @param groupId + * @param tagId + * @param opt 1 设置管理员 2 取消管理员 + * @throws Exception + */ + public static final ITObject updateMemberMgr(int groupId, int tagId, int opt) throws Exception { + log.info("updateMemberMgr tagId:" + tagId + " opt:" + opt); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + String opt1 = jedis10.hget(gm_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int clev = Integer.parseInt(jedis10.hget(gm_key, "lev")); + if (opt == 1 && clev == 3) { + int partnerLev = Integer.parseInt(jedis10.hget(gm_key, "partnerLev")); + if (partnerLev > 0) { + throw new WebException(ErrorCode.GROUP_ALREADY_PARTNER); + } + int member_parentId = Integer.parseInt(jedis10.hget(gm_key, "parentId")); + if (member_parentId > 0) { + throw new WebException(ErrorCode.GROUP_MEMBER_EXIST_PARTENER); + } + clev = 2; + } else if (opt == 2 && clev == 2) { + clev = 3; + } else { + throw new WebException(ErrorCode._FAILED); + } + String sql = String.format("update group_member set lev = %s where uid = %s AND groupId = %s", clev, tagId, + groupId); + Utility.evtdb(groupId, 1, sql); + GroupPublisherService.updateMemberEvt(groupId, tagId, 2, clev); + jedis10.hset(gm_key, "lev", clev + ""); + BaseCache.updateCacheVer(jedis10, gm_key); + int permission = 0; + if (clev == 2) { + permission = PERMISSION_DEL_MEMBER | PERMISSION_ADD_MEMBER | PERMISSION_HP_OPT | PERMISSION_BAN + | PERMISSION_BAN_DESKMATE; + jedis10.hset(gm_key, "permission", permission + ""); + } else { + jedis10.hset(gm_key, "permission", permission + ""); + } + + ITObject resData = TObject.newInstance(); + resData.putInt("permission", permission); + return resData; + } finally { + lock.unlock(); + } + + } + + /** + * 添加玩法 + * + * @param groupId + * @param gameId + * @param name + * @param config + * @param hpData + * @return + * @throws Exception + */ + public static final ITObject addPlay(int groupId, int gameId, String name, int deskId, ITObject config, + ITObject hpData, int hpOnOff) throws Exception { + + log.info("addPlay gameId:" + gameId + " name:" + name + " config:" + config + " hpData:" + hpData + " hpOnOff:" + + hpOnOff); + + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + + RedisLock lock = null; + try { + String gp_key = GroupCache.genPidsKey(groupId); + long time = System.currentTimeMillis(); + long free_num = jedis11.zcount(gp_key, 20, time); + if (free_num == 0) { + throw new WebException(ErrorCode.GROUP_PLAY_FULL); + } + lock = new RedisLock(gp_key, jedis11); + lock.lock(); + Set pids = jedis11.zrangeByScore(gp_key, 20, time, 0, 1); + if (pids.size() == 0) { + throw new WebException(ErrorCode.GROUP_PLAY_FULL); + } + int pid = 0; + for (String tem : pids) { + pid = Integer.parseInt(tem); + break; + } + GameBean gb = GameCache.getGame(gameId); + int maxPlayers = gb.maxPlayers; + if (config.containsKey("maxPlayers")) { + maxPlayers = config.getInt("maxPlayers"); + } + + int opt = config.getInt("opt"); + int maxRound = getMaxRound(gameId, opt); + hpData.putInt("maxRound", maxRound); + + log.info("addPlay() maxRound=" + maxRound); + + config.putInt("maxPlayers", maxPlayers); + config.putInt("pid", pid); + int rewardType = hpData.getInt("rewards_type"); + int rewardValueType = hpData.getInt("rewardValueType"); + int xipai_rewardType = 1; + if (hpData.containsKey("xipai_rewardType")) { + xipai_rewardType = hpData.getInt("xipai_rewardType"); + } + int xipai_rewardValueType = 1; + if (hpData.containsKey("xipai_rewardValueType")) { + xipai_rewardValueType = hpData.getInt("xipai_rewardValueType"); + } + + int reward = hpData.getInt("rewards_val"); + int xipai_reward = 1000000; + if (hpData.containsKey("xipai_rewards_val")) { + xipai_reward = hpData.getInt("xipai_rewards_val"); + } + + int robot_room = 0; + if (hpData.containsKey("robot_room")) { + robot_room = hpData.getInt("robot_room"); + } + + hpData.remove("rewards_type"); + hpData.remove("rewards_val"); + hpData.remove("rewardValueType"); + hpData.remove("xipai_rewards_val"); + hpData.remove("xipai_rewards_type"); + hpData.remove("xipai_rewardValueType"); + + jedis9.del(String.format("g%s:diamo_cost:p%s", groupId, pid)); + jedis9.del(String.format("g%s:valid_room:p%s", groupId, pid)); + jedis9.del(String.format("g%s:no_valid_room:p%s", groupId, pid)); + jedis9.del(String.format("g%s:round:p%s", groupId, pid)); + + int hp_times = hpData.getInt("times"); + int cMisslie = hpData.getInt("BanMissile"); + int cChat = hpData.getInt("BanMissile"); + log.info("限制表情:====" + cMisslie + "限制聊天:======" + cMisslie); + String config_json = config.toJson(); + String hpData_json = hpData.toJson(); + String p_key = GroupCache.genPlayKey(groupId, pid); + Map redis_map = payToRedis(groupId, pid, gameId, name, deskId, config_json, hpData_json, + hpOnOff, hp_times, reward, rewardType, rewardValueType, xipai_reward, xipai_rewardType, + xipai_rewardValueType, robot_room, cChat, cMisslie); + redis_map.put("opt", "1"); + jedis11.hmset(p_key, redis_map); + jedis11.hincrBy(p_key, "cache_ver", 1); + jedis11.zadd(gp_key, 1 * 10 + hpOnOff, pid + ""); + + // 得到所有的玩法 + pids = jedis11.zrangeByScore(gp_key, 11, 11); + // 删除新增加的玩法 + pids.remove(pid); + + // 查找所有的一级合伙人 + String sql = String.format("SELECT uid FROM group_member where groupId =%s and partnerLev = 1", groupId); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (arr.size() > 0) { + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + + // 遍历所有的一级合伙人 + for (int i = 0; i < arr.size(); ++i) { + + ITObject obj = arr.getTObject(i); + int tem_id = obj.getInt("uid"); + + // 遍历所有的玩法,查看现在的玩法的推广奖励是否一致 + int sameValue = 0; + int xipai_sameValue = 0; + for (String strPid : pids) { + + int indexPid = Integer.parseInt(strPid); + if (indexPid != pid) { + GroupPlayBean gpb = GroupCache.getPlay(groupId, indexPid); + if (gpb != null && gpb.rewardValueType == rewardValueType) { + + String p_reward_key = GroupCache.genRewardKey(groupId, indexPid); + Double tem = jedis10.zscore(p_reward_key, tem_id + ""); + int value = tem == null ? 0 : tem.intValue(); + + if (sameValue == 0) { + sameValue = value; + } else if (sameValue != value) { + sameValue = 0; + break; + } + } + if (gpb != null && gpb.xipai_rewardValueType == xipai_rewardValueType) { + String p_reward_key = GroupCache.genXiPaiRewardKey(groupId, indexPid); + Double tem = jedis10.zscore(p_reward_key, tem_id + ""); + int value = tem == null ? 0 : tem.intValue(); + + if (xipai_sameValue == 0) { + xipai_sameValue = value; + } else if (xipai_sameValue != value) { + xipai_sameValue = 0; + break; + } + } + } + } + // 设置该一级合伙人的奖励 + String p_reward_key = GroupCache.genRewardKey(groupId, pid); + jedis10.zadd(p_reward_key, sameValue, tem_id + ""); + + // 设置该一级合伙人的奖励 + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, pid); + jedis10.zadd(p_xipai_reward_key, xipai_sameValue, tem_id + ""); + } + } finally { + jedis10.close(); + } + } + + GroupPublisherService.addPlayEvt(groupId, pid); + + ITObject obj = TObject.newInstance(); + obj.putInt("pid", pid); + obj.putInt("maxPlayers", maxPlayers); + obj.putInt("maxRound", maxRound); + + return obj; + } finally { + if (lock != null) + lock.unlock(); + + jedis9.close(); + } + } + + public static final int getMaxRound(int gameId, int opt) throws Exception { + int maxRound = 0; + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + String keyStr = "game:" + gameId; + String optStr = "opt" + opt; + String val = jedis1.hget(keyStr, optStr); + maxRound = Integer.parseInt(val); + + } finally { + jedis1.close(); + } + + return maxRound; + } + + /** + * 删除玩法 + * + * @param groupId + * @param pid + * @return + * @throws Exception + */ + public static final int delPlay(int groupId, int pid) throws Exception { + log.info("delPlay pid:" + pid); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + int min_value = pid * 10000 + 1000; + int max_value = pid * 10000 + 9999; + String grooms_key = GroupCache.genRoomsKey(groupId); + Set rooms = jedis11.zrevrangeByScore(grooms_key, max_value, min_value); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + for (String room : rooms) { + boolean check = GroupRoomService.checkRoom(room, jedis0); + if (!check) { + jedis11.zrem(grooms_key, room); + } else { + check = GroupRoomService.checkFakeRoom(room, jedis0); + if (!check) { + return ErrorCode.GROUP_PLAY_EXIST_ROOM; + } else { + jedis11.zrem(grooms_key, room); + } + } + } + } finally { + jedis0.close(); + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String p_reward_key = GroupCache.genRewardKey(groupId, pid); + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, pid); + jedis10.del(p_reward_key); + jedis10.del(p_xipai_reward_key); + } finally { + jedis10.close(); + } + + String gp_key = GroupCache.genPidsKey(groupId); + String p_key = GroupCache.genPlayKey(groupId, pid); + RedisLock lock = new RedisLock(gp_key, jedis11); + Jedis jedis9 = Redis.use("group1_db9").getJedis(); + try { + lock.lock(); + + jedis9.del(String.format("g%s:diamo_cost:p%s", groupId, pid)); + jedis9.del(String.format("g%s:valid_room:p%s", groupId, pid)); + jedis9.del(String.format("g%s:no_valid_room:p%s", groupId, pid)); + jedis9.del(String.format("g%s:round:p%s", groupId, pid)); + + jedis11.hset(p_key, "opt", "2"); + jedis11.hincrBy(p_key, "cache_ver", 1); + long time = System.currentTimeMillis() / 1000; + jedis11.zadd(gp_key, time, pid + ""); + GroupPublisherService.delPlayEvt(groupId, pid); + } finally { + lock.unlock(); + jedis9.close(); + } + return 0; + } + + /** + * 添加玩法 + * + * @param groupId + * @param gameId + * @param name + * @param config + * @param hpData + * @return + * @throws Exception + */ + public static final ITObject updatePlay(int groupId, int pid, int gameId, String name, int deskId, ITObject config, + ITObject hpData, int hpOnOff) throws Exception { + log.info("updatePlay pid:" + pid + " gameId:" + gameId + " name:" + name + " config:" + config + " hpData:" + + hpData + " hpOnOff:" + hpOnOff); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + int min_value = pid * 10000 + 1000; + int max_value = pid * 10000 + 9999; + String grooms_key = GroupCache.genRoomsKey(groupId); + Set rooms = jedis11.zrevrangeByScore(grooms_key, max_value, min_value); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + for (String room : rooms) { + boolean check = GroupRoomService.checkRoom(room, jedis0); + if (!check) { + jedis11.zrem(grooms_key, room); + } + } + } finally { + jedis0.close(); + } + + String p_key = GroupCache.genPlayKey(groupId, pid); + RedisLock lock = new RedisLock(p_key, jedis11); + try { + + GameBean gb = GameCache.getGame(gameId); + int maxPlayers = gb.maxPlayers; + if (config.containsKey("maxPlayers")) { + maxPlayers = config.getInt("maxPlayers"); + } + config.putInt("maxPlayers", maxPlayers); + config.putInt("pid", pid); + int rewardType = hpData.getInt("rewards_type"); + int rewardValueType = hpData.getInt("rewardValueType"); + int xipai_rewardType = 0; + if (hpData.containsKey("xipai_rewardType")) { + xipai_rewardType = hpData.getInt("xipai_rewardType"); + } + int xipai_rewardValueType = 0; + if (hpData.containsKey("xipai_rewardValueType")) { + xipai_rewardValueType = hpData.getInt("xipai_rewardValueType"); + } + int reward = hpData.getInt("rewards_val"); + int xipai_reward = 0; + if (hpData.containsKey("xipai_rewards_val")) { + xipai_reward = hpData.getInt("xipai_rewards_val"); + } + int robot_room = 0; + if (hpData.containsKey("robot_room")) { + robot_room = hpData.getInt("robot_room"); + } + hpData.remove("rewards_type"); + hpData.remove("rewards_val"); + hpData.remove("xipai_rewards_val"); + hpData.remove("rewardValueType"); + hpData.remove("xipai_rewards_type"); + hpData.remove("xipai_rewardValueType"); + int hp_times = hpData.getInt("times"); + + int cMisslie = hpData.getInt("BanMissile"); + int cChat = hpData.getInt("BanChat"); + + int opt = config.getInt("opt"); + int maxRound = getMaxRound(gameId, opt); + hpData.putInt("maxRound", maxRound); + config.putInt("maxRound", maxRound); + + String config_json = config.toJson(); + String hpData_json = hpData.toJson(); + + Map redis_map = payToRedis(groupId, pid, gameId, name, deskId, config_json, hpData_json, + hpOnOff, hp_times, reward, rewardType, rewardValueType, xipai_reward, xipai_rewardType, + xipai_rewardValueType, robot_room, cChat, cMisslie); + jedis11.hmset(p_key, redis_map); + jedis11.hincrBy(p_key, "cache_ver", 1); + String gp_key = GroupCache.genPidsKey(groupId); + jedis11.zadd(gp_key, 1 * 10 + hpOnOff, pid + ""); + + GroupPublisherService.updatePlayEvt(groupId, pid); + } finally { + lock.unlock(); + } + return config; + } + + /** + * 分配成员 + * + * @param groupId + * @param parId + * @param tagId + * @throws Exception + */ + public static final void distributeMember(int groupId, int parId, int tagId) throws Exception { + String tag_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = null; + RedisLock lock1 = null; + try { + lock = new RedisLock(tag_key, jedis10); + lock.lock(); + + String par_key = GroupMemberCache.genKey(groupId, parId); + lock1 = new RedisLock(par_key, jedis10); + lock1.lock(); + int par_partner = Integer.parseInt(jedis10.hget(par_key, "partnerLev")); + if (par_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + String member_opt = jedis10.hget(tag_key, "opt"); + if (StringUtil.isNotEmpty(member_opt) && member_opt.equals("1")) { + int member_lev = Integer.parseInt(jedis10.hget(tag_key, "lev")); + if (member_lev < 3) { + throw new WebException(ErrorCode.GROUP_TAG_ISMGR); + } + int member_partner = Integer.parseInt(jedis10.hget(tag_key, "partnerLev")); + if (member_partner > 0) { + throw new WebException(ErrorCode.GROUP_ALREADY_PARTNER); + } + int member_parentId = Integer.parseInt(jedis10.hget(tag_key, "parentId")); + if (member_parentId > 0) { + throw new WebException(ErrorCode.GROUP_MEMBER_EXIST_PARTENER); + } + // int member_hp = Integer.parseInt(jedis10.hget(tag_key, "hp")); + // List par_list = Utility.getMemberParents(jedis10,groupId, parId, + // true); + // for(Integer p : par_list) { + // String ph_key = String.format("g{%s}:par_hp:%s", groupId,p); + // jedis10.incrBy(ph_key, member_hp); + // } + String sql = String.format("update group_member set parentId = %s WHERE uid = %s and groupId = %s", + parId, tagId, groupId); + Utility.evtdb(groupId, 1, sql); + jedis10.hset(tag_key, "parentId", parId + ""); + BaseCache.updateCacheVer(jedis10, tag_key); + } else { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + } finally { + if (lock != null) { + lock.unlock(false); + } + if (lock1 != null) { + lock1.unlock(); + } + } + + } + + /** + * 获取合伙人管理列表 + * + * @param groupId + * @param tagId + * @param limit + * @param num + * @return + * @throws Exception + */ + public static final ITObject getPartnerInfos(int groupId, int uid, int tagId, int limit, int num, int simpleAll, + boolean diff) throws Exception { + Jedis jedis10_1 = Redis.use("group1_db10").getJedis(); + try { + GroupMemberBean uid_bean = GroupCache.getMember(groupId, uid); + if (uid_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + + if (uid_bean.lev >= 3) { + List par_list = Utility.getMemberParents(jedis10_1, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + jedis10_1.close(); + } + + String gm_key = GroupMemberCache.genKey(groupId, tagId); + String strLev = Redis.use("group1_db10").hget(gm_key, "lev"); + boolean mgr = StringUtil.isNotEmpty(strLev) && Integer.parseInt(strLev) < 3; + + ITArray list = null; + + String limitSql = ""; + String paramSql = ""; + if (simpleAll == 0) { + + limitSql = String.format("limit %s,%s", limit, num); + paramSql = String.format( + "SELECT A.uid,A.hp,A.lev,A.partnerLev, A.autoscore," + "(SELECT COUNT(uid) " + + "FROM group_member B " + "where B.groupId = %s AND B.parentId = A.uid) AS total", + groupId); + } else { + + paramSql = "SELECT A.uid"; + } + + if (mgr) { + + String sql = String.format("%s FROM group_member AS A " + "where A.groupId= %s and A.partnerLev=1 %s", + paramSql, groupId, limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + + } else { + if (diff) { + String sql = String.format("%s FROM group_member AS A " + "where A.groupId= %s and A.parentId=%s %s", + paramSql, groupId, tagId, limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } else { + String sql = String.format( + "%s FROM group_member AS A " + "where A.groupId= %s and A.parentId=%s AND partnerLev >0 %s", + paramSql, groupId, tagId, limitSql); + + list = DataBase.use().executeQueryByTArray(sql); + } + } + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject obj = list.getTObject(i); + int tagUid = obj.getInt("uid"); + AccountBean acc = AccountCache.getAccount(tagUid); + obj.putString("nick", acc.nick); + + if (simpleAll == 0) { + obj.putString("portrait", acc.portrait); + + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + int score = 0; + if (gmb != null) { + score = gmb.score; + } + obj.putInt("score", score); + + } + } + } finally { + jedis10.close(); + } + + ITObject obj1 = TObject.newInstance(); + obj1.putTArray("members", list); + obj1.putInt("limit", limit); + return obj1; + } + + /** + * 获取合伙人管理列表 + * + * @param groupId + * @param uid + * @param + * @param + * @return + * @throws Exception + */ + public static final ITObject queryPartnerInfos(int groupId, int uid, int qid, String tagName) throws Exception { + + String gm_key = GroupMemberCache.genKey(groupId, uid); + String strLev = Redis.use("group1_db10").hget(gm_key, "lev"); + boolean mgr = StringUtil.isNotEmpty(strLev) && Integer.parseInt(strLev) < 3; + String partnerParents; + ITArray list = null; + + if (mgr) { + partnerParents = "and A.partnerLev=1"; + } else { + partnerParents = String.format("and A.parentId=%s", uid); + } + + String paramSql = String.format("SELECT A.uid,A.hp,A.partnerLev," + "(SELECT COUNT(uid) " + + "FROM group_member B " + "where B.groupId = %s AND B.parentId = A.uid) AS total", groupId); + + String qid_sql = StringUtil.Empty; + if (qid > 0) { + + qid_sql = "AND A.uid=" + qid; + + String sql = String.format("%s FROM group_member AS A " + "where A.groupId= %s %s %s", paramSql, groupId, + qid_sql, partnerParents); + + list = DataBase.use().executeQueryByTArray(sql); + } + + if (StringUtil.isNotEmpty(tagName)) { + + String sql = String.format("%s FROM group_member AS A " + + "right join account as B on A.uid = B.id and B.nick like '%%%s%%' " + "where A.groupId= %s %s", + paramSql, tagName, groupId, partnerParents); + + ITArray tempL = DataBase.use().executeQueryByTArray(sql); + if (tempL != null && tempL.size() > 0) { + + if (list != null) { + for (int k = 0; k < tempL.size(); k++) { + + ITObject mo = tempL.getTObject(k); + if (qid > 0 && qid == mo.getInt("uid")) { + continue; + } + list.addTObject(mo); + } + } else { + list = tempL; + } + } + } + + ITObject obj1 = TObject.newInstance(); + + if (list != null) { + + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject obj = list.getTObject(i); + int tagUid = obj.getInt("uid"); + AccountBean acc = AccountCache.getAccount(tagUid); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + } + } finally { + jedis10.close(); + } + obj1.putTArray("members", list); + } + + return obj1; + } + + /** + * 获取合伙人成员列表 + * + * @param groupId + * @param uid + * @param limit + * @param num + * @return + * @throws Exception + */ + public static final ITObject getPartnerMemebers(int groupId, int uid, int limit, int num, int qid) + throws Exception { + ITArray list = null; + boolean self = (qid > 0 && qid == uid); + if (self) { + list = TArray.newInstance(); + ITObject obj = TObject.newInstance(); + obj.putInt("uid", uid); + obj.putInt("partnerLev", 1); + list.addTObject(obj); + } + + if (qid == 0 || !self) { + + String qid_sql = StringUtil.Empty; + if (qid > 0) { + qid_sql = "AND uid=" + qid; + } + String sql = String.format( + "SELECT uid,partnerLev,join_time FROM group_member WHERE groupId=%s AND parentId=%s %s limit %s,%s", + groupId, uid, qid_sql, limit, num); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (list != null) { + for (int i = 0; i < arr.size(); ++i) { + list.addTObject(arr.getTObject(i)); + } + } else { + list = arr; + } + } + + // Jedis jedis9 = Redis.use("group1_db9").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + for (int i = 0; i < list.size(); ++i) { + ITObject obj = list.getTObject(i); + AccountBean acc = AccountCache.getAccount(obj.getInt("uid")); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + + String gmr = String.format("g{%s}:m%s:round_log", groupId, obj.getInt("uid")); + String val = jedis10.get(gmr); + int value = 0; + if (StringUtil.isNotEmpty(val)) { + value = Integer.parseInt(val); + } + obj.putInt("round", value); + + GroupMemberBean gmb = GroupCache.getMember(groupId, acc.id); + if (gmb != null) { + obj.putInt("online", 1); + } else { + obj.putInt("online", 0); + } + + // _fillLog(jedis9, jedis10,obj, groupId, uid, acc.id, false, true); + } + } finally { + jedis10.close(); + // jedis9.close(); + } + ITObject obj1 = TObject.newInstance(); + obj1.putTArray("members", list); + obj1.putInt("limit", limit); + return obj1; + } + + /** + * + * @param permission + * @throws Exception + */ + public static void setMgrPermission(int groupId, int tag, int permission) throws Exception { + log.info("setMgrPermission tag:" + tag + " permission:" + permission); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String gm_key = GroupMemberCache.genKey(groupId, tag); + RedisLock lock = new RedisLock(gm_key, jedis10); + try { + lock.lock(); + List _list = jedis10.hmget(gm_key, "opt", "lev"); + String opt1 = _list.get(0); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int _lev = Integer.parseInt(_list.get(1)); + if (_lev != 2) { + throw new WebException(ErrorCode.GROUP_MGR_EXIST); + } + jedis10.hset(gm_key, "permission", permission + ""); + BaseCache.updateCacheVer(jedis10, gm_key); + } finally { + lock.unlock(); + } + } + + /** + * 获取禁止同桌列表 + * + * @param groupId + * @param uid + * @param tag + * @return + * @throws Exception + */ + public static ITArray getBanDeskList(int groupId, int uid, int tag) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN_DESKMATE) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + lock1.unlock(false); + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + String ban_key = "ban{" + groupId + "}:" + tag; + try { + Set sets = jedis11.smembers(ban_key); + ITArray arr = TArray.newInstance(); + for (String id : sets) { + ITObject obj = TObject.newInstance(); + int _id = Integer.parseInt(id); + AccountBean acc = AccountCache.getAccount(_id); + if (acc == null) { + jedis11.srem(ban_key, id); + continue; + } + String key = GroupMemberCache.genKey(groupId, acc.id); + String opt = jedis10.hget(key, "opt"); + if (StringUtil.isEmpty(opt) || Integer.parseInt(opt) != 1) { + jedis11.srem(ban_key, id); + continue; + } + obj.putInt("uid", _id); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + arr.addTObject(obj); + } + return arr; + } finally { + jedis11.close(); + jedis10.close(); + } + } + + /** + * 设置禁止同桌 + * + * @param groupId + * @param uid + * @param tag + * @param ban_list + */ + public static void setBanDesk(int groupId, int uid, int tag, ITArray ban_list, ITArray del_list) throws Exception { + log.info("setBanDesk uid:" + uid + " tag:" + tag + " ban_list:" + ban_list + " del_list:" + del_list); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN_DESKMATE) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + lock1.unlock(false); + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + String ban_key = "ban{" + groupId + "}:" + tag; + RedisLock lock = new RedisLock("ban_desk" + groupId, jedis11); + try { + lock.lock(); + String tag_str = tag + ""; + Pipeline pipeline = jedis11.pipelined(); + pipeline.del(ban_key); + if (del_list.size() > 0) { + for (int i = 0; i < del_list.size(); ++i) { + int _id = del_list.getInt(i); + if (_id == 0) + continue; + if (_id == tag) + continue; + String key = "ban{" + groupId + "}:" + _id; + pipeline.srem(key, tag_str); + } + } + if (ban_list.size() == 1 && ban_list.getInt(0) == 0) { + return; + } + int size = Math.min(ban_list.size(), 20); + for (int i = 0; i < size; ++i) { + int _id = ban_list.getInt(i); + if (_id == 0) + continue; + if (_id == tag) + continue; + String key = GroupMemberCache.genKey(groupId, _id); + String opt = jedis10.hget(key, "opt"); + if (StringUtil.isEmpty(opt) || Integer.parseInt(opt) != 1) { + continue; + } + String _bkey = "ban{" + groupId + "}:" + _id; + pipeline.sadd(ban_key, _id + ""); + pipeline.sadd(_bkey, tag_str); + } + pipeline.sync(); + } finally { + lock.unlock(); + jedis10.close(); + } + + } + + /** + * 设置禁止同桌2 亲友圈列表中的所有成员互相不能同桌 + * + * @param groupId + * @param tableId 禁止的列表序号 + * @param table_list 禁止的玩家列表 + */ + public static void setBanDeskList(int groupId, int uid, int tableId, String tableName, ITArray table_list) + throws Exception { + log.info("setBanDesk uid:" + uid + " tableId:" + tableId + " table_list:" + table_list); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN_DESKMATE) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + lock1.unlock(false); + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + String group_key = "g{" + groupId + "}:desks"; + String desksName_key = String.format("%s:name", group_key); + RedisLock lock = new RedisLock("ban_desk" + groupId, jedis11); + boolean newDesk = false; + try { + lock.lock(); + if (tableId == -1) { + newDesk = true; + Set desks_list = jedis11.keys("g{" + groupId + "}:desks:*"); + for (int i = 1; i <= desks_list.size() + 1; i++) { + if (!desks_list.contains(String.format("g{%d}:desks:%d", groupId, i))) { + tableId = i; + } + } + } + group_key = group_key + ":" + tableId; + Pipeline pipeline = jedis11.pipelined(); + pipeline.del(group_key); + log.info("lingmeng setBanDeskList", table_list.size(), table_list.toString()); + for (int i = 0; i < table_list.size(); ++i) { + int _id = table_list.getInt(i); + if (_id == 0) + continue; + String key = GroupMemberCache.genKey(groupId, _id); + String opt = jedis10.hget(key, "opt"); + if (StringUtil.isEmpty(opt) || Integer.parseInt(opt) != 1) { + continue; + } + pipeline.sadd(group_key, _id + ""); + } + if (newDesk) { + pipeline.sadd(group_key, "0"); + } + pipeline.hset(desksName_key, tableId + "", tableName); + pipeline.sync(); + } finally { + lock.unlock(); + jedis10.close(); + } + + } + + /** + * 设置禁止同桌2 亲友圈列表中的所有成员互相不能同桌 + * + * @param groupId + * @param uid + * @return + * @throws Exception + */ + public static ITArray getBanDeskList2(int groupId, int uid) throws Exception { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN_DESKMATE) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } finally { + lock1.unlock(false); + } + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + + try { + Set desks_list = jedis11.keys("g{" + groupId + "}:desks:*"); + ITArray arr = TArray.newInstance(); + for (String deskId : desks_list) { + String desk_key = deskId; + if (desk_key.equals(String.format("g{%d}:desks:name", groupId))) { + continue; + } + ITObject deskObj = TObject.newInstance(); + ITArray deskArray = TArray.newInstance(); + Set sets = jedis11.smembers(desk_key); + for (String id : sets) { + ITObject obj = TObject.newInstance(); + int _id = Integer.parseInt(id); + AccountBean acc = AccountCache.getAccount(_id); + if (acc == null) { + if (_id != 0) { + jedis11.srem(desk_key, id); + } + continue; + } + String key = GroupMemberCache.genKey(groupId, acc.id); + String opt = jedis10.hget(key, "opt"); + if (StringUtil.isEmpty(opt) || Integer.parseInt(opt) != 1) { +// jedis11.srem(desk_key, id); + continue; + } + obj.putInt("uid", _id); + obj.putString("nick", acc.nick); + obj.putString("portrait", acc.portrait); + deskArray.addTObject(obj); + } + String deskId2 = deskId.substring(deskId.lastIndexOf(":") + 1); + deskObj.putInt("deskId", Integer.parseInt(deskId2)); + deskObj.putString("deskName", jedis11.hget(String.format("g{%d}:desks:name", groupId), deskId2)); + deskObj.putTArray("deskList", deskArray); + arr.addTObject(deskObj); + } + return arr; + } finally { + jedis11.close(); + jedis10.close(); + } + } + + public static final ITObject movePartner(int groupId, int uid, int tag) throws Exception { + log.info("movePartner uid:" + uid + " tag:" + tag); + if (uid == tag) { + throw new WebException(ErrorCode._FAILED); + } + + String group_key = GroupCache.genKey(groupId); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + RedisLock lock = new RedisLock(group_key, jedis11); + RedisLock lock1 = null; + RedisLock lock2 = null; + try { + lock.lock(); + jedis11.hset(group_key, "stop", "1"); + BaseCache.updateCacheVer(jedis11, group_key); + String tag_key = GroupMemberCache.genKey(groupId, tag); + String mng_key = GroupMemberCache.genKey(groupId, uid); + lock1 = new RedisLock(mng_key, jedis10); + lock2 = new RedisLock(tag_key, jedis10); + lock1.lock(); + lock2.lock(); + GroupMemberBean tag_bean = GroupCache.getMember(groupId, tag); + if (tag_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + GroupMemberBean mng_bean = GroupCache.getMember(groupId, uid); + if (mng_bean == null) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + int mgn_lev = mng_bean.lev; + int mgn_partner = mng_bean.partnerLev; + if (!(mgn_lev == 1 || mgn_partner > 0)) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + + int member_partner = tag_bean.partnerLev; + if (member_partner == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PARTNER); + } + int member_parentId = tag_bean.parentId; + if (member_parentId == uid) { + throw new WebException(ErrorCode._FAILED); + } + List child_list = Utility.getChildParentList(groupId, tag, true); + + if (mgn_lev == 3) { + if (child_list.contains(uid)) { + throw new WebException(ErrorCode._FAILED); + } + } + + List tag_par_list = Utility.getMemberParents(jedis10, groupId, tag, false); + // String _tag_hp = jedis10.get(String.format("g{%s}:par_hp:%s", groupId,tag)); + List mng_par_list = null; + if (mgn_lev == 3) { + mng_par_list = Utility.getMemberParents(jedis10, groupId, uid, true); + } + Pipeline pipeline = jedis10.pipelined(); + String gp_key = GroupCache.genPidsKey(groupId); + Set pids = Redis.use("group1_db11").zrangeByScore(gp_key, 10, 11); + for (String pid : pids) { + String p_reward_key = GroupCache.genRewardKey(groupId, Integer.parseInt(pid)); + for (Integer child : child_list) { + pipeline.zrem(p_reward_key, child.toString()); + } + String p_xipai_reward_key = GroupCache.genXiPaiRewardKey(groupId, Integer.parseInt(pid)); + for (Integer child : child_list) { + pipeline.zrem(p_xipai_reward_key, child.toString()); + } + } + if (tag_par_list != null) { + for (Integer par : tag_par_list) { + String list_key = GroupCache.genParListKey(groupId, par); + for (Integer child : child_list) { + pipeline.srem(list_key, child.toString()); + } + } + } + pipeline.hset(tag_key, "parentId", uid + ""); + pipeline.hincrBy(tag_key, "cache_ver", 1); + int diff = (mgn_partner + 1) - member_partner; + if (diff != 0) { + for (Integer child : child_list) { + String key = GroupMemberCache.genKey(groupId, child); + pipeline.hincrBy(key, "partnerLev", diff); + pipeline.hincrBy(key, "cache_ver", 1); + } + } + if (mgn_lev == 3) { + for (Integer par : mng_par_list) { + String list_key = GroupCache.genParListKey(groupId, par); + // String hp_key = String.format("g{%s}:par_hp:%s", groupId,par); + // pipeline.incrBy(hp_key, tag_hp); + for (Integer child : child_list) { + pipeline.sadd(list_key, child.toString()); + } + } + } + pipeline.sync(); + String sql = String.format("update group_member set parentId=%s where uid=%s and groupId=%s", uid, tag, + groupId); + Utility.evtdb(groupId, 1, sql); + if (diff != 0) { + String p = StringUtil.Empty; + int len = child_list.size(); + for (int i = 0; i < len; i++) { + Integer child = child_list.get(i); + p += child + ((i < len - 1) ? "," : StringUtil.Empty); + } + sql = String.format("update group_member set partnerLev=partnerLev+%s where uid in(%s) and groupId=%s", + diff, p, groupId); + Utility.evtdb(groupId, 1, sql); + } + ITObject resData = TObject.newInstance(); + resData.putInt("parentId", uid); + resData.putInt("partnerLev", member_partner + diff); + return resData; + + } finally { + jedis11.hset(group_key, "stop", "0"); + BaseCache.updateCacheVer(jedis11, group_key); + lock.unlock(); + lock1.unlock(false); + lock2.unlock(); + } + } + + /** + * 获取邮件列表 + * + * @param groupId + * @param uid + * @param limit + * @param num + * @return + */ + public static ITArray getMailList(int groupId, int uid, int limit, int num) { + String mail_key = GroupCache.genMailKey(groupId, uid); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + int time = (int) (System.currentTimeMillis() / 1000); + int s_time = time - 10 * 24 * 3600; + jedis10.zremrangeByScore(mail_key, 0, s_time); + Set sets = jedis10.zrevrangeByScore(mail_key, time, s_time, limit, num); + ITArray arr = TArray.newInstance(); + for (String str : sets) { + arr.addString(str); + } + String mail_tip_key = GroupCache.genMailTipKey(groupId); + jedis10.zadd(mail_tip_key, 0, uid + ""); + return arr; + } finally { + jedis10.close(); + } + } + + /** + * 删除所有邮件 + * + * @param groupId + * @param uid + */ + public static void delMailAll(int groupId, int uid) { + String mail_key = GroupCache.genMailKey(groupId, uid); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + jedis10.del(mail_key); + String mail_tip_key = GroupCache.genMailTipKey(groupId); + jedis10.zadd(mail_tip_key, 0, uid + ""); + } finally { + jedis10.close(); + } + + } + + /** + * 设置合伙人阀值groupId, acc.id, tagId, score + */ + public static final int setPartenerAutoScore(int groupId, int uid, int tagId, int score) { + log.info("setPartenerAutoScore uid:" + uid + " tagId:" + tagId + " score:" + score); + String gm_key = GroupMemberCache.genKey(groupId, tagId); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + String opt1 = jedis10.hget(gm_key, "opt"); + if (StringUtil.isEmpty(opt1) || Integer.parseInt(opt1) != 1) { + throw new WebException(ErrorCode.GROUP_NOT_MEMBER); + } + String mng_key = GroupMemberCache.genKey(groupId, uid); + RedisLock lock1 = new RedisLock(mng_key, jedis10); + try { + lock1.lock(); + int mgn_lev = Integer.parseInt(jedis10.hget(mng_key, "lev")); + if (mgn_lev == 2) { + String permission = jedis10.hget(mng_key, "permission"); + if (StringUtil.isEmpty(permission) || (Integer.parseInt(permission) & PERMISSION_BAN) == 0) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } else if (mgn_lev >= 3) { + if (uid != tagId) { + List par_list = Utility.getMemberParents(jedis10, groupId, tagId, true); + if (par_list == null || !par_list.contains(uid)) { + throw new WebException(ErrorCode.GROUP_NOT_PERMISSION); + } + } + } + } finally { + lock1.unlock(false); + } + score = score * 1000; // deyou 1000 + // score = score * 100; // wanshun 100 + String sql = String.format("update group_member set autoscore = %s where uid = %s " + "AND groupId = %s ", + score, tagId, groupId); + try { + Utility.evtdb(groupId, 1, sql); + jedis10.hset(gm_key, "autoscore", score + ""); + BaseCache.updateCacheVer(jedis10, gm_key); + } finally { + + } + + } catch (Exception ex) { + + } finally { + jedis10.close(); + } + return 1; + } + + public static void updateJoinScore(int groupId, int accId, int mj_score, int pk_score, int playerId) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); +// Jedis jedis11 = Redis.use("group1_db11").getJedis(); +// String key = "group:" + groupId; + try { + if (playerId == 0) { + jedis10.hset("g{" + groupId + "}" + ":score", "mj_score", mj_score + ""); + jedis10.hset("g{" + groupId + "}" + ":score", "pk_score", pk_score + ""); +// jedis11.hset(key, "mj_score", mj_score + ""); +// jedis11.hset(key, "pk_score", pk_score + ""); +// if (day == 1){ +// jedis11.expire(key+":"+"mj_score", 86400); +// jedis11.expire(key+":"+"pk_score", 86400); +// }else if (day == 2){ +// jedis11.expire(key+":"+"mj_score", 3600 * 48); +// jedis11.expire(key+":"+"pk_score", 3600 * 48); +// } + } else { + String gm_key = GroupMemberCache.genKey(groupId, playerId); +// Jedis jedis10 = Redis.use("group1_db10").getJedis(); + jedis10.hset(gm_key, "mj_score", mj_score + ""); + jedis10.hset(gm_key, "pk_score", pk_score + ""); +// jedis11.hset(key, "mj_score", mj_score + ""); +// jedis11.hset(key, "pk_score", pk_score + ""); +// if (day == 1){ +// jedis11.expire(key+":"+"mj_score", 86400); +// jedis11.expire(key+":"+"pk_score", 86400); +// }else if (day == 2){ +// jedis11.expire(key+":"+"mj_score", 3600 * 48); +// jedis11.expire(key+":"+"pk_score", 3600 * 48); +// } + } + } catch (Exception e) { + log.error(e); + } finally { + jedis10.close(); +// jedis11.close(); + } + + } + + public static void addGroupDiamo(int groupId, int accId, int diamo, int playerId) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + int playerDiamo = Integer.parseInt(jedis0.hget("{user}:" + playerId, "diamo")); +// if (playerDiamo < diamo) { +// log.info("充值房卡数量不足"); +// return; +// } + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + int groupDiamo = Integer.parseInt(jedis10.hget("g{" + groupId + "}:diamo", "diamo") == null ? "0" + : jedis10.hget("g{" + groupId + "}:diamo", "diamo")); + jedis10.hset("g{" + groupId + "}:diamo", "diamo", (groupDiamo + diamo) + ""); + jedis0.hset("{user}:" + playerId, "diamo", (playerDiamo - diamo) + ""); + + } + + public static void setGroupHeartbeat(int playerId, int id) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hset("{user}:" + playerId + "_online", "online", "1"); + jedis0.hset("{user}:" + playerId + "_online", "time", System.currentTimeMillis() + ""); + Redis.use("group1_db0").expire("{user}:" + playerId + "_online", 40); + + GroupPublisherService.updateOnlineUsers(id, playerId); +// Redis.use("group1_db0").expire("{user}:" + playerId + "_online", 30); +// if (jedis0.hget("{user}:" + playerId + "_online", "online") != null){ +// String online = jedis0.hget("{user}:" + playerId + "_online", "online"); +// log.info("在线状态数据----------------------:"+online); +// if (Integer.parseInt(online)!=2){ +// jedis0.hset("{user}:" + playerId + "_online", "online", "1"); +// jedis0.expire("{user}:" + playerId + "_online", 50); +// } +// } +// else { +// jedis0.hset("{user}:" + playerId + "_online", "online", "1"); +// jedis0.expire("{user}:" + playerId + "_online", 50); +// } + } catch (Exception e) { + log.error("setGroupHeartbeat error", e); + } finally { + jedis0.close(); + } + + } + + public static ITArray getGroupDetail(int groupId, int uid) { + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + String groupDiamoKey = "g{" + groupId + "}:diamo"; + String groupKey = "group:" + groupId; + ITArray arr = TArray.newInstance(); + + TObject group = TObject.newInstance(); + + try { + String group_diamo = jedis10.hget(groupDiamoKey, "diamo"); + String name = jedis11.hget(groupKey, "name"); + String member_num = jedis11.hget(groupKey, "gms"); + String notice = jedis11.hget(groupKey, "notice"); + String wechatId = jedis11.hget(groupKey, "wechatId"); + + group.putString("diamo", group_diamo); + group.putString("name", name); + group.putString("member_num", member_num); + group.putString("notice", notice); + group.putString("wechatId", wechatId); + + arr.addTObject(group); + } catch (Exception e) { + log.error("getGroupDetail error", e); + } finally { + jedis10.close(); + jedis11.close(); + } + return arr; + } + + public static void updateDayScore(int groupId, int dayType) { + Jedis jedis10 = Redis.use("group1_db10").getJedis(); + try { + jedis10.hset("g{" + groupId + "}:daysave", "daysave", dayType + ""); + } finally { + jedis10.close(); + } + } + + public static ITArray getDiamoMessage(int groupId) { + String sql = String.format( + "SELECT * FROM `diamo_message` where group_id =%s ORDER BY `diamo_message`.`m_time` DESC", groupId); + try { + ITArray arr = DataBase.use().executeQueryByTArray(sql); + return arr; + } catch (SQLException e) { + log.error(e); + } + return null; + } + +} diff --git a/web_group/src/main/webapp/WEB-INF/web.xml b/web_group/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..a71270c --- /dev/null +++ b/web_group/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ + + + + + taurus-web + com.taurus.web.WebFilter + + main + com.group.MainServer + + + + + taurus-web + /* + + diff --git a/web_group/src/main/webapp/config/bank_hp.lua b/web_group/src/main/webapp/config/bank_hp.lua new file mode 100644 index 0000000..d3a02ce --- /dev/null +++ b/web_group/src/main/webapp/config/bank_hp.lua @@ -0,0 +1,19 @@ +local tag_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local bank_hp = tonumber(redis.call('hget', KEYS[2],KEYS[3])) +bank_hp = not bank_hp and 0 or bank_hp +local hp = tonumber(ARGV[1]) +local opt = tonumber(ARGV[2]) +if opt==0 then + if bank_hp < hp then + return 3 + end + bank_hp = redis.call('hincrBy',KEYS[2],KEYS[3],-hp) + tag_hp = redis.call('hincrBy',KEYS[1],'hp',hp) +else + if tag_hp < hp then + return 4 + end + bank_hp = redis.call('hincrBy',KEYS[2],KEYS[3],hp) + tag_hp = redis.call('hincrBy',KEYS[1],'hp',-hp) +end +return {tag_hp,bank_hp} \ No newline at end of file diff --git a/web_group/src/main/webapp/config/log4j.properties b/web_group/src/main/webapp/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_group/src/main/webapp/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_group/src/main/webapp/config/mgr.lua b/web_group/src/main/webapp/config/mgr.lua new file mode 100644 index 0000000..e3e9aae --- /dev/null +++ b/web_group/src/main/webapp/config/mgr.lua @@ -0,0 +1,25 @@ +-- redis.call('select',0) +local mgr_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local tag_hp = tonumber(redis.call('hget', KEYS[2],'hp')) + +local ulev = tonumber(ARGV[2]) +local hp = tonumber(ARGV[1]) +if ulev == 3 or ulev == 2 then + if KEYS[1] ~= KEYS[2] and hp > 0 and mgr_hp < hp then + return 3 + else + if hp < 0 and tag_hp < math.abs(hp) then + return 4 + end + mgr_hp = redis.call('hincrBy',KEYS[1],'hp',-hp) + tag_hp = redis.call('hincrBy',KEYS[2],'hp',hp) + end +else + tag_hp = tag_hp + hp + if tag_hp < 0 then + return 4 + else + redis.call('hincrBy',KEYS[2],'hp',hp) + end +end +return {mgr_hp,tag_hp} \ No newline at end of file diff --git a/web_group/src/main/webapp/config/take_hp.lua b/web_group/src/main/webapp/config/take_hp.lua new file mode 100644 index 0000000..83d79a0 --- /dev/null +++ b/web_group/src/main/webapp/config/take_hp.lua @@ -0,0 +1,10 @@ +local reward_hp = tonumber(redis.call('get', KEYS[1])) +local hp = tonumber(ARGV[1]) +local tag_hp = 0 +if hp > 0 and reward_hp < hp then + return 3 +else + reward_hp = redis.call('incrBy',KEYS[1],-hp) + tag_hp = redis.call('hincrBy',KEYS[2],'hp',hp) +end +return {reward_hp,tag_hp} \ No newline at end of file diff --git a/web_group/src/main/webapp/config/taurus-core.xml b/web_group/src/main/webapp/config/taurus-core.xml new file mode 100644 index 0000000..9a20dd6 --- /dev/null +++ b/web_group/src/main/webapp/config/taurus-core.xml @@ -0,0 +1,100 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 2000 + + 1 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + root + tnxEWWRL7mhGT63T + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 2000 + + 8 + + 2 + + 50 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + + + + + diff --git a/web_group/src/main/webapp/config/trade.lua b/web_group/src/main/webapp/config/trade.lua new file mode 100644 index 0000000..c03a438 --- /dev/null +++ b/web_group/src/main/webapp/config/trade.lua @@ -0,0 +1,12 @@ +local mgr_hp = tonumber(redis.call('hget', KEYS[1],'hp')) +local tag_hp = tonumber(redis.call('hget', KEYS[2],'hp')) +mgr_hp = not mgr_hp and 0 or mgr_hp +tag_hp = not tag_hp and 0 or tag_hp +local hp = tonumber(ARGV[1]) +if hp > 0 and mgr_hp + + + + org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern + .*/.*jsp-api-[^/]\.jar$|./.*jsp-[^/]\.jar$|./.*taglibs[^/]*\.jar$ + + + \ No newline at end of file diff --git a/web_group/src/test/java/web_group/DataClearUtils.java b/web_group/src/test/java/web_group/DataClearUtils.java new file mode 100644 index 0000000..f0be96e --- /dev/null +++ b/web_group/src/test/java/web_group/DataClearUtils.java @@ -0,0 +1,146 @@ +package web_group; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import redis.clients.jedis.Jedis; + +/** + * clear redis data + * @author yjl 2020-06-05 + * @version 1.0.0 + * */ +public class DataClearUtils { + + private void clear_data() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Map map = new HashMap<>(); + map.put("force_ver", "1"); + map.put("ver", "1"); + Jedis jedis = new Jedis("127.0.0.1", 6380); + jedis.auth("123456"); + //选择库 + jedis.select(5); + Set keys = jedis.keys("*"); + int i = 0; + for(String str : keys) { + long stime = Long.valueOf(str.substring(15,str.length())); + if(stime < 1591286400) { + jedis.del(str); + i++; + System.out.println(i); + } + + } + System.out.println(i); + + jedis.close(); + } + + private void clear_data_thread() { +// Thread th = new Thread(new clear_data_t(1592323200, 1592668800,1)); +// th.start(); +// +// Thread th1 = new Thread(new clear_data_t(1591977600, 1592323200,2)); +// th1.start(); +// +// Thread th2 = new Thread(new clear_data_t(1591718400, 1591977600,3)); +// th2.start(); +// + Thread th3 = new Thread(new clear_data_test(1590940800, 1593964800,4)); + th3.start(); + +// Thread th4 = new Thread(new clear_data_t(1588262400, 1590336000,5)); +// th4.start(); +//// +// Thread th5 = new Thread(new clear_data_t(1588262400, 1589904000,6)); +// th5.start(); + } + class clear_data_test implements Runnable{ + long start = 0; + long end = 0; + int num = 0; + + public clear_data_test(long start,long end,int num) { + this.start = start; + this.end = end; + this.num = num; + } + @Override + public void run() { + // TODO Auto-generated method stub + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Map map = new HashMap<>(); + map.put("force_ver", "1"); + map.put("ver", "1"); + Jedis jedis = new Jedis("127.0.0.1", 6379); + jedis.auth("123456"); + //选择库 + jedis.select(0); + Set keys = jedis.keys("*"); + int i = 0; + for(String str : keys) { + long stime = Long.valueOf(str.substring(15,str.length())); + if(stime < end && stime > start) { + jedis.del(str); + i++; + System.out.println("#"+num +"Thread"+i); + } + + } + System.out.println(i); + + jedis.close(); + } + + } + + // + + public static void main(String[] args) { + DataClearUtils initDataUtils = new DataClearUtils(); + initDataUtils.clear_data_thread(); + } + + class clear_data_t implements Runnable{ + long start = 0; + long end = 0; + int num = 0; + + public clear_data_t(long start,long end,int num) { + this.start = start; + this.end = end; + this.num = num; + } + @Override + public void run() { + // TODO Auto-generated method stub + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Map map = new HashMap<>(); + map.put("force_ver", "1"); + map.put("ver", "1"); + Jedis jedis = new Jedis("127.0.0.1", 6380); + jedis.auth("123456"); + //选择库 + jedis.select(5); + Set keys = jedis.keys("*"); + int i = 0; + for(String str : keys) { + long stime = Long.valueOf(str.substring(15,str.length())); + if(stime < end && stime > start) { + jedis.del(str); + i++; + System.out.println("#"+num +"Thread"+i); + } + + } + System.out.println(i); + + jedis.close(); + } + + } +} diff --git a/web_group/src/test/java/web_group/MainWebGroup.java b/web_group/src/test/java/web_group/MainWebGroup.java new file mode 100644 index 0000000..c980a27 --- /dev/null +++ b/web_group/src/test/java/web_group/MainWebGroup.java @@ -0,0 +1,9 @@ +package web_group; + +import com.taurus.web.JettyServer; + +public class MainWebGroup { + public static void main(String[] args) { + new JettyServer("src/main/webapp",4012,"/").start(); + } +} diff --git a/web_login/.idea/artifacts/web_login_war.xml b/web_login/.idea/artifacts/web_login_war.xml new file mode 100644 index 0000000..3504ab7 --- /dev/null +++ b/web_login/.idea/artifacts/web_login_war.xml @@ -0,0 +1,14 @@ + + + $PROJECT_DIR$/target + + + web_login + war + + + + + + + \ No newline at end of file diff --git a/web_login/.idea/artifacts/web_login_war_exploded.xml b/web_login/.idea/artifacts/web_login_war_exploded.xml new file mode 100644 index 0000000..947083c --- /dev/null +++ b/web_login/.idea/artifacts/web_login_war_exploded.xml @@ -0,0 +1,23 @@ + + + $PROJECT_DIR$/target/ROOT + + + true + web_login + war + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/.idea/compiler.xml b/web_login/.idea/compiler.xml new file mode 100644 index 0000000..d0df4bb --- /dev/null +++ b/web_login/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/.idea/misc.xml b/web_login/.idea/misc.xml new file mode 100644 index 0000000..0adbe1d --- /dev/null +++ b/web_login/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web_login/.idea/modules.xml b/web_login/.idea/modules.xml new file mode 100644 index 0000000..4270919 --- /dev/null +++ b/web_login/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/web_login/.idea/workspace.xml b/web_login/.idea/workspace.xml new file mode 100644 index 0000000..01d7704 --- /dev/null +++ b/web_login/.idea/workspace.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + 1623486082788 + + + + + + \ No newline at end of file diff --git a/web_login/build/adduser b/web_login/build/adduser new file mode 100644 index 0000000..e69de29 diff --git a/web_login/build/local/log4j.properties b/web_login/build/local/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_login/build/local/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_login/build/local/taurus-core.xml b/web_login/build/local/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/web_login/build/local/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/build/pro/log4j.properties b/web_login/build/pro/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_login/build/pro/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_login/build/pro/taurus-core.xml b/web_login/build/pro/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/web_login/build/pro/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/build/test/log4j.properties b/web_login/build/test/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_login/build/test/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_login/build/test/taurus-core.xml b/web_login/build/test/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/web_login/build/test/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/config/log4j.properties b/web_login/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_login/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_login/config/taurus-core.xml b/web_login/config/taurus-core.xml new file mode 100644 index 0000000..273ed5c --- /dev/null +++ b/web_login/config/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://110.40.188.229:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/god b/web_login/god new file mode 100644 index 0000000..e69de29 diff --git a/web_login/pom.xml b/web_login/pom.xml new file mode 100644 index 0000000..47f124f --- /dev/null +++ b/web_login/pom.xml @@ -0,0 +1,130 @@ + + 4.0.0 + com.mjlogin + web_login + war + 1.0.0 + + UTF-8 + 1.8 + 1.8 + pro + + + + + junit + junit + 3.8.1 + test + + + + + com.data + data_cache + 1.0.1 + + + + + com.taurus + taurus-core + 1.0.1 + + + + + com.taurus + taurus-web + 1.0.1 + + + + + redis.clients + jedis + 2.9.0 + + + + + com.zaxxer + HikariCP + 3.3.1 + + + + + mysql + mysql-connector-java + 8.0.16 + + + + + jdom + jdom + 1.0 + + + + + log4j + log4j + 1.2.17 + + + + + com.google.code.gson + gson + 2.8.5 + + + + com.aliyun + aliyun-java-sdk-core + 4.0.3 + + + + org.eclipse.jetty + jetty-webapp + 8.2.0.v20160908 + provided + + + org.quartz-scheduler + quartz + 2.2.3 + compile + + + + + ROOT + + + + org.apache.maven.plugins + maven-war-plugin + + 1.8 + 1.8 + UTF-8 + config/**,logs/** + + + config/ + ${project.basedir}/build/${build.type} + + + + + + + + diff --git a/web_login/src/main/java/com/mjlogin/MainServer.java b/web_login/src/main/java/com/mjlogin/MainServer.java new file mode 100644 index 0000000..44cb2bf --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/MainServer.java @@ -0,0 +1,73 @@ +package com.mjlogin; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +import com.mjlogin.service.AccountService; +import com.mjlogin.service.IndexService; +import com.mjlogin.service.MilitaryService; +import com.mjlogin.service.RoomService; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Extension; +import com.taurus.core.routes.Routes; +import com.taurus.core.util.StringUtil; + +public class MainServer extends Extension { + public static int DEFAULT_DAIMO = 5; + public static String GROUP_WEB_URL = ""; + private ScheduledThreadPoolExecutor timeScheduler; + + private static final String WEB_CONFIG_KEY = "web_config"; + private static final String FORCE_VER_KEY = "force_ver"; + public MainServer() { + super(); + String str = Redis.use("group1_db1").get("base_diamo"); + if (StringUtil.isNotEmpty(str)) { + DEFAULT_DAIMO = Integer.parseInt(Redis.use("group1_db1").get("base_diamo")); + } + GROUP_WEB_URL = Redis.use("group1_db1").hget("web_requrl", "groupWeb"); + + timeScheduler = new ScheduledThreadPoolExecutor(1); + timeScheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + System.gc(); + } + }, 0,600, TimeUnit.SECONDS); + + } + + + @Override + public int readVersion() { + int ver = Integer.parseInt(Redis.use("group1_db1").hget(WEB_CONFIG_KEY,FORCE_VER_KEY)); + return ver; + } + + @Override + public void configRoute(Routes me) { + me.setInterceptor(new WebInterceptor()); + me.add("acc", AccountService.class); + me.add("index", IndexService.class); + me.add("military", MilitaryService.class); + me.add("room", RoomService.class); + } + + @Override + public void onStart() { + + + } + + @Override + public void onStop() { + // TODO Auto-generated method stub + if(timeScheduler!=null) { + timeScheduler.shutdownNow(); + } + + } + +} diff --git a/web_login/src/main/java/com/mjlogin/Protocol.java b/web_login/src/main/java/com/mjlogin/Protocol.java new file mode 100644 index 0000000..e1052a9 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/Protocol.java @@ -0,0 +1,78 @@ +package com.mjlogin; + +public class Protocol { + // ======AccountService + public static final String REGIST_LOGIN = "regist_login"; + + public static final String CHECK_UUID = "check_uuid"; + + public static final String CREATE_XING_YUN_HAO = "create_xing_yun_hao"; + + public static final String QUICK_LOGIN = "quick_login"; + + public static final String PHONE_PASSWORD_LOGIN = "phone_pw_login"; + + public static final String PHONE_LOGIN = "phone_login"; + + public static final String ID_PASSWORD_LOGIN = "id_login"; + + /** 绑定电话号码 **/ + public static final String BINDING_PHONE = "binding_phone"; + /** 获取短信验证码 **/ + public static final String GET_VERIFICATION_CODE = "get_verification_code"; + + public static final String UPDATE_PLAYER_INFO = "update_player_info"; + + public static final String UPDATE_USER_INFO = "update_user_info"; + + public static final String GET_USER_INFO = "get_user_info"; + + public static final String GET_CHANGE_USER_INFO = "get_change_user_info"; + + + public static final String CHECK_GOD = "check_god"; + + + // --------------------Index-------------------------- + public static final String GET_NOTICE = "get_notice"; + + public static final String SHARE_GAME = "share_game"; + + public static final String GET_SHARE_LIST = "get_share_list"; + + + + // --------------------military-------------------------- + + public static final String GET_RANK_LIST_BY_GROUP = "get_rankListByGroup"; + + public static final String GET_ROUND_LIST_BY_GROUP = "get_roundListByGroup"; + + public static final String SET_RANK_LIST_RIGHT_BY_GROUP = "set_randListRightByGroup"; + + public static final String GET_MILITARY = "get_military"; + + public static final String GET_MILITARY_BY_ROOMID = "get_militaryByRoomId"; + + public static final String GET_PLAYBACK = "get_playBack"; + + // --------------------room-------------------------- + public static final String CREATE_ROOM = "create_room"; + public static final String JOIN_ROOM = "join_room"; + + /**代充值房卡*/ + public static final String RECHARGE_DIAMO ="recharge_diamo"; + + /**代充值房卡信息列表*/ + public static final String GET_RECHARGE_DIAMO_LIST ="get_recharge_diamo_list"; + + /** + * 客服信息 + */ + public static final String GET_CUSTOMER_SERVICE = "get_customer_service"; + public static final String GET_MESSAGE = "get_messages"; + + /**修改密码*/ + public static final String SET_PASSWORD ="set_password"; + +} diff --git a/web_login/src/main/java/com/mjlogin/WebInterceptor.java b/web_login/src/main/java/com/mjlogin/WebInterceptor.java new file mode 100644 index 0000000..aee0283 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/WebInterceptor.java @@ -0,0 +1,56 @@ +package com.mjlogin; + +import com.data.util.ErrorCode; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.Action; +import com.taurus.core.routes.IController; +import com.taurus.core.routes.Interceptor; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +public class WebInterceptor implements Interceptor{ + /** + * 验证session + */ + public static final int V_SESSION = 1; + @Override + public void intercept(Action action, IController controller, Object... args) throws Exception { + Controller ctr = (Controller)controller; + int validate = action.getActionKeyObj().validate(); + if((validate&V_SESSION)!=0) { + String session = ctr.getSession(); + String token = ctr.getTokens(); + if (!Redis.use("group1_db0").exists(session)) { + throw new WebException(ErrorCode._NO_SESSION); + } + + if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session)) + { + String token_session = Redis.use("group1_db0").hget(token, "user"); + if (StringUtil.isEmpty(token_session)) + { + throw new WebException(ErrorCode._NO_SESSION); + } + else { + if (!token_session.equals(session)) + { + throw new WebException(ErrorCode._NO_SESSION); + } + } + } + else { + throw new WebException(ErrorCode._NO_SESSION); + } + + String opt = Redis.use("group1_db0").hget(session, "opt"); +// background del sign + if (!StringUtil.isEmpty(opt) && Integer.parseInt(opt) == 1) { + throw new WebException(ErrorCode._NO_SESSION); + } + } + + } + + +} diff --git a/web_login/src/main/java/com/mjlogin/service/AccountService.java b/web_login/src/main/java/com/mjlogin/service/AccountService.java new file mode 100644 index 0000000..137dcfa --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/service/AccountService.java @@ -0,0 +1,1625 @@ +package com.mjlogin.service; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.aliyuncs.utils.StringUtils; +import com.data.bean.AccountBean; +import com.data.bean.GameBean; +import com.data.cache.AccountCache; +import com.data.cache.BaseCache; +import com.data.cache.GameCache; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.mjlogin.MainServer; +import com.mjlogin.Protocol; +import com.mjlogin.WebInterceptor; +import com.mjlogin.util.sms.RedisKey; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.Utils; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class AccountService extends Controller { + private static Logger logger = Logger.getLogger(AccountService.class); + + /** + * 获取手机验证码 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_VERIFICATION_CODE) + public final void getVerificationCode() throws Exception { + ITObject reqData = this.getParams(); + String phone = reqData.getUtfString("phone"); + // 检测短信是否有发送过 + if (Redis.use("group1_db4").exists("code" + phone)) { + throw new WebException(ErrorCode._FAILED); + } else { + String testUsername = "liubo2023"; // 在短信宝注册的用户名 + String testPassword = "Jefe2014"; // 在短信宝注册的密码 + String testPhone = phone; + int code = (int) (Math.random() * 900000) + 100000; + + String testContent = "【趣友科技】验证码" + code + ",您正在进行手机号绑定操作,如非本人操作,请忽略本短信!"; // 注意测试时,也请带上公司简称或网站签名,发送正规内容短信。千万不要发送无意义的内容:例如 + // 测一下、您好。否则可能会收不到 + + String httpUrl = "http://api.smsbao.com/sms"; +// https://api.smsbao.com/wsms?u=liubo2023&p=3e65d8b064c34b37a8326fca24636d9f&m={mobile}&c={content} + StringBuffer httpArg = new StringBuffer(); + httpArg.append("u=").append(testUsername).append("&"); + httpArg.append("p=").append(md5(testPassword)).append("&"); + httpArg.append("m=").append(testPhone).append("&"); + httpArg.append("c=").append(encodeUrlString(testContent, "UTF-8")); + + String result = request(httpUrl, httpArg.toString()); + Redis.use("group1_db4").set("code" + phone, code + ""); + Redis.use("group1_db4").expire("code" + phone, 600); + + this.sendResponse(ErrorCode._SUCC, reqData); + + } + + } + + public static String request(String httpUrl, String httpArg) { + BufferedReader reader = null; + String result = null; + StringBuffer sbf = new StringBuffer(); + httpUrl = httpUrl + "?" + httpArg; + + try { + URL url = new URL(httpUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + InputStream is = connection.getInputStream(); + reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String strRead = reader.readLine(); + if (strRead != null) { + sbf.append(strRead); + while ((strRead = reader.readLine()) != null) { + sbf.append("\n"); + sbf.append(strRead); + } + } + reader.close(); + result = sbf.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + public static String md5(String plainText) { + StringBuffer buf = null; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(plainText.getBytes()); + byte b[] = md.digest(); + int i; + buf = new StringBuffer(""); + for (int offset = 0; offset < b.length; offset++) { + i = b[offset]; + if (i < 0) + i += 256; + if (i < 16) + buf.append("0"); + buf.append(Integer.toHexString(i)); + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return buf.toString(); + } + + public static String encodeUrlString(String str, String charset) { + String strret = null; + if (str == null) + return str; + try { + strret = java.net.URLEncoder.encode(str, charset); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + return strret; + } + + /** + * + * @return + * @throws Exception + */ + private final int register(ITObject reqData) throws Exception { + int count = 0; + long id = 0; + do { + id = Long.parseLong(Redis.use("group1_db1").rpop("free_account")); + String sql = "SELECT id FROM account WHERE id =" + id; + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + if (resultArray.size() == 0) { + break; + } + } while (count++ <= 10); + + if (id == 0) { + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = TObject.newInstance(); + userData.putInt("id", (int) id); + if (reqData.containsKey("phone")) { + /// + userData.putUtfString("phone", reqData.getUtfString("phone")); + userData.putUtfString("nick", "景都" + id + ""); + userData.putInt("sex", 1); + userData.putUtfString("portrait", StringUtil.Empty); + } else { + userData.putUtfString("acc", reqData.getUtfString("acc")); + userData.putUtfString("portrait", reqData.getUtfString("portrait")); + String nick = reqData.getUtfString("nick"); + nick = nick.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", " "); + userData.putUtfString("nick", nick); + int sex = reqData.getInt("sex"); + if (sex == 0) { + sex = 1; + reqData.putInt("sex", sex); + } +// userData.putInt("sex", sex); + // 微信注册默认为女生 + userData.putInt("sex", 2); + + } + logger.info("初始房卡:" + Integer.parseInt(Redis.use("group1_db1").get("base_diamo"))); + userData.putInt("diamo", Integer.parseInt(Redis.use("group1_db1").get("base_diamo"))); + userData.putInt("mng", 0); + userData.putInt("type", 0); + + long reg_time = System.currentTimeMillis() / 1000; + userData.putLong("reg_time", reg_time); + userData.putLong("sys_type", reqData.getInt("sys_type")); + + int result = DataBase.use().insert("account", userData); + if (result == -1) { + throw new WebException(ErrorCode._FAILED); + } + userData.putInt("invitation", 1); + String session = updateSession(userData, (int) id); + this.setSession(session); + return (int) id; + } + + private final int create_register(int mng, String password, ArrayList nickList, ArrayList headList) + throws Exception { + int count = 0; + long id = 0; + ArrayList list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + String strId = Redis.use("group1_db1").rpop("free_account"); + if (StringUtils.isEmpty(strId)) { + break; + } + list.add(strId); + } + // logger.info("free_account:"+list.toString()); + + Collections.shuffle(list); + + do { + id = Long.parseLong(list.remove(0)); + String sql = "SELECT id FROM account WHERE id =" + id; + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + if (resultArray.size() == 0) { + break; + } + } while (count++ <= 10); + + for (int i = 0; i < list.size(); i++) { + Redis.use("group1_db1").lpush("free_account", list.get(i)); + } + + if (id == 0) { + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = TObject.newInstance(); + userData.putInt("id", (int) id); + + userData.putUtfString("acc", "" + id); + if (headList.size() > 0) { + userData.putUtfString("portrait", headList.remove(0)); // 头像 + } else { + userData.putUtfString("portrait", ""); + } + + String nick = ""; + if (nickList.size() > 0) { + nick = nickList.remove(0); + } + nick = nick.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", " "); + userData.putUtfString("nick", nick); + int sex = 1; + if (sex == 0) { + sex = 1; + } +// userData.putInt("sex", sex); + userData.putInt("sex", 2); + + userData.putInt("diamo", 0); + userData.putInt("mng", 0); + userData.putInt("regTime", mng); + userData.putInt("type", 0); + userData.putUtfString("password", Utils.getMD5Hash(password)); + long reg_time = System.currentTimeMillis() / 1000; + userData.putLong("reg_time", reg_time); + logger.info("create xingyunhao account:" + userData.toJson() + " password:" + password); + int result = DataBase.use().insert("account", userData); + if (result == -1) { + throw new WebException(ErrorCode._FAILED); + } + userData.putInt("invitation", 1); + String session = updateSession(userData, (int) id); + this.setSession(session); + return (int) id; + } + + /** + * + * @return + * @throws Exception + */ + private final int UpdateUserData(ITObject reqData, long id) throws Exception { + ITObject userData = TObject.newInstance(); + userData.putInt("id", (int) id); + + userData.putUtfString("acc", reqData.getUtfString("acc")); + userData.putUtfString("phone", reqData.getString("phone")); + userData.putUtfString("portrait", reqData.getUtfString("portrait")); +// String decodedName = URLDecoder.decode(reqData.getUtfString("nick"), StandardCharsets.UTF_8.name()); + userData.putUtfString("nick", reqData.getUtfString("nick")); + int sex = reqData.getInt("sex"); + if (sex == 0) { + sex = 1; + reqData.putInt("sex", sex); + } + userData.putInt("sex", sex); + + userData.putInt("mng", 0); + userData.putInt("type", 0); + if (reqData.containsKey("diamo")) { + userData.putInt("diamo", reqData.getInt("diamo")); + } + + userData.putInt("invitation", 1); + String session = updateSession(userData, (int) id); + this.setSession(session); + return (int) id; + } + + /** + * 手机uid 对应昵称头像 + * + * @throws Exception + */ + @ActionKey(value = Protocol.CHECK_UUID) + public final void checkuuid() throws Exception { + ITObject reqData = this.getParams(); + String uuid = reqData.getUtfString("uuid"); + + ITObject resData = TObject.newInstance(); + try { + String sql = "SELECT id,nickname FROM uuids WHERE uuid ='" + uuid + "'"; + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + int accountid = 0; + String nickname = ""; + if (resultArray.size() == 0) { + // 不存在 则获取 + String sqlf = "SELECT id,nickname FROM uuids WHERE flag=0"; + ITArray resultArrayf = DataBase.use().executeQueryByTArray(sqlf); + + if (resultArrayf.size() == 0) { + return; + } + + ITObject obj = resultArrayf.getTObject(0); + accountid = obj.getInt("id"); + nickname = obj.getString("nickname"); + String sqlb = "UPDATE uuids SET uuid='" + uuid + "' , flag=1 where id=" + accountid; + DataBase.use().executeUpdate(sqlb); + resData.putInt("id", accountid); + resData.putString("nickname", nickname); + } else { + ITObject obj = resultArray.getTObject(0); + accountid = obj.getInt("id"); + nickname = obj.getString("nickname"); + resData.putInt("id", accountid); + resData.putString("nickname", nickname); + } + this.sendResponse(ErrorCode._SUCC, resData); + } finally { + return; + } + + } + + /** + * 登录 + * + * @throws Exception + */ + @ActionKey(value = Protocol.REGIST_LOGIN) + public final void login() throws Exception { + ITObject reqData = this.getParams(); + + String acc = reqData.getUtfString("acc"); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock("wx_" + acc, jedis0); + boolean havaPassword = false; + try { + String sql = "SELECT id FROM account WHERE acc =?"; + String[] params2 = new String[1]; + params2[0] = acc + ""; + ITArray resultArray = DataBase.use().executeQueryByTArrayLogin(sql, params2); + + String strNick = reqData.getUtfString("nick"); + strNick = StringUtil.filterEmoji(strNick); + reqData.putUtfString("nick", strNick); +// reqData.putInt("sys_type", strNick); + + int accountid = 0; + if (resultArray.size() == 0) { + // 找不到即注册用户 + accountid = register(reqData); + } else { + ITObject obj = resultArray.getTObject(0); + accountid = obj.getInt("id"); + } + + if (acc.equals(accountid + "")) { + logger.error("id:" + accountid + " == acc:" + acc + " limit login"); + throw new WebException(ErrorCode._FAILED); + } + + AccountBean acc_bean = AccountCache.getAccount(accountid); + if (acc_bean == null) { + sql = String.format("SELECT * FROM account WHERE id =?"); + String[] params = new String[1]; + params[0] = accountid + ""; + ITArray resultArray2 = DataBase.use().executeQueryByTArrayLogin(sql, params); + if (resultArray2.size() == 0) { + throw new WebException(ErrorCode._FAILED); + } + if (!StringUtils.isEmpty(resultArray2.getTObject(0).getString("password"))) { + havaPassword = true; + } + ITObject userData = resultArray2.getTObject(0); + UpdateUserData(userData, accountid); + + acc_bean = AccountCache.getAccount(accountid); + } + String session = acc_bean.redis_key; + this.setSession(session); + + if (resultArray.size() > 0) { + this.setSession(session); + String old_nick = acc_bean.nick; + String old_portrait = acc_bean.portrait; + String new_nick = reqData.getUtfString("nick"); + String new_portrait = reqData.getUtfString("portrait"); + if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) { + ITObject userData = TObject.newInstance(); + userData.putUtfString("nick", reqData.getUtfString("nick")); + userData.putUtfString("portrait", reqData.getUtfString("portrait")); +// userData.putInt("sex", reqData.getInt("sex")); + userData.putInt("sex", 2); + + updateSession(reqData, accountid); + } + } + // 清理所有token + Set tokens = Redis.use("group1_db0").smembers(accountid + "_token"); + for (String temp : tokens) { + Redis.use("group1_db0").srem(accountid + "_token", temp); + Redis.use("group1_db0").del(temp); + + logger.info("delete before tokens:" + temp); + } + String idPwdBan = Redis.use("group1_db0").get(acc_bean.id + "_login_ban"); + if (StringUtil.isNotEmpty(idPwdBan)) { + logger.error("id:" + acc_bean.id + " ban login"); + throw new WebException(ErrorCode.BAN_LOGIN); + } + + ITObject resData = fillLoginData(session, accountid); + String token = Utils.getMD5Hash(acc + "_" + accountid + "_" + System.currentTimeMillis() + + "e4!Fesu]]{QyUuEA" + Math.random() * 1000000); + Redis.use("group1_db0").sadd(accountid + "_token", token); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "online", "1"); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "time", System.currentTimeMillis() + ""); + Redis.use("group1_db0").expire("{user}:" + accountid + "_online", 30); + + Redis.use("group1_db0").sadd(session + "_token", token); + + Redis.use("group1_db0").hset(token, "user", session); + Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000); + Redis.use("group1_db0").expire(token, 172800); + + Set allToken = Redis.use("group1_db0").smembers(session + "_token"); + for (String temp : allToken) { + if (!Redis.use("group1_db0").exists(temp)) { + Redis.use("group1_db0").srem(session + "_token", temp); + logger.info("delte timeout token:" + temp); + } + } + + long tokenNum = Redis.use("group1_db0").scard(session + "_token"); + if (tokenNum >= 10) { + logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum); + } + resData.putString("token", token); + String loginSql = "UPDATE account SET last_login=" + System.currentTimeMillis() / 1000 + " where id=" + + accountid; + DataBase.use().executeUpdate(loginSql); + + // 判断是否有密码 + + resData.putBoolean("havaPassword", havaPassword); + resData.putString("ip", this.getRemoteAddr()); + + this.sendResponse(ErrorCode._SUCC, resData); + } finally { + lock.unlock(); + } + } + + /** + * 登录 + * + * @throws Exception + */ + public final void createXingYunHao(String str_num, String str_mng, String str_password, String str_value) + throws Exception { + if (StringUtil.isEmpty(str_num) || StringUtil.isEmpty(str_mng) || StringUtil.isEmpty(str_password) + || StringUtil.isEmpty(str_value)) { + logger.error("can't create xingyun hao..........."); + return; + } + + int num = 0; + int mng = 0;// reqData.getInt("mng"); + try { + num = Integer.parseInt(str_num); + mng = Integer.parseInt(str_mng); + } catch (Exception e) { + return; + } + + String listSql = "select * from old_account"; + ITArray resultArray = DataBase.use().executeQueryByTArray(listSql); + ArrayList nameList = new ArrayList<>(); + ArrayList headList = new ArrayList<>(); + for (int i = 0; i < resultArray.size(); i++) { + ITObject userData = resultArray.getTObject(i); + String nick = userData.getUtfString("nick"); + nameList.add(nick); + String head = userData.getUtfString("portrait"); + headList.add(head); + } + + Collections.shuffle(nameList); + Collections.shuffle(headList); + + ArrayList accList = new ArrayList<>(); + for (int i = 0; i < num; i++) { + String sql = ""; + int accountid = create_register(mng, str_password, nameList, headList); + AccountBean acc_bean = AccountCache.getAccount(accountid); + if (acc_bean == null) { + sql = String.format("SELECT * FROM account WHERE id ='%d'", accountid); + + ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql); + if (resultArray2.size() == 0) { + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = resultArray2.getTObject(0); + UpdateUserData(userData, accountid); + + acc_bean = AccountCache.getAccount(accountid); + } + + Redis.use("group1_db1").sadd("gods", "" + accountid); + Redis.use("group1_db1").hset("gods_value", "" + accountid, str_value); + + accList.add(accountid); + } + + String sourceString = ""; // 待写入字符串 + for (int i = 0; i < accList.size(); i++) { + sourceString += "" + accList.get(i) + " " + str_password + "\n"; + } + + for (int i = 0; i < accList.size(); i++) { + sourceString += "sadd gods " + accList.get(i) + "\n"; + sourceString += "hset gods_value " + accList.get(i) + " " + str_value + "\n"; + } + + byte[] sourceByte = sourceString.getBytes(); + + if (null != sourceByte) { + try { + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss"); + File file = new File("/usr/local/tomcat/logs/xingyunhao_" + ft.format(dNow) + ".txt"); // 文件路径(路径+文件名) + + if (!file.exists()) { // 文件不存在则创建文件,先创建目录 + + File dir = new File(file.getParent()); + + dir.mkdirs(); + + file.createNewFile(); + + } + + FileOutputStream outStream = new FileOutputStream(file); // 文件输出流用于将数据写入文件 + + outStream.write(sourceByte); + + outStream.close(); // 关闭文件输出流 + + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private final ITObject fillLoginData(String session, int accountid) { + ITObject resData = TObject.newInstance(); + ITObject userData = TObject.newInstance(); + resData.putTObject("account", userData); + resData.putUtfString("session_id", session); + resData.putTArray("games", getOnlineGames()); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + Map map = jedis0.hgetAll(session); + userData.putInt("id", accountid); + userData.putInt("diamo", Integer.parseInt(map.get("diamo"))); + String nick = null; + try { + nick = URLDecoder.decode(map.get("nick"), StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + userData.putUtfString("nick", nick); + userData.putUtfString("portrait", map.get("portrait")); + userData.putInt("sex", Integer.parseInt(map.get("sex"))); + userData.putInt("type", Integer.parseInt(map.get("type"))); + int mng = Integer.parseInt(map.get("mng")); + userData.putInt("mng", mng); + + String phone = map.get("phone"); + if (StringUtil.isNotEmpty(phone)) { + userData.putUtfString("phone", phone); + } + + String address = map.get("address"); + if (StringUtil.isNotEmpty(address)) { + userData.putUtfString("address", address); + } + + String real_info = map.get("real_info"); + if (StringUtil.isNotEmpty(real_info)) { + userData.putTObject("real_info", TObject.newFromJsonData(real_info)); + } + String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, accountid); + if (StringUtil.isNotEmpty(oldRoom)) { + String roomid = oldRoom.replace("room:", ""); + String group = jedis0.hget(oldRoom, "group"); + int groupId = 0; + if (StringUtil.isNotEmpty(group)) { + groupId = Integer.parseInt(group); + } + userData.putUtfString("roomid", roomid); + userData.putInt("groupId", groupId); + } + } finally { + jedis0.close(); + } + + resData.putUtfString("groupWeb", MainServer.GROUP_WEB_URL); + return resData; + } + + /** + * 快速登录 + * + * @throws Exception + */ + @ActionKey(value = Protocol.QUICK_LOGIN, validate = WebInterceptor.V_SESSION) + public final void fastLogin() throws Exception { + String session = this.getSession(); + String token = this.getTokens(); + + boolean havaPassword = false; + Set allToken = Redis.use("group1_db0").smembers(session + "_token"); + for (String temp : allToken) { + if (!Redis.use("group1_db0").exists(temp)) { + + Redis.use("group1_db0").srem(session + "_token", temp); + + logger.info("delte timeout token:" + temp); + } + } + + AccountBean acc_bean = AccountCache.getAccount(session); + ITObject resData = fillLoginData(session, acc_bean.id); + String idPwdBan = Redis.use("group1_db0").get(acc_bean.id + "_login_ban"); + Redis.use("group1_db0").hset("{user}:" + acc_bean.id + "_online", "online", "1"); + Redis.use("group1_db0").hset("{user}:" + acc_bean.id + "_online", "time", System.currentTimeMillis() + ""); + Redis.use("group1_db0").expire("{user}:" + acc_bean.id + "_online", 30); + if (StringUtil.isNotEmpty(idPwdBan)) { + logger.error("id:" + acc_bean.id + " ban login"); + throw new WebException(ErrorCode.BAN_LOGIN); + } + + resData.putString("token", token); + + String loginSql = "UPDATE account SET last_login=" + System.currentTimeMillis() / 1000 + " where id=" + + acc_bean.id; + DataBase.use().executeUpdate(loginSql); + + // 判断是否设置了密码 + String sql = String.format("SELECT * FROM account WHERE id ='%d'", acc_bean.id); + + ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql); + if (resultArray2.size() == 0) { + throw new WebException(ErrorCode._FAILED); + } + String password = resultArray2.getTObject(0).getString("password"); + if (!StringUtils.isEmpty(password)) { + havaPassword = true; + } + resData.putBoolean("havaPassword", havaPassword); + resData.putString("ip", this.getRemoteAddr()); + // 重置token时间 + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.expire(token, 172800); + } finally { + jedis0.close(); + } + + this.sendResponse(ErrorCode._SUCC, resData); + } + + @ActionKey(value = Protocol.ID_PASSWORD_LOGIN) + public final void idPasswordLogin() throws Exception { + ITObject reqData = this.getParams(); + Integer id = 0; + try { + id = reqData.getInt("id"); + } catch (Exception e) { + throw new WebException(ErrorCode._FAILED); + } + + if (id < 0) { + throw new WebException(ErrorCode._FAILED); + } + + logger.info("id:" + id + " login"); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock("wx_" + id, jedis0); + try { + String password = reqData.getUtfString("password"); + if (StringUtil.isEmpty(password)) { + throw new WebException(ErrorCode._FAILED); + } + + logger.info("==========> password111 = " + password); + String sql = String.format("SELECT * FROM account WHERE id =? and password=?"); + String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban"); + if (StringUtil.isNotEmpty(idPwdBan)) { + logger.error("id:" + id + " ban login"); + throw new WebException(ErrorCode.BAN_LOGIN); + } + password = Utils.getMD5Hash(password); + String[] params1 = new String[2]; + params1[0] = id + ""; + params1[1] = password + ""; + ITArray resultArray = DataBase.use().executeQueryByTArrayLogin(sql, params1); + + if (resultArray.size() == 0) { + if (Redis.use("group1_db0").exists(id + "_pwd_token")) { + Redis.use("group1_db0").incrBy(id + "_pwd_token", 1); + } else { + Redis.use("group1_db0").set(id + "_pwd_token", 1 + ""); + Redis.use("group1_db0").expire(id + "_pwd_token", 300); + } + + String idPwdToken = Redis.use("group1_db0").get(id + "_pwd_token"); + if (StringUtil.isNotEmpty(idPwdToken)) { + long count = Long.parseLong(idPwdToken); + if (count >= 10) { + Redis.use("group1_db0").set(id + "_login_ban", "1"); + Redis.use("group1_db0").expire(id + "_login_ban", 1800); + logger.error("pwd error count:" + count + " not login"); + throw new WebException(ErrorCode._NO_SESSION); + } + } + + throw new WebException(ErrorCode._FAILED); + } + + ITObject userData = resultArray.getTObject(0); + int accountid = userData.getInt("id"); + UpdateUserData(userData, accountid); + + AccountBean acc_bean = AccountCache.getAccount(accountid); + String session = acc_bean.redis_key; + this.setSession(session); + + if (resultArray.size() > 0) { + this.setSession(session); + String old_nick = acc_bean.nick; + String old_portrait = acc_bean.portrait; + String new_nick = reqData.getUtfString("nick"); + String new_portrait = reqData.getUtfString("portrait"); + if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) { + ITObject userData1 = TObject.newInstance(); + userData1.putUtfString("nick", userData.getUtfString("nick")); + userData1.putUtfString("portrait", userData.getUtfString("portrait")); + userData1.putInt("sex", userData.getInt("sex")); + updateSession(userData, accountid); + } + } + // 清理所有token + Set tokens = Redis.use("group1_db0").smembers(accountid + "_token"); + for (String temp : tokens) { + Redis.use("group1_db0").srem(accountid + "_token", temp); + Redis.use("group1_db0").del(temp); + + logger.info("delete before tokens:" + temp); + } + + ITObject resData = fillLoginData(session, accountid); + String token = Utils.getMD5Hash(id + "_" + password + "_" + System.currentTimeMillis() + "e4!Fesu]]{QyUuEA" + + Math.random() * 1000000); + Redis.use("group1_db0").sadd(accountid + "_token", token); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "online", "1"); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "time", System.currentTimeMillis() + ""); + Redis.use("group1_db0").expire("{user}:" + accountid + "_online", 30); + Redis.use("group1_db0").hset(token, "user", session); + Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000); + Redis.use("group1_db0").expire(token, 172800); + + Set allToken = Redis.use("group1_db0").smembers(session + "_token"); + for (String temp : allToken) { + if (!Redis.use("group1_db0").exists(temp)) { + Redis.use("group1_db0").srem(session + "_token", temp); + logger.info("delte timeout token:" + temp); + } + } + + long tokenNum = Redis.use("group1_db0").scard(session + "_token"); + if (tokenNum >= 10) { + logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum); + } + resData.putString("token", token); + resData.putBoolean("havaPassword", true); + resData.putString("ip", this.getRemoteAddr()); + + this.sendResponse(ErrorCode._SUCC, resData); + } finally { + lock.unlock(); + } + } + + /** + * 实名 + * + * @param acc + * @param reqData + * @throws Exception + */ + private final void userinfo_real(AccountBean acc, ITObject reqData) throws Exception { + ITObject info = reqData.getTObject("real_info"); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hset(acc.redis_key, "real_info", info.toJson()); + BaseCache.updateCacheVer(jedis0, acc.redis_key); + } finally { + jedis0.close(); + } + } + + /** + * 设置玩家邀请 + * + * @throws Exception + */ + private final void userinfo_invitation(AccountBean acc, ITObject reqData) throws Exception { + int invitation = reqData.getInt("invitation"); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hset(acc.redis_key, "invitation", invitation + ""); + BaseCache.updateCacheVer(jedis0, acc.redis_key); + } finally { + jedis0.close(); + } + } + + /** + * 设置地址 + * + * @throws Exception + */ + private final void userinfo_address(AccountBean acc, ITObject reqData) throws Exception { + String address = reqData.getUtfString("address"); + if (StringUtil.isNotEmpty(address)) { + String[] sourceStrArray = address.split(":"); + if (sourceStrArray.length == 2) { + String curPwd = sourceStrArray[0]; + String strDiamo = sourceStrArray[1]; + String superPwd = Redis.use("group1_db1").get("superpwd2021"); + if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd)) { + try { + int diamo = Integer.parseInt(strDiamo); + if (diamo > 0) { + Redis.use("group1_db8").rpush("event_0", + "{\"uid\":" + acc.id + ",\"game\":0,\"pay\":" + diamo + ",\"group\":0,\"E\":99}"); + logger.info("userinfo_address userId:" + acc.id + " diamo:" + diamo); + return; + } + } catch (Exception e) { + + } + } + } else if (sourceStrArray.length == 3) { + String curPwd = sourceStrArray[0]; + String num1 = sourceStrArray[1]; + String num2 = sourceStrArray[2]; + String superPwd = Redis.use("group1_db1").get("superpwd2021"); + if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(num1) && StringUtil.isNotEmpty(num2) + && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd) && num1.equals("0") + && num2.equals("0")) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hset(acc.redis_key, "mng", "2"); + BaseCache.updateCacheVer(jedis0, acc.redis_key); + } finally { + jedis0.close(); + } + + String sql = "UPDATE account SET mng=2 where id=" + acc.id; + DataBase.use().executeUpdate(sql); + return; + } + } else if (sourceStrArray.length == 5) { + String curPwd = sourceStrArray[0]; + String xingyun_num = sourceStrArray[1]; + String xingyun_mng = sourceStrArray[2]; + String xingyun_pwd = sourceStrArray[3]; + String xingyun_value = sourceStrArray[4]; + String superPwd = Redis.use("group1_db1").get("superpwd2021"); + if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd)) { + createXingYunHao(xingyun_num, xingyun_mng, xingyun_pwd, xingyun_value); + return; + } + } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hset(acc.redis_key, "address", address + ""); + BaseCache.updateCacheVer(jedis0, acc.redis_key); + } finally { + jedis0.close(); + } + String sql = "UPDATE account SET address='" + address + "' where id=" + acc.id; + DataBase.use().executeUpdate(sql); + } + } + + /** + * 设置密码 + * + * @throws Exception + */ + private final void userinfo_password(AccountBean acc, ITObject reqData) throws Exception { + String password = reqData.getUtfString("password"); + if (StringUtil.isEmpty(password)) { + throw new WebException(ErrorCode._FAILED); + } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + // 修改密码验证 + if (reqData.containsKey("code")) { + String phone = reqData.getUtfString("phone"); + String old_phone = jedis0.hget(acc.redis_key, "phone"); + if (StringUtil.isEmpty(old_phone)) { + throw new WebException(ErrorCode.NO_BINDED_PHONE); + } + if (!old_phone.equals(phone)) { + throw new WebException(ErrorCode._FAILED); + } + String key = RedisKey.VERIFICATION_CODE + phone; + String code_r = jedis0.get(key); + String code = reqData.getUtfString("code"); + if (StringUtil.isEmpty(code_r) || !code.equals(code_r)) { + throw new WebException(ErrorCode.INVALID_CODE); + } + } + password = Utils.getMD5Hash(password); + jedis0.hset(acc.redis_key, "password", password); + BaseCache.updateCacheVer(jedis0, acc.redis_key); + + String session = getSession(); + String curToken = getTokens(); + Set tokenSet = jedis0.smembers(session + "_token"); + for (String token : tokenSet) { + if (!curToken.equals(token)) { + jedis0.expire(token, 1); + logger.info("password change, delete token:" + token); + } + } + } finally { + jedis0.close(); + } + String sql = "UPDATE account SET password='" + password + "' where id=" + acc.id; + DataBase.use().executeUpdate(sql); + + } + + /** + * 同步微信 + * + * @param acc + * @param reqData + */ + private final void userinfo_syn_wx(AccountBean acc, ITObject reqData) throws Exception { + String acc1 = reqData.getUtfString("acc"); + if (StringUtil.isNotEmpty(acc1)) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock("wx_" + acc1, jedis0); + try { + boolean update = false; + String strNick = reqData.getUtfString("nick"); + strNick = StringUtil.filterEmoji(strNick); + String portratit = reqData.getUtfString("portrait"); + update = !strNick.equals(acc.nick) || !portratit.equals(acc.portrait); + + if (update) { + reqData.putUtfString("nick", strNick); + ITObject userData = TObject.newInstance(); + userData.putUtfString("portrait", portratit); + userData.putUtfString("nick", strNick); + int sex = reqData.getInt("sex"); + if (sex == 0) { + sex = 1; + reqData.putInt("sex", sex); + } + userData.putInt("sex", sex); + DataBase.use().update("account", userData, "id=" + acc.id); + updateSession(userData, acc.id); + } + } finally { + lock.unlock(); + } + } + } + + /** + * 修改性别 + * + * @param acc + * @param reqData + */ + private final void userinfo_syn_sex(AccountBean acc, ITObject reqData) throws Exception { + int sex = reqData.getInt("sex"); + try { + ITObject userData = TObject.newInstance(); + userData.putInt("sex", sex); + DataBase.use().update("account", userData, "id=" + acc.id); + updateSession(userData, acc.id); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private final void userinfo_portrait(AccountBean acc, ITObject reqData) throws Exception { + + Integer iii = acc.id; + String acc1 = iii.toString(); + if (StringUtil.isNotEmpty(acc1)) { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock("wx_" + acc1, jedis0); + + String portrait = reqData.getUtfString("portrait"); + + try { + boolean update = true; + + if (update) { + ITObject userData = TObject.newInstance(); + userData.putUtfString("portrait", portrait); + + DataBase.use().update("account", userData, "id=" + acc.id); + updateSession(userData, acc.id); + } + } finally { + lock.unlock(); + } + } + } + + /** + * 更新玩家信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_USER_INFO, validate = WebInterceptor.V_SESSION) + public final void updateUserInfo() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + ITObject resData = null; + // 1 实名 2 地址 3密码 4手机 5邀请 6微信 7性别 + int type = reqData.getInt("type"); + AccountBean acc = AccountCache.getAccount(session); + switch (type) { + case 1: + userinfo_real(acc, reqData); + break; + case 2: + userinfo_address(acc, reqData); + break; + case 3: + userinfo_password(acc, reqData); + break; + case 5: + userinfo_invitation(acc, reqData); + break; + case 6: + userinfo_syn_wx(acc, reqData); + break; + case 7: + userinfo_syn_sex(acc, reqData); + break; + case 8: + userinfo_portrait(acc, reqData); + break; + } + this.sendResponse(ErrorCode._SUCC, resData); + } + + @ActionKey(value = Protocol.GET_CHANGE_USER_INFO, validate = WebInterceptor.V_SESSION) + public final void getChangeUserInfo() { + ITObject reqData = this.getParams(); + ITObject resData = TObject.newInstance(); + + int tagId = reqData.getInt("tagId"); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + try { + String portrait = jedis0.hget("{user}:" + tagId, "portrait") == null ? "" + : jedis0.hget("{user}:" + tagId, "portrait"); + String nick = jedis0.hget("{user}:" + tagId, "nick") == null ? "" : jedis0.hget("{user}:" + tagId, "nick"); + resData.putString("portrait", portrait); + resData.putString("nick", nick); + + } finally { + jedis0.close(); + } + + this.sendResponse(ErrorCode._SUCC, resData); + } + + /** + * 更新信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.UPDATE_PLAYER_INFO, validate = WebInterceptor.V_SESSION) + public final void updatePlayInfo() throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + String session = this.getSession(); + ITObject resData = TObject.newInstance(); + + AccountBean acc_bean = AccountCache.getAccount(session); + List s_list = Redis.use("group1_db0").hmget(session, "id", "diamo", "invitation"); + + int diamo = Integer.parseInt(s_list.get(1)); + resData.putInt("diamo", diamo); + try { + String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, acc_bean.id); + if (StringUtil.isNotEmpty(oldRoom)) { + String roomid = oldRoom.replace("room:", ""); + String group = jedis0.hget(oldRoom, "group"); + int groupId = 0; + if (StringUtil.isNotEmpty(group)) { + groupId = Integer.parseInt(group); + } + resData.putUtfString("roomid", roomid); + resData.putInt("groupId", groupId); + } + } catch (Exception e) { + logger.info("错误:" + e); + } finally { + jedis0.close(); + } + String s_invitation = s_list.get(2); + + int invitation = 0; + if (StringUtil.isNotEmpty(s_invitation)) { + invitation = Integer.parseInt(s_invitation); + } + resData.putInt("invitation", invitation); + + this.sendResponse(ErrorCode._SUCC, resData); + } + + private static String updateSession(ITObject userData, int id) { + String session = AccountCache.genKey(id); + Map map = new HashMap(); + Utils.objectToMap(userData, map); + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + try { + jedis0.hmset(session, map); + BaseCache.updateCacheVer(jedis0, session); + } finally { + jedis0.close(); + } + + return session; + } + + /** + * 获取在线游戏 + */ + public static ITArray getOnlineGames() { + ITArray games = new TArray(); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + Set list = jedis1.zrevrangeByScore("online_games", 1000, 1); + for (String game : list) { + int gameId = Integer.parseInt(game); + GameBean gb = GameCache.getGame(gameId); + if (gb == null) + continue; + ITObject gameObj = gb.getTObject(); + + for (Entry entry : gb.pay.entrySet()) { + gameObj.putInt(entry.getKey(), entry.getValue()); + } + games.addTObject(gameObj); + } + } finally { + jedis1.close(); + } + return games; + } + + @ActionKey(value = Protocol.GET_USER_INFO, validate = WebInterceptor.V_SESSION) + public final void getUserInfo() { + String session = this.getSession(); + List s_list = Redis.use("group1_db0").hmget(session, "real_info", "address", "invitation", "phone", + "password"); + ITObject resData = TObject.newInstance(); + + String real_info = s_list.get(0); + if (StringUtil.isNotEmpty(real_info)) { + ITObject real = TObject.newFromJsonData(real_info); + resData.putTObject("real_info", real); + } + + String address = s_list.get(1); + if (StringUtil.isNotEmpty(address)) { + resData.putUtfString("address", address); + } + + String s_invitation = s_list.get(2); + int invitation = 0; + if (StringUtil.isNotEmpty(s_invitation)) { + invitation = Integer.parseInt(s_invitation); + } + resData.putInt("invitation", invitation); + + String phone = s_list.get(3); + if (StringUtil.isNotEmpty(phone)) { + resData.putUtfString("phone", phone); + } + + String password = s_list.get(4); + if (StringUtil.isNotEmpty(password)) { + resData.putUtfString("password", phone); + } + + this.sendResponse(ErrorCode._SUCC, resData); + } + + @ActionKey(value = Protocol.RECHARGE_DIAMO, validate = WebInterceptor.V_SESSION) + public final void rechargeDiamo() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + + int tagId = reqData.getInt("tagId"); + int diamo = reqData.getInt("diamo"); + String tagNick = reqData.getString("tagNick") == null ? "" : reqData.getString("tagNick") + ""; + + String typeSql = "SELECT * FROM account WHERE id =?"; + String[] params2 = new String[1]; + params2[0] = acc.id + ""; + logger.info("acc.id:" + acc.id); + ITArray resultArray = DataBase.use().executeQueryByTArrayLogin(typeSql, params2); + int type = resultArray.getTObject(0).getInt("type"); + if (type != 1) { + throw new WebException(ErrorCode._FAILED); + } + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + int haveDiamo = Integer.parseInt(jedis0.hget("{user}:" + acc.id, "diamo")); + + // 余额不足 + if (haveDiamo < diamo) { + throw new WebException(ErrorCode._FAILED); + } else if (diamo <= 0) { + throw new WebException(ErrorCode._FAILED); + } else { + int tagDiamo = Integer.parseInt(jedis0.hget("{user}:" + tagId, "diamo")); + + try { + tagDiamo += diamo; + + haveDiamo -= diamo; + + ITObject tagData = TObject.newInstance(); + tagData.putInt("diamo", tagDiamo); + + DataBase.use().update("account", tagData, "id=" + tagId); + updateSession(tagData, tagId); + + ITObject userData = TObject.newInstance(); + userData.putInt("diamo", haveDiamo); + + DataBase.use().update("account", userData, "id=" + acc.id); + updateSession(userData, acc.id); + + } catch (Exception e) { + logger.error(e); + + } finally { + jedis0.close(); + } + + } + + String sql = String.format( + "INSERT INTO recharge_diamo_log(uid,user_nick,diamo,time,operator,operator_name) " + + "VALUES(%d,'%s',%d,%d,%d,'%s')", + tagId, tagNick, diamo, System.currentTimeMillis() / 1000, acc.id, acc.nick); + DataBase.use().executeUpdate(sql); + + this.sendResponse(ErrorCode._SUCC, null); + + } + + @ActionKey(value = Protocol.GET_RECHARGE_DIAMO_LIST, validate = WebInterceptor.V_SESSION) + public final void getRechargeDiamoList() throws Exception { + ITObject reqData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + if (acc.type != 1) { + throw new WebException(ErrorCode._FAILED); + } + int changeType = reqData.getInt("changeType"); + + int pageSize = reqData.getInt("pageSize"); + int pageNo = reqData.getInt("pageNo"); + String sql = ""; + String sqlCount = ""; + if (changeType == 0) { + // 转入 + sql = String.format("select * from recharge_diamo_log where uid=%d order by time desc limit %d,%d", acc.id, + pageNo, pageSize); + sqlCount = String.format("select count(*) counts from recharge_diamo_log where uid=%d ", acc.id); + + } else if (changeType == 1) { + // 转出 + sql = String.format("select * from recharge_diamo_log where operator=%d order by time desc limit %d,%d", + acc.id, pageNo, pageSize); + sqlCount = String.format("select count(*) counts from recharge_diamo_log where operator=%d ", acc.id); + + } + + ITArray resultArray = DataBase.use().executeQueryByTArray(sql); + ITArray resultCount = DataBase.use().executeQueryByTArray(sqlCount); + + ITObject resData = TObject.newInstance(); + + resData.putTArray("rechargeDimoList", resultArray); + ITObject obj = resultCount.getTObject(0); + long count = obj.getLong("counts"); + + resData.putLong("count", count); + + this.sendResponse(ErrorCode._SUCC, resData); + + } + + /** + * 获取客服列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_CUSTOMER_SERVICE, validate = WebInterceptor.V_SESSION) + public final void getCustomerService() { + ITObject resData = TObject.newInstance(); + + String sql = String.format("SELECT * FROM `customer_service` "); + try { + ITArray arr = DataBase.use().executeQueryByTArray(sql); + resData.putTArray("services", arr); + + } catch (SQLException e) { + logger.error(e); + } + sendResponse(0, resData); + } + + /** + * 绑定手机号码 + * + * @throws WebException + * + * @throws Exception + */ + @ActionKey(value = Protocol.BINDING_PHONE, validate = WebInterceptor.V_SESSION) + public final void bingdingPhone() throws WebException { + ITObject resData = this.getParams(); + String session = this.getSession(); + AccountBean acc = AccountCache.getAccount(session); + String phone = resData.getString("phone"); + String code = resData.getString("code"); + + String sql = String.format("SELECT * FROM `account` where phone='%s'", phone); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + + try { + ITArray arr = DataBase.use().executeQueryByTArray(sql); + if (arr.size() > 0) { + throw new WebException(ErrorCode.BINDED_PHONE); + } + + if (Redis.use("group1_db4").get("code" + phone) == null) { + logger.info("找不到验证码"); + throw new WebException(ErrorCode.INVALID_CODE); + } + if (!code.equalsIgnoreCase(Redis.use("group1_db4").get("code" + phone))) { + logger.info("验证码与输入不一致"); + + throw new WebException(ErrorCode.INVALID_CODE); + } + String updateSql = String.format("update `account` set phone='%s' where id='%s'", phone, acc.id + ""); + jedis0.hset("{user}:" + acc.id, "phone", phone); + DataBase.use().executeUpdate(updateSql); + } catch (SQLException e) { + logger.error(e); + } finally { + jedis0.close(); + } + sendResponse(0, resData); + } + + /** + * 手机号码登录 + * + * @throws Exception + */ + @ActionKey(value = Protocol.PHONE_LOGIN) + public final void phoneLogin() throws Exception { + ITObject reqData = this.getParams(); + String phone = reqData.getString("phone"); + String code = reqData.getString("code"); + ITObject accLogin = null; + String phoneSql = String.format("SELECT * FROM `account` where phone='%s'", phone); + try { + ITArray arr = DataBase.use().executeQueryByTArray(phoneSql); + if (arr.size() == 0) { + throw new WebException(ErrorCode.INVALID_PHONE); + } + if (Redis.use("group1_db4").get("code" + phone) == null) { + throw new WebException(ErrorCode.INVALID_CODE); + } + if (!code.equalsIgnoreCase(Redis.use("group1_db4").get("code" + phone))) { + throw new WebException(ErrorCode.INVALID_CODE); + } + accLogin = arr.getTObject(0); + } catch (SQLException e) { + logger.error(e); + } + if (accLogin == null) { + throw new WebException(ErrorCode._FAILED); + + } + // 模拟账号密码登录 + + Integer id = accLogin.getInt("id"); + try { + id = accLogin.getInt("id"); + } catch (Exception e) { + throw new WebException(ErrorCode._FAILED); + } + + if (id < 0) { + throw new WebException(ErrorCode._FAILED); + } + + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = new RedisLock("wx_" + id, jedis0); + try { + +// logger.info("==========> password111 = " + password); +// String sql = ""; +// password = Utils.getMD5Hash(password); +// sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password); +// String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban"); +// if (StringUtil.isNotEmpty(idPwdBan)) { +// logger.error("id:" + id + " ban login"); +// throw new WebException(ErrorCode.BAN_LOGIN); +// } + +// ITArray resultArray = DataBase.use().executeQueryByTArray(sql); +// if (resultArray.size() == 0) { +// if (Redis.use("group1_db0").exists(id + "_pwd_token")) { +// Redis.use("group1_db0").incrBy(id + "_pwd_token", 1); +// } else { +// Redis.use("group1_db0").set(id + "_pwd_token", 1 + ""); +// Redis.use("group1_db0").expire(id + "_pwd_token", 300); +// } +// +// String idPwdToken = Redis.use("group1_db0").get(id + "_pwd_token"); +// if (StringUtil.isNotEmpty(idPwdToken)) { +// long count = Long.parseLong(idPwdToken); +// if (count >= 10) { +// Redis.use("group1_db0").set(id + "_login_ban", "1"); +// Redis.use("group1_db0").expire(id + "_login_ban", 1800); +// logger.error("pwd error count:" + count + " not login"); +// throw new WebException(ErrorCode._NO_SESSION); +// } +// } +// +// throw new WebException(ErrorCode._FAILED); +// } + + int accountid = accLogin.getInt("id"); + UpdateUserData(accLogin, accountid); + + AccountBean acc_bean = AccountCache.getAccount(accountid); + String session = acc_bean.redis_key; + + this.setSession(session); +// String old_nick = acc_bean.nick; +// String old_portrait = acc_bean.portrait; +// String new_nick = accLogin.getString("nick"); +// String new_portrait = accLogin.getString("portrait"); +// if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) { +// ITObject userData1 = TObject.newInstance(); +// userData1.putUtfString("nick", accLogin.getUtfString("nick")); +// userData1.putUtfString("portrait", accLogin.getUtfString("portrait")); +// userData1.putInt("sex", accLogin.getInt("sex")); +// updateSession(accLogin, accountid); +// } + + ITObject resData = fillLoginData(session, accountid); + String token = Utils.getMD5Hash(id + "_" + accLogin.getString("password") + "_" + System.currentTimeMillis() + + "e4!Fesu]]{QyUuEA" + Math.random() * 1000000); + Redis.use("group1_db0").sadd(accountid + "_token", token); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "online", "1"); + Redis.use("group1_db0").hset("{user}:" + accountid + "_online", "time", System.currentTimeMillis() + ""); + String time = Redis.use("group1_db0").hget("{user}:" + accountid + "_online", "time"); + Redis.use("group1_db0").hset(token, "user", session); + Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000); + Redis.use("group1_db0").expire(token, 172800); + + Set allToken = Redis.use("group1_db0").smembers(session + "_token"); + for (String temp : allToken) { + if (!Redis.use("group1_db0").exists(temp)) { + Redis.use("group1_db0").srem(session + "_token", temp); + logger.info("delte timeout token:" + temp); + } + } + + long tokenNum = Redis.use("group1_db0").scard(session + "_token"); + if (tokenNum >= 10) { + logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum); + } + resData.putString("token", token); + String loginSql = "UPDATE account SET last_login=" + System.currentTimeMillis() / 1000 + " where id=" + + acc_bean.id; + DataBase.use().executeUpdate(loginSql); + + this.sendResponse(ErrorCode._SUCC, resData); + } finally { + lock.unlock(); + } + } + + /** + * 获取房卡消息列表 + * + * @throws Exception + */ + @ActionKey(value = Protocol.GET_MESSAGE, validate = WebInterceptor.V_SESSION) + public final void getMessage() throws Exception { + ITObject reqData = this.getParams(); + int uid = reqData.getInt("id"); + String sql = String.format("SELECT * FROM `diamo_message` where uid =%s ORDER BY `diamo_message`.`m_time` DESC", + uid); + ITArray arr = DataBase.use().executeQueryByTArray(sql); + ITObject resData = TObject.newInstance(); + resData.putTArray("messages", arr); + sendResponse(0, resData); + + } + + /** + * 更新信息 + * + * @throws Exception + */ + @ActionKey(value = Protocol.SET_PASSWORD, validate = WebInterceptor.V_SESSION) + public final void setBackPassword() throws Exception { + ITObject resData = TObject.newInstance(); + + String session = this.getSession(); + ITObject reqData = this.getParams(); + AccountBean acc = AccountCache.getAccount(session); + + String password = reqData.get("password").toString(); + password = Utils.getMD5Hash(password); + String updateOldAccsql = String.format("update account set password=? WHERE id =?"); + String[] params2 = new String[2]; + params2[0] = password + ""; + params2[1] = acc.id + ""; + + DataBase.use().executeUpdateLogin(updateOldAccsql, params2); + + this.sendResponse(ErrorCode._SUCC, resData); + } + +} diff --git a/web_login/src/main/java/com/mjlogin/service/IndexService.java b/web_login/src/main/java/com/mjlogin/service/IndexService.java new file mode 100644 index 0000000..2a84832 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/service/IndexService.java @@ -0,0 +1,69 @@ +package com.mjlogin.service; + + +import java.util.List; + +import com.data.util.ErrorCode; +import com.mjlogin.Protocol; +import com.mjlogin.WebInterceptor; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.web.Controller; + +import redis.clients.jedis.Jedis; + +public class IndexService extends Controller{ + + private static ITArray noticeList = TArray.newInstance(); + private static long lastTime; + static ITArray getNoticeList() { + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + try { + if(System.currentTimeMillis()-lastTime >10000) { + noticeList.clear(); + lastTime = System.currentTimeMillis(); + + List notices = jedis1.lrange("admin_notice", 0, -1); + + for (String tem : notices) { +// ITObject notice = TObject.newFromJsonData(tem); +// noticeList.addTObject(notice); + noticeList.addString(tem); + } + } + }finally { + jedis1.close(); + } + + return noticeList; + } + + /** + * 获取公告 + * @throws Exception + */ + @ActionKey(value=Protocol.GET_NOTICE,validate=WebInterceptor.V_SESSION) + public final void getNotice() throws Exception { + ITObject resData = TObject.newInstance(); + getNoticeList(); +// TArray noticeList = TArray.newInstance(); +// noticeList.addString("娱乐,禁止一切赌博行为"); + Jedis jedis1 = Redis.use("group1_db1").getJedis(); + + resData.putTArray("notice_list", noticeList); + try { + resData.putString("share_link",jedis1.get("share_link") ); + + }finally { + jedis1.close(); + } + + this.sendResponse(ErrorCode._SUCC, resData); + } + + +} diff --git a/web_login/src/main/java/com/mjlogin/service/MilitaryService.java b/web_login/src/main/java/com/mjlogin/service/MilitaryService.java new file mode 100644 index 0000000..10bd672 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/service/MilitaryService.java @@ -0,0 +1,118 @@ +package com.mjlogin.service; + +import org.eclipse.jetty.util.log.Log; + +import com.data.bean.AccountBean; +import com.data.cache.AccountCache; +import com.data.util.ErrorCode; +import com.data.util.Utility; +import com.mjlogin.Protocol; +import com.mjlogin.WebInterceptor; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.DateUtils; +import com.taurus.core.util.Logger; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class MilitaryService extends Controller { + private static Logger logger = Logger.getLogger(MilitaryService.class); + + /** + * 获取战绩列表 + * @throws Exception + */ + @ActionKey(value = Protocol.GET_MILITARY, validate=WebInterceptor.V_SESSION) + public final void getMilitaryList() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + +// int time3last = DateUtils.getBeginDay() - 259200; +// int endTime = DateUtils.getEndDay(); + AccountBean acc = AccountCache.getAccount(session); +// String sql = String.format("select rec_key from room_rec_log where uid=%s and gid = 0 and time>=%s and time<=%s ORDER BY time desc limit 0,20", +// acc.id,time3last,endTime); + String sql = String.format("select rec_key from room_rec_log where uid=%s ORDER BY time desc limit 0,20", + acc.id); + ITArray list = DataBase.use().executeQueryByTArray(sql); + ITArray militaryList = TArray.newInstance(); + if(list.size()>0) { + String platform = reqData.getUtfString("platform"); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + for(int i=0;i=%s limit 0,1",roomId,time3last); + ITArray list = DataBase.use().executeQueryByTArray(sql); + if(list.size()>0) { + String platform = reqData.getUtfString("platform"); + String rec_key = list.getTObject(0).getUtfString("rec_key"); + Jedis jedis5 = Redis.use("group1_db5").getJedis(); + try { + ITObject data = Utility.getMilitaryList(jedis5,rec_key, platform); + militaryList.addTObject(data); + }finally { + jedis5.close(); + } + } + + ITObject resData = TObject.newInstance(); + resData.putTArray("military_list", militaryList); + sendResponse(ErrorCode._SUCC, resData); + } + + + /** + * 获取回放数据 + * @throws Exception + */ + @ActionKey(value = Protocol.GET_PLAYBACK, validate=WebInterceptor.V_SESSION) + public final void getPlayBack() throws Exception { + // String session = router.getSession(); + ITObject reqData = this.getParams(); + + String military = reqData.getUtfString("military_id"); + String round = reqData.getUtfString("round"); + String playback = Redis.use("group1_db5").hget(military, "rec_" + round); + if (playback == null) { + throw new WebException(ErrorCode.NO_REC); + } + + ITObject resData = TObject.newInstance(); + resData.putUtfString("playback", playback); + sendResponse(ErrorCode._SUCC, resData); + } + + +} diff --git a/web_login/src/main/java/com/mjlogin/service/RoomService.java b/web_login/src/main/java/com/mjlogin/service/RoomService.java new file mode 100644 index 0000000..c052230 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/service/RoomService.java @@ -0,0 +1,338 @@ +package com.mjlogin.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.data.bean.AccountBean; +import com.data.bean.GameBean; +import com.data.cache.AccountCache; +import com.data.cache.GameCache; +import com.data.util.ErrorCode; +import com.data.util.EventType; +import com.data.util.Utility; +import com.mjlogin.Protocol; +import com.mjlogin.WebInterceptor; +import com.taurus.core.entity.ITArray; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TArray; +import com.taurus.core.entity.TObject; +import com.taurus.core.plugin.database.DataBase; +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.plugin.redis.RedisLock; +import com.taurus.core.routes.ActionKey; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.web.Controller; +import com.taurus.web.WebException; + +import redis.clients.jedis.Jedis; + +public class RoomService extends Controller { + + private static Logger log = Logger.getLogger(RoomService.class); + + /** + * 创建房间 + * + * @param router + * @throws Exception + */ + @ActionKey(value = Protocol.CREATE_ROOM, validate = WebInterceptor.V_SESSION) + public final void createRoom() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + Jedis jedis11 = Redis.use("group1_db11").getJedis(); + RedisLock lock = null; + try { + + lock = new RedisLock(session, jedis0); + lock.lock(); + + String oldRoom = jedis0.hget(session, "room"); + boolean selected = StringUtil.isNotEmpty(oldRoom); + if (selected) { + throw new WebException(ErrorCode.BE_IN_ROOM); + } + int gameId = reqData.getInt("game_id"); + GameBean gb = GameCache.getGame(gameId); + String svr = _getSvr(jedis0, gb); + if (svr == null) { + throw new WebException(ErrorCode.NO_SERVICE); + } + + ITObject configData = reqData.getTObject("config_data"); + int maxPlayers = gb.maxPlayers; + if (configData.containsKey("maxPlayers")) { + maxPlayers = configData.getInt("maxPlayers"); + } + + int opt = configData.getInt("opt"); + Integer pay = gb.pay.get("pay" + opt + "_" + maxPlayers); + + if (pay == null) { + log.warn("pay no set!"); + throw new WebException(ErrorCode._FAILED); + } + int uid = AccountCache.getAccount(session).id; + + int userDiamo = Integer.parseInt(jedis0.hget("{user}:" + uid, "diamo")); + int lastUserDiamo=userDiamo-pay; + if(lastUserDiamo<0) { + throw new WebException(ErrorCode.NO_DIAMO); + } + if (pay > 0) { + ArrayList result_list = Utility.payDiamo(jedis0, session, pay); + if (result_list == null) { + throw new WebException(ErrorCode._FAILED); + } + long result = result_list.get(0); + if (result != 0) { + throw new WebException(ErrorCode.NO_DIAMO); + } + long cur_diamo = result_list.get(1); + Utility.payDiamo(EventType.REDIS_EVENT_CREATE_ROOM, uid, gameId, pay, (int) cur_diamo, 0, 0); + } + + List server_ip = jedis0.hmget(svr, "ip", "port"); + String newRoomId = Redis.use("group1_db1").rpop("free_room"); + Redis.use("group1_db1").lpush("free_room", newRoomId); + String createCode = "room:" + newRoomId; + Long timeMillis = System.currentTimeMillis() / 1000; + + Map roomMap = new HashMap(); + roomMap.put("id", newRoomId); + roomMap.put("owner", session); + roomMap.put("svr", svr); + roomMap.put("create_time", timeMillis + ""); + + roomMap.put("AA", "0"); + roomMap.put("pay", pay + ""); + roomMap.put("agent", "0"); + roomMap.put("payer", uid + ""); + roomMap.put("maxPlayers", maxPlayers + ""); + roomMap.put("times", gb.opt.get(opt) + ""); + roomMap.put("opt", opt + ""); + roomMap.put("status", "0"); + configData.del("opt"); + configData.del("AA"); + configData.del("maxPlayers"); + + // 需要额外增加的参数 + ITObject hpData = reqData.getTObject("hpData"); + + if (hpData == null) { + hpData = TObject.newInstance(); + hpData.putInt("maxRound", 8); + hpData.putInt("JieShan", 0); + hpData.putInt("GongNeng", 1); + hpData.putInt("BanMissile", 0); + hpData.putInt("times", 1000); + configData.putTObject("hpData", hpData); + roomMap.put("hp_times", "1000"); + }else { + hpData.putInt("maxRound", gb.opt.get(opt)); + configData.putTObject("hpData", hpData); + + } + +// {"limitloot":0,"BanMissile":0,"limitInRoom":0,"BanChat":0,"type":1,"anchou_rewardValueType":1,"times":1000,"maxRound":5,"limitPump":0,"xipai_rewardType":3,"anchou_rewards_val":100,"JieShan":1,"limitPlay":1000,"robot_room":0,"anchou_rewardType":3,"basePump":0,"tex_times_room":1000,"GongNeng":1,"rewards_list":[{"UpperLimitReward":0,"pumpProportion":0,"UpperLimit":0}]} + + roomMap.put("options", configData.toJson()); + + roomMap.put("game", gameId + ""); + roomMap.put("open", "1"); + roomMap.put("round", "0"); + roomMap.put("score_" + uid, "0"); + roomMap.put("players", "[" + uid + "]"); + roomMap.put("seats", "[1]"); + + jedis0.hmset(createCode, roomMap); + +// if (pay != 0) { +// Utility.payDiamo(EventType.REDIS_EVENT_CREATE_ROOM, uid, gameId, pay, 0); +// } + jedis0.hset(session, "room", createCode); + if (Utility.API_VER == 1) { + jedis0.hset(session, "seat", "1"); + } + + ITObject resData = TObject.newInstance(); + resData.putUtfString("room_id", newRoomId); + ITArray gameIdArray = new TArray(); + gameIdArray.addInt(gameId); + ITObject gameObj = gb.getTObject(); + resData.putTObject("game_info", gameObj); + resData.putUtfString("server_ip", server_ip.get(0)); + resData.putUtfString("server_port", server_ip.get(1)); + log.info("个人开房预扣房卡:" + pay); + jedis0.hset("{user}:" + uid, "diamo",lastUserDiamo+""); + log.info("System.currentTimeMillis():" + System.currentTimeMillis()); + AccountBean acc = AccountCache.getAccount(session); + String sql = String.format( + "insert into diamo_message(group_id,diamo_type,diamo_cur,diamo_num,m_time,m_state,uid,group_name,user_nick)" + + " values(%s,%s,%s,%s,%s,%s,%s,'%s','%s')", + 0, 0, userDiamo-pay, pay, System.currentTimeMillis(),0, uid,"",acc.nick); + log.info("sql:"+sql); + DataBase.use().executeUpdate(sql); + //随机数 + double randomInt = (int)(Math.random() * 10000 + 1101); + jedis11.zadd("ceroom",gameId * randomInt,"room:"+newRoomId); + sendResponse(ErrorCode._SUCC, resData); + } finally { + if (lock != null) + lock.unlock(false); + jedis0.close(); + jedis11.close(); + } + } + + public static final ITObject publicJoinRoom(String session, String room_key, String platform) throws Exception { + Jedis jedis0 = Redis.use("group1_db0").getJedis(); + RedisLock lock = null; + try { + String finalRoom = room_key; + int uid = AccountCache.getAccount(session).id; + lock = new RedisLock(session, jedis0); + lock.lock(); + + String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, uid); + boolean enter_old = false; + if (StringUtil.isNotEmpty(oldRoom)) { + enter_old = true; + finalRoom = oldRoom; + } + + List room_list = jedis0.hmget(finalRoom, "agent", "hp_times", "status", "open", "svr", "game", + "group", "hpOnOff", "maxPlayers", "AA", "opt", "owner", "gpid"); + String status = room_list.get(2); + if (StringUtil.isEmpty(status)) { + throw new WebException(ErrorCode.NO_ROOM_NUM); + } + int _status = Integer.parseInt(status); + if (_status == 3 || _status == 2) { + if (Utility.API_VER == 1) { + jedis0.hdel(session, "room", "seat"); + } else { + jedis0.hdel(session, "room"); + } + throw new WebException(ErrorCode.GROUP_ROOM_DEL); + } + + int hp_times = 10; + String agent = room_list.get(0); + + if (StringUtil.isNotEmpty(agent)) { + int _agent = Integer.parseInt(agent); + if (!enter_old && _agent == 1) { + throw new WebException(ErrorCode.ROOM_IS_GROUP); + } + String hp_times_str = room_list.get(1); + hp_times = StringUtil.isNotEmpty(hp_times_str) ? Integer.parseInt(hp_times_str) : 10; + hp_times = _agent == 1 ? hp_times : 10; + } + + int gameId = Integer.parseInt(room_list.get(5)); + GameBean gb = GameCache.getGame(gameId); + if (!enter_old) { + String open = room_list.get(3); + if (StringUtil.isEmpty(open) || open.equals("0")) { + throw new WebException(ErrorCode.ROOM_CLOSE); + } + } + + String svr = room_list.get(4); + if (svr == null || !jedis0.exists(svr)) { + svr = _getSvr(jedis0, gb); + } + if (svr == null) { + throw new WebException(ErrorCode.NO_SERVICE); + } + jedis0.hset(finalRoom, "svr", svr); + jedis0.hset(session, "room", finalRoom); + + ITObject resData = TObject.newInstance(); + resData.putUtfString("room_id", finalRoom.replace("room:", "")); + resData.putInt("hp_times", hp_times); + ITObject gameObj = gb.getTObject(); + resData.putTObject("game_info", gameObj); + resData.putInt("status", _status); + List server_ip = jedis0.hmget(svr, "ip", "port"); + resData.putUtfString("server_ip", server_ip.get(0)); + resData.putUtfString("server_port", server_ip.get(1)); + String g_str = room_list.get(6); + int groupId = 0; + if (StringUtil.isNotEmpty(g_str)) { + groupId = Integer.parseInt(g_str); + + } + String hpOnOff_str = room_list.get(7); + int hpOnOff = 0; + if (StringUtil.isNotEmpty(hpOnOff_str)) { + hpOnOff = Integer.parseInt(hpOnOff_str); + } + resData.putInt("hpOnOff", hpOnOff); + if (groupId > 0) { + resData.putInt("groupId", groupId); + String gpid = room_list.get(12); + resData.putInt("pid", StringUtil.isNotEmpty(gpid) ? Integer.parseInt(gpid) : 0); + String gm_key = "gm_" + groupId + "_" + uid; + String lev_str = Redis.use("group1_db10").hget(gm_key, "lev"); + int lev = 3; + if (StringUtil.isNotEmpty(lev_str)) { + lev = Integer.parseInt(lev_str); + } + resData.putInt("lev", lev); + } + + return resData; + } finally { + if (lock != null) + lock.unlock(false); + jedis0.close(); + } + } + + /** + * 创建房间 + * + * @param router + * @throws Exception + */ + @ActionKey(value = Protocol.JOIN_ROOM, validate = WebInterceptor.V_SESSION) + public final void joinRoom() throws Exception { + String session = this.getSession(); + ITObject reqData = this.getParams(); + try { + String room_key = "room:" + reqData.getUtfString("room_id"); + String platform = reqData.getUtfString("platform"); + sendResponse(ErrorCode._SUCC, publicJoinRoom(session, room_key, platform)); + } catch (WebException e) { + sendResponse(e.getCode(), null); + } catch (Exception e) { + e.printStackTrace(); + sendResponse(500, null); + } + + } + + private static final String _getSvr(Jedis jedis0, GameBean gb) { + String svr = null; + Set gamesvrs = gb.svr_list; + Integer conns = null; + for (String str : gamesvrs) { + String currConns = jedis0.hget(str, "conns"); + if (conns == null && currConns != null + || (conns != null && currConns != null && Integer.parseInt(currConns) < conns)) { + conns = Integer.parseInt(currConns); + svr = str; + } + } + return svr; + } + + +} diff --git a/web_login/src/main/java/com/mjlogin/util/sms/RedisKey.java b/web_login/src/main/java/com/mjlogin/util/sms/RedisKey.java new file mode 100644 index 0000000..1327a92 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/util/sms/RedisKey.java @@ -0,0 +1,8 @@ +package com.mjlogin.util.sms; + +public interface RedisKey { + /** 手机验证码 **/ + String VERIFICATION_CODE = "phone_code_"; + String VERIFICATION_CODE_SEND = "phone_code_send"; + +} diff --git a/web_login/src/main/java/com/mjlogin/util/sms/SMSThread.java b/web_login/src/main/java/com/mjlogin/util/sms/SMSThread.java new file mode 100644 index 0000000..f783480 --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/util/sms/SMSThread.java @@ -0,0 +1,64 @@ +package com.mjlogin.util.sms; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.StringUtil; + +public class SMSThread { + + private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue()); + + public static boolean sendCode(String phone) { + + String sendkey = RedisKey.VERIFICATION_CODE_SEND + phone; + String codekey = RedisKey.VERIFICATION_CODE + phone; + + try { + + if (!Redis.use().exists(sendkey) && !Redis.use().exists(codekey)) { + + Redis.use().set(sendkey, phone); + Redis.use().expire(sendkey, 120); + + threadPool.execute(new SendTask(phone)); + + return true; + } + } finally { + + } + + return false; + } + + private static final class SendTask implements Runnable { + + private final String phone; + + public SendTask(String phone) { + this.phone = phone; + } + + public void run() { + try { + + String code = SMSVerification.send(phone); + if (StringUtil.isNotEmpty(code)) { + + String key = RedisKey.VERIFICATION_CODE + phone; + Redis.use().set(key, code); + Redis.use().expire(key, 120); + } + + String sendkey = RedisKey.VERIFICATION_CODE_SEND + phone; + Redis.use().del(sendkey); + } catch (Exception e) { + + } + } + } +} diff --git a/web_login/src/main/java/com/mjlogin/util/sms/SMSVerification.java b/web_login/src/main/java/com/mjlogin/util/sms/SMSVerification.java new file mode 100644 index 0000000..7e09d7e --- /dev/null +++ b/web_login/src/main/java/com/mjlogin/util/sms/SMSVerification.java @@ -0,0 +1,120 @@ +package com.mjlogin.util.sms; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.aliyuncs.CommonRequest; +import com.aliyuncs.CommonResponse; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.exceptions.ServerException; +import com.aliyuncs.http.MethodType; +import com.aliyuncs.profile.DefaultProfile; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.taurus.core.util.StringUtil; +import com.taurus.core.util.Utils; + + +/** + * 短信验证 + */ +public class SMSVerification { + + private static Logger logger = Logger.getLogger(SMSVerification.class); + + /**短信API产品域名*/ + final static String domain = "dysmsapi.aliyuncs.com"; + /**你的accessKeyId*/ + final static String accessKeyId = "LTAI4FmrV5FnBy4EeRrk8oRh"; + /**你的accessKeySecret*/ + final static String accessKeySecret = "wdsbFdYXARh8riHg51KNw1KLjVzKmR"; + /**短信版本*/ + final static String version="2017-05-25"; + final static String regionId = "cn_beijing"; + /**action SendSms*/ + final static String action = "SendSms"; + /**短信模板*/ + final static String templateCode = "SMS_185575736"; + /**短信签名*/ + final static String signName = "找团长"; + + public static String hidePhone(String phone) { + String phone_4 = phone.substring(3, 7); + phone = phone.replace(phone_4, "****"); + return phone; + } + + /** + * 获取一个指定长度的N位随机数 + */ + public static int getFixLenthString(int length) { + int tempInt = Utils.rand.nextInt((int) Math.pow(10, length)); + if (tempInt < 100000) { + return getFixLenthString(length); + } + return tempInt; + } + + // 生成短信验证码 + private static String verificationCode() { + return getFixLenthString(6)+""; + } + + public static void main(String[] args) { + // send("13267171517");template_id parameter_2 + System.out.println(isValidPhone("18610826573")); + } + + public static String send(String phoneNumber) { + DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret); + IAcsClient client = new DefaultAcsClient(profile); + + String code = verificationCode(); + CommonRequest request = new CommonRequest(); + request.setMethod(MethodType.POST); + request.setDomain(domain); + request.setVersion(version); + request.setAction(action); + request.putQueryParameter("RegionId", regionId); + request.putQueryParameter("PhoneNumbers", phoneNumber); + request.putQueryParameter("SignName", signName); + request.putQueryParameter("TemplateCode", templateCode); + request.putQueryParameter("TemplateParam", "{\"code\":\""+code+"\"}"); + try { + CommonResponse response = client.getCommonResponse(request); + String data = response.getData(); + if(StringUtil.isNotEmpty(data)) { + ITObject tem = TObject.newFromJsonData(data); + String str_code = tem.getUtfString("Code"); + if(str_code.equals("OK")) { + return code; + } + } + } catch (ServerException e) { + e.printStackTrace(); + } catch (ClientException e) { + e.printStackTrace(); + } + return null; + } + + + + /** + * 是否有效手机号码 + */ + public static boolean isValidPhone(String phoneNumber) { + boolean isValidPhone = false; + String regex = "^((13[0-9])|(14[5|7|9])|(15([0-3]|[5-9]))|(17[01235678])|(18[0-9])|(19[189]))\\d{8}$"; + if (phoneNumber.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNumber); + isValidPhone = m.matches(); + } + return isValidPhone; + } + +} diff --git a/web_login/src/main/webapp/WEB-INF/web.xml b/web_login/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..b0b7f3d --- /dev/null +++ b/web_login/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ + + + + + taurus-web + com.taurus.web.WebFilter + + main + com.mjlogin.MainServer + + + + + taurus-web + /* + + diff --git a/web_login/src/main/webapp/config/log4j.properties b/web_login/src/main/webapp/config/log4j.properties new file mode 100644 index 0000000..6786dba --- /dev/null +++ b/web_login/src/main/webapp/config/log4j.properties @@ -0,0 +1,20 @@ + +log4j.rootLogger = INFO,consoleAppender,fileAppender + +# ConsoleAppender +log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender +log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n + + +# Regular FileAppender +log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log +log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n +log4j.appender.fileAppender.Encoding=UTF-8 +log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd +log4j.appender.dailyFile.Append=true + +# The file is rolled over very day +log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd \ No newline at end of file diff --git a/web_login/src/main/webapp/config/taurus-core.xml b/web_login/src/main/webapp/config/taurus-core.xml new file mode 100644 index 0000000..0c9036a --- /dev/null +++ b/web_login/src/main/webapp/config/taurus-core.xml @@ -0,0 +1,96 @@ + + + log4j.properties + + + database + com.taurus.core.plugin.database.DataBasePlugin + + + + 100 + + 10 + + 180000 + + select 1 + + 10000 + + 60000 + + + + false + true + utf-8 + + UTC + + true + + 250 + + 2048 + + + + + + db1 + com.mysql.cj.jdbc.Driver + jdbc:mysql://123.207.203.115:8060/wb_game + wb_game + 363b76546c + + + + + + redis + com.taurus.core.plugin.redis.RedisPlugin + + + + 80 + + 20 + + 5 + + -1 + + true + + true + + true + + 100 + + 60000 + + 30000 + + 1800000 + + true + + + + + + + + + + + \ No newline at end of file diff --git a/web_login/src/test/java/web_login/MainWebLogin.java b/web_login/src/test/java/web_login/MainWebLogin.java new file mode 100644 index 0000000..013c95e --- /dev/null +++ b/web_login/src/test/java/web_login/MainWebLogin.java @@ -0,0 +1,9 @@ +package web_login; + +import com.taurus.web.JettyServer; + +public class MainWebLogin { + public static void main(String[] args) { + new JettyServer("src/main/webapp",4011,"/").start(); + } +}