MaimMim Man in the middle minetest interceptor
- prototype - between client and server, allow to capture all exchanges and potentially change them - created to capture server maps in laby - first test get only MapBlock, support version serialization version 28 - prepartion for 29 with zstd but untested.
This commit is contained in:
4
java/org/artisanlogiciel/games/minetest/net/Address.java
Normal file
4
java/org/artisanlogiciel/games/minetest/net/Address.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public class Address {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
import org.artisanlogiciel.games.minetest.core.Serialize;
|
||||
|
||||
public class BufferedPacket {
|
||||
|
||||
public static int BASE_HEADER_SIZE = 7;
|
||||
|
||||
// Data of the packet, including headers
|
||||
byte[] m_data;
|
||||
|
||||
BufferedPacket(byte[] data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
int getSeqNum()
|
||||
throws PacketException
|
||||
{
|
||||
return Serialize.readU16(m_data, BASE_HEADER_SIZE + 1, size());
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return m_data.length;
|
||||
}
|
||||
}
|
||||
9
java/org/artisanlogiciel/games/minetest/net/Channel.java
Normal file
9
java/org/artisanlogiciel/games/minetest/net/Channel.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public class Channel {
|
||||
|
||||
int readNextIncomingSeqNum()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public class ConnectionEvent {
|
||||
|
||||
ConnectionEventType m_event_type;
|
||||
int m_peer_id;
|
||||
byte[] m_data;
|
||||
boolean m_timeout;
|
||||
|
||||
|
||||
ConnectionEvent(ConnectionEventType eventType)
|
||||
{
|
||||
m_event_type = eventType;
|
||||
}
|
||||
|
||||
String describe()
|
||||
{
|
||||
return m_event_type.toString();
|
||||
}
|
||||
|
||||
ConnectionEventPtr create(ConnectionEventType type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ConnectionEventPtr dataReceived(int peer_id, byte[] data)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ConnectionEventPtr peerAdded(int peer_id, Address address)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ConnectionEventPtr peerRemoved(int peer_id, boolean is_timeout, Address address)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ConnectionEventPtr bindFailed()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public class ConnectionEventPtr {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public enum ConnectionEventType {
|
||||
CONNEVENT_NONE,
|
||||
CONNEVENT_DATA_RECEIVED,
|
||||
CONNEVENT_PEER_ADDED,
|
||||
CONNEVENT_PEER_REMOVED,
|
||||
CONNEVENT_BIND_FAILED
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
import org.artisanlogiciel.games.minetest.core.Serialize;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class IncomingSplitBuffer {
|
||||
|
||||
int m_seqnum;
|
||||
int m_chunk_count;
|
||||
int m_chunk_num;
|
||||
|
||||
// number of chunks
|
||||
int m_got = 0;
|
||||
|
||||
NetworkPacket m_list[] = null;
|
||||
BufferedPacket m_reassembled = null;
|
||||
|
||||
BufferedPacket insert(NetworkPacket networkPacket)
|
||||
throws PacketException
|
||||
{
|
||||
|
||||
byte[] buffer = networkPacket.getBuffer();
|
||||
int length = networkPacket.getLength();
|
||||
int offset = networkPacket.getOffset();
|
||||
|
||||
int type = Serialize.readU8(buffer , offset, length);
|
||||
int seqnum = Serialize.readU16(buffer, offset + 1, length);
|
||||
// total number of chunk
|
||||
int chunk_count = Serialize.readU16(buffer, offset + 3, length);
|
||||
// this chunk number
|
||||
int chunk_num = Serialize.readU16(buffer, offset+ 5, length);
|
||||
|
||||
System.out.println("Split length " + length + " type " + type + " seqnum " + seqnum + " chunk_num/chunk_count " + chunk_num + "/" + chunk_count );
|
||||
|
||||
// move to next header
|
||||
networkPacket.addOffset(7);
|
||||
|
||||
if (m_reassembled != null)
|
||||
{
|
||||
return m_reassembled;
|
||||
}
|
||||
|
||||
if (m_list == null )
|
||||
{
|
||||
m_list = new NetworkPacket[chunk_count];
|
||||
}
|
||||
|
||||
if ( chunk_num < chunk_count && (m_list[chunk_num] == null) )
|
||||
{
|
||||
m_list[chunk_num] = networkPacket;
|
||||
m_got ++;
|
||||
}
|
||||
//todo seqnum
|
||||
m_seqnum = seqnum;
|
||||
|
||||
// fully obtained
|
||||
if ( m_got == chunk_count )
|
||||
{
|
||||
reassemble();
|
||||
}
|
||||
|
||||
return m_reassembled;
|
||||
|
||||
}
|
||||
|
||||
private void reassemble()
|
||||
{
|
||||
// keep first header since result is a valid BufferedPacket
|
||||
int fullLength = BufferedPacket.BASE_HEADER_SIZE;
|
||||
for (NetworkPacket networkPacket : m_list )
|
||||
{
|
||||
fullLength += networkPacket.getLength() - networkPacket.getOffset();
|
||||
}
|
||||
byte[] reassembled = new byte[fullLength];
|
||||
NetworkPacket first = m_list[0];
|
||||
System.arraycopy(first.getBuffer(),0,reassembled,0,BufferedPacket.BASE_HEADER_SIZE);
|
||||
int offset = BufferedPacket.BASE_HEADER_SIZE;
|
||||
for (NetworkPacket networkPacket : m_list )
|
||||
{
|
||||
int dataLength = networkPacket.getLength() - networkPacket.getOffset();
|
||||
System.arraycopy(networkPacket.getBuffer(), networkPacket.getOffset(),reassembled,offset,dataLength);
|
||||
offset+=dataLength;
|
||||
}
|
||||
m_reassembled = new BufferedPacket(reassembled);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
127
java/org/artisanlogiciel/games/minetest/net/MiM.java
Normal file
127
java/org/artisanlogiciel/games/minetest/net/MiM.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
|
||||
/**
|
||||
* Man in the middle UDP
|
||||
* very simple for one client only
|
||||
*/
|
||||
|
||||
public class MiM {
|
||||
|
||||
DatagramSocket serverSocket;
|
||||
boolean running = false;
|
||||
InetSocketAddress serverAddress;
|
||||
// will be captured, incoming address & port
|
||||
SocketAddress fromClient = null;
|
||||
int localPort;
|
||||
PacketHandler handler = null;
|
||||
|
||||
public MiM(int myPort, InetSocketAddress remoteAddress)
|
||||
{
|
||||
localPort = myPort;
|
||||
serverAddress = remoteAddress;
|
||||
}
|
||||
|
||||
public void launch()
|
||||
{
|
||||
// ServerSocket socket = new ServerSocket()
|
||||
try {
|
||||
handler = new PacketHandler();
|
||||
serverSocket = new DatagramSocket(localPort);
|
||||
DatagramSocket in = serverSocket;
|
||||
SocketAddress fromServer = serverAddress;
|
||||
Thread toServer = new Thread( () -> {runFromToServer(in,fromServer);});
|
||||
running = true;
|
||||
toServer.start();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
System.out.println("problem");
|
||||
e.printStackTrace(System.err);
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
public void runFromToServer(DatagramSocket in, SocketAddress fromServer) {
|
||||
try {
|
||||
|
||||
while (running) {
|
||||
// quick way, a new buffer at each reception
|
||||
// to handle split packets that are buffered
|
||||
byte[] buf = new byte[4096];
|
||||
SocketAddress toRemote = null;
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
||||
in.receive(packet);
|
||||
SocketAddress from = packet.getSocketAddress();
|
||||
if ( from.equals(fromServer)) {
|
||||
// no client yet
|
||||
if ( fromClient == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fromServer(buf,packet.getLength());
|
||||
toRemote = fromClient;
|
||||
}
|
||||
else
|
||||
{
|
||||
// record client
|
||||
// later on to be smart : could try to record peer id ?
|
||||
// will add a constraint : only one auth at a time
|
||||
if ( fromClient == null ) {
|
||||
fromClient = from;
|
||||
}
|
||||
fromClient(buf,packet.getLength());
|
||||
toRemote = fromServer;
|
||||
}
|
||||
packet = new DatagramPacket(buf, packet.getLength(), toRemote);
|
||||
in.send(packet);
|
||||
}
|
||||
}
|
||||
catch( IOException ioException)
|
||||
{
|
||||
//
|
||||
System.out.println("oops");
|
||||
}
|
||||
// socket.close();
|
||||
}
|
||||
|
||||
void fromServer(byte[] buffer, int length)
|
||||
{
|
||||
try {
|
||||
// reply from server
|
||||
if (handler != null) {
|
||||
handler.fromServer(buffer, length);
|
||||
}
|
||||
}
|
||||
catch (PacketException packetException)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
void fromClient(byte[] buffer, int length)
|
||||
{
|
||||
try {
|
||||
// reply from client
|
||||
if (handler != null) {
|
||||
handler.fromClient(buffer, length);
|
||||
}
|
||||
}
|
||||
catch (PacketException packetException)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
import org.artisanlogiciel.games.minetest.core.Serialize;
|
||||
import org.artisanlogiciel.games.minetest.core.v3s16;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class NetworkPacket {
|
||||
|
||||
int m_protocol_id;
|
||||
int m_peer_id;
|
||||
int m_channel;
|
||||
public PacketType packetType;
|
||||
|
||||
// somehow a BufferedPacket ...
|
||||
byte[] m_buffer; // m_data
|
||||
// used part in buffer
|
||||
int m_length; // m_datasize ?
|
||||
// current header index in packet
|
||||
int m_offset; // m_read_offset
|
||||
|
||||
short m_command = 0;
|
||||
|
||||
public NetworkPacket(int protocol_id, int peer_id, int channel, PacketType type, byte[] buffer, int length) {
|
||||
this.m_protocol_id = protocol_id;
|
||||
this.m_peer_id = peer_id;
|
||||
this.m_channel = channel;
|
||||
this.packetType = type;
|
||||
m_buffer = buffer;
|
||||
m_length = length;
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
public int getChannel()
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
public byte[] getBuffer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void addOffset(int offset)
|
||||
{
|
||||
m_offset += offset;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public v3s16 v3s16()
|
||||
throws PacketException
|
||||
{
|
||||
return Serialize.readV3S16(m_buffer, m_offset, m_length);
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer()
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.wrap(m_buffer,m_offset,m_length-m_offset);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
287
java/org/artisanlogiciel/games/minetest/net/PacketHandler.java
Normal file
287
java/org/artisanlogiciel/games/minetest/net/PacketHandler.java
Normal file
@@ -0,0 +1,287 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
import com.github.luben.zstd.Zstd;
|
||||
import org.artisanlogiciel.games.minetest.MapBlock;
|
||||
import org.artisanlogiciel.games.minetest.MapNode;
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
import org.artisanlogiciel.games.minetest.core.Serialize;
|
||||
import org.artisanlogiciel.games.minetest.core.v2s16;
|
||||
import org.artisanlogiciel.games.minetest.core.v3s16;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* see src/network/networkprotocol.h of minetest sources
|
||||
*
|
||||
*
|
||||
* === NOTES ===
|
||||
*
|
||||
* A packet is sent through a channel to a peer with a basic header:
|
||||
* Header (7 bytes):
|
||||
* [0] u32 protocol_id
|
||||
* [4] session_t sender_peer_id
|
||||
* [6] u8 channel
|
||||
* sender_peer_id:
|
||||
* Unique to each peer.
|
||||
* value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
|
||||
* value 1 (PEER_ID_SERVER) is reserved for server
|
||||
* these constants are defined in constants.h
|
||||
* channel:
|
||||
* Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist.
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
public class PacketHandler {
|
||||
|
||||
ReliablePacketBuffer reliableBuffer = null;
|
||||
|
||||
IncomingSplitBuffer[] incomingChanneleSplitBuffer = new IncomingSplitBuffer[4];
|
||||
|
||||
// server serialization in hello version
|
||||
int ser_version;
|
||||
|
||||
// minetest protocol should be 0x4f457403
|
||||
static int readProtocolId(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
return Serialize.readU32(buffer, 0, length);
|
||||
}
|
||||
|
||||
static int readPeerId(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
return Serialize.readU16(buffer,4,length);
|
||||
}
|
||||
|
||||
static int readChannel(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
return Serialize.readU8(buffer, 6, length);
|
||||
}
|
||||
|
||||
NetworkPacket handleAny(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
int protocol_id = readProtocolId(buffer, length);
|
||||
int peer_id = readPeerId(buffer, length);
|
||||
int channel = readChannel(buffer, length);
|
||||
int type = Serialize.readU8(buffer,7,length);
|
||||
PacketType packetType = PacketType.getPacketType(type);
|
||||
|
||||
NetworkPacket networkPacket = new NetworkPacket(protocol_id,peer_id,channel,packetType, buffer, length);
|
||||
|
||||
// offset of packet within buffer.
|
||||
networkPacket.addOffset(BufferedPacket.BASE_HEADER_SIZE);
|
||||
|
||||
System.out.println("length " + length + " protocol_id " + String.format("%x", protocol_id) + " peer_id " + peer_id + " channel " + channel + " type " + packetType);
|
||||
|
||||
return networkPacket;
|
||||
}
|
||||
|
||||
void handlePacketType_Control(NetworkPacket networkPacket)
|
||||
throws PacketException {
|
||||
}
|
||||
|
||||
void handlePacketType_Reliable(NetworkPacket networkPacket)
|
||||
throws PacketException
|
||||
{
|
||||
// TODO handle misordered...
|
||||
/*
|
||||
if ( reliableBuffer == null )
|
||||
{
|
||||
reliableBuffer = new ReliablePacketBuffer();
|
||||
}
|
||||
|
||||
BufferedPacket packet = new BufferedPacket(buffer);
|
||||
int nextExpected = 0;
|
||||
reliableBuffer.insert(packet, nextExpected);
|
||||
*/
|
||||
|
||||
// handle nested packet
|
||||
networkPacket.addOffset(3);
|
||||
int offset = networkPacket.getOffset();
|
||||
byte buffer[] = networkPacket.getBuffer();
|
||||
int length = networkPacket.getLength();
|
||||
|
||||
PacketType packetType = PacketType.getPacketType(Serialize.readU8(buffer,offset,length));
|
||||
|
||||
System.out.println( "reliable " + packetType.toString());
|
||||
|
||||
switch (packetType)
|
||||
{
|
||||
case PACKET_TYPE_CONTROL:
|
||||
//
|
||||
handlePacketType_Control(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_ORIGINAL:
|
||||
handlePacketType_Original(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_SPLIT:
|
||||
handlePacketType_Split(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_RELIABLE:
|
||||
// this is an error, no nested reliable accepted.
|
||||
throw new PacketException("nested reliable");
|
||||
default: // error
|
||||
throw new PacketException("unknown type");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleCommand_Hello(NetworkPacket networkPacket)
|
||||
throws PacketException {
|
||||
|
||||
// u8 deployed serialisation version
|
||||
ByteBuffer buffer = networkPacket.getByteBuffer();
|
||||
int ser_ver = Serialize.readU8(buffer);
|
||||
ser_version = ser_ver;
|
||||
// u16 deployed network compression mode
|
||||
int net_compress = Serialize.readU16(buffer);
|
||||
// u16 deployed protocol version
|
||||
int deployed = Serialize.readU16(buffer);
|
||||
System.out.println(String.format("HELLO ser_ver=%d net_compress %d deployed %d", ser_ver,net_compress,deployed));
|
||||
// u32 supported auth methods
|
||||
// std::string username that should be used for legacy hash (for proper casing)
|
||||
|
||||
}
|
||||
|
||||
// clientpackethandler.cpp Client::handleCommand_BlockData(NetworkPacket* pkt)
|
||||
// TOCLIENT_BLOCKDATA
|
||||
void handleCommand_BlockData(NetworkPacket networkPacket)
|
||||
throws PacketException
|
||||
{
|
||||
v3s16 p = networkPacket.v3s16();
|
||||
|
||||
// will be used to get vector...
|
||||
// v2s16 p2d = new v2s16(p.X,p.Z);
|
||||
|
||||
System.out.println(String.format(" (X,Y,Z) %d %d %d", p.X, p.Y,p.Z));
|
||||
//
|
||||
networkPacket.addOffset(6);
|
||||
|
||||
// FIXME get it from handshake
|
||||
int version = 28;
|
||||
|
||||
// Should be a MapBlock
|
||||
MapBlock block = new MapBlock();
|
||||
block.deSerialize(networkPacket.getByteBuffer(),version);
|
||||
|
||||
// now we have a block ! what to do with it ?
|
||||
}
|
||||
|
||||
void handlePacketCommand(NetworkPacket networkPacket)
|
||||
throws PacketException {
|
||||
|
||||
// consume type and ??? well ... 2
|
||||
int command = Serialize.readU16(networkPacket.getBuffer(),networkPacket.getOffset(),networkPacket.getLength());
|
||||
|
||||
System.out.println(String.format("command %x length %d", command, networkPacket.getLength()));
|
||||
|
||||
networkPacket.addOffset(2);
|
||||
// Original ... toClient - toServer
|
||||
switch (command)
|
||||
{
|
||||
case 0x02:
|
||||
{
|
||||
System.out.println("TOCLIENT_HELLO");
|
||||
handleCommand_Hello(networkPacket);
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
{
|
||||
System.out.println("TOCLIENT_BLOCKDATA");
|
||||
handleCommand_BlockData(networkPacket);
|
||||
}
|
||||
break;
|
||||
case 0x4f:
|
||||
{
|
||||
//TOCLIENT_SET_SKY = 0x4f,
|
||||
System.out.println("TOCLIENT_SET_SKY");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handlePacketType_Original(NetworkPacket networkPacket)
|
||||
throws PacketException {
|
||||
|
||||
// eat original type 1.
|
||||
networkPacket.addOffset(1);
|
||||
handlePacketCommand(networkPacket);
|
||||
}
|
||||
|
||||
void handlePacketType_Split(NetworkPacket networkPacket)
|
||||
throws PacketException {
|
||||
|
||||
int channel = networkPacket.getChannel();
|
||||
if ( channel < incomingChanneleSplitBuffer.length) {
|
||||
IncomingSplitBuffer splitBuffer = incomingChanneleSplitBuffer[channel];
|
||||
if ( splitBuffer == null )
|
||||
{
|
||||
splitBuffer = new IncomingSplitBuffer();
|
||||
incomingChanneleSplitBuffer[channel] = splitBuffer;
|
||||
}
|
||||
if ( splitBuffer != null ) {
|
||||
BufferedPacket bufferedPacket = splitBuffer.insert(networkPacket);
|
||||
if ( bufferedPacket != null ) {
|
||||
// well should handle it.
|
||||
System.out.println("Reassembled packet size " + bufferedPacket.m_data.length);
|
||||
// reset it.
|
||||
incomingChanneleSplitBuffer[channel] = new IncomingSplitBuffer();
|
||||
handleBufferedPacket(bufferedPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new PacketException("invalid channel " + channel);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void handleBufferedPacket(BufferedPacket bufferedPacket)
|
||||
throws PacketException
|
||||
{
|
||||
// FIXME, why a BufferedPacket anyway since we finaly need a NetworkPacket ?
|
||||
NetworkPacket networkPacket = new NetworkPacket(0,0,0, PacketType.PACKET_TYPE_ORIGINAL,bufferedPacket.m_data, bufferedPacket.size());
|
||||
networkPacket.addOffset(BufferedPacket.BASE_HEADER_SIZE);
|
||||
handlePacketCommand(networkPacket);
|
||||
}
|
||||
|
||||
void fromServer(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
System.out.print(" <- ");
|
||||
NetworkPacket networkPacket = handleAny(buffer,length);
|
||||
|
||||
switch (networkPacket.packetType)
|
||||
{
|
||||
case PACKET_TYPE_CONTROL:
|
||||
//
|
||||
handlePacketType_Control(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_RELIABLE:
|
||||
//
|
||||
handlePacketType_Reliable(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_ORIGINAL:
|
||||
handlePacketType_Original(networkPacket);
|
||||
break;
|
||||
case PACKET_TYPE_SPLIT:
|
||||
handlePacketType_Split(networkPacket);
|
||||
break;
|
||||
default: // error
|
||||
throw new PacketException("unknown type");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void fromClient(byte[] buffer, int length)
|
||||
throws PacketException
|
||||
{
|
||||
System.out.print(" -> ");
|
||||
handleAny(buffer,length);
|
||||
}
|
||||
|
||||
}
|
||||
27
java/org/artisanlogiciel/games/minetest/net/PacketType.java
Normal file
27
java/org/artisanlogiciel/games/minetest/net/PacketType.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
public enum PacketType {
|
||||
PACKET_TYPE_CONTROL,
|
||||
PACKET_TYPE_ORIGINAL,
|
||||
PACKET_TYPE_SPLIT,
|
||||
PACKET_TYPE_RELIABLE,
|
||||
PACKET_TYPE_ERROR;
|
||||
|
||||
static PacketType getPacketType(int value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
return PACKET_TYPE_CONTROL;
|
||||
case 1:
|
||||
return PACKET_TYPE_ORIGINAL;
|
||||
case 2:
|
||||
return PACKET_TYPE_SPLIT;
|
||||
case 3:
|
||||
return PACKET_TYPE_RELIABLE;
|
||||
default:
|
||||
return PACKET_TYPE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.artisanlogiciel.games.minetest.net;
|
||||
|
||||
import org.artisanlogiciel.games.minetest.core.PacketException;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReliablePacketBuffer {
|
||||
|
||||
List<BufferedPacket> m_list = new LinkedList<>();
|
||||
|
||||
void insert(BufferedPacket packet, int nextExpected)
|
||||
throws PacketException
|
||||
{
|
||||
//
|
||||
int seqNum = packet.getSeqNum();
|
||||
m_list.add(packet);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user