Grasscutter/src/main/java/emu/grasscutter/server/game/GameSessionManager.java
zhaodice b3f1103292
[Ready]Replace deprecated KCP library (#1237)
* Replace deprecated KCP library

support get srtt

Waiting server to establish

logicThread

Print Bad Package Information

Avoid orphan data

improve conv id security

* Improve connection subsequence
2022-06-15 04:13:35 -07:00

111 lines
3.5 KiB
Java

package emu.grasscutter.server.game;
import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.Utils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.DefaultEventLoop;
import kcp.highway.KcpListener;
import kcp.highway.Ukcp;
public class GameSessionManager {
private static final DefaultEventLoop logicThread = new DefaultEventLoop();
private static final ConcurrentHashMap<Ukcp,GameSession> sessions = new ConcurrentHashMap<>();
private static final KcpListener listener = new KcpListener(){
@Override
public void onConnected(Ukcp ukcp) {
int times = 0;
GameServer server = Grasscutter.getGameServer();
while (server==null){//Waiting server to establish
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
ukcp.close();
return;
}
if(times++>5){
Grasscutter.getLogger().error("Service is not available!");
ukcp.close();
return;
}
server = Grasscutter.getGameServer();
}
GameSession conversation = new GameSession(server);
conversation.onConnected(new KcpTunnel(){
@Override
public InetSocketAddress getAddress() {
return ukcp.user().getRemoteAddress();
}
@Override
public void writeData(byte[] bytes) {
ByteBuf buf = Unpooled.wrappedBuffer(bytes);
ukcp.write(buf);
buf.release();
}
@Override
public void close() {
ukcp.close();
}
@Override
public int getSrtt() {
return ukcp.srtt();
}
});
sessions.put(ukcp,conversation);
}
@Override
public void handleReceive(ByteBuf buf, Ukcp kcp) {
byte[] byteData = Utils.byteBufToArray(buf);
logicThread.execute(() -> {
try {
GameSession conversation = sessions.get(kcp);
if(conversation!=null) {
conversation.handleReceive(byteData);
}
}catch (Exception e){
e.printStackTrace();
}
});
}
@Override
public void handleException(Throwable ex, Ukcp ukcp) {
}
@Override
public void handleClose(Ukcp ukcp) {
GameSession conversation = sessions.get(ukcp);
if(conversation!=null) {
conversation.handleClose();
sessions.remove(ukcp);
}
}
};
public static KcpListener getListener() {
return listener;
}
interface KcpTunnel{
InetSocketAddress getAddress();
void writeData(byte[] bytes);
void close();
int getSrtt();
}
interface KcpChannel{
void onConnected(KcpTunnel tunnel);
void handleClose();
void handleReceive(byte[] bytes);
}
}