From 94b3a94cbb8a82a03bbdeff3d1683b9b6d3e4da1 Mon Sep 17 00:00:00 2001 From: shmyga Date: Mon, 10 Jun 2019 16:12:08 +0300 Subject: [PATCH] [server] join game after relogin --- .../display/DisplayObjectContainerExtender.hx | 14 ++++++++ .../haxe/ru/m/tankz/network/NetworkGame.hx | 4 +-- .../haxe/ru/m/tankz/network/NetworkManager.hx | 9 +++-- src/client/haxe/ru/m/tankz/render/Render.hx | 5 +-- src/common/proto/game.proto | 5 +++ src/common/proto/pack.proto | 6 ++-- .../ru/m/tankz/server/game/GameManager.hx | 7 ++-- .../ru/m/tankz/server/game/IGameManager.hx | 1 + .../haxe/ru/m/tankz/server/game/ServerGame.hx | 17 ++++++++-- .../ru/m/tankz/server/session/GameSession.hx | 34 ++++++++++++------- 10 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 src/client/haxe/ru/m/display/DisplayObjectContainerExtender.hx diff --git a/src/client/haxe/ru/m/display/DisplayObjectContainerExtender.hx b/src/client/haxe/ru/m/display/DisplayObjectContainerExtender.hx new file mode 100644 index 0000000..ab6fe56 --- /dev/null +++ b/src/client/haxe/ru/m/display/DisplayObjectContainerExtender.hx @@ -0,0 +1,14 @@ +package ru.m.display; + +import flash.display.DisplayObject; +import flash.display.DisplayObjectContainer; + +class DisplayObjectContainerExtender { + + public static function removeChildSafety(self:DisplayObjectContainer, child:DisplayObject):DisplayObject { + if (self.contains(child)) { + return self.removeChild(child); + } + return null; + } +} diff --git a/src/client/haxe/ru/m/tankz/network/NetworkGame.hx b/src/client/haxe/ru/m/tankz/network/NetworkGame.hx index e6f34f7..c9c0923 100644 --- a/src/client/haxe/ru/m/tankz/network/NetworkGame.hx +++ b/src/client/haxe/ru/m/tankz/network/NetworkGame.hx @@ -22,8 +22,8 @@ class NetworkGame extends Game { } private function onGameEventProto(game:GameEventResponse):Void { - var time = game.time; - var eventStr = game.event; + var time = game.event.time; + var eventStr = game.event.event; var event:GameEvent = Unserializer.run(eventStr); gameEventSignal.emit(event); } diff --git a/src/client/haxe/ru/m/tankz/network/NetworkManager.hx b/src/client/haxe/ru/m/tankz/network/NetworkManager.hx index 13ae471..8d945de 100644 --- a/src/client/haxe/ru/m/tankz/network/NetworkManager.hx +++ b/src/client/haxe/ru/m/tankz/network/NetworkManager.hx @@ -1,5 +1,6 @@ package ru.m.tankz.network; +import ru.m.tankz.proto.game.GameEventProto; import ru.m.tankz.proto.room.SlotProto; import ru.m.tankz.proto.room.SlotRequest; import haxe.Serializer; @@ -106,9 +107,11 @@ class NetworkManager { } public function action(tankId:Int, action:TankAction):Void { - connection.send(new Request().setGameEvent(new GameEventRequest().setTime(0).setEvent( - Serializer.run(GameEvent.ACTION(tankId, action)) - ))); + connection.send(new Request().setGameEvent(new GameEventRequest().setEvent( + new GameEventProto().setTime(0).setEvent( + Serializer.run(GameEvent.ACTION(tankId, action)) + ))) + ); } private function connect():Void { diff --git a/src/client/haxe/ru/m/tankz/render/Render.hx b/src/client/haxe/ru/m/tankz/render/Render.hx index 991b1e0..bab93d5 100755 --- a/src/client/haxe/ru/m/tankz/render/Render.hx +++ b/src/client/haxe/ru/m/tankz/render/Render.hx @@ -21,6 +21,7 @@ import ru.m.tankz.render.item.EagleRenderItem; import ru.m.tankz.render.item.IRenderItem; import ru.m.tankz.render.item.TankRenderItem; import ru.m.tankz.Type; +using ru.m.display.DisplayObjectContainerExtender; class Render extends SpriteView implements IRender { @@ -237,7 +238,7 @@ class Render extends SpriteView implements IRender { return animate.play().then(function(animate:Animate):Void { // ToDo: clean animates on reset if (upperLayer.contains(animate)) { - upperLayer.removeChild(animate); + upperLayer.removeChildSafety(animate); } animate.dispose(); }); @@ -252,6 +253,6 @@ class Render extends SpriteView implements IRender { view.x = point.x - view.width / 2; view.y = point.y - view.height / 2; upperLayer.addChild(view.content); - Timer.delay(function() upperLayer.removeChild(view.content), 1000); + Timer.delay(function() upperLayer.removeChildSafety(view.content), 1000); } } diff --git a/src/common/proto/game.proto b/src/common/proto/game.proto index 3ed9f3f..ca59ccd 100644 --- a/src/common/proto/game.proto +++ b/src/common/proto/game.proto @@ -1,3 +1,8 @@ syntax = "proto3"; package ru.m.tankz.proto.game; + +message GameEventProto { + int32 time = 1; + string event = 2; +} diff --git a/src/common/proto/pack.proto b/src/common/proto/pack.proto index 1c925ed..e905926 100644 --- a/src/common/proto/pack.proto +++ b/src/common/proto/pack.proto @@ -25,13 +25,11 @@ message LogoutRequest {} message LogoutResponse {} message GameEventRequest { - int32 time = 1; - string event = 2; + ru.m.tankz.proto.game.GameEventProto event = 1; } message GameEventResponse { - int32 time = 1; - string event = 2; + ru.m.tankz.proto.game.GameEventProto event = 1; } message Request { diff --git a/src/server/haxe/ru/m/tankz/server/game/GameManager.hx b/src/server/haxe/ru/m/tankz/server/game/GameManager.hx index 7aafacb..989cea5 100644 --- a/src/server/haxe/ru/m/tankz/server/game/GameManager.hx +++ b/src/server/haxe/ru/m/tankz/server/game/GameManager.hx @@ -1,14 +1,13 @@ package ru.m.tankz.server.game; -import ru.m.tankz.config.Config.PlayerControl; -import ru.m.tankz.proto.room.RoomSlotProto; -import ru.m.tankz.proto.room.SlotProto; -import ru.m.tankz.proto.room.RoomProto; import ru.m.tankz.game.GameEvent; import ru.m.tankz.game.IGame.GameListener; import ru.m.tankz.game.IGame; import ru.m.tankz.proto.core.GameProto; import ru.m.tankz.proto.core.UserProto; +import ru.m.tankz.proto.room.RoomProto; +import ru.m.tankz.proto.room.RoomSlotProto; +import ru.m.tankz.proto.room.SlotProto; import ru.m.tankz.server.game.IGameManager; class _GameListener implements GameListener { diff --git a/src/server/haxe/ru/m/tankz/server/game/IGameManager.hx b/src/server/haxe/ru/m/tankz/server/game/IGameManager.hx index ca5acba..891c99f 100644 --- a/src/server/haxe/ru/m/tankz/server/game/IGameManager.hx +++ b/src/server/haxe/ru/m/tankz/server/game/IGameManager.hx @@ -23,6 +23,7 @@ interface IGameManager { public var games(default, null):Array; public var gamesById(default, null):Map; public var gamesByCreator(default, null):Map; + public var gamesByUser(default, null):Map; private var createSignal(default, null):Signal; private var changeSignal(default, null):Signal2; diff --git a/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx b/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx index c8102a4..3e7b9e9 100644 --- a/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx +++ b/src/server/haxe/ru/m/tankz/server/game/ServerGame.hx @@ -28,12 +28,23 @@ class ServerGame extends GameRunner { return room.game.id; } + public function contains(user:UserProto):Bool { + for (slot in room.slots) { + if (slot.hasUser() && slot.user.uuid == user.uuid) { + return true; + } + } + return false; + } + public function join(user:UserProto):Void { - leave(user); - room.users.push(user); + if (!contains(user)) { + room.users.push(user); + } } public function slot(user:UserProto, slot:SlotProto):Void { + join(user); for (s in room.slots) { if (s.hasUser() && s.user.uuid == user.uuid) { s.clearUser(); @@ -73,6 +84,7 @@ class ServerGame extends GameRunner { var result = []; result.push(EventUtil.buildBricksSpawn(engine.map)); result = result.concat(EventUtil.buildCellsDestroyed(engine.map)); + result.push(START(state)); for (entity in engine.entities) { switch EntityTypeResolver.of(entity) { case EAGLE(eagle): result.push(EventUtil.buildEagleSpawn(eagle)); @@ -82,7 +94,6 @@ class ServerGame extends GameRunner { case CELL(_): } } - result.push(START(state)); return result; } } diff --git a/src/server/haxe/ru/m/tankz/server/session/GameSession.hx b/src/server/haxe/ru/m/tankz/server/session/GameSession.hx index da26f54..387eacc 100644 --- a/src/server/haxe/ru/m/tankz/server/session/GameSession.hx +++ b/src/server/haxe/ru/m/tankz/server/session/GameSession.hx @@ -1,5 +1,6 @@ package ru.m.tankz.server.session; +import ru.m.tankz.proto.game.GameEventProto; import com.hurlant.crypto.extra.UUID; import com.hurlant.crypto.prng.Random; import haxe.Serializer; @@ -57,15 +58,26 @@ class GameSession extends ProtoSession implements GameManager } } - private function logout():Void { + private function logout(leave:Bool = true):Void { gameId = -1; gameManager.disconnect(this); - if (user != null) { + if (user != null && leave) { gameManager.leave(user); user = null; } } + private function join(gameId:Int, restore:Bool):Void { + this.gameId = gameId; + gameManager.join(gameId, user); + var game = gameManager.gamesById[gameId]; + if (restore && game.room.game.started) { + for (event in game.restore()) { + send(new Response().setGameEvent(new GameEventResponse().setEvent(new GameEventProto().setTime(0).setEvent(Serializer.run(event))))); + } + } + } + override private function onRequest(request:Request):Void { #if proto_debug L.d(TAG, '$tag onRequest: ${request}'); #end try { @@ -79,6 +91,9 @@ class GameSession extends ProtoSession implements GameManager .setName(request.login.name); gameManager.connect(this); send(new Response().setLogin(new LoginResponse().setUser(user))); + if (gameManager.gamesByUser.exists(user.uuid)) { + join(gameManager.gamesByUser[user.uuid].id, false); + } // logout } else if (request.hasLogout()) { logout(); @@ -90,14 +105,7 @@ class GameSession extends ProtoSession implements GameManager gameId = game.id; send(new Response().setRoom(new RoomResponse().setRoom(game.room))); } else if (request.room.hasJoin()) { - gameId = request.room.join.gameId; - gameManager.join(gameId, user); - var game = gameManager.gamesById[gameId]; - if (request.room.join.restore && game.room.game.started) { - for (event in game.restore()) { - send(new Response().setGameEvent(new GameEventResponse().setTime(0).setEvent(Serializer.run(event)))); - } - } + join(request.room.join.gameId, request.room.join.restore); } else if (request.room.hasLeave()) { gameManager.leave(user); } else if (request.room.hasSlot()) { @@ -113,7 +121,7 @@ class GameSession extends ProtoSession implements GameManager } } else if (request.hasGameEvent()) { if (gameManager.gamesById.exists(gameId)) { - var event:GameEvent = Unserializer.run(request.gameEvent.event); + var event:GameEvent = Unserializer.run(request.gameEvent.event.event); gameManager.gamesById[gameId].gameEventSignal.emit(event); } } @@ -125,7 +133,7 @@ class GameSession extends ProtoSession implements GameManager override public function disconnect():Void { L.d(TAG, '$tag disconnect'); - logout(); + logout(false); super.disconnect(); } @@ -165,7 +173,7 @@ class GameSession extends ProtoSession implements GameManager public function onEvent(game:ServerGame, event:GameEvent):Void { if (gameId == game.id) { - send(new Response().setGameEvent(new GameEventResponse().setTime(0).setEvent(Serializer.run(event)))); + send(new Response().setGameEvent(new GameEventResponse().setEvent(new GameEventProto().setTime(0).setEvent(Serializer.run(event))))); } } }