mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-03-25 00:53:47 +01:00
Initial commit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package emu.grasscutter.server.dispatch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
|
||||
public class DispatchHttpJsonHandler implements HttpHandler {
|
||||
private final String response;
|
||||
|
||||
public DispatchHttpJsonHandler(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("application/json"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
package emu.grasscutter.server.dispatch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpsConfigurator;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp;
|
||||
import emu.grasscutter.net.proto.QueryRegionListHttpRspOuterClass.QueryRegionListHttpRsp;
|
||||
import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo;
|
||||
import emu.grasscutter.net.proto.RegionSimpleInfoOuterClass.RegionSimpleInfo;
|
||||
import emu.grasscutter.server.dispatch.json.ComboTokenReqJson;
|
||||
import emu.grasscutter.server.dispatch.json.ComboTokenResJson;
|
||||
import emu.grasscutter.server.dispatch.json.LoginAccountRequestJson;
|
||||
import emu.grasscutter.server.dispatch.json.LoginResultJson;
|
||||
import emu.grasscutter.server.dispatch.json.LoginTokenRequestJson;
|
||||
import emu.grasscutter.server.dispatch.json.ComboTokenReqJson.LoginTokenData;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
public class DispatchServer {
|
||||
private HttpsServer server;
|
||||
private final InetSocketAddress address;
|
||||
private final Gson gson;
|
||||
private QueryCurrRegionHttpRsp currRegion;
|
||||
|
||||
public String regionListBase64;
|
||||
public String regionCurrentBase64;
|
||||
|
||||
public static String query_region_list = "";
|
||||
public static String query_cur_region = "";
|
||||
|
||||
public DispatchServer() {
|
||||
this.address = new InetSocketAddress(Grasscutter.getConfig().DispatchServerIp, Grasscutter.getConfig().DispatchServerPort);
|
||||
this.gson = new GsonBuilder().create();
|
||||
|
||||
this.loadQueries();
|
||||
this.initRegion();
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public Gson getGsonFactory() {
|
||||
return gson;
|
||||
}
|
||||
|
||||
public QueryCurrRegionHttpRsp getCurrRegion() {
|
||||
return currRegion;
|
||||
}
|
||||
|
||||
public void loadQueries() {
|
||||
File file;
|
||||
|
||||
file = new File(Grasscutter.getConfig().DATA_FOLDER + "query_region_list.txt");
|
||||
if (file.exists()) {
|
||||
query_region_list = new String(FileUtils.read(file));
|
||||
} else {
|
||||
Grasscutter.getLogger().warn("query_region_list not found! Using default region list.");
|
||||
}
|
||||
|
||||
file = new File(Grasscutter.getConfig().DATA_FOLDER + "query_cur_region.txt");
|
||||
if (file.exists()) {
|
||||
query_cur_region = new String(FileUtils.read(file));
|
||||
} else {
|
||||
Grasscutter.getLogger().warn("query_cur_region not found! Using default current region.");
|
||||
}
|
||||
}
|
||||
|
||||
private void initRegion() {
|
||||
try {
|
||||
byte[] decoded = Base64.getDecoder().decode(query_region_list);
|
||||
QueryRegionListHttpRsp rl = QueryRegionListHttpRsp.parseFrom(decoded);
|
||||
|
||||
byte[] decoded2 = Base64.getDecoder().decode(query_cur_region);
|
||||
QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(decoded2);
|
||||
|
||||
RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
|
||||
.setName("os_usa")
|
||||
.setTitle(Grasscutter.getConfig().GameServerName)
|
||||
.setType("DEV_PUBLIC")
|
||||
.setDispatchUrl("https://" + Grasscutter.getConfig().DispatchServerIp + ":" + getAddress().getPort() + "/query_cur_region")
|
||||
.build();
|
||||
|
||||
RegionSimpleInfo serverTest2 = RegionSimpleInfo.newBuilder()
|
||||
.setName("os_euro")
|
||||
.setTitle("Grasscutter")
|
||||
.setType("DEV_PUBLIC")
|
||||
.setDispatchUrl("https://" + Grasscutter.getConfig().DispatchServerIp + ":" + getAddress().getPort() + "/query_cur_region")
|
||||
.build();
|
||||
|
||||
QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.newBuilder()
|
||||
.addServers(server)
|
||||
.addServers(serverTest2)
|
||||
.setClientSecretKey(rl.getClientSecretKey())
|
||||
.setClientCustomConfigEncrypted(rl.getClientCustomConfigEncrypted())
|
||||
.setEnableLoginPc(true)
|
||||
.build();
|
||||
|
||||
RegionInfo currentRegion = regionQuery.getRegionInfo().toBuilder()
|
||||
.setIp(Grasscutter.getConfig().GameServerIp)
|
||||
.setPort(Grasscutter.getConfig().GameServerPort)
|
||||
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
|
||||
.build();
|
||||
|
||||
QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(currentRegion).build();
|
||||
|
||||
this.regionListBase64 = Base64.getEncoder().encodeToString(regionList.toByteString().toByteArray());
|
||||
this.regionCurrentBase64 = Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray());
|
||||
this.currRegion = parsedRegionQuery;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
server = HttpsServer.create(getAddress(), 0);
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().DispatchServerKeystorePath)) {
|
||||
char[] keystorePassword = Grasscutter.getConfig().DispatchServerKeystorePassword.toCharArray();
|
||||
KeyStore ks = KeyStore.getInstance("PKCS12");
|
||||
ks.load(fis, keystorePassword);
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(ks, keystorePassword);
|
||||
|
||||
sslContext.init(kmf.getKeyManagers(), null, null);
|
||||
|
||||
server.setHttpsConfigurator(new HttpsConfigurator(sslContext));
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("No SSL cert found!");
|
||||
return;
|
||||
}
|
||||
|
||||
server.createContext("/", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
//Create a response form the request query parameters
|
||||
String response = "Hello";
|
||||
//Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
//Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Dispatch
|
||||
server.createContext("/query_region_list", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Log
|
||||
Grasscutter.getLogger().info("Client request: query_region_list");
|
||||
// Create a response form the request query parameters
|
||||
String response = regionListBase64;
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
server.createContext("/query_cur_region", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Log
|
||||
Grasscutter.getLogger().info("Client request: query_cur_region");
|
||||
// Create a response form the request query parameters
|
||||
URI uri = t.getRequestURI();
|
||||
String response = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw==";
|
||||
if (uri.getQuery() != null && uri.getQuery().length() > 0) {
|
||||
response = regionCurrentBase64;
|
||||
}
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
// Login via account
|
||||
server.createContext("/hk4e_global/mdk/shield/api/login", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Get post data
|
||||
LoginAccountRequestJson requestData = null;
|
||||
try {
|
||||
String body = Utils.toString(t.getRequestBody());
|
||||
requestData = getGsonFactory().fromJson(body, LoginAccountRequestJson.class);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// Create response json
|
||||
if (requestData == null) {
|
||||
return;
|
||||
}
|
||||
LoginResultJson responseData = new LoginResultJson();
|
||||
|
||||
// Login
|
||||
Account account = DatabaseHelper.getAccountByName(requestData.account);
|
||||
|
||||
// Test
|
||||
if (account == null) {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = "Username not found.";
|
||||
} else {
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
}
|
||||
|
||||
// Create a response
|
||||
String response = getGsonFactory().toJson(responseData);
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("application/json"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
// Login via token
|
||||
server.createContext("/hk4e_global/mdk/shield/api/verify", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Get post data
|
||||
LoginTokenRequestJson requestData = null;
|
||||
try {
|
||||
String body = Utils.toString(t.getRequestBody());
|
||||
requestData = getGsonFactory().fromJson(body, LoginTokenRequestJson.class);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// Create response json
|
||||
if (requestData == null) {
|
||||
return;
|
||||
}
|
||||
LoginResultJson responseData = new LoginResultJson();
|
||||
|
||||
// Login
|
||||
Account account = DatabaseHelper.getAccountById(requestData.uid);
|
||||
|
||||
// Test
|
||||
if (account == null || !account.getSessionKey().equals(requestData.token)) {
|
||||
responseData.retcode = -111;
|
||||
responseData.message = "Game account cache information error";
|
||||
} else {
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = requestData.uid;
|
||||
responseData.data.account.token = requestData.token;
|
||||
responseData.data.account.email = account.getEmail();
|
||||
}
|
||||
|
||||
// Create a response
|
||||
String response = getGsonFactory().toJson(responseData);
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("application/json"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
// Exchange for combo token
|
||||
server.createContext("/hk4e_global/combo/granter/login/v2/login", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
// Get post data
|
||||
ComboTokenReqJson requestData = null;
|
||||
try {
|
||||
String body = Utils.toString(t.getRequestBody());
|
||||
requestData = getGsonFactory().fromJson(body, ComboTokenReqJson.class);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// Create response json
|
||||
if (requestData == null || requestData.data == null) {
|
||||
return;
|
||||
}
|
||||
LoginTokenData loginData = getGsonFactory().fromJson(requestData.data, LoginTokenData.class); // Get login data
|
||||
ComboTokenResJson responseData = new ComboTokenResJson();
|
||||
|
||||
// Login
|
||||
Account account = DatabaseHelper.getAccountById(loginData.uid);
|
||||
|
||||
// Test
|
||||
if (account == null || !account.getSessionKey().equals(loginData.token)) {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = "Wrong session key.";
|
||||
} else {
|
||||
responseData.message = "OK";
|
||||
responseData.data.open_id = loginData.uid;
|
||||
responseData.data.combo_id = "157795300";
|
||||
responseData.data.combo_token = account.generateLoginToken();
|
||||
}
|
||||
|
||||
// Create a response
|
||||
String response = getGsonFactory().toJson(responseData);
|
||||
// Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("application/json"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
// Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
// Agreement and Protocol
|
||||
server.createContext( // hk4e-sdk-os.hoyoverse.com
|
||||
"/hk4e_global/mdk/agreement/api/getAgreementInfos",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"marketing_agreements\":[]}}")
|
||||
);
|
||||
server.createContext( // hk4e-sdk-os.hoyoverse.com
|
||||
"/hk4e_global/combo/granter/api/compareProtocolVersion",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"modified\":true,\"protocol\":{\"id\":0,\"app_id\":4,\"language\":\"en\",\"user_proto\":\"\",\"priv_proto\":\"\",\"major\":7,\"minimum\":0,\"create_time\":\"0\",\"teenager_proto\":\"\",\"third_proto\":\"\"}}}")
|
||||
);
|
||||
// Game data
|
||||
server.createContext( // hk4e-api-os.hoyoverse.com
|
||||
"/common/hk4e_global/announcement/api/getAlertPic",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"total\":0,\"list\":[]}}")
|
||||
);
|
||||
server.createContext( // hk4e-api-os.hoyoverse.com
|
||||
"/common/hk4e_global/announcement/api/getAlertAnn",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"alert\":false,\"alert_id\":0,\"remind\":true}}")
|
||||
);
|
||||
server.createContext( // hk4e-api-os.hoyoverse.com
|
||||
"/common/hk4e_global/announcement/api/getAnnList",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0,\"type_list\":[],\"alert\":false,\"alert_id\":0,\"timezone\":0,\"t\":\"" + System.currentTimeMillis() + "\"}}")
|
||||
);
|
||||
server.createContext( // hk4e-api-os-static.hoyoverse.com
|
||||
"/common/hk4e_global/announcement/api/getAnnContent",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0}}")
|
||||
);
|
||||
server.createContext( // hk4e-sdk-os.hoyoverse.com
|
||||
"/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"suggest_currency\":\"USD\",\"tiers\":[]}}")
|
||||
);
|
||||
// Captcha
|
||||
server.createContext( // api-account-os.hoyoverse.com
|
||||
"/account/risky/api/check",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"c8820f246a5241ab9973f71df3ddd791\",\"action\":\"\",\"geetest\":{\"challenge\":\"\",\"gt\":\"\",\"new_captcha\":0,\"success\":1}}}")
|
||||
);
|
||||
// Config
|
||||
server.createContext( // sdk-os-static.hoyoverse.com
|
||||
"/combo/box/api/config/sdk/combo",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"vals\":{\"disable_email_bind_skip\":\"false\",\"email_bind_remind_interval\":\"7\",\"email_bind_remind\":\"true\"}}}")
|
||||
);
|
||||
server.createContext( // hk4e-sdk-os-static.hoyoverse.com
|
||||
"/hk4e_global/combo/granter/api/getConfig",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"protocol\":true,\"qr_enabled\":false,\"log_level\":\"INFO\",\"announce_url\":\"https://webstatic-sea.hoyoverse.com/hk4e/announcement/index.html?sdk_presentation_style=fullscreen\\u0026sdk_screen_transparent=true\\u0026game_biz=hk4e_global\\u0026auth_appid=announcement\\u0026game=hk4e#/\",\"push_alias_type\":2,\"disable_ysdk_guard\":false,\"enable_announce_pic_popup\":true}}")
|
||||
);
|
||||
server.createContext( // hk4e-sdk-os-static.hoyoverse.com
|
||||
"/hk4e_global/mdk/shield/api/loadConfig",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":6,\"game_key\":\"hk4e_global\",\"client\":\"PC\",\"identity\":\"I_IDENTITY\",\"guest\":false,\"ignore_versions\":\"\",\"scene\":\"S_NORMAL\",\"name\":\"原神海外\",\"disable_regist\":false,\"enable_email_captcha\":false,\"thirdparty\":[\"fb\",\"tw\"],\"disable_mmt\":false,\"server_guest\":false,\"thirdparty_ignore\":{\"tw\":\"\",\"fb\":\"\"},\"enable_ps_bind_account\":false,\"thirdparty_login_configs\":{\"tw\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800},\"fb\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800}}}}")
|
||||
);
|
||||
// Test api?
|
||||
server.createContext( // abtest-api-data-sg.hoyoverse.com
|
||||
"/data_abtest_api/config/experiment/list",
|
||||
new DispatchHttpJsonHandler("{\"retcode\":0,\"success\":true,\"message\":\"\",\"data\":[{\"code\":1000,\"type\":2,\"config_id\":\"14\",\"period_id\":\"6036_99\",\"version\":\"1\",\"configs\":{\"cardType\":\"old\"}}]}")
|
||||
);
|
||||
// Log Server
|
||||
server.createContext( // log-upload-os.mihoyo.com
|
||||
"/log/sdk/upload",
|
||||
new DispatchHttpJsonHandler("{\"code\":0}")
|
||||
);
|
||||
server.createContext( // log-upload-os.mihoyo.com
|
||||
"/sdk/upload",
|
||||
new DispatchHttpJsonHandler("{\"code\":0}")
|
||||
);
|
||||
// Start server
|
||||
server.start();
|
||||
Grasscutter.getLogger().info("Dispatch server started on port " + getAddress().getPort());
|
||||
|
||||
// Logging servers
|
||||
HttpServer overseaLogServer = HttpServer.create(new InetSocketAddress(Grasscutter.getConfig().DispatchServerIp, 8888), 0);
|
||||
overseaLogServer.createContext( // overseauspider.yuanshen.com
|
||||
"/log",
|
||||
new DispatchHttpJsonHandler("{\"code\":0}")
|
||||
);
|
||||
overseaLogServer.start();
|
||||
Grasscutter.getLogger().info("Log server (overseauspider) started on port " + 8888);
|
||||
|
||||
HttpServer uploadLogServer = HttpServer.create(new InetSocketAddress(Grasscutter.getConfig().DispatchServerIp, 80), 0);
|
||||
uploadLogServer.createContext( // log-upload-os.mihoyo.com
|
||||
"/crash/dataUpload",
|
||||
new DispatchHttpJsonHandler("{\"code\":0}")
|
||||
);
|
||||
uploadLogServer.createContext("/gacha", new HttpHandler() {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
//Create a response form the request query parameters
|
||||
String response = "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>";
|
||||
//Set the response header status and length
|
||||
t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8"));
|
||||
t.sendResponseHeaders(200, response.getBytes().length);
|
||||
//Write the response string
|
||||
OutputStream os = t.getResponseBody();
|
||||
os.write(response.getBytes());
|
||||
os.close();
|
||||
}
|
||||
});
|
||||
uploadLogServer.start();
|
||||
Grasscutter.getLogger().info("Log server (log-upload-os) started on port " + 80);
|
||||
}
|
||||
|
||||
private Map<String, String> parseQueryString(String qs) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
if (qs == null)
|
||||
return result;
|
||||
|
||||
int last = 0, next, l = qs.length();
|
||||
while (last < l) {
|
||||
next = qs.indexOf('&', last);
|
||||
if (next == -1)
|
||||
next = l;
|
||||
|
||||
if (next > last) {
|
||||
int eqPos = qs.indexOf('=', last);
|
||||
try {
|
||||
if (eqPos < 0 || eqPos > next)
|
||||
result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), "");
|
||||
else
|
||||
result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java
|
||||
}
|
||||
}
|
||||
last = next + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package emu.grasscutter.server.dispatch.json;
|
||||
|
||||
public class ComboTokenReqJson {
|
||||
public int app_id;
|
||||
public int channel_id;
|
||||
public String data;
|
||||
public String device;
|
||||
public String sign;
|
||||
|
||||
public class LoginTokenData {
|
||||
public String uid;
|
||||
public String token;
|
||||
public boolean guest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.dispatch.json;
|
||||
|
||||
public class ComboTokenResJson {
|
||||
public String message;
|
||||
public int retcode;
|
||||
public LoginData data = new LoginData();
|
||||
|
||||
public class LoginData {
|
||||
public int account_type = 1;
|
||||
public boolean heartbeat;
|
||||
public String combo_id;
|
||||
public String combo_token;
|
||||
public String open_id;
|
||||
public String data = "{\"guest\":false}";
|
||||
public String fatigue_remind = null; // ?
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package emu.grasscutter.server.dispatch.json;
|
||||
|
||||
public class LoginAccountRequestJson {
|
||||
public String account;
|
||||
public String password;
|
||||
public boolean is_crypto;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package emu.grasscutter.server.dispatch.json;
|
||||
|
||||
public class LoginResultJson {
|
||||
public String message;
|
||||
public int retcode;
|
||||
public VerifyData data = new VerifyData();
|
||||
|
||||
public class VerifyData {
|
||||
public VerifyAccountData account = new VerifyAccountData();
|
||||
public boolean device_grant_required = false;
|
||||
public String realname_operation = "NONE";
|
||||
public boolean realperson_required = false;
|
||||
public boolean safe_mobile_required = false;
|
||||
}
|
||||
|
||||
public class VerifyAccountData {
|
||||
public String uid;
|
||||
public String name = "";
|
||||
public String email;
|
||||
public String mobile = "";
|
||||
public String is_email_verify = "0";
|
||||
public String realname = "";
|
||||
public String identity_card = "";
|
||||
public String token;
|
||||
public String safe_mobile = "";
|
||||
public String facebook_name = "";
|
||||
public String twitter_name = "";
|
||||
public String game_center_name = "";
|
||||
public String google_name = "";
|
||||
public String apple_name = "";
|
||||
public String sony_name = "";
|
||||
public String tap_name = "";
|
||||
public String country = "US";
|
||||
public String reactivate_ticket = "";
|
||||
public String area_code = "**";
|
||||
public String device_grant_ticket = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package emu.grasscutter.server.dispatch.json;
|
||||
|
||||
public class LoginTokenRequestJson {
|
||||
public String uid;
|
||||
public String token;
|
||||
}
|
||||
160
src/main/java/emu/grasscutter/server/game/GameServer.java
Normal file
160
src/main/java/emu/grasscutter/server/game/GameServer.java
Normal file
@@ -0,0 +1,160 @@
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import emu.grasscutter.GenshinConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.GenshinPlayer;
|
||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
||||
import emu.grasscutter.game.gacha.GachaManager;
|
||||
import emu.grasscutter.game.managers.ChatManager;
|
||||
import emu.grasscutter.game.managers.InventoryManager;
|
||||
import emu.grasscutter.game.managers.MultiplayerManager;
|
||||
import emu.grasscutter.game.shop.ShopManager;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||
import emu.grasscutter.netty.MihoyoKcpServer;
|
||||
|
||||
public class GameServer extends MihoyoKcpServer {
|
||||
private final InetSocketAddress address;
|
||||
private final GameServerPacketHandler packetHandler;
|
||||
private final Timer gameLoop;
|
||||
|
||||
private final Map<Integer, GenshinPlayer> players;
|
||||
|
||||
private final ChatManager chatManager;
|
||||
private final InventoryManager inventoryManager;
|
||||
private final GachaManager gachaManager;
|
||||
private final ShopManager shopManager;
|
||||
private final MultiplayerManager multiplayerManager;
|
||||
private final DungeonManager dungeonManager;
|
||||
|
||||
public GameServer(InetSocketAddress address) {
|
||||
super(address);
|
||||
this.setServerInitializer(new GameServerInitializer(this));
|
||||
this.address = address;
|
||||
this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
|
||||
this.players = new ConcurrentHashMap<>();
|
||||
|
||||
this.chatManager = new ChatManager(this);
|
||||
this.inventoryManager = new InventoryManager(this);
|
||||
this.gachaManager = new GachaManager(this);
|
||||
this.shopManager = new ShopManager(this);
|
||||
this.multiplayerManager = new MultiplayerManager(this);
|
||||
this.dungeonManager = new DungeonManager(this);
|
||||
|
||||
// Ticker
|
||||
this.gameLoop = new Timer();
|
||||
this.gameLoop.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
onTick();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, new Date(), 1000L);
|
||||
|
||||
// Shutdown hook
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
|
||||
}
|
||||
|
||||
public GameServerPacketHandler getPacketHandler() {
|
||||
return packetHandler;
|
||||
}
|
||||
|
||||
public Map<Integer, GenshinPlayer> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public ChatManager getChatManager() {
|
||||
return chatManager;
|
||||
}
|
||||
|
||||
public InventoryManager getInventoryManager() {
|
||||
return inventoryManager;
|
||||
}
|
||||
|
||||
public GachaManager getGachaManager() {
|
||||
return gachaManager;
|
||||
}
|
||||
|
||||
public ShopManager getShopManager() {
|
||||
return shopManager;
|
||||
}
|
||||
|
||||
public MultiplayerManager getMultiplayerManager() {
|
||||
return multiplayerManager;
|
||||
}
|
||||
|
||||
public DungeonManager getDungeonManager() {
|
||||
return dungeonManager;
|
||||
}
|
||||
|
||||
public void registerPlayer(GenshinPlayer player) {
|
||||
getPlayers().put(player.getId(), player);
|
||||
}
|
||||
|
||||
public GenshinPlayer getPlayerById(int id) {
|
||||
return this.getPlayers().get(id);
|
||||
}
|
||||
|
||||
public GenshinPlayer forceGetPlayerById(int id) {
|
||||
// Console check
|
||||
if (id == GenshinConstants.SERVER_CONSOLE_UID) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get from online players
|
||||
GenshinPlayer player = this.getPlayerById(id);
|
||||
|
||||
// Check database if character isnt here
|
||||
if (player == null) {
|
||||
player = DatabaseHelper.getPlayerById(id);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
public SocialDetail.Builder getSocialDetailById(int id) {
|
||||
// Get from online players
|
||||
GenshinPlayer player = this.forceGetPlayerById(id);
|
||||
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return player.getSocialDetail();
|
||||
}
|
||||
|
||||
public void onTick() throws Exception {
|
||||
for (GenshinPlayer player : this.getPlayers().values()) {
|
||||
player.onTick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartFinish() {
|
||||
Grasscutter.getLogger().info("Game Server started on port " + address.getPort());
|
||||
}
|
||||
|
||||
public void onServerShutdown() {
|
||||
// Kick and save all players
|
||||
List<GenshinPlayer> list = new ArrayList<>(this.getPlayers().size());
|
||||
list.addAll(this.getPlayers().values());
|
||||
|
||||
for (GenshinPlayer player : list) {
|
||||
player.getSession().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import emu.grasscutter.netty.MihoyoKcpServerInitializer;
|
||||
import io.jpower.kcp.netty.UkcpChannel;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
|
||||
public class GameServerInitializer extends MihoyoKcpServerInitializer {
|
||||
private GameServer server;
|
||||
|
||||
public GameServerInitializer(GameServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initChannel(UkcpChannel ch) throws Exception {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
GameSession session = new GameSession(server);
|
||||
pipeline.addLast(session);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class GameServerPacketHandler {
|
||||
private final Int2ObjectMap<PacketHandler> handlers;
|
||||
|
||||
public GameServerPacketHandler(Class<? extends PacketHandler> handlerClass) {
|
||||
this.handlers = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
this.registerHandlers(handlerClass);
|
||||
}
|
||||
|
||||
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
|
||||
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
|
||||
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
|
||||
|
||||
for (Object obj : handlerClasses) {
|
||||
Class<?> c = (Class<?>) obj;
|
||||
|
||||
try {
|
||||
Opcodes opcode = c.getAnnotation(Opcodes.class);
|
||||
|
||||
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PacketHandler packetHandler = (PacketHandler) c.newInstance();
|
||||
|
||||
this.handlers.put(opcode.value(), packetHandler);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
Grasscutter.getLogger().info("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
|
||||
}
|
||||
|
||||
public void handle(GameSession session, int opcode, byte[] header, byte[] payload) {
|
||||
PacketHandler handler = null;
|
||||
|
||||
handler = this.handlers.get(opcode);
|
||||
|
||||
if (handler != null) {
|
||||
try {
|
||||
// Make sure session is ready for packets
|
||||
SessionState state = session.getState();
|
||||
|
||||
if (opcode == PacketOpcodes.PingReq) {
|
||||
// Always continue if packet is ping request
|
||||
} else if (opcode == PacketOpcodes.GetPlayerTokenReq) {
|
||||
if (state != SessionState.WAITING_FOR_TOKEN) {
|
||||
return;
|
||||
}
|
||||
} else if (opcode == PacketOpcodes.PlayerLoginReq) {
|
||||
if (state != SessionState.WAITING_FOR_LOGIN) {
|
||||
return;
|
||||
}
|
||||
} else if (opcode == PacketOpcodes.SetPlayerBornDataReq) {
|
||||
if (state != SessionState.PICKING_CHARACTER) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (state != SessionState.ACTIVE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle
|
||||
handler.handle(session, header, payload);
|
||||
} catch (Exception ex) {
|
||||
// TODO Remove this when no more needed
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return; // Packet successfully handled
|
||||
}
|
||||
|
||||
// Log unhandled packets
|
||||
if (Grasscutter.getConfig().LOG_PACKETS) {
|
||||
//Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode));
|
||||
}
|
||||
}
|
||||
}
|
||||
250
src/main/java/emu/grasscutter/server/game/GameSession.java
Normal file
250
src/main/java/emu/grasscutter/server/game/GameSession.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package emu.grasscutter.server.game;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.GenshinPlayer;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodesUtil;
|
||||
import emu.grasscutter.netty.MihoyoKcpChannel;
|
||||
import emu.grasscutter.utils.Crypto;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
public class GameSession extends MihoyoKcpChannel {
|
||||
private GameServer server;
|
||||
|
||||
private Account account;
|
||||
private GenshinPlayer player;
|
||||
|
||||
private boolean useSecretKey;
|
||||
private SessionState state;
|
||||
|
||||
private int clientTime;
|
||||
private long lastPingTime;
|
||||
private int lastClientSeq = 10;
|
||||
|
||||
public GameSession(GameServer server) {
|
||||
this.server = server;
|
||||
this.state = SessionState.WAITING_FOR_TOKEN;
|
||||
this.lastPingTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public GameServer getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
if (this.getChannel() == null) {
|
||||
return null;
|
||||
}
|
||||
return this.getChannel().remoteAddress();
|
||||
}
|
||||
|
||||
public boolean useSecretKey() {
|
||||
return useSecretKey;
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(Account account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return this.getAccount().getId();
|
||||
}
|
||||
|
||||
public GenshinPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public synchronized void setPlayer(GenshinPlayer player) {
|
||||
this.player = player;
|
||||
this.player.setSession(this);
|
||||
this.player.setAccount(this.getAccount());
|
||||
}
|
||||
|
||||
public SessionState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(SessionState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return this.getPlayer() != null;
|
||||
}
|
||||
|
||||
public void setUseSecretKey(boolean useSecretKey) {
|
||||
this.useSecretKey = useSecretKey;
|
||||
}
|
||||
|
||||
public int getClientTime() {
|
||||
return this.clientTime;
|
||||
}
|
||||
|
||||
public long getLastPingTime() {
|
||||
return lastPingTime;
|
||||
}
|
||||
|
||||
public void updateLastPingTime(int clientTime) {
|
||||
this.clientTime = clientTime;
|
||||
this.lastPingTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public int getNextClientSequence() {
|
||||
return ++lastClientSeq;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConnect() {
|
||||
Grasscutter.getLogger().info("Client connected from " + getAddress().getHostString().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void onDisconnect() { // Synchronize so we dont add character at the same time
|
||||
Grasscutter.getLogger().info("Client disconnected from " + getAddress().getHostString().toLowerCase());
|
||||
|
||||
// Set state so no more packets can be handled
|
||||
this.setState(SessionState.INACTIVE);
|
||||
|
||||
// Save after disconnecting
|
||||
if (this.isLoggedIn()) {
|
||||
// Save
|
||||
getPlayer().onLogout();
|
||||
// Remove from gameserver
|
||||
getServer().getPlayers().remove(getPlayer().getId());
|
||||
}
|
||||
}
|
||||
|
||||
protected void logPacket(ByteBuffer buf) {
|
||||
ByteBuf b = Unpooled.wrappedBuffer(buf.array());
|
||||
logPacket(b);
|
||||
}
|
||||
|
||||
public void replayPacket(int opcode, String name) {
|
||||
String filePath = Grasscutter.getConfig().PACKETS_FOLDER + name;
|
||||
File p = new File(filePath);
|
||||
|
||||
if (!p.exists()) return;
|
||||
|
||||
byte[] packet = FileUtils.read(p);
|
||||
|
||||
GenshinPacket genshinPacket = new GenshinPacket(opcode);
|
||||
genshinPacket.setData(packet);
|
||||
|
||||
// Log
|
||||
logPacket(genshinPacket.getOpcode());
|
||||
|
||||
send(genshinPacket);
|
||||
}
|
||||
|
||||
public void send(GenshinPacket genshinPacket) {
|
||||
// Test
|
||||
if (genshinPacket.getOpcode() <= 0) {
|
||||
Grasscutter.getLogger().warn("Tried to send packet with missing cmd id!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Header
|
||||
if (genshinPacket.shouldBuildHeader()) {
|
||||
genshinPacket.buildHeader(this.getNextClientSequence());
|
||||
}
|
||||
|
||||
// Build packet
|
||||
byte[] data = genshinPacket.build();
|
||||
|
||||
// Log
|
||||
if (Grasscutter.getConfig().LOG_PACKETS) {
|
||||
logPacket(genshinPacket);
|
||||
}
|
||||
|
||||
// Send
|
||||
send(data);
|
||||
}
|
||||
|
||||
private void logPacket(int opcode) {
|
||||
//Grasscutter.getLogger().info("SEND: " + PacketOpcodesUtil.getOpcodeName(opcode));
|
||||
//System.out.println(Utils.bytesToHex(genshinPacket.getData()));
|
||||
}
|
||||
|
||||
private void logPacket(GenshinPacket genshinPacket) {
|
||||
Grasscutter.getLogger().info("SEND: " + PacketOpcodesUtil.getOpcodeName(genshinPacket.getOpcode()) + " (" + genshinPacket.getOpcode() + ")");
|
||||
System.out.println(Utils.bytesToHex(genshinPacket.getData()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(ChannelHandlerContext ctx, ByteBuf data) {
|
||||
// Decrypt and turn back into a packet
|
||||
byte[] byteData = Utils.byteBufToArray(data);
|
||||
Crypto.xor(byteData, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
|
||||
ByteBuf packet = Unpooled.wrappedBuffer(byteData);
|
||||
|
||||
// Log
|
||||
//logPacket(packet);
|
||||
|
||||
// Handle
|
||||
try {
|
||||
while (packet.readableBytes() > 0) {
|
||||
// Length
|
||||
if (packet.readableBytes() < 12) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Packet sanity check
|
||||
int const1 = packet.readShort();
|
||||
if (const1 != 17767) {
|
||||
return; // Bad packet
|
||||
}
|
||||
|
||||
// Data
|
||||
int opcode = packet.readShort();
|
||||
int headerLength = packet.readShort();
|
||||
int payloadLength = packet.readInt();
|
||||
|
||||
byte[] header = new byte[headerLength];
|
||||
byte[] payload = new byte[payloadLength];
|
||||
|
||||
packet.readBytes(header);
|
||||
packet.readBytes(payload);
|
||||
|
||||
// Sanity check #2
|
||||
int const2 = packet.readShort();
|
||||
if (const2 != -30293) {
|
||||
return; // Bad packet
|
||||
}
|
||||
|
||||
// Log packet
|
||||
if (Grasscutter.getConfig().LOG_PACKETS) {
|
||||
Grasscutter.getLogger().info("RECV: " + PacketOpcodesUtil.getOpcodeName(opcode) + " (" + opcode + ")");
|
||||
System.out.println(Utils.bytesToHex(payload));
|
||||
}
|
||||
|
||||
// Handle
|
||||
getServer().getPacketHandler().handle(this, opcode, header, payload);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
packet.release();
|
||||
}
|
||||
}
|
||||
|
||||
public enum SessionState {
|
||||
INACTIVE,
|
||||
WAITING_FOR_TOKEN,
|
||||
WAITING_FOR_LOGIN,
|
||||
PICKING_CHARACTER,
|
||||
ACTIVE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.NONE)
|
||||
public class Handler extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AbilityInvocationsNotifyOuterClass.AbilityInvocationsNotify;
|
||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AbilityInvocationsNotify)
|
||||
public class HandlerAbilityInvocationsNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AbilityInvocationsNotify notif = AbilityInvocationsNotify.parseFrom(payload);
|
||||
|
||||
for (AbilityInvokeEntry entry : notif.getInvokesList()) {
|
||||
//System.out.println(entry.getArgumentType() + ": " + Utils.bytesToHex(entry.getAbilityData().toByteArray()));
|
||||
session.getPlayer().getAbilityInvokeHandler().addEntry(entry.getForwardType(), entry);
|
||||
}
|
||||
|
||||
if (notif.getInvokesList().size() > 0) {
|
||||
session.getPlayer().getAbilityInvokeHandler().update(session.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AskAddFriendReqOuterClass.AskAddFriendReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AskAddFriendReq)
|
||||
public class HandlerAskAddFriendReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AskAddFriendReq req = AskAddFriendReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getFriendsList().sendFriendRequest(req.getTargetUid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarChangeCostumeReqOuterClass.AvatarChangeCostumeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarChangeCostumeRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarChangeCostumeReq)
|
||||
public class HandlerAvatarChangeCostumeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarChangeCostumeReq req = AvatarChangeCostumeReq.parseFrom(payload);
|
||||
|
||||
boolean success = session.getPlayer().getAvatars().changeCostume(req.getAvatarGuid(), req.getCostumeId());
|
||||
|
||||
if (success) {
|
||||
session.getPlayer().sendPacket(new PacketAvatarChangeCostumeRsp(req.getAvatarGuid(), req.getCostumeId()));
|
||||
} else {
|
||||
session.getPlayer().sendPacket(new PacketAvatarChangeCostumeRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarDieAnimationEndReqOuterClass.AvatarDieAnimationEndReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarDieAnimationEndReq)
|
||||
public class HandlerAvatarDieAnimationEndReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarDieAnimationEndReq req = AvatarDieAnimationEndReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().onAvatarDie(req.getDieGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarPromoteReqOuterClass.AvatarPromoteReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarPromoteReq)
|
||||
public class HandlerAvatarPromoteReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarPromoteReq req = AvatarPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend avatar
|
||||
session.getServer().getInventoryManager().promoteAvatar(session.getPlayer(), req.getGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarSkillUpgradeReqOuterClass.AvatarSkillUpgradeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarSkillUpgradeReq)
|
||||
public class HandlerAvatarSkillUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarSkillUpgradeReq req = AvatarSkillUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar talent
|
||||
session.getServer().getInventoryManager().upgradeAvatarSkill(session.getPlayer(), req.getAvatarGuid(), req.getAvatarSkillId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarUpgradeReqOuterClass.AvatarUpgradeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarUpgradeReq)
|
||||
public class HandlerAvatarUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarUpgradeReq req = AvatarUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar
|
||||
session.getServer().getInventoryManager().upgradeAvatar(
|
||||
session.getPlayer(),
|
||||
req.getAvatarGuid(),
|
||||
req.getItemId(),
|
||||
req.getCount()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarWearFlycloakReqOuterClass.AvatarWearFlycloakReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarWearFlycloakRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarWearFlycloakReq)
|
||||
public class HandlerAvatarWearFlycloakReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarWearFlycloakReq req = AvatarWearFlycloakReq.parseFrom(payload);
|
||||
|
||||
boolean success = session.getPlayer().getAvatars().wearFlycloak(req.getAvatarGuid(), req.getFlycloakId());
|
||||
|
||||
if (success) {
|
||||
session.getPlayer().sendPacket(new PacketAvatarWearFlycloakRsp(req.getAvatarGuid(), req.getFlycloakId()));
|
||||
} else {
|
||||
session.getPlayer().sendPacket(new PacketAvatarWearFlycloakRsp());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CalcWeaponUpgradeReturnItemsReqOuterClass.CalcWeaponUpgradeReturnItemsReq;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketCalcWeaponUpgradeReturnItemsRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.CalcWeaponUpgradeReturnItemsReq)
|
||||
public class HandlerCalcWeaponUpgradeReturnItemsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
CalcWeaponUpgradeReturnItemsReq req = CalcWeaponUpgradeReturnItemsReq.parseFrom(payload);
|
||||
|
||||
List<ItemParam> returnOres = session.getServer().getInventoryManager().calcWeaponUpgradeReturnItems(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
|
||||
if (returnOres != null) {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp(req.getTargetWeaponGuid(), returnOres));
|
||||
} else {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeAvatarReqOuterClass.ChangeAvatarReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeAvatarReq)
|
||||
public class HandlerChangeAvatarReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeAvatarReq req = ChangeAvatarReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().changeAvatar(req.getGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeGameTimeReqOuterClass.ChangeGameTimeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeGameTimeRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeGameTimeReq)
|
||||
public class HandlerChangeGameTimeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getWorld().changeTime(req.getGameTime());
|
||||
session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer().getWorld()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeMpTeamAvatarReqOuterClass.ChangeMpTeamAvatarReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeMpTeamAvatarReq)
|
||||
public class HandlerChangeMpTeamAvatarReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeMpTeamAvatarReq req = ChangeMpTeamAvatarReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setupMpTeam(req.getAvatarGuidListList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeTeamNameReqOuterClass.ChangeTeamNameReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeTeamNameReq)
|
||||
public class HandlerChangeTeamNameReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeTeamNameReq req = ChangeTeamNameReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setTeamName(req.getTeamId(), req.getTeamName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChooseCurAvatarTeamReqOuterClass.ChooseCurAvatarTeamReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChooseCurAvatarTeamReq)
|
||||
public class HandlerChooseCurAvatarTeamReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChooseCurAvatarTeamReq req = ChooseCurAvatarTeamReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setCurrentTeam(req.getTeamId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.entity.GenshinEntity;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify;
|
||||
import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
|
||||
import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo;
|
||||
import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.CombatInvocationsNotify)
|
||||
public class HandlerCombatInvocationsNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload);
|
||||
|
||||
for (CombatInvokeEntry entry : notif.getInvokeListList()) {
|
||||
switch (entry.getArgumentType()) {
|
||||
case CombatEvtBeingHit:
|
||||
// Handle damage
|
||||
EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData());
|
||||
session.getPlayer().getWorld().handleAttack(hitInfo.getAttackResult());
|
||||
break;
|
||||
case EntityMove:
|
||||
// Handle movement
|
||||
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
|
||||
GenshinEntity entity = session.getPlayer().getWorld().getEntityById(moveInfo.getEntityId());
|
||||
if (entity != null) {
|
||||
entity.getPosition().set(moveInfo.getMotionInfo().getPos());
|
||||
entity.getRotation().set(moveInfo.getMotionInfo().getRot());
|
||||
entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime());
|
||||
entity.setLastMoveReliableSeq(moveInfo.getReliableSeq());
|
||||
entity.setMotionState(moveInfo.getMotionInfo().getState());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry);
|
||||
}
|
||||
|
||||
if (notif.getInvokeListList().size() > 0) {
|
||||
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.DealAddFriendReqOuterClass.DealAddFriendReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DealAddFriendReq)
|
||||
public class HandlerDealAddFriendReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DealAddFriendReq req = DealAddFriendReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getFriendsList().handleFriendRequest(req.getTargetUid(), req.getDealAddFriendResult());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.DeleteFriendReqOuterClass.DeleteFriendReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DeleteFriendReq)
|
||||
public class HandlerDeleteFriendReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DeleteFriendReq req = DeleteFriendReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getFriendsList().deleteFriend(req.getTargetUid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.DestroyMaterialReqOuterClass.DestroyMaterialReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DestroyMaterialReq)
|
||||
public class HandlerDestroyMaterialReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DestroyMaterialReq req = DestroyMaterialReq.parseFrom(payload);
|
||||
|
||||
// Delete items
|
||||
session.getServer().getInventoryManager().destroyMaterial(session.getPlayer(), req.getMaterialListList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.DoGachaReqOuterClass.DoGachaReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DoGachaReq)
|
||||
public class HandlerDoGachaReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DoGachaReq req = DoGachaReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getGachaManager().doPulls(session.getPlayer(), req.getGachaType(), req.getGachaTimes());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DungeonEntryInfoReq)
|
||||
public class HandlerDungeonEntryInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.GenshinPlayer.SceneLoadState;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketEnterSceneDoneRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerTimeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePlayerLocationNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWorldPlayerLocationNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.EnterSceneDoneReq)
|
||||
public class HandlerEnterSceneDoneReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Finished loading
|
||||
session.getPlayer().setSceneLoadState(SceneLoadState.LOADED);
|
||||
|
||||
// Done
|
||||
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
|
||||
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
|
||||
|
||||
// Spawn player in world
|
||||
session.getPlayer().getWorld().spawnPlayer(session.getPlayer());
|
||||
|
||||
// Spawn other entites already in world
|
||||
session.getPlayer().getWorld().showOtherEntities(session.getPlayer());
|
||||
|
||||
// Locations
|
||||
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
|
||||
session.send(new PacketScenePlayerLocationNotify(session.getPlayer()));
|
||||
session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketEnterScenePeerNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketEnterSceneReadyRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.EnterSceneReadyReq)
|
||||
public class HandlerEnterSceneReadyReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) {
|
||||
session.send(new PacketEnterScenePeerNotify(session.getPlayer()));
|
||||
session.send(new PacketEnterSceneReadyRsp(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.EnterWorldAreaReqOuterClass.EnterWorldAreaReq;
|
||||
import emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketEnterWorldAreaRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.EnterWorldAreaReq)
|
||||
public class HandlerEnterWorldAreaReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PacketHead head = PacketHead.parseFrom(header);
|
||||
EnterWorldAreaReq enterWorld = EnterWorldAreaReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketEnterWorldAreaRsp(head.getClientSequenceId(), enterWorld));
|
||||
//session.send(new PacketScenePlayerLocationNotify(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.EntityAiSyncNotifyOuterClass.EntityAiSyncNotify;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityAiSyncNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.EntityAiSyncNotify)
|
||||
public class HandlerEntityAiSyncNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
EntityAiSyncNotify notify = EntityAiSyncNotify.parseFrom(payload);
|
||||
|
||||
if (notify.getLocalAvatarAlertedMonsterListCount() > 0) {
|
||||
session.getPlayer().getWorld().broadcastPacket(new PacketEntityAiSyncNotify(notify));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.EvtAiSyncCombatThreatInfoNotify)
|
||||
public class HandlerEvtAiSyncCombatThreatInfoNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.EvtAiSyncSkillCdNotify)
|
||||
public class HandlerEvtAiSyncSkillCdNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.entity.EntityClientGadget;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.EvtCreateGadgetNotify)
|
||||
public class HandlerEvtCreateGadgetNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
EvtCreateGadgetNotify notify = EvtCreateGadgetNotify.parseFrom(payload);
|
||||
|
||||
// Dont handle in singleplayer
|
||||
if (!session.getPlayer().getWorld().isMultiplayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create entity and summon in world
|
||||
EntityClientGadget gadget = new EntityClientGadget(session.getPlayer().getWorld(), session.getPlayer(), notify);
|
||||
session.getPlayer().getWorld().onPlayerCreateGadget(gadget);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.EvtDestroyGadgetNotifyOuterClass.EvtDestroyGadgetNotify;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.EvtDestroyGadgetNotify)
|
||||
public class HandlerEvtDestroyGadgetNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
EvtDestroyGadgetNotify notify = EvtDestroyGadgetNotify.parseFrom(payload);
|
||||
|
||||
// Dont handle in singleplayer
|
||||
if (!session.getPlayer().getWorld().isMultiplayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
session.getPlayer().getWorld().onPlayerDestroyGadget(notify.getEntityId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.GadgetInteractReq)
|
||||
public class HandlerGadgetInteractReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GadgetInteractReq req = GadgetInteractReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().interactWith(req.getGadgetEntityId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetActivityInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetActivityInfoReq)
|
||||
public class HandlerGetActivityInfoReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetActivityInfoRsp());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketH5ActivityIdsNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetAllH5ActivityInfoReq)
|
||||
public class HandlerGetAllH5ActivityInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketH5ActivityIdsNotify());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetAllUnlockNameCardRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetAllUnlockNameCardReq)
|
||||
public class HandlerGetAllUnlockNameCardReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetAllUnlockNameCardRsp(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetAuthkeyRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetAuthkeyReq)
|
||||
public class HandlerGetAuthkeyReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetAuthkeyRsp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetGachaInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetGachaInfoReq)
|
||||
public class HandlerGetGachaInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaManager()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetPlayerBlacklistReq)
|
||||
public class HandlerGetPlayerBlacklistReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new GenshinPacket(PacketOpcodes.GetPlayerBlacklistRsp).buildHeader(3));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetPlayerFriendListRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetPlayerFriendListReq)
|
||||
public class HandlerGetPlayerFriendListReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
//session.send(new PacketGetPlayerAskFriendListRsp(session.getPlayer()));
|
||||
session.send(new PacketGetPlayerFriendListRsp(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetPlayerSocialDetailReqOuterClass.GetPlayerSocialDetailReq;
|
||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetPlayerSocialDetailRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetPlayerSocialDetailReq)
|
||||
public class HandlerGetPlayerSocialDetailReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetPlayerSocialDetailReq req = GetPlayerSocialDetailReq.parseFrom(payload);
|
||||
|
||||
SocialDetail.Builder detail = session.getServer().getSocialDetailById(req.getUid());
|
||||
|
||||
if (detail != null) {
|
||||
detail.setIsFriend(session.getPlayer().getFriendsList().isFriendsWith(req.getUid()));
|
||||
}
|
||||
|
||||
session.send(new PacketGetPlayerSocialDetailRsp(detail));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetPlayerTokenReqOuterClass.GetPlayerTokenReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
||||
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetPlayerTokenReq)
|
||||
public class HandlerGetPlayerTokenReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
|
||||
|
||||
// Authenticate
|
||||
Account account = DatabaseHelper.getAccountById(req.getAccountUid());
|
||||
if (account == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check token
|
||||
if (!account.getToken().equals(req.getAccountToken())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set account
|
||||
session.setAccount(account);
|
||||
session.setUseSecretKey(true);
|
||||
session.setState(SessionState.WAITING_FOR_LOGIN);
|
||||
|
||||
// Has character
|
||||
boolean doesPlayerExist = false;
|
||||
if (account.getPlayerId() > 0) {
|
||||
// Set flag for player existing
|
||||
doesPlayerExist = DatabaseHelper.checkPlayerExists(account.getPlayerId());
|
||||
}
|
||||
|
||||
// Set reserve player id if account doesnt exist
|
||||
if (!doesPlayerExist) {
|
||||
int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerId());
|
||||
if (id != session.getAccount().getPlayerId()) {
|
||||
session.getAccount().setPlayerId(id);
|
||||
session.getAccount().save();
|
||||
}
|
||||
}
|
||||
|
||||
// Send packet
|
||||
session.send(new PacketGetPlayerTokenRsp(session, doesPlayerExist));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetRegionSearchReq)
|
||||
public class HandlerGetRegionSearchReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetSceneAreaReqOuterClass.GetSceneAreaReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetSceneAreaRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetSceneAreaReq)
|
||||
public class HandlerGetSceneAreaReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetSceneAreaReq req = GetSceneAreaReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketGetSceneAreaRsp(req.getSceneId()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetScenePointReqOuterClass.GetScenePointReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetScenePointRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetScenePointReq)
|
||||
public class HandlerGetScenePointReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetScenePointReq req = GetScenePointReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketGetScenePointRsp(req.getSceneId()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetShopReqOuterClass.GetShopReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetShopRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetShopReq)
|
||||
public class HandlerGetShopReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetShopReq req = GetShopReq.parseFrom(payload);
|
||||
|
||||
// TODO
|
||||
session.send(new PacketGetShopRsp(req.getShopType()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetShopmallDataRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetShopmallDataReq)
|
||||
public class HandlerGetShopmallDataReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// TODO add the correct shops
|
||||
session.send(new PacketGetShopmallDataRsp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetWidgetSlotReq)
|
||||
public class HandlerGetWidgetSlotReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Unhandled
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketGetWorldMpInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetWorldMpInfoReq)
|
||||
public class HandlerGetWorldMpInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetWorldMpInfoRsp(session.getPlayer().getWorld()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
|
||||
import emu.grasscutter.net.proto.OperationOuterClass.Operation;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.MarkMapReq)
|
||||
public class HandlerMarkMapReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
MarkMapReq req = MarkMapReq.parseFrom(payload);
|
||||
|
||||
if (req.getOp() != Operation.Add) {
|
||||
return;
|
||||
}
|
||||
|
||||
session.getPlayer().getPos().setX(req.getMark().getPos().getX());
|
||||
session.getPlayer().getPos().setZ(req.getMark().getPos().getZ());
|
||||
session.getPlayer().getPos().setY(300);
|
||||
|
||||
Grasscutter.getLogger().info("Player [" + session.getPlayer().getId() + ":" + session.getPlayer().getNickname() + "] tp to " + session.getPlayer().getPos());
|
||||
|
||||
session.getPlayer().getWorld().broadcastPacket(new PacketSceneEntityAppearNotify(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.MonsterAIConfigHashNotify)
|
||||
public class HandlerMonsterAIConfigHashNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ObstacleModifyNotify)
|
||||
public class HandlerObstacleModifyNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPathfindingEnterSceneRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PathfindingEnterSceneReq)
|
||||
public class HandlerPathfindingEnterSceneReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PacketHead head = PacketHead.parseFrom(header);
|
||||
session.send(new PacketPathfindingEnterSceneRsp(head.getClientSequenceId()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead;
|
||||
import emu.grasscutter.net.proto.PingReqOuterClass.PingReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPingRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PingReq)
|
||||
public class HandlerPingReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PacketHead head = PacketHead.parseFrom(header);
|
||||
PingReq ping = PingReq.parseFrom(payload);
|
||||
|
||||
session.updateLastPingTime(ping.getClientTime());
|
||||
|
||||
session.send(new PacketPingRsp(head.getClientSequenceId(), ping.getClientTime()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerApplyEnterMpReqOuterClass.PlayerApplyEnterMpReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerApplyEnterMpReq)
|
||||
public class HandlerPlayerApplyEnterMpReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpReq req = PlayerApplyEnterMpReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerManager().applyEnterMp(session.getPlayer(), req.getTargetUid());
|
||||
session.send(new PacketPlayerApplyEnterMpRsp(req.getTargetUid()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerApplyEnterMpResultReqOuterClass.PlayerApplyEnterMpResultReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpResultRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerApplyEnterMpResultReq)
|
||||
public class HandlerPlayerApplyEnterMpResultReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpResultReq req = PlayerApplyEnterMpResultReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerManager().applyEnterMpReply(session.getPlayer(), req.getApplyUid(), req.getIsAgreed());
|
||||
session.send(new PacketPlayerApplyEnterMpResultRsp(req.getApplyUid(), req.getIsAgreed()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo;
|
||||
import emu.grasscutter.net.proto.PlayerChatReqOuterClass.PlayerChatReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerChatRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerChatReq)
|
||||
public class HandlerPlayerChatReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerChatReq req = PlayerChatReq.parseFrom(payload);
|
||||
ChatInfo.ContentCase content = req.getChatInfo().getContentCase();
|
||||
|
||||
if (content == ChatInfo.ContentCase.TEXT) {
|
||||
session.getServer().getChatManager().sendTeamChat(session.getPlayer(), req.getChannelId(), req.getChatInfo().getText());
|
||||
} else if (content == ChatInfo.ContentCase.ICON) {
|
||||
session.getServer().getChatManager().sendTeamChat(session.getPlayer(), req.getChannelId(), req.getChatInfo().getIcon());
|
||||
}
|
||||
|
||||
session.send(new PacketPlayerChatRsp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerForceExitReq)
|
||||
public class HandlerPlayerForceExitReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Client should auto disconnect right now
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerGetForceQuitBanInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerGetForceQuitBanInfoReq)
|
||||
public class HandlerPlayerGetForceQuitBanInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
|
||||
if (session.getServer().getMultiplayerManager().leaveCoop(session.getPlayer())) {
|
||||
// Success
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(0));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.GenshinPlayer;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerLoginReqOuterClass.PlayerLoginReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
|
||||
public class HandlerPlayerLoginReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Check
|
||||
if (session.getAccount() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse request
|
||||
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
|
||||
|
||||
// Authenticate session
|
||||
if (!req.getToken().equals(session.getAccount().getToken())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load character from db
|
||||
GenshinPlayer player = DatabaseHelper.getPlayerById(session.getAccount().getPlayerId());
|
||||
|
||||
if (player == null) {
|
||||
// Send packets
|
||||
session.setState(SessionState.PICKING_CHARACTER);
|
||||
session.send(new GenshinPacket(PacketOpcodes.DoSetPlayerBornDataNotify));
|
||||
} else {
|
||||
// Set character
|
||||
session.setPlayer(player);
|
||||
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
session.setState(SessionState.ACTIVE);
|
||||
}
|
||||
|
||||
// Final packet to tell client logging in is done
|
||||
session.send(new PacketPlayerLoginRsp(session));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead;
|
||||
import emu.grasscutter.net.proto.PlayerSetPauseReqOuterClass.PlayerSetPauseReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerSetPauseRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerSetPauseReq)
|
||||
public class HandlerPlayerSetPauseReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PacketHead head = PacketHead.parseFrom(header);
|
||||
PlayerSetPauseReq req = PlayerSetPauseReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketPlayerSetPauseRsp(head.getClientSequenceId()));
|
||||
session.getPlayer().setPaused(req.getIsPaused());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPostEnterSceneRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PostEnterSceneReq)
|
||||
public class HandlerPostEnterSceneReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PrivateChatReqOuterClass.PrivateChatReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PrivateChatReq)
|
||||
public class HandlerPrivateChatReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PrivateChatReq req = PrivateChatReq.parseFrom(payload);
|
||||
PrivateChatReq.ContentCase content = req.getContentCase();
|
||||
|
||||
if (content == PrivateChatReq.ContentCase.TEXT) {
|
||||
session.getServer().getChatManager().sendPrivChat(session.getPlayer(), req.getTargetUid(), req.getText());
|
||||
} else if (content == PrivateChatReq.ContentCase.ICON) {
|
||||
session.getServer().getChatManager().sendPrivChat(session.getPlayer(), req.getTargetUid(), req.getIcon());
|
||||
}
|
||||
|
||||
//session.send(new GenshinPacket(PacketOpcodes.PrivateChatRsp)); // Unused by server
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PullPrivateChatReqOuterClass.PullPrivateChatReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPullPrivateChatRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PullPrivateChatReq)
|
||||
public class HandlerPullPrivateChatReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PullPrivateChatReq req = PullPrivateChatReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketPullPrivateChatRsp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPullRecentChatRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PullRecentChatReq)
|
||||
public class HandlerPullRecentChatReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketPullRecentChatRsp(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.QueryPathReq)
|
||||
public class HandlerQueryPathReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ReliquaryUpgradeReqOuterClass.ReliquaryUpgradeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ReliquaryUpgradeReq)
|
||||
public class HandlerReliquaryUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ReliquaryUpgradeReq req = ReliquaryUpgradeReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventoryManager().upgradeRelic(session.getPlayer(), req.getTargetReliquaryGuid(), req.getFoodReliquaryGuidListList(), req.getItemParamListList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.GenshinPlayer.SceneLoadState;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHostPlayerNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneInitFinishRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePlayerInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneTimeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketServerTimeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWorldDataNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWorldPlayerInfoNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.SceneInitFinishReq)
|
||||
public class HandlerSceneInitFinishReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Info packets
|
||||
session.send(new PacketServerTimeNotify());
|
||||
session.send(new PacketWorldPlayerInfoNotify(session.getPlayer().getWorld()));
|
||||
session.send(new PacketWorldDataNotify(session.getPlayer().getWorld()));
|
||||
session.send(new GenshinPacket(PacketOpcodes.SceneForceUnlockNotify));
|
||||
session.send(new PacketHostPlayerNotify(session.getPlayer().getWorld()));
|
||||
|
||||
session.send(new PacketSceneTimeNotify(session.getPlayer()));
|
||||
session.send(new PacketPlayerGameTimeNotify(session.getPlayer().getWorld(), session.getPlayer()));
|
||||
session.send(new PacketPlayerEnterSceneInfoNotify(session.getPlayer()));
|
||||
session.send(new PacketSceneAreaWeatherNotify(session.getPlayer().getWorld(), session.getPlayer()));
|
||||
session.send(new PacketScenePlayerInfoNotify(session.getPlayer().getWorld()));
|
||||
session.send(new PacketSceneTeamUpdateNotify(session.getPlayer()));
|
||||
|
||||
session.send(new PacketSyncTeamEntityNotify(session.getPlayer()));
|
||||
session.send(new PacketSyncScenePlayTeamEntityNotify(session.getPlayer()));
|
||||
|
||||
// Done Packet
|
||||
session.send(new PacketSceneInitFinishRsp(session.getPlayer()));
|
||||
|
||||
// Set state
|
||||
session.getPlayer().setSceneLoadState(SceneLoadState.INIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SceneKickPlayerReqOuterClass.SceneKickPlayerReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneKickPlayerRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SceneKickPlayerReq)
|
||||
public class HandlerSceneKickPlayerReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SceneKickPlayerReq req = SceneKickPlayerReq.parseFrom(payload);
|
||||
|
||||
if (session.getServer().getMultiplayerManager().kickPlayer(session.getPlayer(), req.getTargetUid())) {
|
||||
// Success
|
||||
session.send(new PacketSceneKickPlayerRsp(req.getTargetUid()));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketSceneKickPlayerRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetEntityClientDataNotify)
|
||||
public class HandlerSetEntityClientDataNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetEquipLockStateReqOuterClass.SetEquipLockStateReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetEquipLockStateReq)
|
||||
public class HandlerSetEquipLockStateReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetEquipLockStateReq req = SetEquipLockStateReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventoryManager().lockEquip(session.getPlayer(), req.getTargetEquipGuid(), req.getIsLocked());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetNameCardReqOuterClass.SetNameCardReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetNameCardReq)
|
||||
public class HandlerSetNameCardReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetNameCardReq req = SetNameCardReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().setNameCard(req.getNameCardId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.GenshinConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GenshinData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.GenshinPlayer;
|
||||
import emu.grasscutter.game.avatar.GenshinAvatar;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetPlayerBornDataReqOuterClass.SetPlayerBornDataReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetPlayerBornDataReq)
|
||||
public class HandlerSetPlayerBornDataReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetPlayerBornDataReq req = SetPlayerBornDataReq.parseFrom(payload);
|
||||
|
||||
// Sanity checks
|
||||
int avatarId = req.getAvatarId();
|
||||
int startingSkillDepot = 0;
|
||||
if (avatarId == GenshinConstants.MAIN_CHARACTER_MALE) {
|
||||
startingSkillDepot = 504;
|
||||
} else if (avatarId == GenshinConstants.MAIN_CHARACTER_FEMALE) {
|
||||
startingSkillDepot = 704;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
String nickname = req.getNickName();
|
||||
if (nickname == null) {
|
||||
nickname = "Traveler";
|
||||
}
|
||||
|
||||
// Create character
|
||||
GenshinPlayer player = new GenshinPlayer(session);
|
||||
player.setNickname(nickname);
|
||||
|
||||
try {
|
||||
// Save to db
|
||||
DatabaseHelper.createPlayer(player, session.getAccount().getPlayerId());
|
||||
|
||||
// Create avatar
|
||||
if (player.getAvatars().getAvatarCount() == 0) {
|
||||
GenshinAvatar mainCharacter = new GenshinAvatar(avatarId);
|
||||
mainCharacter.setSkillDepot(GenshinData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
|
||||
player.addAvatar(mainCharacter);
|
||||
player.setMainCharacterId(avatarId);
|
||||
player.setHeadImage(avatarId);
|
||||
player.getTeamManager().getCurrentSinglePlayerTeamInfo().getAvatars().add(mainCharacter.getAvatarId());
|
||||
player.save(); // TODO save player team in different object
|
||||
}
|
||||
|
||||
// Save account
|
||||
session.getAccount().setPlayerId(player.getId());
|
||||
session.getAccount().save();
|
||||
|
||||
// Set character
|
||||
session.setPlayer(player);
|
||||
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
session.setState(SessionState.ACTIVE);
|
||||
|
||||
// Born resp packet
|
||||
session.send(new GenshinPacket(PacketOpcodes.SetPlayerBornDataRsp));
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error creating player object: ", e);
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetPlayerHeadImageReqOuterClass.SetPlayerHeadImageReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetPlayerHeadImageRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetPlayerHeadImageReq)
|
||||
public class HandlerSetPlayerHeadImageReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetPlayerHeadImageReq req = SetPlayerHeadImageReq.parseFrom(payload);
|
||||
|
||||
int id = req.getAvatarId();
|
||||
|
||||
if (session.getPlayer().getAvatars().hasAvatar(id)) {
|
||||
session.getPlayer().setHeadImage(id);
|
||||
session.send(new PacketSetPlayerHeadImageRsp(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetPlayerNameReqOuterClass.SetPlayerNameReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetPlayerNameRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetPlayerNameReq)
|
||||
public class HandlerSetPlayerNameReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
SetPlayerNameReq req = SetPlayerNameReq.parseFrom(payload);
|
||||
|
||||
if (req.getNickName() != null && req.getNickName().length() > 0) {
|
||||
session.getPlayer().setNickname(req.getNickName());
|
||||
session.send(new PacketSetPlayerNameRsp(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetPlayerSignatureReqOuterClass.SetPlayerSignatureReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetPlayerSignatureRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetPlayerSignatureReq)
|
||||
public class HandlerSetPlayerSignatureReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
SetPlayerSignatureReq req = SetPlayerSignatureReq.parseFrom(payload);
|
||||
|
||||
if (req.getSignature() != null && req.getSignature().length() > 0) {
|
||||
session.getPlayer().setSignature(req.getSignature());
|
||||
session.send(new PacketSetPlayerSignatureRsp(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetUpAvatarTeamReqOuterClass.SetUpAvatarTeamReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetUpAvatarTeamReq)
|
||||
public class HandlerSetUpAvatarTeamReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetUpAvatarTeamReq req = SetUpAvatarTeamReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setupAvatarTeam(req.getTeamId(), req.getAvatarTeamGuidListList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.TakeoffEquipReqOuterClass.TakeoffEquipReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketTakeoffEquipRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.TakeoffEquipReq)
|
||||
public class HandlerTakeoffEquipReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
TakeoffEquipReq req = TakeoffEquipReq.parseFrom(payload);
|
||||
|
||||
if (session.getPlayer().getInventory().unequipItem(req.getAvatarGuid(), req.getSlot())) {
|
||||
session.send(new PacketTakeoffEquipRsp(req.getAvatarGuid(), req.getSlot()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketTowerAllDataRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.TowerAllDataReq)
|
||||
public class HandlerTowerAllDataReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketTowerAllDataRsp());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.UnionCmdNotifyOuterClass.UnionCmdNotify;
|
||||
import emu.grasscutter.net.proto.UnionCmdOuterClass.UnionCmd;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.UnionCmdNotify)
|
||||
public class HandlerUnionCmdNotify extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnionCmdNotify req = UnionCmdNotify.parseFrom(payload);
|
||||
for (UnionCmd cmd : req.getCmdListList()) {
|
||||
session.getServer().getPacketHandler().handle(session, cmd.getMessageId(), EMPTY_BYTE_ARRAY, cmd.getBody().toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.UnlockAvatarTalentReqOuterClass.UnlockAvatarTalentReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.UnlockAvatarTalentReq)
|
||||
public class HandlerUnlockAvatarTalentReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnlockAvatarTalentReq req = UnlockAvatarTalentReq.parseFrom(payload);
|
||||
|
||||
// Unlock avatar const
|
||||
session.getServer().getInventoryManager().unlockAvatarConstellation(session.getPlayer(), req.getAvatarGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.inventory.GenshinItem;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.UseItemReqOuterClass.UseItemReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketUseItemRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.UseItemReq)
|
||||
public class HandlerUseItemReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UseItemReq req = UseItemReq.parseFrom(payload);
|
||||
|
||||
GenshinItem useItem = session.getServer().getInventoryManager().useItem(session.getPlayer(), req.getTargetGuid(), req.getGuid(), req.getCount());
|
||||
if (useItem != null) {
|
||||
session.send(new PacketUseItemRsp(req.getTargetGuid(), useItem));
|
||||
} else {
|
||||
session.send(new PacketUseItemRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WeaponAwakenReqOuterClass.WeaponAwakenReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponAwakenReq)
|
||||
public class HandlerWeaponAwakenReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponAwakenReq req = WeaponAwakenReq.parseFrom(payload);
|
||||
|
||||
// Weapon refinement
|
||||
session.getServer().getInventoryManager().refineWeapon(session.getPlayer(), req.getTargetWeaponGuid(), req.getItemGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WeaponPromoteReqOuterClass.WeaponPromoteReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponPromoteReq)
|
||||
public class HandlerWeaponPromoteReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponPromoteReq req = WeaponPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend weapon
|
||||
session.getServer().getInventoryManager().promoteWeapon(session.getPlayer(), req.getTargetWeaponGuid());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WeaponUpgradeReqOuterClass.WeaponUpgradeReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponUpgradeReq)
|
||||
public class HandlerWeaponUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponUpgradeReq req = WeaponUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up weapon
|
||||
session.getServer().getInventoryManager().upgradeWeapon(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WearEquipReqOuterClass.WearEquipReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketWearEquipRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.WearEquipReq)
|
||||
public class HandlerWearEquipReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WearEquipReq req = WearEquipReq.parseFrom(payload);
|
||||
|
||||
if (session.getPlayer().getInventory().equipItem(req.getAvatarGuid(), req.getEquipGuid())) {
|
||||
session.send(new PacketWearEquipRsp(req.getAvatarGuid(), req.getEquipGuid()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WorldPlayerReviveReq)
|
||||
public class HandlerWorldPlayerReviveReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getPlayer().getTeamManager().respawnTeam();
|
||||
}
|
||||
|
||||
}
|
||||
12
src/main/java/emu/grasscutter/server/packet/send/Packet.java
Normal file
12
src/main/java/emu/grasscutter/server/packet/send/Packet.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
|
||||
public class Packet extends GenshinPacket {
|
||||
|
||||
public Packet() {
|
||||
super(PacketOpcodes.NONE);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AbilityChangeNotifyOuterClass.AbilityChangeNotify;
|
||||
|
||||
public class PacketAbilityChangeNotify extends GenshinPacket {
|
||||
|
||||
public PacketAbilityChangeNotify(EntityAvatar entity) {
|
||||
super(PacketOpcodes.AbilityChangeNotify);
|
||||
|
||||
AbilityChangeNotify proto = AbilityChangeNotify.newBuilder()
|
||||
.setEntityId(entity.getId())
|
||||
.setAbilityControlBlock(entity.getAbilityControlBlock())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AbilityInvocationsNotifyOuterClass.AbilityInvocationsNotify;
|
||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||
|
||||
public class PacketAbilityInvocationsNotify extends GenshinPacket {
|
||||
|
||||
public PacketAbilityInvocationsNotify(AbilityInvokeEntry entry) {
|
||||
super(PacketOpcodes.AbilityInvocationsNotify, true);
|
||||
|
||||
AbilityInvocationsNotify proto = AbilityInvocationsNotify.newBuilder()
|
||||
.addInvokes(entry)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketAbilityInvocationsNotify(List<AbilityInvokeEntry> entries) {
|
||||
super(PacketOpcodes.AbilityInvocationsNotify, true);
|
||||
|
||||
AbilityInvocationsNotify proto = AbilityInvocationsNotify.newBuilder()
|
||||
.addAllInvokes(entries)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.friends.Friendship;
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AskAddFriendNotifyOuterClass.AskAddFriendNotify;
|
||||
|
||||
public class PacketAskAddFriendNotify extends GenshinPacket {
|
||||
|
||||
public PacketAskAddFriendNotify(Friendship friendship) {
|
||||
super(PacketOpcodes.AskAddFriendNotify);
|
||||
|
||||
AskAddFriendNotify proto = AskAddFriendNotify.newBuilder()
|
||||
.setTargetUid(friendship.getFriendId())
|
||||
.setTargetFriendBrief(friendship.toProto())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AskAddFriendRspOuterClass.AskAddFriendRsp;
|
||||
|
||||
public class PacketAskAddFriendRsp extends GenshinPacket {
|
||||
|
||||
public PacketAskAddFriendRsp(int targetUid) {
|
||||
super(PacketOpcodes.AskAddFriendRsp);
|
||||
|
||||
AskAddFriendRsp proto = AskAddFriendRsp.newBuilder()
|
||||
.setTargetUid(targetUid)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user