mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-03-28 02:23:31 +01:00
Upgrade to REL3.7 (#2164)
* Remove hardcoded quest data * Remove deprecated fields * Try to fix packet * Apply fix for token exchange * Upgrade to REL3.7 * Add obfuscated protocol definitions * Add missing enum (other protos too maybe) * Re-add field setters and add note on removal
This commit is contained in:
@@ -1,9 +1,5 @@
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import emu.grasscutter.game.Account;
|
||||
@@ -20,7 +16,12 @@ import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.GAME_INFO;
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public class GameSession implements GameSessionManager.KcpChannel {
|
||||
@@ -158,7 +159,10 @@ public class GameSession implements GameSessionManager.KcpChannel {
|
||||
@Override
|
||||
public void handleReceive(byte[] bytes) {
|
||||
// Decrypt and turn back into a packet
|
||||
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
|
||||
if (this.getState() != SessionState.WAITING_FOR_TOKEN)
|
||||
Crypto.xor(bytes, useSecretKey() ?
|
||||
Crypto.ENCRYPT_KEY :
|
||||
Crypto.DISPATCH_KEY);
|
||||
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
|
||||
|
||||
// Log
|
||||
|
||||
@@ -1,110 +1,109 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
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;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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) {
|
||||
var 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class PacketGachaWishRsp extends BasePacket {
|
||||
GachaWishRsp proto = GachaWishRsp.newBuilder()
|
||||
.setGachaType(gachaType)
|
||||
.setGachaScheduleId(scheduleId)
|
||||
.setWishItemId(itemId)
|
||||
.setTenCostItemId(itemId)
|
||||
.setWishProgress(progress)
|
||||
.setWishMaxProgress(maxProgress)
|
||||
.build();
|
||||
|
||||
@@ -14,6 +14,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||
|
||||
this.setUseDispatchKey(true);
|
||||
this.shouldEncrypt = false;
|
||||
|
||||
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
|
||||
.setUid(session.getPlayer().getUid())
|
||||
@@ -37,6 +38,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||
|
||||
this.setUseDispatchKey(true);
|
||||
this.shouldEncrypt = false;
|
||||
|
||||
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
|
||||
.setUid(session.getPlayer().getUid())
|
||||
@@ -56,6 +58,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||
|
||||
this.setUseDispatchKey(true);
|
||||
this.shouldEncrypt = false;
|
||||
|
||||
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
|
||||
.setUid(session.getPlayer().getUid())
|
||||
|
||||
@@ -42,9 +42,11 @@ public class PacketGetShopRsp extends BasePacket {
|
||||
.setEndTime(info.getEndTime())
|
||||
.setMinLevel(info.getMinLevel())
|
||||
.setMaxLevel(info.getMaxLevel())
|
||||
.setMcoin(info.getMcoin())
|
||||
.setDisableType(info.getDisableType())
|
||||
.setSecondarySheetId(info.getSecondarySheetId());
|
||||
.setMcoin(info.getMcoin());
|
||||
|
||||
// These fields are deprecated as of REL3.7
|
||||
// .setDisableType(info.getDisableType())
|
||||
// .setSecondarySheetId(info.getSecondarySheetId());
|
||||
if (info.getCostItemList() != null) {
|
||||
goods.addAllCostItemList(info.getCostItemList().stream().map(x -> ItemParamOuterClass.ItemParam.newBuilder().setItemId(x.getId()).setCount(x.getCount()).build()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user