mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-07-08 23:07:46 +07:00
Added MCP server module which acts as the server browser
Added MCP server module which acts as the server browser MCP only supports listing games at this time Minor changes to LoginScreen to reflect how LobbyScreen was written differently Added desktop with networking run config which starts up server instances and then a client Created GameSession class which is used as a cache for mcp GameSession packets
This commit is contained in:
8
.idea/runConfigurations/desktop__networking_.xml
generated
Normal file
8
.idea/runConfigurations/desktop__networking_.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="desktop (networking)" type="CompoundRunConfigurationType" factoryName="Compound Run Configuration">
|
||||||
|
<toRun type="Application" name="BNLS" />
|
||||||
|
<toRun type="Application" name="MCP" />
|
||||||
|
<toRun type="Application" name="desktop (debug) (854x480)" />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
20
build.gradle
20
build.gradle
@ -236,6 +236,26 @@ project(":server:bnls") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project(":server:mcp") {
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// TODO: $gdxVersion is pulling an older file for some reason
|
||||||
|
compile "com.badlogicgames.gdx:gdx-backend-headless:$gdxVersion"
|
||||||
|
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(":core")
|
||||||
|
compile group: 'commons-cli', name: 'commons-cli', version: cliVersion
|
||||||
|
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
project(":mpqlib") {
|
project(":mpqlib") {
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
|
24
core/gen/com/riiablo/net/packet/mcp/ConnectionAccepted.java
Normal file
24
core/gen/com/riiablo/net/packet/mcp/ConnectionAccepted.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class ConnectionAccepted extends Table {
|
||||||
|
public static ConnectionAccepted getRootAsConnectionAccepted(ByteBuffer _bb) { return getRootAsConnectionAccepted(_bb, new ConnectionAccepted()); }
|
||||||
|
public static ConnectionAccepted getRootAsConnectionAccepted(ByteBuffer _bb, ConnectionAccepted obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public ConnectionAccepted __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
|
||||||
|
public static void startConnectionAccepted(FlatBufferBuilder builder) { builder.startObject(0); }
|
||||||
|
public static int endConnectionAccepted(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
core/gen/com/riiablo/net/packet/mcp/ConnectionClosed.java
Normal file
35
core/gen/com/riiablo/net/packet/mcp/ConnectionClosed.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class ConnectionClosed extends Table {
|
||||||
|
public static ConnectionClosed getRootAsConnectionClosed(ByteBuffer _bb) { return getRootAsConnectionClosed(_bb, new ConnectionClosed()); }
|
||||||
|
public static ConnectionClosed getRootAsConnectionClosed(ByteBuffer _bb, ConnectionClosed obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public ConnectionClosed __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public String reason() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer reasonAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
|
||||||
|
public ByteBuffer reasonInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); }
|
||||||
|
|
||||||
|
public static int createConnectionClosed(FlatBufferBuilder builder,
|
||||||
|
int reasonOffset) {
|
||||||
|
builder.startObject(1);
|
||||||
|
ConnectionClosed.addReason(builder, reasonOffset);
|
||||||
|
return ConnectionClosed.endConnectionClosed(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startConnectionClosed(FlatBufferBuilder builder) { builder.startObject(1); }
|
||||||
|
public static void addReason(FlatBufferBuilder builder, int reasonOffset) { builder.addOffset(0, reasonOffset, 0); }
|
||||||
|
public static int endConnectionClosed(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
67
core/gen/com/riiablo/net/packet/mcp/CreateGame.java
Normal file
67
core/gen/com/riiablo/net/packet/mcp/CreateGame.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class CreateGame extends Table {
|
||||||
|
public static CreateGame getRootAsCreateGame(ByteBuffer _bb) { return getRootAsCreateGame(_bb, new CreateGame()); }
|
||||||
|
public static CreateGame getRootAsCreateGame(ByteBuffer _bb, CreateGame obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public CreateGame __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public int diff() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
public int levelDifference() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
public int maxPlayers() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
public String gameName() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer gameNameAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
|
||||||
|
public ByteBuffer gameNameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
|
||||||
|
public String password() { int o = __offset(12); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer passwordAsByteBuffer() { return __vector_as_bytebuffer(12, 1); }
|
||||||
|
public ByteBuffer passwordInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 12, 1); }
|
||||||
|
public String description() { int o = __offset(14); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer descriptionAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
|
||||||
|
public ByteBuffer descriptionInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 1); }
|
||||||
|
public int gameToken() { int o = __offset(16); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
public int result() { int o = __offset(18); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
|
||||||
|
public static int createCreateGame(FlatBufferBuilder builder,
|
||||||
|
int diff,
|
||||||
|
int levelDifference,
|
||||||
|
int maxPlayers,
|
||||||
|
int gameNameOffset,
|
||||||
|
int passwordOffset,
|
||||||
|
int descriptionOffset,
|
||||||
|
int gameToken,
|
||||||
|
int result) {
|
||||||
|
builder.startObject(8);
|
||||||
|
CreateGame.addResult(builder, result);
|
||||||
|
CreateGame.addGameToken(builder, gameToken);
|
||||||
|
CreateGame.addDescription(builder, descriptionOffset);
|
||||||
|
CreateGame.addPassword(builder, passwordOffset);
|
||||||
|
CreateGame.addGameName(builder, gameNameOffset);
|
||||||
|
CreateGame.addMaxPlayers(builder, maxPlayers);
|
||||||
|
CreateGame.addLevelDifference(builder, levelDifference);
|
||||||
|
CreateGame.addDiff(builder, diff);
|
||||||
|
return CreateGame.endCreateGame(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startCreateGame(FlatBufferBuilder builder) { builder.startObject(8); }
|
||||||
|
public static void addDiff(FlatBufferBuilder builder, int diff) { builder.addInt(0, diff, 0); }
|
||||||
|
public static void addLevelDifference(FlatBufferBuilder builder, int levelDifference) { builder.addInt(1, levelDifference, 0); }
|
||||||
|
public static void addMaxPlayers(FlatBufferBuilder builder, int maxPlayers) { builder.addInt(2, maxPlayers, 0); }
|
||||||
|
public static void addGameName(FlatBufferBuilder builder, int gameNameOffset) { builder.addOffset(3, gameNameOffset, 0); }
|
||||||
|
public static void addPassword(FlatBufferBuilder builder, int passwordOffset) { builder.addOffset(4, passwordOffset, 0); }
|
||||||
|
public static void addDescription(FlatBufferBuilder builder, int descriptionOffset) { builder.addOffset(5, descriptionOffset, 0); }
|
||||||
|
public static void addGameToken(FlatBufferBuilder builder, int gameToken) { builder.addInt(6, gameToken, 0); }
|
||||||
|
public static void addResult(FlatBufferBuilder builder, int result) { builder.addInt(7, result, 0); }
|
||||||
|
public static int endCreateGame(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
53
core/gen/com/riiablo/net/packet/mcp/GameSession.java
Normal file
53
core/gen/com/riiablo/net/packet/mcp/GameSession.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class GameSession extends Table {
|
||||||
|
public static GameSession getRootAsGameSession(ByteBuffer _bb) { return getRootAsGameSession(_bb, new GameSession()); }
|
||||||
|
public static GameSession getRootAsGameSession(ByteBuffer _bb, GameSession obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public GameSession __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public long index() { int o = __offset(4); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||||
|
public int players() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
|
||||||
|
public String name() { int o = __offset(8); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(8, 1); }
|
||||||
|
public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); }
|
||||||
|
public String desc() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer descAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
|
||||||
|
public ByteBuffer descInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
|
||||||
|
public long flags() { int o = __offset(12); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||||
|
|
||||||
|
public static int createGameSession(FlatBufferBuilder builder,
|
||||||
|
long index,
|
||||||
|
int players,
|
||||||
|
int nameOffset,
|
||||||
|
int descOffset,
|
||||||
|
long flags) {
|
||||||
|
builder.startObject(5);
|
||||||
|
GameSession.addFlags(builder, flags);
|
||||||
|
GameSession.addDesc(builder, descOffset);
|
||||||
|
GameSession.addName(builder, nameOffset);
|
||||||
|
GameSession.addIndex(builder, index);
|
||||||
|
GameSession.addPlayers(builder, players);
|
||||||
|
return GameSession.endGameSession(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startGameSession(FlatBufferBuilder builder) { builder.startObject(5); }
|
||||||
|
public static void addIndex(FlatBufferBuilder builder, long index) { builder.addInt(0, (int)index, (int)0L); }
|
||||||
|
public static void addPlayers(FlatBufferBuilder builder, int players) { builder.addByte(1, (byte)players, (byte)0); }
|
||||||
|
public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(2, nameOffset, 0); }
|
||||||
|
public static void addDesc(FlatBufferBuilder builder, int descOffset) { builder.addOffset(3, descOffset, 0); }
|
||||||
|
public static void addFlags(FlatBufferBuilder builder, long flags) { builder.addInt(4, (int)flags, (int)0L); }
|
||||||
|
public static int endGameSession(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
49
core/gen/com/riiablo/net/packet/mcp/JoinGame.java
Normal file
49
core/gen/com/riiablo/net/packet/mcp/JoinGame.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class JoinGame extends Table {
|
||||||
|
public static JoinGame getRootAsJoinGame(ByteBuffer _bb) { return getRootAsJoinGame(_bb, new JoinGame()); }
|
||||||
|
public static JoinGame getRootAsJoinGame(ByteBuffer _bb, JoinGame obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public JoinGame __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public String gameName() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer gameNameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
|
||||||
|
public ByteBuffer gameNameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); }
|
||||||
|
public String password() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; }
|
||||||
|
public ByteBuffer passwordAsByteBuffer() { return __vector_as_bytebuffer(6, 1); }
|
||||||
|
public ByteBuffer passwordInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); }
|
||||||
|
public long ip() { int o = __offset(8); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||||
|
public int result() { int o = __offset(10); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||||
|
|
||||||
|
public static int createJoinGame(FlatBufferBuilder builder,
|
||||||
|
int gameNameOffset,
|
||||||
|
int passwordOffset,
|
||||||
|
long ip,
|
||||||
|
int result) {
|
||||||
|
builder.startObject(4);
|
||||||
|
JoinGame.addResult(builder, result);
|
||||||
|
JoinGame.addIp(builder, ip);
|
||||||
|
JoinGame.addPassword(builder, passwordOffset);
|
||||||
|
JoinGame.addGameName(builder, gameNameOffset);
|
||||||
|
return JoinGame.endJoinGame(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startJoinGame(FlatBufferBuilder builder) { builder.startObject(4); }
|
||||||
|
public static void addGameName(FlatBufferBuilder builder, int gameNameOffset) { builder.addOffset(0, gameNameOffset, 0); }
|
||||||
|
public static void addPassword(FlatBufferBuilder builder, int passwordOffset) { builder.addOffset(1, passwordOffset, 0); }
|
||||||
|
public static void addIp(FlatBufferBuilder builder, long ip) { builder.addInt(2, (int)ip, (int)0L); }
|
||||||
|
public static void addResult(FlatBufferBuilder builder, int result) { builder.addInt(3, result, 0); }
|
||||||
|
public static int endJoinGame(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
41
core/gen/com/riiablo/net/packet/mcp/ListGames.java
Normal file
41
core/gen/com/riiablo/net/packet/mcp/ListGames.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class ListGames extends Table {
|
||||||
|
public static ListGames getRootAsListGames(ByteBuffer _bb) { return getRootAsListGames(_bb, new ListGames()); }
|
||||||
|
public static ListGames getRootAsListGames(ByteBuffer _bb, ListGames obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public ListGames __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public long flags() { int o = __offset(4); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||||
|
public GameSession games(int j) { return games(new GameSession(), j); }
|
||||||
|
public GameSession games(GameSession obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||||
|
public int gamesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
|
||||||
|
|
||||||
|
public static int createListGames(FlatBufferBuilder builder,
|
||||||
|
long flags,
|
||||||
|
int gamesOffset) {
|
||||||
|
builder.startObject(2);
|
||||||
|
ListGames.addGames(builder, gamesOffset);
|
||||||
|
ListGames.addFlags(builder, flags);
|
||||||
|
return ListGames.endListGames(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startListGames(FlatBufferBuilder builder) { builder.startObject(2); }
|
||||||
|
public static void addFlags(FlatBufferBuilder builder, long flags) { builder.addInt(0, (int)flags, (int)0L); }
|
||||||
|
public static void addGames(FlatBufferBuilder builder, int gamesOffset) { builder.addOffset(1, gamesOffset, 0); }
|
||||||
|
public static int createGamesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
|
||||||
|
public static void startGamesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
|
||||||
|
public static int endListGames(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
core/gen/com/riiablo/net/packet/mcp/MCP.java
Normal file
39
core/gen/com/riiablo/net/packet/mcp/MCP.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class MCP extends Table {
|
||||||
|
public static MCP getRootAsMCP(ByteBuffer _bb) { return getRootAsMCP(_bb, new MCP()); }
|
||||||
|
public static MCP getRootAsMCP(ByteBuffer _bb, MCP obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||||
|
public MCP __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||||
|
|
||||||
|
public byte dataType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
|
||||||
|
public Table data(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; }
|
||||||
|
|
||||||
|
public static int createMCP(FlatBufferBuilder builder,
|
||||||
|
byte data_type,
|
||||||
|
int dataOffset) {
|
||||||
|
builder.startObject(2);
|
||||||
|
MCP.addData(builder, dataOffset);
|
||||||
|
MCP.addDataType(builder, data_type);
|
||||||
|
return MCP.endMCP(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startMCP(FlatBufferBuilder builder) { builder.startObject(2); }
|
||||||
|
public static void addDataType(FlatBufferBuilder builder, byte dataType) { builder.addByte(0, dataType, 0); }
|
||||||
|
public static void addData(FlatBufferBuilder builder, int dataOffset) { builder.addOffset(1, dataOffset, 0); }
|
||||||
|
public static int endMCP(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
public static void finishMCPBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
|
||||||
|
public static void finishSizePrefixedMCPBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset); }
|
||||||
|
}
|
||||||
|
|
18
core/gen/com/riiablo/net/packet/mcp/MCPData.java
Normal file
18
core/gen/com/riiablo/net/packet/mcp/MCPData.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
public final class MCPData {
|
||||||
|
private MCPData() { }
|
||||||
|
public static final byte NONE = 0;
|
||||||
|
public static final byte ConnectionClosed = 1;
|
||||||
|
public static final byte ConnectionAccepted = 2;
|
||||||
|
public static final byte CreateGame = 3;
|
||||||
|
public static final byte JoinGame = 4;
|
||||||
|
public static final byte ListGames = 5;
|
||||||
|
|
||||||
|
public static final String[] names = { "NONE", "ConnectionClosed", "ConnectionAccepted", "CreateGame", "JoinGame", "ListGames", };
|
||||||
|
|
||||||
|
public static String name(int e) { return names[e]; }
|
||||||
|
}
|
||||||
|
|
23
core/gen/com/riiablo/net/packet/mcp/Result.java
Normal file
23
core/gen/com/riiablo/net/packet/mcp/Result.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
package com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
public final class Result {
|
||||||
|
private Result() { }
|
||||||
|
public static final int SUCCESS = 0;
|
||||||
|
public static final int INVALID_NAME = 30;
|
||||||
|
public static final int ALREAD_EXISTS = 31;
|
||||||
|
public static final int SERVER_DOWN = 32;
|
||||||
|
public static final int INVALID_PASSWORD = 41;
|
||||||
|
public static final int GAME_DOES_NOT_EXIST = 42;
|
||||||
|
public static final int GAME_IS_FULL = 43;
|
||||||
|
public static final int LEVEL_REQUIREMENTS = 44;
|
||||||
|
public static final int HARDCORE_DEAD = 110;
|
||||||
|
public static final int HARDCORE_SOFTCORE = 113;
|
||||||
|
public static final int UNABLE_NIGHTMARE = 115;
|
||||||
|
public static final int UNABLE_HELL = 116;
|
||||||
|
public static final int NONEXP_EXPANSION = 120;
|
||||||
|
public static final int EXPANSION_NONEXP = 121;
|
||||||
|
public static final int NONLADDER_LADDER = 125;
|
||||||
|
}
|
||||||
|
|
19
core/src/com/riiablo/net/GameSession.java
Normal file
19
core/src/com/riiablo/net/GameSession.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.riiablo.net;
|
||||||
|
|
||||||
|
public class GameSession {
|
||||||
|
public String name;
|
||||||
|
public String password;
|
||||||
|
public String desc;
|
||||||
|
|
||||||
|
public GameSession() {}
|
||||||
|
|
||||||
|
public GameSession(com.riiablo.net.packet.mcp.GameSession game) {
|
||||||
|
name = game.name();
|
||||||
|
desc = game.desc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
4
core/src/com/riiablo/net/mcp/ConnectionAccepted.fbs
Normal file
4
core/src/com/riiablo/net/mcp/ConnectionAccepted.fbs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
table ConnectionAccepted {
|
||||||
|
}
|
5
core/src/com/riiablo/net/mcp/ConnectionClosed.fbs
Normal file
5
core/src/com/riiablo/net/mcp/ConnectionClosed.fbs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
table ConnectionClosed {
|
||||||
|
reason:string;
|
||||||
|
}
|
25
core/src/com/riiablo/net/mcp/CreateGame.fbs
Normal file
25
core/src/com/riiablo/net/mcp/CreateGame.fbs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
include "Result.fbs";
|
||||||
|
|
||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
//enum Result : int {
|
||||||
|
// SUCCESS = 0x00,
|
||||||
|
// INVALID_NAME = 0x1E,
|
||||||
|
// ALREAD_EXISTS = 0x1F,
|
||||||
|
// SERVER_DOWN = 0x20,
|
||||||
|
// HARDCORE_DEAD = 0x6E,
|
||||||
|
//}
|
||||||
|
|
||||||
|
table CreateGame {
|
||||||
|
// request
|
||||||
|
diff:int;
|
||||||
|
levelDifference:int;
|
||||||
|
maxPlayers:int;
|
||||||
|
gameName:string;
|
||||||
|
password:string;
|
||||||
|
description:string;
|
||||||
|
|
||||||
|
// response
|
||||||
|
gameToken:int;
|
||||||
|
result:Result;
|
||||||
|
}
|
28
core/src/com/riiablo/net/mcp/JoinGame.fbs
Normal file
28
core/src/com/riiablo/net/mcp/JoinGame.fbs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
include "Result.fbs";
|
||||||
|
|
||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
//enum Result : int {
|
||||||
|
// SUCCESS = 0x00,
|
||||||
|
// INVALID_PASSWORD = 0x29,
|
||||||
|
// GAME_DOES_NOT_EXIST = 0x2A,
|
||||||
|
// GAME_IS_FULL = 0x2B,
|
||||||
|
// LEVEL_REQUIREMENTS = 0x2C,
|
||||||
|
// HARDCORE_DEAD = 0x6E,
|
||||||
|
// HARDCORE_SOFTCORE = 0x71,
|
||||||
|
// UNABLE_NIGHTMARE = 0x73,
|
||||||
|
// UNABLE_HELL = 0x74,
|
||||||
|
// NONEXP_EXPANSION = 0x78,
|
||||||
|
// EXPANSION_NONEXP = 0x79,
|
||||||
|
// NONLADDER_LADDER = 0x7D,
|
||||||
|
//}
|
||||||
|
|
||||||
|
table JoinGame {
|
||||||
|
// request
|
||||||
|
gameName:string;
|
||||||
|
password:string;
|
||||||
|
|
||||||
|
// response
|
||||||
|
ip:uint32;
|
||||||
|
result:Result;
|
||||||
|
}
|
17
core/src/com/riiablo/net/mcp/ListGames.fbs
Normal file
17
core/src/com/riiablo/net/mcp/ListGames.fbs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
table ListGames {
|
||||||
|
// request
|
||||||
|
flags:uint32;
|
||||||
|
|
||||||
|
// response
|
||||||
|
games:[GameSession];
|
||||||
|
}
|
||||||
|
|
||||||
|
table GameSession {
|
||||||
|
index:uint32;
|
||||||
|
players:uint8;
|
||||||
|
name:string;
|
||||||
|
desc:string;
|
||||||
|
flags:uint32;
|
||||||
|
}
|
22
core/src/com/riiablo/net/mcp/MCP.fbs
Normal file
22
core/src/com/riiablo/net/mcp/MCP.fbs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
include "Result.fbs";
|
||||||
|
include "ConnectionClosed.fbs";
|
||||||
|
include "ConnectionAccepted.fbs";
|
||||||
|
include "CreateGame.fbs";
|
||||||
|
include "JoinGame.fbs";
|
||||||
|
include "ListGames.fbs";
|
||||||
|
|
||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
union MCPData {
|
||||||
|
ConnectionClosed,
|
||||||
|
ConnectionAccepted,
|
||||||
|
CreateGame,
|
||||||
|
JoinGame,
|
||||||
|
ListGames,
|
||||||
|
}
|
||||||
|
|
||||||
|
table MCP {
|
||||||
|
data:MCPData;
|
||||||
|
}
|
||||||
|
|
||||||
|
root_type MCP;
|
19
core/src/com/riiablo/net/mcp/Result.fbs
Normal file
19
core/src/com/riiablo/net/mcp/Result.fbs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
namespace com.riiablo.net.packet.mcp;
|
||||||
|
|
||||||
|
enum Result : int {
|
||||||
|
SUCCESS = 0x00,
|
||||||
|
INVALID_NAME = 0x1E,
|
||||||
|
ALREAD_EXISTS = 0x1F,
|
||||||
|
SERVER_DOWN = 0x20,
|
||||||
|
INVALID_PASSWORD = 0x29,
|
||||||
|
GAME_DOES_NOT_EXIST = 0x2A,
|
||||||
|
GAME_IS_FULL = 0x2B,
|
||||||
|
LEVEL_REQUIREMENTS = 0x2C,
|
||||||
|
HARDCORE_DEAD = 0x6E,
|
||||||
|
HARDCORE_SOFTCORE = 0x71,
|
||||||
|
UNABLE_NIGHTMARE = 0x73,
|
||||||
|
UNABLE_HELL = 0x74,
|
||||||
|
NONEXP_EXPANSION = 0x78,
|
||||||
|
EXPANSION_NONEXP = 0x79,
|
||||||
|
NONLADDER_LADDER = 0x7D,
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
package com.riiablo.screen;
|
package com.riiablo.screen;
|
||||||
|
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Input;
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.Net;
|
import com.badlogic.gdx.Net;
|
||||||
import com.badlogic.gdx.ScreenAdapter;
|
import com.badlogic.gdx.ScreenAdapter;
|
||||||
import com.badlogic.gdx.assets.AssetDescriptor;
|
import com.badlogic.gdx.assets.AssetDescriptor;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.net.HttpRequestBuilder;
|
|
||||||
import com.badlogic.gdx.net.Socket;
|
import com.badlogic.gdx.net.Socket;
|
||||||
import com.badlogic.gdx.net.SocketHints;
|
import com.badlogic.gdx.net.SocketHints;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
@ -24,17 +25,20 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.Json;
|
import com.badlogic.gdx.utils.BufferUtils;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
import com.badlogic.gdx.utils.SerializationException;
|
|
||||||
import com.riiablo.CharData;
|
import com.riiablo.CharData;
|
||||||
import com.riiablo.Riiablo;
|
import com.riiablo.Riiablo;
|
||||||
import com.riiablo.codec.DC6;
|
import com.riiablo.codec.DC6;
|
||||||
import com.riiablo.graphics.PaletteIndexedBatch;
|
import com.riiablo.graphics.PaletteIndexedBatch;
|
||||||
import com.riiablo.loader.DC6Loader;
|
import com.riiablo.loader.DC6Loader;
|
||||||
|
import com.riiablo.net.GameSession;
|
||||||
|
import com.riiablo.net.packet.mcp.ListGames;
|
||||||
|
import com.riiablo.net.packet.mcp.MCP;
|
||||||
|
import com.riiablo.net.packet.mcp.MCPData;
|
||||||
import com.riiablo.server.Account;
|
import com.riiablo.server.Account;
|
||||||
import com.riiablo.server.Session;
|
|
||||||
import com.riiablo.server.SessionError;
|
|
||||||
import com.riiablo.util.EventUtils;
|
import com.riiablo.util.EventUtils;
|
||||||
import com.riiablo.widget.Label;
|
import com.riiablo.widget.Label;
|
||||||
import com.riiablo.widget.TextArea;
|
import com.riiablo.widget.TextArea;
|
||||||
@ -45,13 +49,20 @@ import org.apache.commons.io.IOUtils;
|
|||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.ConnectException;
|
import java.nio.ByteBuffer;
|
||||||
import java.net.SocketTimeoutException;
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class LobbyScreen extends ScreenAdapter {
|
public class LobbyScreen extends ScreenAdapter {
|
||||||
private static final String TAG = "LobbyScreen";
|
private static final String TAG = "LobbyScreen";
|
||||||
|
private static final boolean DEBUG = true;
|
||||||
|
private static final boolean DEBUG_CONNECTION = DEBUG && true;
|
||||||
|
|
||||||
// FIXME: This background is not feasible and will always require shaving, easier to just use
|
// FIXME: This background is not feasible and will always require shaving, easier to just use
|
||||||
// component panels and button groups to create my own?
|
// component panels and button groups to create my own?
|
||||||
@ -91,6 +102,8 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
private PrintWriter out;
|
private PrintWriter out;
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
public LobbyScreen(Account account, CharData player) {
|
public LobbyScreen(Account account, CharData player) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -277,47 +290,47 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
btnCreateGame.addListener(new ClickListener() {
|
btnCreateGame.addListener(new ClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void clicked(InputEvent event, float x, float y) {
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
// Net.HttpRequest request = new HttpRequestBuilder()
|
||||||
.newRequest()
|
// .newRequest()
|
||||||
.method(Net.HttpMethods.POST)
|
// .method(Net.HttpMethods.POST)
|
||||||
.url("http://" + Riiablo.client.getRealm() + ":6112/create-session")
|
// .url("http://" + Riiablo.client.getRealm() + ":6112/create-session")
|
||||||
.jsonContent(new Session.Builder() {{
|
// .jsonContent(new Session.Builder() {{
|
||||||
name = tfGameName.getText();
|
// name = tfGameName.getText();
|
||||||
password = tfPassword.getText();
|
// password = tfPassword.getText();
|
||||||
desc = tfDesc.getText();
|
// desc = tfDesc.getText();
|
||||||
}})
|
// }})
|
||||||
.build();
|
// .build();
|
||||||
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
// Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void handleHttpResponse(Net.HttpResponse httpResponse) {
|
// public void handleHttpResponse(Net.HttpResponse httpResponse) {
|
||||||
String response = httpResponse.getResultAsString();
|
// String response = httpResponse.getResultAsString();
|
||||||
try {
|
// try {
|
||||||
final Session session = new Json().fromJson(Session.class, response);
|
// final Session session = new Json().fromJson(Session.class, response);
|
||||||
Gdx.app.log(TAG, "create-session " + response);
|
// Gdx.app.log(TAG, "create-session " + response);
|
||||||
Gdx.app.postRunnable(new Runnable() {
|
// Gdx.app.postRunnable(new Runnable() {
|
||||||
@Override
|
// @Override
|
||||||
public void run() {
|
// public void run() {
|
||||||
Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, session.host, session.port, null);
|
// Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, session.host, session.port, null);
|
||||||
Gdx.app.log(TAG, "create-session connect " + session.host + ":" + session.port + " " + socket.isConnected());
|
// Gdx.app.log(TAG, "create-session connect " + session.host + ":" + session.port + " " + socket.isConnected());
|
||||||
Riiablo.client.pushScreen(new GameLoadingScreen(new GameScreen(player, socket)));
|
// Riiablo.client.pushScreen(new GameLoadingScreen(new GameScreen(player, socket)));
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
} catch (SerializationException e) {
|
// } catch (SerializationException e) {
|
||||||
SessionError error = new Json().fromJson(SessionError.class, response);
|
// SessionError error = new Json().fromJson(SessionError.class, response);
|
||||||
Gdx.app.log(TAG, "create-session " + error.toString());
|
// Gdx.app.log(TAG, "create-session " + error.toString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void failed(Throwable t) {
|
// public void failed(Throwable t) {
|
||||||
Gdx.app.log(TAG, "create-session " + t.getMessage());
|
// Gdx.app.log(TAG, "create-session " + t.getMessage());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void cancelled() {
|
// public void cancelled() {
|
||||||
Gdx.app.log(TAG, "create-session " + "cancelled");
|
// Gdx.app.log(TAG, "create-session " + "cancelled");
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tfGameName.addListener(new ChangeListener() {
|
tfGameName.addListener(new ChangeListener() {
|
||||||
@ -392,7 +405,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
|
|
||||||
List.ListStyle style3 = new List.ListStyle(Riiablo.fonts.fontformal10, Riiablo.colors.gold, Riiablo.colors.white,
|
List.ListStyle style3 = new List.ListStyle(Riiablo.fonts.fontformal10, Riiablo.colors.gold, Riiablo.colors.white,
|
||||||
new TextureRegionDrawable(Riiablo.textures.white));
|
new TextureRegionDrawable(Riiablo.textures.white));
|
||||||
final List<Session> list = new List<>(style3);
|
final List<GameSession> list = new List<>(style3);
|
||||||
list.setPosition(14, 54);
|
list.setPosition(14, 54);
|
||||||
list.setSize(158, 177);
|
list.setSize(158, 177);
|
||||||
addActor(list);
|
addActor(list);
|
||||||
@ -412,7 +425,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
list.getSelection().setRequired(true);
|
list.getSelection().setRequired(true);
|
||||||
btnJoinGame.setDisabled(list.getSelection().isEmpty());
|
btnJoinGame.setDisabled(list.getSelection().isEmpty());
|
||||||
Session selected = list.getSelected();
|
GameSession selected = list.getSelected();
|
||||||
tfGameName.setText(selected != null ? selected.toString() : "");
|
tfGameName.setText(selected != null ? selected.toString() : "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -420,14 +433,14 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void clicked(InputEvent event, float x, float y) {
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
if (btnJoinGame.isDisabled()) return;
|
if (btnJoinGame.isDisabled()) return;
|
||||||
final Session session = list.getSelected();
|
final GameSession session = list.getSelected();
|
||||||
Gdx.app.log(TAG, "join-session " + session);
|
Gdx.app.log(TAG, "join-session " + session);
|
||||||
Gdx.app.postRunnable(new Runnable() {
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, session.host, session.port, null);
|
// Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, session.host, session.port, null);
|
||||||
Gdx.app.log(TAG, "join-session connect " + session.host + ":" + session.port + " " + socket.isConnected());
|
// Gdx.app.log(TAG, "join-session connect " + session.host + ":" + session.port + " " + socket.isConnected());
|
||||||
Riiablo.client.pushScreen(new GameLoadingScreen(new GameScreen(player, socket)));
|
// Riiablo.client.pushScreen(new GameLoadingScreen(new GameScreen(player, socket)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -459,31 +472,22 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
list.clearItems();
|
list.clearItems();
|
||||||
list.getSelection().setRequired(false);
|
list.getSelection().setRequired(false);
|
||||||
stage.setKeyboardFocus(tfGameName);
|
stage.setKeyboardFocus(tfGameName);
|
||||||
Net.HttpRequest request = new HttpRequestBuilder()
|
|
||||||
.newRequest()
|
ListGames(new ResponseListener() {
|
||||||
.method(Net.HttpMethods.GET)
|
|
||||||
.url("http://" + Riiablo.client.getRealm() + ":6112/get-sessions")
|
|
||||||
.build();
|
|
||||||
Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void handleHttpResponse(Net.HttpResponse httpResponse) {
|
public void handleResponse(MCP packet) {
|
||||||
Array<Session> sessions = (Array<Session>) new Json().fromJson(Array.class, httpResponse.getResultAsStream());
|
Array<GameSession> sessions = new Array<>();
|
||||||
|
ListGames listGames = (ListGames) packet.data(new ListGames());
|
||||||
|
for (int i = 0, length = listGames.gamesLength(); i < length; i++) {
|
||||||
|
sessions.add(new GameSession(listGames.games(i)));
|
||||||
|
}
|
||||||
Gdx.app.log(TAG, sessions.toString());
|
Gdx.app.log(TAG, sessions.toString());
|
||||||
list.setItems(sessions);
|
list.setItems(sessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(Throwable t) {
|
public void failed(Throwable t) {
|
||||||
if (t.getClass() == SocketTimeoutException.class
|
Gdx.app.error(TAG, t.getMessage(), t);
|
||||||
|| t.getClass() == ConnectException.class) {
|
|
||||||
Gdx.app.log(TAG, t.getMessage());
|
|
||||||
} else {
|
|
||||||
Gdx.app.log(TAG, t.getMessage(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -521,8 +525,10 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
|
|
||||||
Riiablo.input.addProcessor(stage);
|
Riiablo.input.addProcessor(stage);
|
||||||
connect();
|
connect();
|
||||||
|
connectToMCP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BNCS
|
||||||
private void connect() {
|
private void connect() {
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -540,6 +546,20 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void connectToMCP() {
|
||||||
|
assert connection == null;
|
||||||
|
Socket socket = null;
|
||||||
|
try {
|
||||||
|
socket = Gdx.net.newClientSocket(Net.Protocol.TCP, Riiablo.client.getRealm(), 6111, null);
|
||||||
|
connection = new Connection(socket);
|
||||||
|
connection.start();
|
||||||
|
} catch (GdxRuntimeException t) {
|
||||||
|
Gdx.app.error(TAG, t.getMessage());
|
||||||
|
if (connection != null) connection.kill.set(true);
|
||||||
|
else if (socket != null) socket.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hide() {
|
public void hide() {
|
||||||
Riiablo.input.removeProcessor(stage);
|
Riiablo.input.removeProcessor(stage);
|
||||||
@ -557,6 +577,7 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
Riiablo.assets.unload(chatrighttopbuttonsDescriptor.fileName);
|
Riiablo.assets.unload(chatrighttopbuttonsDescriptor.fileName);
|
||||||
Riiablo.assets.unload(cancelbuttonblankDescriptor.fileName);
|
Riiablo.assets.unload(cancelbuttonblankDescriptor.fileName);
|
||||||
Riiablo.assets.unload(gamebuttonblankDescriptor.fileName);
|
Riiablo.assets.unload(gamebuttonblankDescriptor.fileName);
|
||||||
|
if (connection != null) connection.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -583,6 +604,30 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
stage.draw();
|
stage.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void process(Socket socket, MCP packet) throws IOException {
|
||||||
|
switch (packet.dataType()) {
|
||||||
|
case MCPData.ConnectionClosed:
|
||||||
|
Gdx.app.debug(TAG, "Connection closed :(");
|
||||||
|
break;
|
||||||
|
case MCPData.ConnectionAccepted:
|
||||||
|
Gdx.app.debug(TAG, "Connection accepted!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Gdx.app.error(TAG, "Unknown packet type: " + packet.dataType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ListGames(ResponseListener listener) {
|
||||||
|
Gdx.app.debug(TAG, "Requesting games list");
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
ListGames.startListGames(builder);
|
||||||
|
int listGamesOffset = ListGames.endListGames(builder);
|
||||||
|
int id = MCP.createMCP(builder, MCPData.ListGames, listGamesOffset);
|
||||||
|
builder.finish(id);
|
||||||
|
ByteBuffer data = builder.dataBuffer();
|
||||||
|
connection.sendRequest(data, listener);
|
||||||
|
}
|
||||||
|
|
||||||
static class TabbedPane extends Container<TabbedPane.TabGroup> {
|
static class TabbedPane extends Container<TabbedPane.TabGroup> {
|
||||||
TextureRegion defaultBackground;
|
TextureRegion defaultBackground;
|
||||||
ClickListener clickListener;
|
ClickListener clickListener;
|
||||||
@ -665,4 +710,93 @@ public class LobbyScreen extends ScreenAdapter {
|
|||||||
@Override public void exited() {}
|
@Override public void exited() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
PENDING,
|
||||||
|
WAITING
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResponseListener {
|
||||||
|
void handleResponse(MCP packet);
|
||||||
|
void failed(Throwable t);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Connection extends Thread implements Disposable {
|
||||||
|
Socket socket;
|
||||||
|
ByteBuffer buffer = BufferUtils.newByteBuffer(4096);
|
||||||
|
AtomicBoolean kill = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
LobbyScreen.State state = LobbyScreen.State.PENDING;
|
||||||
|
|
||||||
|
Connection(Socket socket) {
|
||||||
|
super(Connection.class.getName());
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendRequest(ByteBuffer data, ResponseListener listener) {
|
||||||
|
if (state != LobbyScreen.State.WAITING) throw new IllegalStateException("Sending request before connection has been accepted!");
|
||||||
|
try {
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
WritableByteChannel channelOut = Channels.newChannel(out);
|
||||||
|
channelOut.write(data);
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
buffer.mark();
|
||||||
|
InputStream in = socket.getInputStream();
|
||||||
|
ReadableByteChannel channelIn = Channels.newChannel(in);
|
||||||
|
channelIn.read(buffer);
|
||||||
|
buffer.limit(buffer.position());
|
||||||
|
buffer.reset();
|
||||||
|
|
||||||
|
MCP packet = MCP.getRootAsMCP(buffer);
|
||||||
|
Gdx.app.log(TAG, "packet type " + MCPData.name(packet.dataType()));
|
||||||
|
listener.handleResponse(packet);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
listener.failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Gdx.app.log(TAG, "Connecting to MCP " + socket.getRemoteAddress());
|
||||||
|
while (!kill.get()) {
|
||||||
|
try {
|
||||||
|
switch (state) {
|
||||||
|
case PENDING: {
|
||||||
|
if (DEBUG_CONNECTION) Gdx.app.debug(TAG, "pending connection...");
|
||||||
|
buffer.clear();
|
||||||
|
buffer.mark();
|
||||||
|
ReadableByteChannel in = Channels.newChannel(socket.getInputStream());
|
||||||
|
in.read(buffer);
|
||||||
|
buffer.limit(buffer.position());
|
||||||
|
buffer.reset();
|
||||||
|
|
||||||
|
MCP packet = MCP.getRootAsMCP(buffer);
|
||||||
|
Gdx.app.log(TAG, "packet type " + MCPData.name(packet.dataType()));
|
||||||
|
process(socket, packet);
|
||||||
|
state = LobbyScreen.State.WAITING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WAITING:
|
||||||
|
try {
|
||||||
|
Thread.sleep(100); // sleep to save cpu
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Gdx.app.log(TAG, t.getMessage(), t);
|
||||||
|
kill.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, "closing socket...");
|
||||||
|
if (socket != null) socket.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
kill.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import com.badlogic.gdx.utils.BufferUtils;
|
import com.badlogic.gdx.utils.BufferUtils;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
import com.riiablo.Riiablo;
|
import com.riiablo.Riiablo;
|
||||||
import com.riiablo.codec.Animation;
|
import com.riiablo.codec.Animation;
|
||||||
@ -125,7 +126,7 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
connection.start();
|
connection.start();
|
||||||
} catch (GdxRuntimeException t) {
|
} catch (GdxRuntimeException t) {
|
||||||
Gdx.app.error(TAG, t.getMessage());
|
Gdx.app.error(TAG, t.getMessage());
|
||||||
if (connection != null) connection.kill.set(true);
|
if (connection != null) connection.dispose();
|
||||||
else if (socket != null) socket.dispose();
|
else if (socket != null) socket.dispose();
|
||||||
}
|
}
|
||||||
} else if (actor == btnAccountSettings) {
|
} else if (actor == btnAccountSettings) {
|
||||||
@ -230,7 +231,7 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
Riiablo.assets.unload(buttonDescriptor.fileName);
|
Riiablo.assets.unload(buttonDescriptor.fileName);
|
||||||
Riiablo.assets.unload(selectDescriptor.fileName);
|
Riiablo.assets.unload(selectDescriptor.fileName);
|
||||||
Riiablo.assets.unload(textbox2Descriptor.fileName);
|
Riiablo.assets.unload(textbox2Descriptor.fileName);
|
||||||
if (connection != null) connection.kill.set(true);
|
if (connection != null) connection.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -275,7 +276,7 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
ACCEPTED
|
ACCEPTED
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Connection extends Thread {
|
private class Connection extends Thread implements Disposable {
|
||||||
Socket socket;
|
Socket socket;
|
||||||
ByteBuffer buffer = BufferUtils.newByteBuffer(4096);
|
ByteBuffer buffer = BufferUtils.newByteBuffer(4096);
|
||||||
AtomicBoolean kill = new AtomicBoolean(false);
|
AtomicBoolean kill = new AtomicBoolean(false);
|
||||||
@ -290,6 +291,7 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Gdx.app.log(TAG, "Connecting to BNLS " + socket.getRemoteAddress());
|
||||||
while (!kill.get()) {
|
while (!kill.get()) {
|
||||||
try {
|
try {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -348,5 +350,10 @@ public class LoginScreen extends ScreenAdapter {
|
|||||||
Gdx.app.log(TAG, "closing socket...");
|
Gdx.app.log(TAG, "closing socket...");
|
||||||
if (socket != null) socket.dispose();
|
if (socket != null) socket.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
kill.set(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
server/mcp/build.gradle
Normal file
29
server/mcp/build.gradle
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
sourceCompatibility = 1.7
|
||||||
|
sourceSets.main.java.srcDirs = [ "src/" ]
|
||||||
|
sourceSets.test.java.srcDirs = [ "test/" ]
|
||||||
|
|
||||||
|
project.ext.mainClassName = "com.riiablo.server.mcp.MCP"
|
||||||
|
project.ext.assetsDir = new File("../android/assets");
|
||||||
|
|
||||||
|
task run(dependsOn: classes, type: JavaExec) {
|
||||||
|
main = project.mainClassName
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
standardInput = System.in
|
||||||
|
workingDir = project.assetsDir
|
||||||
|
ignoreExitValue = true
|
||||||
|
}
|
||||||
|
|
||||||
|
task dist(type: Jar) {
|
||||||
|
from files(sourceSets.main.output.classesDir)
|
||||||
|
from files(sourceSets.main.output.resourcesDir)
|
||||||
|
from {configurations.compile.collect {zipTree(it)}}
|
||||||
|
from files(project.assetsDir);
|
||||||
|
|
||||||
|
manifest {
|
||||||
|
attributes 'Server-Class': project.mainClassName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dist.dependsOn classes
|
277
server/mcp/src/com/riiablo/server/mcp/MCP.java
Normal file
277
server/mcp/src/com/riiablo/server/mcp/MCP.java
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
package com.riiablo.server.mcp;
|
||||||
|
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.ApplicationAdapter;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Net;
|
||||||
|
import com.badlogic.gdx.backends.headless.HeadlessApplication;
|
||||||
|
import com.badlogic.gdx.backends.headless.HeadlessApplicationConfiguration;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
import com.badlogic.gdx.net.ServerSocket;
|
||||||
|
import com.badlogic.gdx.net.Socket;
|
||||||
|
import com.badlogic.gdx.utils.BufferUtils;
|
||||||
|
import com.riiablo.net.GameSession;
|
||||||
|
import com.riiablo.net.packet.bnls.ConnectionAccepted;
|
||||||
|
import com.riiablo.net.packet.bnls.ConnectionClosed;
|
||||||
|
import com.riiablo.net.packet.mcp.ListGames;
|
||||||
|
import com.riiablo.net.packet.mcp.MCPData;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class MCP extends ApplicationAdapter {
|
||||||
|
private static final String TAG = "MCP";
|
||||||
|
|
||||||
|
private static final int PORT = 6111;
|
||||||
|
private static final int MAX_CLIENTS = 32;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
|
||||||
|
new HeadlessApplication(new MCP(), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSocket server;
|
||||||
|
ByteBuffer buffer;
|
||||||
|
Thread main;
|
||||||
|
AtomicBoolean kill;
|
||||||
|
Thread cli;
|
||||||
|
ThreadGroup clientThreads;
|
||||||
|
CopyOnWriteArrayList<Client> CLIENTS = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
Map<String, GameSession> sessions = new ConcurrentHashMap<>();
|
||||||
|
{
|
||||||
|
sessions.put("test1", new GameSession() {{
|
||||||
|
this.name = "test1";
|
||||||
|
this.desc = "desc1";
|
||||||
|
}});
|
||||||
|
sessions.put("test2", new GameSession() {{
|
||||||
|
this.name = "test2";
|
||||||
|
this.desc = "desc2";
|
||||||
|
}});
|
||||||
|
sessions.put("test3", new GameSession() {{
|
||||||
|
this.name = "test3";
|
||||||
|
this.desc = "desc3";
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
MCP() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
final Calendar calendar = Calendar.getInstance();
|
||||||
|
DateFormat format = DateFormat.getDateTimeInstance();
|
||||||
|
Gdx.app.log(TAG, format.format(calendar.getTime()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
InetAddress address = InetAddress.getLocalHost();
|
||||||
|
Gdx.app.log(TAG, "IP Address: " + address.getHostAddress() + ":" + PORT);
|
||||||
|
Gdx.app.log(TAG, "Host Name: " + address.getHostName());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
Gdx.app.error(TAG, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
clientThreads = new ThreadGroup("MCPClients");
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, "Starting server...");
|
||||||
|
server = Gdx.net.newServerSocket(Net.Protocol.TCP, PORT, null);
|
||||||
|
buffer = BufferUtils.newByteBuffer(4096);
|
||||||
|
kill = new AtomicBoolean(false);
|
||||||
|
main = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!kill.get()) {
|
||||||
|
Gdx.app.log(TAG, "waiting...");
|
||||||
|
Socket socket = server.accept(null);
|
||||||
|
Gdx.app.log(TAG, "connection from " + socket.getRemoteAddress());
|
||||||
|
if (CLIENTS.size() >= MAX_CLIENTS) {
|
||||||
|
try {
|
||||||
|
ConnectionDenied(socket, "Server is Full");
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
} finally {
|
||||||
|
socket.dispose();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
ConnectionAccepted(socket);
|
||||||
|
new Client(socket).start();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
socket.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, "killing child threads...");
|
||||||
|
for (Client client : CLIENTS) {
|
||||||
|
if (client != null) {
|
||||||
|
client.kill.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, "killing thread...");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
main.setName("MCP");
|
||||||
|
main.start();
|
||||||
|
|
||||||
|
cli = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||||
|
while (!kill.get()) {
|
||||||
|
try {
|
||||||
|
if (!reader.ready()) continue;
|
||||||
|
String in = reader.readLine();
|
||||||
|
if (in.equalsIgnoreCase("exit")) {
|
||||||
|
Gdx.app.exit();
|
||||||
|
} else if (in.equalsIgnoreCase("games")) {
|
||||||
|
Gdx.app.log(TAG, "games:");
|
||||||
|
for (GameSession session : sessions.values()) {
|
||||||
|
Gdx.app.log(TAG, " " + session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Gdx.app.log(TAG, t.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cli.setName("CLI");
|
||||||
|
cli.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
Gdx.app.log(TAG, "Shutting down...");
|
||||||
|
kill.set(true);
|
||||||
|
server.dispose();
|
||||||
|
try {
|
||||||
|
main.join();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(Socket socket, com.riiablo.net.packet.mcp.MCP packet) throws IOException {
|
||||||
|
switch (packet.dataType()) {
|
||||||
|
case MCPData.ListGames:
|
||||||
|
ListGames(socket, packet);
|
||||||
|
break;
|
||||||
|
// case MCPData.LoginResponse:
|
||||||
|
// LoginResponse(socket, packet);
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
Gdx.app.error(TAG, "Unknown packet type: " + packet.dataType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ConnectionDenied(Socket socket, String reason) throws IOException {
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
int reasonOffset = builder.createString(reason);
|
||||||
|
int connectionDeniedId = ConnectionClosed.createConnectionClosed(builder, reasonOffset);
|
||||||
|
int id = com.riiablo.net.packet.mcp.MCP.createMCP(builder, MCPData.ConnectionClosed, connectionDeniedId);
|
||||||
|
builder.finish(id);
|
||||||
|
|
||||||
|
ByteBuffer data = builder.dataBuffer();
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
WritableByteChannel channel = Channels.newChannel(out);
|
||||||
|
channel.write(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ConnectionAccepted(Socket socket) throws IOException {
|
||||||
|
Gdx.app.debug(TAG, "Connection accepted!");
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
ConnectionAccepted.startConnectionAccepted(builder);
|
||||||
|
int connectionAcceptedId = ConnectionAccepted.endConnectionAccepted(builder);
|
||||||
|
int id = com.riiablo.net.packet.mcp.MCP.createMCP(builder, MCPData.ConnectionAccepted, connectionAcceptedId);
|
||||||
|
builder.finish(id);
|
||||||
|
|
||||||
|
ByteBuffer data = builder.dataBuffer();
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
WritableByteChannel channel = Channels.newChannel(out);
|
||||||
|
channel.write(data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ListGames(Socket socket, com.riiablo.net.packet.mcp.MCP packet) throws IOException {
|
||||||
|
ListGames listGames = (ListGames) packet.data(new ListGames());
|
||||||
|
Gdx.app.debug(TAG, "Games list requested by " + socket.getRemoteAddress());
|
||||||
|
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int[] sessions = new int[this.sessions.size()];
|
||||||
|
for (GameSession session : this.sessions.values()) {
|
||||||
|
sessions[i++] = com.riiablo.net.packet.mcp.GameSession.createGameSession(builder, i, 0, builder.createString(session.name), builder.createString(session.desc), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sessionsVec = ListGames.createGamesVector(builder, sessions);
|
||||||
|
|
||||||
|
ListGames.startListGames(builder);
|
||||||
|
ListGames.addGames(builder, sessionsVec);
|
||||||
|
int listGamesOffset = ListGames.endListGames(builder);
|
||||||
|
int id = com.riiablo.net.packet.mcp.MCP.createMCP(builder, MCPData.ListGames, listGamesOffset);
|
||||||
|
builder.finish(id);
|
||||||
|
|
||||||
|
ByteBuffer data = builder.dataBuffer();
|
||||||
|
OutputStream out = socket.getOutputStream();
|
||||||
|
WritableByteChannel channel = Channels.newChannel(out);
|
||||||
|
channel.write(data);
|
||||||
|
Gdx.app.log(TAG, "returning games list...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String generateClientName() {
|
||||||
|
return String.format("Client-%08X", MathUtils.random(1, Integer.MAX_VALUE - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Client extends Thread {
|
||||||
|
Socket socket;
|
||||||
|
AtomicBoolean kill = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
Client(Socket socket) {
|
||||||
|
super(clientThreads, generateClientName());
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!kill.get()) {
|
||||||
|
try {
|
||||||
|
buffer.clear();
|
||||||
|
buffer.mark();
|
||||||
|
ReadableByteChannel in = Channels.newChannel(socket.getInputStream());
|
||||||
|
if (in.read(buffer) == -1) {
|
||||||
|
kill.set(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer.limit(buffer.position());
|
||||||
|
buffer.reset();
|
||||||
|
|
||||||
|
com.riiablo.net.packet.mcp.MCP packet = com.riiablo.net.packet.mcp.MCP.getRootAsMCP(buffer);
|
||||||
|
Gdx.app.log(TAG, "packet type " + MCPData.name(packet.dataType()));
|
||||||
|
process(socket, packet);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Gdx.app.log(TAG, t.getMessage(), t);
|
||||||
|
kill.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, "closing socket...");
|
||||||
|
if (socket != null) socket.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
include 'tools', 'tester', 'ds1viewer', 'mpqviewer', 'server:bnls', 'desktop', 'android', 'mpqlib', 'core'
|
include 'tools', 'tester', 'ds1viewer', 'mpqviewer', 'server:bnls', 'server:mcp', 'desktop', 'android', 'mpqlib', 'core'
|
Reference in New Issue
Block a user