[server] GameManager restore

This commit is contained in:
2018-03-02 16:08:53 +03:00
parent 0565eec871
commit 73c46d821e
9 changed files with 119 additions and 137 deletions

View File

@@ -20,6 +20,7 @@ const build = () => function build() {
'orm', 'orm',
'haxework:git', 'haxework:git',
'haxe-crypto', 'haxe-crypto',
'yield',
], ],
cp: [ cp: [
'src/common/haxe', 'src/common/haxe',

View File

@@ -3,8 +3,12 @@ package ru.m.tankz;
import haxework.provider.Provider; import haxework.provider.Provider;
import haxework.resources.IResources; import haxework.resources.IResources;
import haxework.resources.Resources; import haxework.resources.Resources;
import ru.m.tankz.bundle.ConfigBundle;
import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.bundle.ILevelBundle;
import ru.m.tankz.bundle.LevelBundle; import ru.m.tankz.bundle.LevelBundle;
import ru.m.tankz.control.ClientControlFactory;
import ru.m.tankz.control.IControlFactory;
import ru.m.tankz.game.ClassicGame; import ru.m.tankz.game.ClassicGame;
import ru.m.tankz.game.DotaGame; import ru.m.tankz.game.DotaGame;
import ru.m.tankz.game.Game; import ru.m.tankz.game.Game;
@@ -19,11 +23,12 @@ class Init {
public static function init():Void { public static function init():Void {
Provider.setFactory(IResources, Resources); Provider.setFactory(IResources, Resources);
Provider.setFactory(ILevelBundle, LevelBundle); Provider.setFactory(ILevelBundle, LevelBundle);
Provider.setFactory(ILevelBundle, LevelBundle); Provider.setFactory(IConfigBundle, ConfigBundle);
Provider.setFactory(SaveStorage, SaveStorage); Provider.setFactory(SaveStorage, SaveStorage);
Provider.setFactory(UserStorage, UserStorage); Provider.setFactory(UserStorage, UserStorage);
Provider.setFactory(SoundManager, SoundManager); Provider.setFactory(SoundManager, SoundManager);
Provider.setFactory(NetworkManager, NetworkManager); Provider.setFactory(NetworkManager, NetworkManager);
Provider.setFactory(IControlFactory, ClientControlFactory);
Provider.setFactory(Game, ClassicGame, ClassicGame.TYPE); Provider.setFactory(Game, ClassicGame, ClassicGame.TYPE);
Provider.setFactory(Game, DotaGame, DotaGame.TYPE); Provider.setFactory(Game, DotaGame, DotaGame.TYPE);
} }

View File

@@ -0,0 +1,23 @@
package ru.m.tankz.control;
import ru.m.tankz.game.Player;
import ru.m.tankz.bot.BotControl;
class ClientControlFactory implements IControlFactory {
private var humanControlIndex:Int;
public function new() {
humanControlIndex = 0;
}
public function build(player:Player):Control {
return switch (player.config.control) {
case Control.HUMAN: new HumanControl(player.id, humanControlIndex++);
case Control.BOT: new BotControl(player.id);
case Control.NONE: null;
case _: throw 'Unsupported control type: "${player.config.control}"';
}
}
}

View File

@@ -0,0 +1,8 @@
package ru.m.tankz.control;
import ru.m.tankz.game.Player;
interface IControlFactory {
public function build(player:Player):Control;
}

View File

@@ -0,0 +1,11 @@
package ru.m.tankz.control;
import ru.m.tankz.game.Player;
class NoneControlFactory implements IControlFactory {
public function build(player:Player):Control {
return null;
}
}

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.game; package ru.m.tankz.game;
import ru.m.tankz.control.IControlFactory;
import ru.m.tankz.game.GameSave.PlayerSave; import ru.m.tankz.game.GameSave.PlayerSave;
import haxe.ds.Option; import haxe.ds.Option;
import haxe.Timer; import haxe.Timer;
@@ -8,12 +9,10 @@ import promhx.Deferred;
import promhx.Stream; import promhx.Stream;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.geom.Point; import ru.m.geom.Point;
import ru.m.tankz.bot.BotControl;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.bundle.ILevelBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.control.HumanControl;
import ru.m.tankz.core.Bonus; import ru.m.tankz.core.Bonus;
import ru.m.tankz.core.Eagle; import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Entity; import ru.m.tankz.core.Entity;
@@ -88,19 +87,14 @@ class Game implements EngineListener {
points = level.points != null ? level.points : config.points; points = level.points != null ? level.points : config.points;
engine.map.setData(level.data); engine.map.setData(level.data);
teams = new Map<TeamId, Team>(); teams = new Map<TeamId, Team>();
var humanControlIndex = 0; var controlFactory:IControlFactory = Provider.build(IControlFactory);
for (teamConfig in preset.teams) { for (teamConfig in preset.teams) {
var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id); var teamPoints = points.filter(function(p:SpawnPoint) return p.team == teamConfig.id);
var team:Team = new Team(teamConfig, teamPoints, save); var team:Team = new Team(teamConfig, teamPoints, save);
teams[team.id] = team; teams[team.id] = team;
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
if (player.config.control != null) { if (player.config.control != null) {
var control = switch (player.config.control) { var control = controlFactory.build(player);
case Control.HUMAN: new HumanControl(player.id, humanControlIndex++);
case Control.BOT: new BotControl(player.id);
case Control.NONE: null;
case _: throw 'Unsupported control type: "${player.config.control}"';
}
L.d(TAG, 'control(${player.id} - ${control})'); L.d(TAG, 'control(${player.id} - ${control})');
if (control != null) { if (control != null) {
player.control = control; player.control = control;

View File

@@ -1,11 +1,20 @@
package ru.m.tankz.server.game; package ru.m.tankz.server.game;
import ru.m.tankz.game.GameSave;
import ru.m.tankz.proto.pack.StartGameResponse;
import ru.m.tankz.game.ClassicGame;
import ru.m.tankz.proto.pack.LeaveGameResponse;
import ru.m.tankz.proto.pack.JoinGameResponse;
import ru.m.tankz.proto.pack.ListGameResponse;
import ru.m.tankz.proto.pack.CreateGameResponse;
import ru.m.tankz.proto.pack.Response;
import ru.m.tankz.game.Game as RunGame;
import ru.m.tankz.proto.core.GameState; import ru.m.tankz.proto.core.GameState;
import ru.m.tankz.proto.core.Game; import ru.m.tankz.proto.core.Game;
import ru.m.tankz.proto.core.User;
import ru.m.tankz.server.session.Thread; import ru.m.tankz.server.session.Thread;
import ru.m.tankz.engine.Engine;
import ru.m.tankz.server.session.Session; import ru.m.tankz.server.session.Session;
import protohx.Message;
/** /**
* *
@@ -44,13 +53,12 @@ class GameManager {
public static var byGameId:Map<Int, GameManager> = new Map<Int, GameManager>(); public static var byGameId:Map<Int, GameManager> = new Map<Int, GameManager>();
public static var byPersonId:Map<String, GameManager> = new Map<String, GameManager>(); public static var byPersonId:Map<String, GameManager> = new Map<String, GameManager>();
public static var subscribers:Map<Int, Bool> = new Map<Int, Bool>(); public static var subscribers:Map<String, Bool> = new Map<String, Bool>();
private static var idCounter:Int = 0; private static var idCounter:Int = 0;
public var game(default, null):Game; public var game(default, null):Game;
public var runGame(default, null):RunGame;
public var engine(default, null):Engine;
private var timer:NekoTimer; private var timer:NekoTimer;
@@ -64,7 +72,7 @@ class GameManager {
game.addPlayers(creator); game.addPlayers(creator);
byGameId.set(game.id, this); byGameId.set(game.id, this);
byPersonId.set(creator.uuid, this); byPersonId.set(creator.uuid, this);
broadcast(new CreateGameResponse().setGame(game)); broadcast(new Response().setCreateGame(new CreateGameResponse().setGame(game)));
broadcastGames(); broadcastGames();
} }
@@ -73,32 +81,32 @@ class GameManager {
} }
public function broadcastGames() { public function broadcastGames() {
var packet = new GamesResponse().setGames(getReadyGames()); var packet = new Response().setListGame(new ListGameResponse().setGames(getReadyGames()));
for (personId in subscribers.keys()) { for (personId in subscribers.keys()) {
var session = Session.sessions.get(personId); var session:Session = Session.sessions.get(personId);
session.send(packet); session.send(packet);
} }
} }
public function broadcast(packet:Message) { public function broadcast(packet:Response) {
for (player in game.players) { for (player in game.players) {
var session = Session.sessions.get(player.uuid); var session:Session = Session.sessions.get(player.uuid);
session.send(packet); session.send(packet);
} }
} }
public function join(person:Person) { public function join(user:User) {
game.addPersons(person); game.addPlayers(user);
byPersonId.set(person.id, this); byPersonId.set(user.uuid, this);
broadcast(new JoinGameResponse().setGame(game)); broadcast(new Response().setJoinGame(new JoinGameResponse().setGame(game)));
} }
public function leave(person:Person) { public function leave(user:User) {
game.setPersons(game.persons.filter(function(p) return p.id != person.id)); game.setPlayers(game.players.filter(function(p) return p.uuid != user.uuid));
byPersonId.remove(person.id); byPersonId.remove(user.uuid);
var packet = new LeaveGameResponse().setGame(game); var packet = new Response().setLeaveGame(new LeaveGameResponse().setGame(game));
Session.sessions.get(person.id).send(packet); Session.sessions.get(user.uuid).send(packet);
if (game.persons.length == 0/* || person.id == game.creator.id*/) { if (game.players.length == 0/* || person.id == game.creator.id*/) {
stop(); stop();
} else { } else {
broadcast(packet); broadcast(packet);
@@ -107,67 +115,33 @@ class GameManager {
public function start() { public function start() {
game.setState(GameState.STARTED); game.setState(GameState.STARTED);
engine = new Engine(); runGame = new ClassicGame();
engine.init(DEFAULT.CONFIG); runGame.start(new GameSave({type: ClassicGame.TYPE, presetId: ClassicGame.PLAYER1}));
var changes = engine.initTanks(game.persons);
timer = new NekoTimer(30); timer = new NekoTimer(30);
timer.run = update; timer.run = update;
broadcast(new StartGameResponse().setGame(game)); broadcast(new Response().setStartGame(new StartGameResponse().setGame(game)));
broadcast(new GameUpdateResponse().setChanges(changes));
} }
public function stop() { public function stop() {
game.setState(GameState.ENDED); game.setState(GameState.ENDED);
game.setPersons([]); game.setPlayers([]);
byGameId.remove(game.id); byGameId.remove(game.id);
for (p in game.persons) byPersonId.remove(p.id); for (p in game.players) byPersonId.remove(p.uuid);
if (timer != null) { if (timer != null) {
timer.stop(); timer.stop();
timer = null; timer = null;
} }
broadcast(new LeaveGameResponse().setGame(game)); broadcast(new Response().setLeaveGame(new LeaveGameResponse().setGame(game)));
broadcastGames(); broadcastGames();
} }
public function action(person:Person, action:GameActionRequest) {
var tank = engine.tanks.get(person.id);
switch (action.type) {
case GameActionType.SHOT:
var bullet = tank.shot();
if (bullet != null) {
engine.mobileEntities.set(bullet.id, bullet);
changes.push(new GameChange()
.setType(GameChangeType.APPEND)
.setObjectType(GameObjectType.BULLET)
.setPersonId(bullet.personId)
.setObjectId(bullet.id)
.setX(bullet.x)
.setY(bullet.y)
.setDirectionX(bullet.direction.x)
.setDirectionY(bullet.direction.y)
);
}
case GameActionType.MOVE:
tank.move(Direction.from(action.directionX, action.directionY));
changes.push(new GameChange()
.setType(GameChangeType.DIRECTION)
.setObjectType(GameObjectType.TANK)
.setPersonId(tank.personId)
.setObjectId(tank.id)
.setDirectionX(tank.direction.x)
.setDirectionY(tank.direction.y)
);
case GameActionType.STOP:
tank.stop();
}
}
private function update() { private function update() {
var changes = engine.update(); runGame.engine.update();
/*var changes = engine.update();
changes = this.changes.concat(changes); changes = this.changes.concat(changes);
this.changes = []; this.changes = [];
if (changes.length > 0) { if (changes.length > 0) {
broadcast(new GameUpdateResponse().setChanges(changes)); broadcast(new GameUpdateResponse().setChanges(changes));
} }*/
} }
} }

View File

@@ -1,25 +1,28 @@
package ru.m.tankz.server.session; package ru.m.tankz.server.session;
import ru.m.tankz.proto.pack.LeaveGameRequest; import com.hurlant.crypto.extra.UUID;
import ru.m.tankz.proto.pack.LeaveGameResponse;
import ru.m.tankz.proto.pack.LogoutResponse;
import ru.m.tankz.proto.pack.LogoutRequest;
import haxe.io.Bytes; import haxe.io.Bytes;
import ru.m.connect.IConnection; import ru.m.connect.IConnection;
import ru.m.connect.neko.NekoConnection; import ru.m.connect.neko.NekoConnection;
import ru.m.connect.neko.NekoWebConnection; import ru.m.connect.neko.NekoWebConnection;
import ru.m.tankz.proto.core.Game;
import ru.m.tankz.proto.core.User; import ru.m.tankz.proto.core.User;
import ru.m.tankz.proto.pack.CreateGameRequest; import ru.m.tankz.proto.pack.CreateGameRequest;
import ru.m.tankz.proto.pack.CreateGameResponse; import ru.m.tankz.proto.pack.CreateGameResponse;
import ru.m.tankz.proto.pack.JoinGameRequest; import ru.m.tankz.proto.pack.JoinGameRequest;
import ru.m.tankz.proto.pack.JoinGameResponse; import ru.m.tankz.proto.pack.JoinGameResponse;
import ru.m.tankz.proto.pack.LeaveGameRequest;
import ru.m.tankz.proto.pack.LeaveGameResponse;
import ru.m.tankz.proto.pack.ListGameRequest; import ru.m.tankz.proto.pack.ListGameRequest;
import ru.m.tankz.proto.pack.ListGameResponse; import ru.m.tankz.proto.pack.ListGameResponse;
import ru.m.tankz.proto.pack.LoginRequest; import ru.m.tankz.proto.pack.LoginRequest;
import ru.m.tankz.proto.pack.LoginResponse; import ru.m.tankz.proto.pack.LoginResponse;
import ru.m.tankz.proto.pack.LogoutRequest;
import ru.m.tankz.proto.pack.LogoutResponse;
import ru.m.tankz.proto.pack.Request; import ru.m.tankz.proto.pack.Request;
import ru.m.tankz.proto.pack.Response; import ru.m.tankz.proto.pack.Response;
import ru.m.tankz.proto.pack.StartGameRequest;
import ru.m.tankz.proto.pack.StartGameResponse;
import ru.m.tankz.server.game.GameManager;
import sys.net.Socket; import sys.net.Socket;
@@ -66,96 +69,59 @@ class Session {
public function onRequest(request:Request):Void { public function onRequest(request:Request):Void {
if (request.hasLogin()) { if (request.hasLogin()) {
connection.send(new Response().setLogin(login(request.login))); send(new Response().setLogin(login(request.login)));
} else if (request.hasLogout()) { } else if (request.hasLogout()) {
connection.send(new Response().setLogout(logout(request.logout))); send(new Response().setLogout(logout(request.logout)));
} else if (request.hasListGame()) { } else if (request.hasListGame()) {
connection.send(new Response().setListGame(listGame(request.listGame))); send(new Response().setListGame(listGame(request.listGame)));
} else if (request.hasCreateGame()) { } else if (request.hasCreateGame()) {
connection.send(new Response().setCreateGame(createGame(request.createGame))); send(new Response().setCreateGame(createGame(request.createGame)));
} else if (request.hasJoinGame()) { } else if (request.hasJoinGame()) {
connection.send(new Response().setJoinGame(joinGame(request.joinGame))); send(new Response().setJoinGame(joinGame(request.joinGame)));
} else if (request.hasLeaveGame()) { } else if (request.hasLeaveGame()) {
connection.send(new Response().setLeaveGame(leaveGame(request.leaveGame))); send(new Response().setLeaveGame(leaveGame(request.leaveGame)));
} }
} }
private function login(request:LoginRequest):LoginResponse { private function login(request:LoginRequest):LoginResponse {
user = new User() user = new User()
.setUuid(request.uuid != null ? request.uuid : 'xxx') .setUuid(request.uuid != null ? request.uuid : UUID.generateRandom().toString())
.setName(request.name); .setName(request.name);
sessions.set(user.uuid, this); sessions.set(user.uuid, this);
GameManager.subscribers.set(user.uuid, true);
return new LoginResponse().setUser(user); return new LoginResponse().setUser(user);
} }
private function logout(request:LogoutRequest):LogoutResponse { private function logout(request:LogoutRequest):LogoutResponse {
GameManager.subscribers.remove(user.uuid);
user = null; user = null;
return new LogoutResponse(); return new LogoutResponse();
} }
private function listGame(request:ListGameRequest):ListGameResponse { private function listGame(request:ListGameRequest):ListGameResponse {
return new ListGameResponse().setGames([ return new ListGameResponse().setGames(GameManager.getReadyGames());
new Game().setId(1).setType('test').setPlayers([new User().setUuid('test').setName('test')])
]);
} }
private function createGame(request:CreateGameRequest):CreateGameResponse { private function createGame(request:CreateGameRequest):CreateGameResponse {
return new CreateGameResponse().setGame( var gameManager:GameManager = new GameManager(user);
new Game().setId(2).setType(request.type).setPlayers([user]) return new CreateGameResponse().setGame(gameManager.game);
);
} }
private function joinGame(request:JoinGameRequest):JoinGameResponse { private function joinGame(request:JoinGameRequest):JoinGameResponse {
return new JoinGameResponse().setGame( var gameManager:GameManager = GameManager.byGameId.get(request.gameId);
new Game().setId(request.gameId).setType('test').setPlayers([ gameManager.join(user);
new User().setUuid('test').setName('test'), return new JoinGameResponse().setGame(gameManager.game);
user
])
);
} }
private function leaveGame(request:LeaveGameRequest):LeaveGameResponse { private function leaveGame(request:LeaveGameRequest):LeaveGameResponse {
return new LeaveGameResponse(); var gameManager:GameManager = GameManager.byPersonId.get(user.uuid);
gameManager.leave(user);
return new LeaveGameResponse().setGame(gameManager.game);
} }
/*public function onPersonSelectRequest(packet:PersonSelectRequest):Void { private function startGame(request:StartGameRequest):StartGameResponse {
var db = new DbProvider(); var gameManager:GameManager = GameManager.byPersonId.get(user.uuid);
var person = db.getPerson(packet.personId); gameManager.start();
if (person != null) { return new StartGameResponse().setGame(gameManager.game);
this.person = person;
sessions.set(person.id, this);
connection.send(new PersonSelectResponse().setPerson(person));
} else {
connection.send(new ErrorResponse().setCode(404).setMessage("Person not found"));
} }
}
public function onGamesSubscribeRequest(packet:GamesSubscribeRequest):Void {
GameManager.subscribers.set(person.id, true);
connection.send(new GamesResponse().setGames(GameManager.getReadyGames()));
}
public function onGamesUnSubscribeRequest(packet:GamesUnSubscribeRequest):Void {
GameManager.subscribers.remove(person.id);
}
public function onCreateGameRequest(packet:CreateGameRequest):Void {
new GameManager(person);
}
public function onJoinGameRequest(packet:JoinGameRequest):Void {
GameManager.byGameId.get(packet.gameId).join(person);
}
public function onLeaveGameRequest(packet:LeaveGameRequest):Void {
GameManager.byPersonId.get(person.id).leave(person);
}
public function onStartGameRequest(packet:StartGameRequest):Void {
GameManager.byPersonId.get(person.id).start();
}
public function onGameActionRequest(packet:GameActionRequest):Void {
GameManager.byPersonId.get(person.id).action(person, packet);
}*/
} }