[client] update proto
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
package ru.m.tankz;
|
package ru.m.tankz;
|
||||||
|
|
||||||
import flash.events.KeyboardEvent;
|
import openfl.Assets;
|
||||||
import flash.text.Font;
|
import ru.m.tankz.frame.StartFrame;
|
||||||
import flash.ui.Keyboard;
|
import flash.ui.Keyboard;
|
||||||
|
import flash.events.KeyboardEvent;
|
||||||
|
import ru.m.tankz.proto.pack.Response;
|
||||||
|
import ru.m.tankz.proto.pack.Request;
|
||||||
|
import flash.text.Font;
|
||||||
import haxework.gui.frame.IFrameSwitcher;
|
import haxework.gui.frame.IFrameSwitcher;
|
||||||
import haxework.gui.Root;
|
import haxework.gui.Root;
|
||||||
import haxework.gui.VGroupView;
|
import haxework.gui.VGroupView;
|
||||||
@@ -11,10 +15,7 @@ import haxework.log.TraceLogger;
|
|||||||
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 openfl.Assets;
|
|
||||||
import ru.m.connect.IConnection;
|
import ru.m.connect.IConnection;
|
||||||
import ru.m.tankz.frame.StartFrame;
|
|
||||||
import ru.m.tankz.PacketBuilder;
|
|
||||||
#if flash import haxework.log.JSLogger; #end
|
#if flash import haxework.log.JSLogger; #end
|
||||||
#if debug import haxework.log.SocketLogger; #end
|
#if debug import haxework.log.SocketLogger; #end
|
||||||
|
|
||||||
@@ -23,9 +24,7 @@ interface ClientLayout {
|
|||||||
var switcher(default, null):IFrameSwitcher;
|
var switcher(default, null):IFrameSwitcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:template('ru/m/tankz/Client.yaml', 'ru/m/tankz/Style.yaml')
|
class Client {
|
||||||
class Client extends VGroupView implements ClientLayout implements ViewBuilder {
|
|
||||||
|
|
||||||
private static inline var TAG = 'Tankz';
|
private static inline var TAG = 'Tankz';
|
||||||
|
|
||||||
public static function main() {
|
public static function main() {
|
||||||
@@ -41,29 +40,35 @@ class Client extends VGroupView implements ClientLayout implements ViewBuilder {
|
|||||||
L.d(TAG, 'Debug: ${Const.DEBUG}');
|
L.d(TAG, 'Debug: ${Const.DEBUG}');
|
||||||
L.i(TAG, 'Version: ${Const.VERSION}');
|
L.i(TAG, 'Version: ${Const.VERSION}');
|
||||||
L.i(TAG, 'Build: ${Const.BUILD}');
|
L.i(TAG, 'Build: ${Const.BUILD}');
|
||||||
var client:Client = new Client();
|
var view:ClientView = new ClientView();
|
||||||
Root.bind(client);
|
Root.bind(view);
|
||||||
|
view.launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function init() {
|
}
|
||||||
Provider.setFactory(IResources, Resources);
|
|
||||||
|
|
||||||
|
@:template('ru/m/tankz/Client.yaml', 'ru/m/tankz/Style.yaml')
|
||||||
|
class ClientView extends VGroupView implements ClientLayout implements ViewBuilder {
|
||||||
|
|
||||||
|
private static inline var TAG = 'Tankz';
|
||||||
|
|
||||||
|
public function init():Void {
|
||||||
var font:Font = Font.enumerateFonts()[0];
|
var font:Font = Font.enumerateFonts()[0];
|
||||||
Provider.get(IResources).text.put('font', 'Bookman Old Style');
|
Provider.get(IResources).text.put('font', 'Bookman Old Style');
|
||||||
Provider.get(IResources).text.put('version', 'v${Const.VERSION} b${Const.BUILD}');
|
Provider.get(IResources).text.put('version', 'v${Const.VERSION} b${Const.BUILD}');
|
||||||
|
|
||||||
Provider.set(IPacketBuilder, new PacketBuilder());
|
|
||||||
#if flash
|
#if flash
|
||||||
Provider.set(IConnection, new ru.m.connect.flash.FlashConnection('localhost', 5001));
|
Provider.set(IConnection, new ru.m.connect.flash.FlashConnection<Request, Response>('localhost', 5001, Response));
|
||||||
#elseif html5
|
#elseif html5
|
||||||
Provider.set(IConnection, new ru.m.connect.js.JsConnection('localhost', 5001));
|
Provider.set(IConnection, new ru.m.connect.js.JsConnection('localhost', 5001));
|
||||||
#else
|
#else
|
||||||
Provider.set(IConnection, new ru.m.connect.fake.FakeConnection());
|
Provider.set(IConnection, new ru.m.connect.fake.FakeConnection());
|
||||||
#end
|
#end
|
||||||
|
|
||||||
Provider.get(IConnection).handler.addListener(this);
|
|
||||||
|
|
||||||
Provider.set(IFrameSwitcher, switcher);
|
Provider.set(IFrameSwitcher, switcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch():Void {
|
||||||
content.stage.stageFocusRect = false;
|
content.stage.stageFocusRect = false;
|
||||||
|
|
||||||
content.stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):Void {
|
content.stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):Void {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package ru.m.tankz;
|
package ru.m.tankz;
|
||||||
|
|
||||||
import haxework.provider.Provider;
|
import haxework.provider.Provider;
|
||||||
import ru.m.tankz.bundle.ConfigBundle;
|
import haxework.resources.IResources;
|
||||||
import ru.m.tankz.bundle.IConfigBundle;
|
import haxework.resources.Resources;
|
||||||
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.game.ClassicGame;
|
import ru.m.tankz.game.ClassicGame;
|
||||||
@@ -17,7 +17,8 @@ import ru.m.tankz.storage.UserStorage;
|
|||||||
class Init {
|
class Init {
|
||||||
|
|
||||||
public static function init():Void {
|
public static function init():Void {
|
||||||
Provider.setFactory(IConfigBundle, ConfigBundle);
|
Provider.setFactory(IResources, Resources);
|
||||||
|
Provider.setFactory(ILevelBundle, LevelBundle);
|
||||||
Provider.setFactory(ILevelBundle, LevelBundle);
|
Provider.setFactory(ILevelBundle, LevelBundle);
|
||||||
Provider.setFactory(SaveStorage, SaveStorage);
|
Provider.setFactory(SaveStorage, SaveStorage);
|
||||||
Provider.setFactory(UserStorage, UserStorage);
|
Provider.setFactory(UserStorage, UserStorage);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package ru.m.tankz.frame;
|
package ru.m.tankz.frame;
|
||||||
|
|
||||||
import ru.m.tankz.sound.SoundManager;
|
|
||||||
import flash.events.Event;
|
import flash.events.Event;
|
||||||
import haxe.ds.Option;
|
import haxe.ds.Option;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
@@ -9,13 +8,11 @@ import haxework.gui.LabelView;
|
|||||||
import haxework.gui.VGroupView;
|
import haxework.gui.VGroupView;
|
||||||
import haxework.gui.ViewBuilder;
|
import haxework.gui.ViewBuilder;
|
||||||
import haxework.provider.Provider;
|
import haxework.provider.Provider;
|
||||||
import protohx.Message;
|
|
||||||
import ru.m.connect.IConnection;
|
|
||||||
import ru.m.tankz.game.Game;
|
import ru.m.tankz.game.Game;
|
||||||
import ru.m.tankz.game.GameSave;
|
import ru.m.tankz.game.GameSave;
|
||||||
import ru.m.tankz.game.GameState;
|
import ru.m.tankz.game.GameState;
|
||||||
import ru.m.tankz.proto.pack.GameUpdateResponse;
|
|
||||||
import ru.m.tankz.render.Render;
|
import ru.m.tankz.render.Render;
|
||||||
|
import ru.m.tankz.sound.SoundManager;
|
||||||
import ru.m.tankz.storage.SaveStorage;
|
import ru.m.tankz.storage.SaveStorage;
|
||||||
|
|
||||||
|
|
||||||
@@ -25,7 +22,7 @@ interface GameFrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@:template("ru/m/tankz/frame/GameFrame.yaml", "ru/m/tankz/Style.yaml")
|
@:template("ru/m/tankz/frame/GameFrame.yaml", "ru/m/tankz/Style.yaml")
|
||||||
class GameFrame extends VGroupView implements ViewBuilder implements IPacketHandler implements GameFrameLayout {
|
class GameFrame extends VGroupView implements ViewBuilder implements GameFrameLayout {
|
||||||
|
|
||||||
private static inline var TAG = "GameFrame";
|
private static inline var TAG = "GameFrame";
|
||||||
|
|
||||||
@@ -126,11 +123,4 @@ class GameFrame extends VGroupView implements ViewBuilder implements IPacketHand
|
|||||||
private function redraw(_):Void {
|
private function redraw(_):Void {
|
||||||
render.draw(game.engine);
|
render.draw(game.engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onGameUpdateResponse(packet:GameUpdateResponse):Void {
|
|
||||||
//engine.updateFromChanges(packet.changes);
|
|
||||||
render.draw(game.engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPacket(packet:Message):Void {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ package ru.m.tankz.network;
|
|||||||
|
|
||||||
import haxework.provider.Provider;
|
import haxework.provider.Provider;
|
||||||
import hxsignal.impl.Signal1;
|
import hxsignal.impl.Signal1;
|
||||||
import protohx.Message;
|
|
||||||
import ru.m.connect.IConnection;
|
import ru.m.connect.IConnection;
|
||||||
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.Request;
|
||||||
|
import ru.m.tankz.proto.pack.Response;
|
||||||
import ru.m.tankz.storage.UserStorage;
|
import ru.m.tankz.storage.UserStorage;
|
||||||
|
|
||||||
|
|
||||||
class NetworkManager implements IPacketHandler implements IConnectionHandler {
|
typedef ClientConnection = IConnection<Request, Response>;
|
||||||
|
|
||||||
|
class NetworkManager {
|
||||||
|
|
||||||
public var state(default, null):String;
|
public var state(default, null):String;
|
||||||
public var stateSignal:Signal1<String>;
|
public var stateSignal:Signal1<String>;
|
||||||
public var user(default, null):User;
|
public var user(default, null):User;
|
||||||
|
|
||||||
private var connection(get, never):IConnection;
|
private var connection(get, never):ClientConnection;
|
||||||
private var storage(get, never):UserStorage;
|
private var storage(get, never):UserStorage;
|
||||||
|
|
||||||
inline private function get_connection():IConnection {
|
inline private function get_connection():ClientConnection {
|
||||||
return Provider.get(IConnection);
|
return Provider.get(IConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,8 +31,8 @@ class NetworkManager implements IPacketHandler implements IConnectionHandler {
|
|||||||
public function new() {
|
public function new() {
|
||||||
stateSignal = new Signal1<String>();
|
stateSignal = new Signal1<String>();
|
||||||
updateState('offline');
|
updateState('offline');
|
||||||
connection.handler.addListener(this);
|
connection.handler.connect(onConnectionEvent);
|
||||||
connection.packetHandler.addListener(this);
|
connection.packetHandler.connect(onResponse);
|
||||||
user = storage.read();
|
user = storage.read();
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = {name: 'User', uuid: null};
|
user = {name: 'User', uuid: null};
|
||||||
@@ -44,39 +46,29 @@ class NetworkManager implements IPacketHandler implements IConnectionHandler {
|
|||||||
|
|
||||||
public function login(name:String):Void {
|
public function login(name:String):Void {
|
||||||
user.name = name;
|
user.name = name;
|
||||||
if (!connection.connected) {
|
updateState('connect...');
|
||||||
updateState('connect...');
|
connection.connect().then(function(c:ClientConnection) {
|
||||||
connection.connect();
|
updateState('login...');
|
||||||
} else {
|
c.send(new Request().setLogin(
|
||||||
onConnected();
|
new LoginRequest()
|
||||||
|
.setUuid(user.uuid)
|
||||||
|
.setName(user.name)
|
||||||
|
));
|
||||||
|
}).catchError(function(_) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onConnectionEvent(event:ConnectionEvent):Void {
|
||||||
|
updateState(Std.string(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onResponse(packet:Response):Void {
|
||||||
|
if (packet.hasLogin()) {
|
||||||
|
user = {
|
||||||
|
uuid: packet.login.user.uuid,
|
||||||
|
name: packet.login.user.name,
|
||||||
|
};
|
||||||
|
storage.write(user);
|
||||||
|
updateState('online');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onConnected():Void {
|
|
||||||
updateState('login...');
|
|
||||||
connection.send(
|
|
||||||
new LoginRequest()
|
|
||||||
.setUuid(user.uuid)
|
|
||||||
.setName(user.name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onDisconnected():Void {
|
|
||||||
updateState('offline');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onError(error:Dynamic):Void {
|
|
||||||
updateState('error');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onLoginResponse(packet:LoginResponse):Void {
|
|
||||||
user = {
|
|
||||||
uuid: packet.user.uuid,
|
|
||||||
name: packet.user.name,
|
|
||||||
};
|
|
||||||
storage.write(user);
|
|
||||||
updateState('online');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPacket(packet:Message):Void {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +1,45 @@
|
|||||||
package ru.m.connect;
|
package ru.m.connect;
|
||||||
|
|
||||||
import haxework.dispath.Dispatcher;
|
import promhx.Deferred;
|
||||||
import haxework.dispath.IDispatcher;
|
import hxsignal.impl.Signal1;
|
||||||
import haxework.provider.Provider;
|
|
||||||
import haxe.io.Bytes;
|
import haxe.io.Bytes;
|
||||||
|
import promhx.Promise;
|
||||||
import protohx.Message;
|
import protohx.Message;
|
||||||
import ru.m.connect.IConnection;
|
import ru.m.connect.IConnection;
|
||||||
|
|
||||||
class BaseConnection implements IConnection {
|
|
||||||
public var handler(default,default):IDispatcher<IConnectionHandler>;
|
|
||||||
public var packetHandler(default,default):IDispatcher<IPacketHandler>;
|
|
||||||
public var connected(default, null):Bool;
|
|
||||||
public var queue(default, null):PacketQueue;
|
|
||||||
public var builder(default, null):IPacketBuilder;
|
|
||||||
|
|
||||||
public function new() {
|
class BaseConnection<O:Message, I:Message> implements IConnection<O, I> {
|
||||||
this.builder = Provider.get(IPacketBuilder);
|
public var handler(default, default):Signal1<ConnectionEvent>;
|
||||||
this.queue = new PacketQueue(builder);
|
public var packetHandler(default, default):Signal1<I>;
|
||||||
this.handler = new Dispatcher<IConnectionHandler>();
|
public var connected(default, null):Bool;
|
||||||
this.packetHandler = new Dispatcher<IPacketHandler>();
|
public var queue(default, null):PacketQueue<I>;
|
||||||
}
|
|
||||||
|
|
||||||
public function connect():Void {
|
private var connectDeferred:Deferred<IConnection<O, I>>;
|
||||||
throw "Not implemented";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function disconnect():Void {
|
public function new(i:Class<I>) {
|
||||||
throw "Not implemented";
|
queue = new PacketQueue<I>(i);
|
||||||
}
|
handler = new Signal1<ConnectionEvent>();
|
||||||
|
packetHandler = new Signal1<I>();
|
||||||
public function pushData(bytes:Bytes):Void {
|
connectDeferred = new Deferred();
|
||||||
queue.addBytes(bytes);
|
|
||||||
while (queue.hasMsg()) {
|
|
||||||
var packet:Message = queue.popMsg();
|
|
||||||
try {
|
|
||||||
receive(packet);
|
|
||||||
} catch (error:Dynamic) {
|
|
||||||
trace(error);
|
|
||||||
handler.dispatch(function(h) h.onError(error));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
public function send(packet:Message):Void {
|
|
||||||
#if proto_debug L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
|
|
||||||
}
|
|
||||||
|
|
||||||
public function receive(packet:Message):Void {
|
public function connect():Promise<IConnection<O, I>> {
|
||||||
#if proto_debug L.d("Receive", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
|
throw "Not implemented";
|
||||||
var name = "on" + Type.getClassName(Type.getClass(packet)).split(".").pop();
|
}
|
||||||
packetHandler.dispatch(function(h) {
|
|
||||||
var method = Reflect.field(h, name);
|
public function disconnect():Void {
|
||||||
if (method != null && Reflect.isFunction(method)) {
|
throw "Not implemented";
|
||||||
Reflect.callMethod(h, method, [packet]);
|
}
|
||||||
} else {
|
|
||||||
h.onPacket(packet);
|
public function pushData(bytes:Bytes):Void {
|
||||||
}
|
queue.addBytes(bytes);
|
||||||
});
|
while (queue.hasMsg()) {
|
||||||
}
|
var packet:I = queue.popMsg();
|
||||||
|
packetHandler.emit(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send(packet:O):Void {
|
||||||
|
#if proto_debug L.d("Send", Type.getClassName(Type.getClass(packet)).split(".").pop()); #end
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,37 +6,19 @@ import promhx.Promise;
|
|||||||
import protohx.Message;
|
import protohx.Message;
|
||||||
|
|
||||||
|
|
||||||
interface IConnection {
|
enum ConnectionEvent {
|
||||||
|
CONNECTED;
|
||||||
|
DISCONNECTED;
|
||||||
|
ERROR(error:Dynamic);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IConnection<O:Message, I:Message> {
|
||||||
public var connected(default, null):Bool;
|
public var connected(default, null):Bool;
|
||||||
public var handler(default, default):Signal1<IConnectionHandler>;
|
public var handler(default, null):Signal1<ConnectionEvent>;
|
||||||
public var packetHandler(default, default):Signal1<IPacketHandler>;
|
public var packetHandler(default, null):Signal1<I>;
|
||||||
|
|
||||||
public var builder(default, null):IPacketBuilder;
|
public function connect():Promise<IConnection<O, I>>;
|
||||||
|
|
||||||
public function connect():Promise<IConnection>;
|
|
||||||
public function disconnect():Void;
|
public function disconnect():Void;
|
||||||
public function send(packet:Message):Void;
|
public function send(packet:O):Void;
|
||||||
public function pushData(bytes:Bytes):Void;
|
public function pushData(bytes:Bytes):Void;
|
||||||
|
|
||||||
public function receive(packet:Message):Void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IConnectionHandler {
|
|
||||||
public function onConnected():Void;
|
|
||||||
public function onDisconnected():Void;
|
|
||||||
public function onError(error:Dynamic):Void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IPacketHandler {
|
|
||||||
public function onPacket(packet:Message):Void;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef PacketMeta = {
|
|
||||||
var family:Int;
|
|
||||||
var id:Int;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IPacketBuilder {
|
|
||||||
public function packetMeta(packet:Message):PacketMeta;
|
|
||||||
public function buildPacket(meta:PacketMeta):Message;
|
|
||||||
}
|
}
|
||||||
@@ -1,80 +1,75 @@
|
|||||||
package ru.m.connect;
|
package ru.m.connect;
|
||||||
|
|
||||||
import ru.m.connect.IConnection.IPacketBuilder;
|
|
||||||
import protohx.Message;
|
|
||||||
import haxe.io.BytesInput;
|
|
||||||
import haxe.io.BytesBuffer;
|
|
||||||
import haxe.io.Bytes;
|
import haxe.io.Bytes;
|
||||||
|
import haxe.io.BytesBuffer;
|
||||||
|
import haxe.io.BytesInput;
|
||||||
|
import protohx.Message;
|
||||||
|
|
||||||
class PacketQueue {
|
|
||||||
|
|
||||||
public static inline var HEADER_SIZE:Int = 4;
|
class PacketQueue<P:Message> {
|
||||||
|
|
||||||
private var builder:IPacketBuilder;
|
private var packetClass:Class<P>;
|
||||||
private var bytesBuff:Bytes;
|
private var bytesBuff:Bytes;
|
||||||
private var msgs:List<Message>;
|
private var msgs:List<P>;
|
||||||
|
|
||||||
public function new(builder:IPacketBuilder) {
|
public function new(packetClass:Class<P>) {
|
||||||
this.builder = builder;
|
this.packetClass = packetClass;
|
||||||
msgs = new List<Message>();
|
msgs = new List<P>();
|
||||||
}
|
|
||||||
|
|
||||||
public inline function hasMsg():Bool {
|
|
||||||
return !msgs.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public inline function popMsg():Message {
|
|
||||||
return msgs.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public inline function addMsg(msg:Message):Void {
|
|
||||||
msgs.add(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addBytes(bytes:Bytes) {
|
|
||||||
if (bytes == null) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (bytesBuff == null) {
|
|
||||||
bytesBuff = bytes;
|
public inline function hasMsg():Bool {
|
||||||
} else {
|
return !msgs.isEmpty();
|
||||||
var buffer = new BytesBuffer();
|
|
||||||
buffer.add(bytesBuff);
|
|
||||||
buffer.add(bytes);
|
|
||||||
bytesBuff = buffer.getBytes();
|
|
||||||
}
|
}
|
||||||
if (bytesBuff == null || bytesBuff.length < HEADER_SIZE) {
|
|
||||||
return;
|
public inline function popMsg():P {
|
||||||
|
return msgs.pop();
|
||||||
}
|
}
|
||||||
var available = bytesBuff.length;
|
|
||||||
var bi = new BytesInput(bytesBuff);
|
public inline function addMsg(msg:P):Void {
|
||||||
bi.bigEndian = false;
|
msgs.add(msg);
|
||||||
while (available >= HEADER_SIZE) {
|
|
||||||
var family = bi.readByte();
|
|
||||||
var id = bi.readByte();
|
|
||||||
var packetSize = bi.readUInt16();
|
|
||||||
available -= HEADER_SIZE;
|
|
||||||
if (packetSize <= available) {
|
|
||||||
available -= packetSize;
|
|
||||||
var msgBytes = bi.read(packetSize);
|
|
||||||
var packet = builder.buildPacket({family:family, id:id});
|
|
||||||
packet.mergeFrom(msgBytes);
|
|
||||||
addMsg(packet);
|
|
||||||
} else {
|
|
||||||
available += HEADER_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (available == 0) {
|
|
||||||
bytesBuff = null;
|
public function addBytes(bytes:Bytes):Void {
|
||||||
} else if (available > 0) {
|
if (bytes == null) {
|
||||||
if (bytesBuff.length != available) {
|
return;
|
||||||
var pos = bytesBuff.length - available;
|
}
|
||||||
bytesBuff = bytesBuff.sub(pos, available);
|
if (bytesBuff == null) {
|
||||||
}
|
bytesBuff = bytes;
|
||||||
} else {
|
} else {
|
||||||
throw "Wrong available: " + available;
|
var buffer = new BytesBuffer();
|
||||||
|
buffer.add(bytesBuff);
|
||||||
|
buffer.add(bytes);
|
||||||
|
bytesBuff = buffer.getBytes();
|
||||||
|
}
|
||||||
|
if (bytesBuff == null || bytesBuff.length < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var available = bytesBuff.length;
|
||||||
|
var bi = new BytesInput(bytesBuff);
|
||||||
|
bi.bigEndian = false;
|
||||||
|
while (available > 0) {
|
||||||
|
var packetSize = bi.readUInt16();
|
||||||
|
available -= 1;
|
||||||
|
if (packetSize <= available) {
|
||||||
|
var msgBytes = bi.read(packetSize);
|
||||||
|
var packet:P = Type.createInstance(packetClass, []);
|
||||||
|
packet.mergeFrom(msgBytes);
|
||||||
|
addMsg(packet);
|
||||||
|
available -= packetSize;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (available == 0) {
|
||||||
|
bytesBuff = null;
|
||||||
|
} else if (available > 0) {
|
||||||
|
if (bytesBuff.length != available) {
|
||||||
|
var pos = bytesBuff.length - available;
|
||||||
|
bytesBuff = bytesBuff.sub(pos, available);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw "Wrong available: " + available;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.m.connect.flash;
|
package ru.m.connect.flash;
|
||||||
|
|
||||||
import ru.m.connect.IConnection.IConnectionHandler;
|
import ru.m.connect.IConnection.ConnectionEvent;
|
||||||
|
import promhx.Promise;
|
||||||
import flash.utils.Endian;
|
import flash.utils.Endian;
|
||||||
import haxe.io.BytesOutput;
|
import haxe.io.BytesOutput;
|
||||||
import protohx.Message;
|
import protohx.Message;
|
||||||
@@ -12,76 +13,77 @@ import flash.events.SecurityErrorEvent;
|
|||||||
import flash.events.IOErrorEvent;
|
import flash.events.IOErrorEvent;
|
||||||
import flash.net.Socket;
|
import flash.net.Socket;
|
||||||
|
|
||||||
class FlashConnection extends BaseConnection {
|
|
||||||
|
|
||||||
private var host:String;
|
class FlashConnection<O:Message, I:Message> extends BaseConnection<O, I> {
|
||||||
private var port:Int;
|
|
||||||
private var socket:Socket;
|
|
||||||
|
|
||||||
public function new(host:String, port:Int) {
|
private var host:String;
|
||||||
super();
|
private var port:Int;
|
||||||
this.host = host;
|
private var socket:Socket;
|
||||||
this.port = port;
|
|
||||||
connected = false;
|
|
||||||
socket = new Socket();
|
|
||||||
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
|
|
||||||
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
|
|
||||||
socket.addEventListener(Event.CLOSE, onClose);
|
|
||||||
socket.addEventListener(Event.CONNECT, onConnect);
|
|
||||||
socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
|
|
||||||
socket.endian = Endian.LITTLE_ENDIAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
override public function connect():Void {
|
public function new(host:String, port:Int, i:Class<I>) {
|
||||||
socket.connect(host, port);
|
super(i);
|
||||||
}
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
override public function disconnect():Void {
|
connected = false;
|
||||||
if (socket.connected) {
|
socket = new Socket();
|
||||||
socket.close();
|
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
|
||||||
connected = false;
|
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
|
||||||
handler.dispatch(function(h) h.onDisconnected());
|
socket.addEventListener(Event.CLOSE, onClose);
|
||||||
|
socket.addEventListener(Event.CONNECT, onConnect);
|
||||||
|
socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
|
||||||
|
socket.endian = Endian.LITTLE_ENDIAN;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private function onError(event:ErrorEvent):Void {
|
override public function connect():Promise<IConnection<O, I>> {
|
||||||
socket.close();
|
socket.connect(host, port);
|
||||||
connected = false;
|
return connectDeferred.promise();
|
||||||
handler.dispatch(function(h) h.onError(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function onConnect(_):Void {
|
|
||||||
connected = true;
|
|
||||||
handler.dispatch(function(h) h.onConnected());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function onClose(_):Void {
|
|
||||||
socket.close();
|
|
||||||
connected = false;
|
|
||||||
handler.dispatch(function(h) h.onDisconnected());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function onSocketData(_):Void {
|
|
||||||
try {
|
|
||||||
var b = new flash.utils.ByteArray();
|
|
||||||
socket.readBytes(b);
|
|
||||||
var bs = Bytes.ofData(cast b);
|
|
||||||
pushData(bs);
|
|
||||||
} catch (error:Dynamic) {
|
|
||||||
handler.dispatch(function(h) h.onError(error));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override public function send(packet:Message):Void {
|
override public function disconnect():Void {
|
||||||
super.send(packet);
|
if (socket.connected) {
|
||||||
var meta = builder.packetMeta(packet);
|
socket.close();
|
||||||
socket.writeByte(meta.family);
|
//connected = false;
|
||||||
socket.writeByte(meta.id);
|
//handler.emit(ConnectionEvent.DISCONNECTED);
|
||||||
var out = new BytesOutput();
|
}
|
||||||
packet.writeTo(out);
|
}
|
||||||
var bytes = out.getBytes();
|
|
||||||
socket.writeShort(bytes.length);
|
private function onError(event:ErrorEvent):Void {
|
||||||
socket.writeBytes(cast bytes.getData());
|
socket.close();
|
||||||
socket.flush();
|
connected = false;
|
||||||
}
|
handler.emit(ConnectionEvent.ERROR(event));
|
||||||
|
connectDeferred.throwError(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onConnect(_):Void {
|
||||||
|
connected = true;
|
||||||
|
handler.emit(ConnectionEvent.CONNECTED);
|
||||||
|
connectDeferred.resolve(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onClose(_):Void {
|
||||||
|
socket.close();
|
||||||
|
connected = false;
|
||||||
|
handler.emit(ConnectionEvent.DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onSocketData(_):Void {
|
||||||
|
try {
|
||||||
|
var b = new flash.utils.ByteArray();
|
||||||
|
socket.readBytes(b);
|
||||||
|
var bs = Bytes.ofData(cast b);
|
||||||
|
pushData(bs);
|
||||||
|
} catch (error:Dynamic) {
|
||||||
|
handler.emit(ConnectionEvent.ERROR(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function send(packet:O):Void {
|
||||||
|
super.send(packet);
|
||||||
|
var out = new BytesOutput();
|
||||||
|
packet.writeTo(out);
|
||||||
|
var bytes = out.getBytes();
|
||||||
|
socket.writeShort(bytes.length);
|
||||||
|
socket.writeBytes(cast bytes.getData());
|
||||||
|
socket.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package ru.m.tankz;
|
|
||||||
|
|
||||||
import protohx.Message;
|
|
||||||
import ru.m.connect.IConnection;
|
|
||||||
import ru.m.tankz.proto.pack.*;
|
|
||||||
import Type;
|
|
||||||
|
|
||||||
|
|
||||||
class PacketBuilder implements IPacketBuilder {
|
|
||||||
|
|
||||||
private static var MAP:Map<Int, Map<Int, Class<Message>>> = [
|
|
||||||
0x00 => [
|
|
||||||
0x0001 => ErrorResponse
|
|
||||||
],
|
|
||||||
0x01 => [
|
|
||||||
0x0001 => LoginRequest,
|
|
||||||
0x0002 => LoginResponse,
|
|
||||||
],
|
|
||||||
0x02 => [
|
|
||||||
0x0001 => GameListRequest,
|
|
||||||
0x0002 => GameListResponse,
|
|
||||||
0x0003 => CreateGameRequest,
|
|
||||||
0x0004 => CreateGameResponse,
|
|
||||||
0x0005 => GameListResponse,
|
|
||||||
0x0006 => JoinGameRequest,
|
|
||||||
0x0007 => JoinGameResponse,
|
|
||||||
0x0008 => StartGameRequest,
|
|
||||||
0x0009 => StartGameResponse,
|
|
||||||
0x000a => LeaveGameRequest,
|
|
||||||
0x000b => LeaveGameResponse
|
|
||||||
],
|
|
||||||
0x03 => [
|
|
||||||
0x0001 => GameActionRequest,
|
|
||||||
0x0002 => GameUpdateResponse
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
public function new() {}
|
|
||||||
|
|
||||||
public function packetMeta(packet:Message):PacketMeta {
|
|
||||||
for (family in MAP.keys()) {
|
|
||||||
var subMap = MAP[family];
|
|
||||||
for (id in subMap.keys()) {
|
|
||||||
var packetClass = subMap[id];
|
|
||||||
if (Std.is(packet, packetClass)) {
|
|
||||||
return {
|
|
||||||
family:family,
|
|
||||||
id:id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw "Unsupported packet(" + Type.getClassName(Type.getClass(packet)).split(".").pop() + ")";
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildPacket(meta:PacketMeta):Message {
|
|
||||||
if (!MAP.exists(meta.family)) throw "Unsupported family(" + meta.family + ")";
|
|
||||||
if (!MAP[meta.family].exists(meta.id)) throw "Unsupported family(" + meta.family + ") id(" + meta.id + ")";
|
|
||||||
var packetClass = MAP[meta.family][meta.id];
|
|
||||||
return Type.createInstance(packetClass, []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -65,3 +65,20 @@ message GameActionRequest {
|
|||||||
message GameUpdateResponse {
|
message GameUpdateResponse {
|
||||||
repeated ru.m.tankz.proto.game.GameChange changes = 1;
|
repeated ru.m.tankz.proto.game.GameChange changes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
message Request {
|
||||||
|
oneof content {
|
||||||
|
LoginRequest login = 1;
|
||||||
|
CreateGameRequest createGame = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response {
|
||||||
|
oneof content {
|
||||||
|
LoginResponse login = 1;
|
||||||
|
CreateGameResponse createGame = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user