mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-18 09:54:59 +01:00
Merge development into plugin-auth
This commit is contained in:
@@ -14,6 +14,8 @@ import emu.grasscutter.game.managers.ChatManager;
|
||||
import emu.grasscutter.game.managers.InventoryManager;
|
||||
import emu.grasscutter.game.managers.MultiplayerManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.ServerQuestHandler;
|
||||
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
|
||||
import emu.grasscutter.game.shop.ShopManager;
|
||||
import emu.grasscutter.game.tower.TowerScheduleManager;
|
||||
import emu.grasscutter.game.world.World;
|
||||
@@ -37,7 +39,8 @@ import static emu.grasscutter.Configuration.*;
|
||||
public final class GameServer extends KcpServer {
|
||||
private final InetSocketAddress address;
|
||||
private final GameServerPacketHandler packetHandler;
|
||||
|
||||
private final ServerQuestHandler questHandler;
|
||||
|
||||
private final Map<Integer, Player> players;
|
||||
private final Set<World> worlds;
|
||||
|
||||
@@ -68,6 +71,7 @@ public final class GameServer extends KcpServer {
|
||||
this.setServerInitializer(new GameServerInitializer(this));
|
||||
this.address = address;
|
||||
this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
|
||||
this.questHandler = new ServerQuestHandler();
|
||||
this.players = new ConcurrentHashMap<>();
|
||||
this.worlds = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
@@ -91,6 +95,10 @@ public final class GameServer extends KcpServer {
|
||||
return packetHandler;
|
||||
}
|
||||
|
||||
public ServerQuestHandler getQuestHandler() {
|
||||
return questHandler;
|
||||
}
|
||||
|
||||
public Map<Integer, Player> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,7 @@ public class GameSession extends KcpChannel {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
data.release();
|
||||
packet.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.*;
|
||||
import emu.grasscutter.net.proto.RegionInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo;
|
||||
import emu.grasscutter.net.proto.RegionSimpleInfoOuterClass.RegionSimpleInfo;
|
||||
import emu.grasscutter.server.event.dispatch.QueryAllRegionsEvent;
|
||||
import emu.grasscutter.server.event.dispatch.QueryCurrentRegionEvent;
|
||||
import emu.grasscutter.server.http.Router;
|
||||
import emu.grasscutter.utils.Crypto;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import express.Express;
|
||||
@@ -30,45 +33,24 @@ import static emu.grasscutter.net.proto.QueryRegionListHttpRspOuterClass.*;
|
||||
* Handles requests related to region queries.
|
||||
*/
|
||||
public final class RegionHandler implements Router {
|
||||
private String regionQuery = "";
|
||||
private String regionList = "";
|
||||
|
||||
private static final Map<String, RegionData> regions = new ConcurrentHashMap<>();
|
||||
private static String regionListResponse;
|
||||
|
||||
public RegionHandler() {
|
||||
try { // Read & initialize region data.
|
||||
this.readRegionData();
|
||||
this.initialize();
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().error("Failed to initialize region data.", exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads initial region data.
|
||||
*/
|
||||
private void readRegionData() {
|
||||
File file;
|
||||
|
||||
file = new File(DATA("query_region_list.txt"));
|
||||
if (file.exists())
|
||||
this.regionList = new String(FileUtils.read(file));
|
||||
else Grasscutter.getLogger().error("[Dispatch] 'query_region_list' not found!");
|
||||
|
||||
file = new File(DATA("query_cur_region.txt"));
|
||||
if (file.exists())
|
||||
regionQuery = new String(FileUtils.read(file));
|
||||
else Grasscutter.getLogger().warn("[Dispatch] 'query_cur_region' not found!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures region data according to configuration.
|
||||
*/
|
||||
private void initialize() throws InvalidProtocolBufferException {
|
||||
// Decode the initial region query.
|
||||
byte[] queryBase64 = Base64.getDecoder().decode(this.regionQuery);
|
||||
QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(queryBase64);
|
||||
private void initialize() {
|
||||
String dispatchDomain = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort);
|
||||
|
||||
// Create regions.
|
||||
List<RegionSimpleInfo> servers = new ArrayList<>();
|
||||
@@ -87,37 +69,33 @@ public final class RegionHandler implements Router {
|
||||
Grasscutter.getLogger().error("Region name already in use.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create a region identifier.
|
||||
var identifier = RegionSimpleInfo.newBuilder()
|
||||
.setName(region.Name).setTitle(region.Title)
|
||||
.setType("DEV_PUBLIC").setDispatchUrl(
|
||||
"http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
||||
+ "/query_cur_region/" + region.Name)
|
||||
.setName(region.Name).setTitle(region.Title).setType("DEV_PUBLIC")
|
||||
.setDispatchUrl(dispatchDomain + "/query_cur_region/" + region.Name)
|
||||
.build();
|
||||
usedNames.add(region.Name); servers.add(identifier);
|
||||
|
||||
// Create a region info object.
|
||||
var regionInfo = regionQuery.getRegionInfo().toBuilder()
|
||||
var regionInfo = RegionInfo.newBuilder()
|
||||
.setGateserverIp(region.Ip).setGateserverPort(region.Port)
|
||||
.setSecretKey(ByteString.copyFrom(FileUtils.read(KEYS_FOLDER + "/dispatchSeed.bin")))
|
||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||
.build();
|
||||
// Create an updated region query.
|
||||
var updatedQuery = regionQuery.toBuilder().setRegionInfo(regionInfo).build();
|
||||
var updatedQuery = QueryCurrRegionHttpRsp.newBuilder().setRegionInfo(regionInfo).build();
|
||||
regions.put(region.Name, new RegionData(updatedQuery, Utils.base64Encode(updatedQuery.toByteString().toByteArray())));
|
||||
});
|
||||
|
||||
// Decode the initial region list.
|
||||
byte[] listBase64 = Base64.getDecoder().decode(this.regionList);
|
||||
QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.parseFrom(listBase64);
|
||||
// Create a config object.
|
||||
byte[] customConfig = "{\"sdkenv\":\"2\",\"checkdevice\":\"false\",\"loadPatch\":\"false\",\"showexception\":\"false\",\"regionConfig\":\"pm|fk|add\",\"downloadMode\":\"0\"}".getBytes();
|
||||
Crypto.xor(customConfig, Crypto.DISPATCH_KEY); // XOR the config with the key.
|
||||
|
||||
// Create an updated region list.
|
||||
QueryRegionListHttpRsp updatedRegionList = QueryRegionListHttpRsp.newBuilder()
|
||||
.addAllRegionList(servers)
|
||||
.setClientSecretKey(regionList.getClientSecretKey())
|
||||
.setClientCustomConfigEncrypted(regionList.getClientCustomConfigEncrypted())
|
||||
.setClientSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||
.setClientCustomConfigEncrypted(ByteString.copyFrom(customConfig))
|
||||
.setEnableLoginPc(true).build();
|
||||
|
||||
// Set the region list response.
|
||||
|
||||
@@ -3,6 +3,8 @@ package emu.grasscutter.server.http.handlers;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.server.http.objects.HttpJsonResponse;
|
||||
import emu.grasscutter.server.http.Router;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import express.Express;
|
||||
import express.http.Request;
|
||||
import express.http.Response;
|
||||
@@ -11,6 +13,7 @@ import io.javalin.Javalin;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
|
||||
import static emu.grasscutter.Configuration.DATA;
|
||||
@@ -19,6 +22,18 @@ import static emu.grasscutter.Configuration.DATA;
|
||||
* Handles requests related to the announcements page.
|
||||
*/
|
||||
public final class AnnouncementsHandler implements Router {
|
||||
private static String template, swjs, vue;
|
||||
|
||||
public AnnouncementsHandler() {
|
||||
var templateFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/index.html")));
|
||||
var swjsFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/sw.js")));
|
||||
var vueFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/vue.min.js")));
|
||||
|
||||
template = templateFile.exists() ? new String(FileUtils.read(template)) : null;
|
||||
swjs = swjsFile.exists() ? new String(FileUtils.read(swjs)) : null;
|
||||
vue = vueFile.exists() ? new String(FileUtils.read(vueFile)) : null;
|
||||
}
|
||||
|
||||
@Override public void applyRoutes(Express express, Javalin handle) {
|
||||
// hk4e-api-os.hoyoverse.com
|
||||
express.all("/common/hk4e_global/announcement/api/getAlertPic", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"total\":0,\"list\":[]}}"));
|
||||
@@ -30,14 +45,45 @@ public final class AnnouncementsHandler implements Router {
|
||||
express.all("/common/hk4e_global/announcement/api/getAnnContent", AnnouncementsHandler::getAnnouncement);
|
||||
// hk4e-sdk-os.hoyoverse.com
|
||||
express.all("/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"suggest_currency\":\"USD\",\"tiers\":[]}}"));
|
||||
|
||||
express.get("/hk4e/announcement/*", AnnouncementsHandler::getPageResources);
|
||||
express.get("/sw.js", AnnouncementsHandler::getPageResources);
|
||||
express.get("/dora/lib/vue/2.6.11/vue.min.js", AnnouncementsHandler::getPageResources);
|
||||
}
|
||||
|
||||
private static void getAnnouncement(Request request, Response response) {
|
||||
if (Objects.equals(request.baseUrl(), "/common/hk4e_global/announcement/api/getAnnContent")) {
|
||||
response.send("{\"retcode\":0,\"message\":\"OK\",\"data\":" + readToString(new File(DATA("GameAnnouncement.json"))) +"}");
|
||||
String data = readToString(Paths.get(DATA("GameAnnouncement.json")).toFile());
|
||||
response.send("{\"retcode\":0,\"message\":\"OK\",\"data\":" + data + "}");
|
||||
} else if (Objects.equals(request.baseUrl(), "/common/hk4e_global/announcement/api/getAnnList")) {
|
||||
String data = readToString(new File(DATA("GameAnnouncementList.json"))).replace("System.currentTimeMillis()",String.valueOf(System.currentTimeMillis()));
|
||||
response.send("{\"retcode\":0,\"message\":\"OK\",\"data\": "+data +"}");
|
||||
String data = readToString(Paths.get(DATA("GameAnnouncementList.json")).toFile())
|
||||
.replace("System.currentTimeMillis()", String.valueOf(System.currentTimeMillis()));
|
||||
response.send("{\"retcode\":0,\"message\":\"OK\",\"data\": " + data + "}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void getPageResources(Request request, Response response) {
|
||||
var path = request.path();
|
||||
switch(path) {
|
||||
case "/sw.js" -> response.send(swjs);
|
||||
case "/hk4e/announcement/index.html" -> response.send(template);
|
||||
case "/dora/lib/vue/2.6.11/vue.min.js" -> response.send(vue);
|
||||
|
||||
default -> {
|
||||
File renderFile = new File(Utils.toFilePath(DATA(path)));
|
||||
if(!renderFile.exists()) {
|
||||
Grasscutter.getLogger().info("File not exist: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
String ext = path.substring(path.lastIndexOf(".") + 1);
|
||||
if ("css".equals(ext)) {
|
||||
response.type("text/css");
|
||||
response.send(FileUtils.read(renderFile));
|
||||
} else {
|
||||
response.send(FileUtils.read(renderFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ package emu.grasscutter.server.http.handlers;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.gacha.GachaBanner;
|
||||
import emu.grasscutter.game.gacha.GachaManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.http.Router;
|
||||
import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
@@ -13,8 +17,12 @@ import io.javalin.Javalin;
|
||||
import io.javalin.http.staticfiles.Location;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static emu.grasscutter.Configuration.DATA;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
/**
|
||||
* Handles all gacha-related HTTP requests.
|
||||
@@ -22,7 +30,8 @@ import static emu.grasscutter.Configuration.DATA;
|
||||
public final class GachaHandler implements Router {
|
||||
private final String gachaMappings;
|
||||
|
||||
private static String frontendTemplate = "{{REPLACE_RECORD}}";
|
||||
private static String recordsTemplate = "";
|
||||
private static String detailsTemplate = "";
|
||||
|
||||
public GachaHandler() {
|
||||
this.gachaMappings = Utils.toFilePath(DATA("/gacha_mappings.js"));
|
||||
@@ -35,12 +44,15 @@ public final class GachaHandler implements Router {
|
||||
}
|
||||
|
||||
var templateFile = new File(DATA("/gacha_records.html"));
|
||||
if(templateFile.exists())
|
||||
frontendTemplate = new String(FileUtils.read(templateFile));
|
||||
recordsTemplate = templateFile.exists() ? new String(FileUtils.read(templateFile)) : "{{REPLACE_RECORD}}";
|
||||
|
||||
templateFile = new File(Utils.toFilePath(DATA("/gacha_details.html")));
|
||||
detailsTemplate = templateFile.exists() ? new String(FileUtils.read(templateFile)) : null;
|
||||
}
|
||||
|
||||
@Override public void applyRoutes(Express express, Javalin handle) {
|
||||
express.get("/gacha", GachaHandler::gachaRecords);
|
||||
express.get("/gacha/details", GachaHandler::gachaDetails);
|
||||
|
||||
express.useStaticFallback("/gacha/mappings", this.gachaMappings, Location.EXTERNAL);
|
||||
}
|
||||
@@ -63,9 +75,62 @@ public final class GachaHandler implements Router {
|
||||
String records = DatabaseHelper.getGachaRecords(account.getPlayerUid(), gachaType, page).toString();
|
||||
long maxPage = DatabaseHelper.getGachaRecordsMaxPage(account.getPlayerUid(), page, gachaType);
|
||||
|
||||
response.send(frontendTemplate
|
||||
response.send(recordsTemplate
|
||||
.replace("{{REPLACE_RECORD}}", records)
|
||||
.replace("{{REPLACE_MAXPAGE}}", String.valueOf(maxPage)));
|
||||
}
|
||||
}
|
||||
|
||||
private static void gachaDetails(Request request, Response response) {
|
||||
String template = detailsTemplate;
|
||||
|
||||
// Get player info (for langauge).
|
||||
String sessionKey = request.query("s");
|
||||
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
|
||||
Player player = Grasscutter.getGameServer().getPlayerByUid(account.getPlayerUid());
|
||||
|
||||
// If the template was not loaded, return an error.
|
||||
if (detailsTemplate == null) {
|
||||
response.send(translate(player, "gacha.details.template_missing"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Add translated title etc. to the page.
|
||||
template = template.replace("{{TITLE}}", translate(player, "gacha.details.title"))
|
||||
.replace("{{AVAILABLE_FIVE_STARS}}", translate(player, "gacha.details.available_five_stars"))
|
||||
.replace("{{AVAILABLE_FOUR_STARS}}", translate(player, "gacha.details.available_four_stars"))
|
||||
.replace("{{AVAILABLE_THREE_STARS}}", translate(player, "gacha.details.available_three_stars"))
|
||||
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
|
||||
|
||||
// Get the banner info for the banner we want.
|
||||
int gachaType = Integer.parseInt(request.query("gachaType"));
|
||||
GachaManager manager = Grasscutter.getGameServer().getGachaManager();
|
||||
GachaBanner banner = manager.getGachaBanners().get(gachaType);
|
||||
|
||||
// Add 5-star items.
|
||||
Set<String> fiveStarItems = new LinkedHashSet<>();
|
||||
|
||||
Arrays.stream(banner.getRateUpItems5()).forEach(i -> fiveStarItems.add(Integer.toString(i)));
|
||||
Arrays.stream(banner.getFallbackItems5Pool1()).forEach(i -> fiveStarItems.add(Integer.toString(i)));
|
||||
Arrays.stream(banner.getFallbackItems5Pool2()).forEach(i -> fiveStarItems.add(Integer.toString(i)));
|
||||
|
||||
template = template.replace("{{FIVE_STARS}}", "[" + String.join(",", fiveStarItems) + "]");
|
||||
|
||||
// Add 4-star items.
|
||||
Set<String> fourStarItems = new LinkedHashSet<>();
|
||||
|
||||
Arrays.stream(banner.getRateUpItems4()).forEach(i -> fourStarItems.add(Integer.toString(i)));
|
||||
Arrays.stream(banner.getFallbackItems4Pool1()).forEach(i -> fourStarItems.add(Integer.toString(i)));
|
||||
Arrays.stream(banner.getFallbackItems4Pool2()).forEach(i -> fourStarItems.add(Integer.toString(i)));
|
||||
|
||||
template = template.replace("{{FOUR_STARS}}", "[" + String.join(",", fourStarItems) + "]");
|
||||
|
||||
// Add 3-star items.
|
||||
Set<String> threeStarItems = new LinkedHashSet<>();
|
||||
Arrays.stream(banner.getFallbackItems3()).forEach(i -> threeStarItems.add(Integer.toString(i)));
|
||||
template = template.replace("{{THREE_STARS}}", "[" + String.join(",", threeStarItems) + "]");
|
||||
|
||||
// Done.
|
||||
response.send(template);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import emu.grasscutter.server.packet.send.PacketBuyGoodsRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketStoreItemChangeNotify;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -56,36 +56,13 @@ public class HandlerBuyGoodsReq extends PacketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sg.getScoin() > 0 && session.getPlayer().getMora() < buyGoodsReq.getBoughtNum() * sg.getScoin()) {
|
||||
List<ItemParamData> costs = new ArrayList<ItemParamData>(sg.getCostItemList()); // Can this even be null?
|
||||
costs.add(new ItemParamData(202, sg.getScoin()));
|
||||
costs.add(new ItemParamData(201, sg.getHcoin()));
|
||||
costs.add(new ItemParamData(203, sg.getMcoin()));
|
||||
if (!session.getPlayer().getInventory().payItems(costs.toArray(new ItemParamData[0]), buyGoodsReq.getBoughtNum())) {
|
||||
return;
|
||||
}
|
||||
if (sg.getHcoin() > 0 && session.getPlayer().getPrimogems() < buyGoodsReq.getBoughtNum() * sg.getHcoin()) {
|
||||
return;
|
||||
}
|
||||
if (sg.getMcoin() > 0 && session.getPlayer().getCrystals() < buyGoodsReq.getBoughtNum() * sg.getMcoin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap<GameItem, Integer> itemsCache = new HashMap<>();
|
||||
if (sg.getCostItemList() != null) {
|
||||
for (ItemParamData p : sg.getCostItemList()) {
|
||||
Optional<GameItem> invItem = session.getPlayer().getInventory().getItems().values().stream().filter(x -> x.getItemId() == p.getId()).findFirst();
|
||||
if (invItem.isEmpty() || invItem.get().getCount() < p.getCount())
|
||||
return;
|
||||
itemsCache.put(invItem.get(), p.getCount() * buyGoodsReq.getBoughtNum());
|
||||
}
|
||||
}
|
||||
|
||||
session.getPlayer().setMora(session.getPlayer().getMora() - buyGoodsReq.getBoughtNum() * sg.getScoin());
|
||||
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() - buyGoodsReq.getBoughtNum() * sg.getHcoin());
|
||||
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - buyGoodsReq.getBoughtNum() * sg.getMcoin());
|
||||
|
||||
if (!itemsCache.isEmpty()) {
|
||||
for (GameItem gi : itemsCache.keySet()) {
|
||||
session.getPlayer().getInventory().removeItem(gi, itemsCache.get(gi));
|
||||
}
|
||||
itemsCache.clear();
|
||||
}
|
||||
|
||||
session.getPlayer().addShopLimit(sg.getGoodsId(), buyGoodsReq.getBoughtNum(), ShopManager.getShopNextRefreshTime(sg));
|
||||
GameItem item = new GameItem(GameData.getItemDataMap().get(sg.getGoodsItem().getId()));
|
||||
|
||||
@@ -11,12 +11,6 @@ import emu.grasscutter.server.game.GameSession;
|
||||
public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||
Player player = session.getPlayer();
|
||||
SotSManager sotsManager = player.getSotSManager();
|
||||
|
||||
sotsManager.refillSpringVolume();
|
||||
sotsManager.autoRevive(session);
|
||||
sotsManager.scheduleAutoRecover(session);
|
||||
// TODO: allow interaction with the SotS?
|
||||
session.getPlayer().getSotSManager().handleEnterTransPointRegionNotify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.managers.SotSManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
@@ -11,8 +12,6 @@ import emu.grasscutter.server.game.GameSession;
|
||||
public class HandlerExitTransPointRegionNotify extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||
Player player = session.getPlayer();
|
||||
SotSManager sotsManager = player.getSotSManager();
|
||||
sotsManager.cancelAutoRecover();
|
||||
session.getPlayer().getSotSManager().handleExitTransPointRegionNotify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
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.PacketGetShopRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketGetWidgetSlotRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetWidgetSlotReq)
|
||||
public class HandlerGetWidgetSlotReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Unhandled
|
||||
Player player = session.getPlayer();
|
||||
session.send(new PacketGetWidgetSlotRsp(player));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeChooseModuleReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeChooseModuleRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeComfortInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerHomeCompInfoNotify;
|
||||
|
||||
|
||||
@Opcodes(PacketOpcodes.HomeChooseModuleReq)
|
||||
public class HandlerHomeChooseModuleReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
HomeChooseModuleReqOuterClass.HomeChooseModuleReq req =
|
||||
HomeChooseModuleReqOuterClass.HomeChooseModuleReq.parseFrom(payload);
|
||||
session.getPlayer().addRealmList(req.getModuleId());
|
||||
session.getPlayer().setCurrentRealmId(req.getModuleId());
|
||||
session.send(new PacketHomeChooseModuleRsp(req.getModuleId()));
|
||||
session.send(new PacketPlayerHomeCompInfoNotify(session.getPlayer()));
|
||||
session.send(new PacketHomeComfortInfoNotify(session.getPlayer()));
|
||||
}
|
||||
}
|
||||
@@ -1,84 +1,17 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.managers.MapMarkManager.MapMark;
|
||||
import emu.grasscutter.game.managers.MapMarkManager.MapMarksManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.*;
|
||||
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketMarkMapRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketMarkNewNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Opcodes(PacketOpcodes.MarkMapReq)
|
||||
public class HandlerMarkMapReq extends PacketHandler {
|
||||
|
||||
private static boolean isInt(String str) {
|
||||
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
int x = Integer.parseInt(str);
|
||||
return true; // String is an Integer
|
||||
} catch (NumberFormatException e) {
|
||||
return false; // String is not an Integer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
MarkMapReq req = MarkMapReq.parseFrom(payload);
|
||||
MarkMapReq.Operation op = req.getOp();
|
||||
Player player = session.getPlayer();
|
||||
MapMarksManager mapMarksManager = player.getMapMarksManager();
|
||||
if (op == MarkMapReq.Operation.ADD) {
|
||||
MapMark newMapMark = new MapMark(req.getMark());
|
||||
// keep teleporting functionality on fishhook mark.
|
||||
if (newMapMark.getMapMarkPointType() == MapMarkPointTypeOuterClass.MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) {
|
||||
teleport(player, newMapMark);
|
||||
return;
|
||||
}
|
||||
if (mapMarksManager.addMapMark(newMapMark)) {
|
||||
player.save();
|
||||
}
|
||||
} else if (op == MarkMapReq.Operation.MOD) {
|
||||
MapMark newMapMark = new MapMark(req.getMark());
|
||||
if (mapMarksManager.removeMapMark(newMapMark.getPosition())) {
|
||||
if (mapMarksManager.addMapMark(newMapMark)) {
|
||||
player.save();
|
||||
}
|
||||
}
|
||||
} else if (op == MarkMapReq.Operation.DEL) {
|
||||
MapMark newMapMark = new MapMark(req.getMark());
|
||||
if (mapMarksManager.removeMapMark(newMapMark.getPosition())) {
|
||||
player.save();
|
||||
}
|
||||
} else if (op == MarkMapReq.Operation.GET) {
|
||||
// no-op
|
||||
}
|
||||
// send all marks to refresh client map view.
|
||||
HashMap<String, MapMark> mapMarks = mapMarksManager.getAllMapMarks();
|
||||
session.send(new PacketMarkMapRsp(player, mapMarks));
|
||||
}
|
||||
|
||||
private void teleport(Player player, MapMark mapMark) {
|
||||
float y = isInt(mapMark.getName()) ? Integer.parseInt(mapMark.getName()) : 300;
|
||||
float x = mapMark.getPosition().getX();
|
||||
float z = mapMark.getPosition().getZ();
|
||||
player.getPos().set(x, y, z);
|
||||
if (mapMark.getSceneId() != player.getSceneId()) {
|
||||
player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(),
|
||||
player.getPos());
|
||||
} else {
|
||||
player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
|
||||
}
|
||||
session.getPlayer().getMapMarksManager().handleMapMarkReq(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.NpcTalkReqOuterClass.NpcTalkReq;
|
||||
@@ -14,6 +15,10 @@ public class HandlerNpcTalkReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
NpcTalkReq req = NpcTalkReq.parseFrom(payload);
|
||||
|
||||
// Why are there 2 quest triggers that do the same thing...
|
||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId());
|
||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId());
|
||||
|
||||
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetWidgetSlotReqOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotOpOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetWidgetSlotRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketWidgetSlotChangeNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetWidgetSlotReq)
|
||||
public class HandlerSetWidgetSlotReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetWidgetSlotReqOuterClass.SetWidgetSlotReq req = SetWidgetSlotReqOuterClass.SetWidgetSlotReq.parseFrom(payload);
|
||||
|
||||
Player player = session.getPlayer();
|
||||
player.setWidgetId(req.getMaterialId());
|
||||
|
||||
// WidgetSlotChangeNotify op & slot key
|
||||
session.send(new PacketWidgetSlotChangeNotify(WidgetSlotOpOuterClass.WidgetSlotOp.DETACH));
|
||||
// WidgetSlotChangeNotify slot
|
||||
session.send(new PacketWidgetSlotChangeNotify(req.getMaterialId()));
|
||||
|
||||
// SetWidgetSlotRsp
|
||||
session.send(new PacketSetWidgetSlotRsp(req.getMaterialId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.TryEnterHomeReqOuterClass;
|
||||
import emu.grasscutter.scripts.data.SceneConfig;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketTryEnterHomeRsp;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
@Opcodes(PacketOpcodes.TryEnterHomeReq)
|
||||
public class HandlerTryEnterHomeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
TryEnterHomeReqOuterClass.TryEnterHomeReq req =
|
||||
TryEnterHomeReqOuterClass.TryEnterHomeReq.parseFrom(payload);
|
||||
|
||||
if (req.getTargetUid() != session.getPlayer().getUid()) {
|
||||
// I hope that tomorrow there will be a hero who can support multiplayer mode and write code like a poem
|
||||
session.send(new PacketTryEnterHomeRsp());
|
||||
return;
|
||||
}
|
||||
|
||||
int realmId = 2000 + session.getPlayer().getCurrentRealmId();
|
||||
|
||||
Scene scene = session.getPlayer().getWorld().getSceneById(realmId);
|
||||
Position pos = scene.getScriptManager().getConfig().born_pos;
|
||||
|
||||
session.getPlayer().getWorld().transferPlayerToScene(
|
||||
session.getPlayer(),
|
||||
realmId,
|
||||
pos
|
||||
);
|
||||
|
||||
|
||||
session.send(new PacketTryEnterHomeRsp(req.getTargetUid()));
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ public class HandlerVehicleInteractReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
VehicleInteractReqOuterClass.VehicleInteractReq req = VehicleInteractReqOuterClass.VehicleInteractReq.parseFrom(payload);
|
||||
session.getPlayer().getStaminaManager().handleVehicleInteractReq(session, req.getEntityId(), req.getInteractType());
|
||||
session.send(new PacketVehicleInteractRsp(session.getPlayer(), req.getEntityId(), req.getInteractType()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.def.GadgetData;
|
||||
import emu.grasscutter.game.entity.EntityVehicle;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.LifeState;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.*;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWidgetCoolDownNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketWidgetDoBagRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketWidgetGadgetDataNotify;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Opcodes(PacketOpcodes.WidgetDoBagReq)
|
||||
public class HandlerWidgetDoBagReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WidgetDoBagReqOuterClass.WidgetDoBagReq req = WidgetDoBagReqOuterClass.WidgetDoBagReq.parseFrom(payload);
|
||||
switch (req.getMaterialId()) {
|
||||
case 220026 -> {
|
||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(70500025);
|
||||
Position pos = new Position(req.getWidgetCreatorInfo().getLocationInfo().getPos());
|
||||
Position rot = new Position(req.getWidgetCreatorInfo().getLocationInfo().getRot());
|
||||
GameEntity entity = new EntityVehicle(
|
||||
session.getPlayer().getScene(),
|
||||
session.getPlayer(),
|
||||
gadgetData.getId(),
|
||||
0,
|
||||
pos,
|
||||
rot
|
||||
);
|
||||
|
||||
session.getPlayer().getScene().addEntity(entity);
|
||||
|
||||
session.send(new PacketWidgetGadgetDataNotify(70500025, List.of(entity.getId()))); // ???
|
||||
session.send(new PacketWidgetCoolDownNotify(15, System.currentTimeMillis() + 5000L, true));
|
||||
session.send(new PacketWidgetCoolDownNotify(15, System.currentTimeMillis() + 5000L, true));
|
||||
// Send twice, and I don't know why, Ask mhy
|
||||
session.send(new PacketWidgetDoBagRsp());
|
||||
}
|
||||
default -> {
|
||||
session.send(new PacketWidgetDoBagRsp());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AllWidgetDataNotifyOuterClass.AllWidgetDataNotify;
|
||||
import emu.grasscutter.net.proto.LunchBoxDataOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotDataOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotTagOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketAllWidgetDataNotify extends BasePacket {
|
||||
|
||||
public PacketAllWidgetDataNotify(Player player) {
|
||||
super(PacketOpcodes.AllWidgetDataNotify);
|
||||
|
||||
// TODO: Implement this
|
||||
|
||||
AllWidgetDataNotify.Builder proto = AllWidgetDataNotify.newBuilder()
|
||||
// If you want to implement this, feel free to do so. :)
|
||||
.setLunchBoxData(
|
||||
LunchBoxDataOuterClass.LunchBoxData.newBuilder().build()
|
||||
)
|
||||
// Maybe it's a little difficult, or it makes you upset :(
|
||||
.addAllOneoffGatherPointDetectorDataList(List.of())
|
||||
// So, goodbye, and hopefully sometime in the future o(* ̄▽ ̄*)ブ
|
||||
.addAllCoolDownGroupDataList(List.of())
|
||||
// I'll see your PR with a title that says (・∀・(・∀・(・∀・*)
|
||||
.addAllAnchorPointList(List.of())
|
||||
// "Complete implementation of widget functionality" b( ̄▽ ̄)d
|
||||
.addAllClientCollectorDataList(List.of())
|
||||
// Good luck, my boy.
|
||||
.addAllNormalCoolDownDataList(List.of());
|
||||
|
||||
if (player.getWidgetId() == null) {
|
||||
proto.addAllSlotList(List.of());
|
||||
} else {
|
||||
proto.addSlotList(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setIsActive(true)
|
||||
.setMaterialId(player.getWidgetId())
|
||||
.build()
|
||||
);
|
||||
|
||||
proto.addSlotList(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setTag(WidgetSlotTagOuterClass.WidgetSlotTag.WIDGET_SLOT_ATTACH_AVATAR)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
AllWidgetDataNotify protoData = proto.build();
|
||||
|
||||
this.setData(protoData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CodexDataFullNotifyOuterClass.CodexDataFullNotify;
|
||||
import emu.grasscutter.net.proto.CodexTypeDataOuterClass.CodexTypeData;
|
||||
import emu.grasscutter.net.proto.CodexTypeOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
public class PacketCodexDataFullNotify extends BasePacket {
|
||||
public PacketCodexDataFullNotify(Player player) {
|
||||
super(PacketOpcodes.CodexDataFullNotify, true);
|
||||
|
||||
//Quests
|
||||
CodexTypeData.Builder questTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(1);
|
||||
|
||||
//Tips
|
||||
CodexTypeData.Builder pushTipsTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(6);
|
||||
|
||||
//Views
|
||||
CodexTypeData.Builder viewTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(7);
|
||||
|
||||
//Weapons
|
||||
CodexTypeData.Builder weaponTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(2);
|
||||
|
||||
|
||||
player.getQuestManager().forEachMainQuest(mainQuest -> {
|
||||
if(mainQuest.isFinished()){
|
||||
var codexQuest = GameData.getCodexQuestIdMap().get(mainQuest.getParentQuestId());
|
||||
if(codexQuest != null){
|
||||
questTypeData.addCodexIdList(codexQuest.getId()).addAllHaveViewedList(Collections.singleton(true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CodexDataFullNotify.Builder proto = CodexDataFullNotify.newBuilder()
|
||||
.addTypeDataList(questTypeData.build())
|
||||
.addTypeDataList(pushTipsTypeData.build())
|
||||
.addTypeDataList(viewTypeData.build())
|
||||
.addTypeDataList(weaponTypeData);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CodexDataUpdateNotifyOuterClass.CodexDataUpdateNotify;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
public class PacketCodexDataUpdateNotify extends BasePacket {
|
||||
public PacketCodexDataUpdateNotify(GameMainQuest quest) {
|
||||
super(PacketOpcodes.CodexDataUpdateNotify, true);
|
||||
var codexQuest = GameData.getCodexQuestIdMap().get(quest.getParentQuestId());
|
||||
if(codexQuest != null){
|
||||
CodexDataUpdateNotify proto = CodexDataUpdateNotify.newBuilder()
|
||||
.setTypeValue(1)
|
||||
.setId(codexQuest.getId())
|
||||
.build();
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.game.gacha.GachaBanner;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
@@ -14,16 +15,18 @@ public class PacketDoGachaRsp extends BasePacket {
|
||||
public PacketDoGachaRsp(GachaBanner banner, List<GachaItem> list) {
|
||||
super(PacketOpcodes.DoGachaRsp);
|
||||
|
||||
ItemParamData costItem = banner.getCost(1);
|
||||
ItemParamData costItem10 = banner.getCost(10);
|
||||
DoGachaRsp p = DoGachaRsp.newBuilder()
|
||||
.setGachaType(banner.getGachaType())
|
||||
.setGachaScheduleId(banner.getScheduleId())
|
||||
.setGachaTimes(list.size())
|
||||
.setNewGachaRandom(12345)
|
||||
.setLeftGachaTimes(Integer.MAX_VALUE)
|
||||
.setCostItemId(banner.getCostItem())
|
||||
.setCostItemNum(1)
|
||||
.setTenCostItemId(banner.getCostItem())
|
||||
.setTenCostItemNum(10)
|
||||
.setCostItemId(costItem.getId())
|
||||
.setCostItemNum(costItem.getCount())
|
||||
.setTenCostItemId(costItem10.getId())
|
||||
.setTenCostItemNum(costItem10.getCount())
|
||||
.addAllGachaItemList(list)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.FinishedParentQuestNotifyOuterClass.FinishedParentQuestNotify;
|
||||
|
||||
public class PacketFinishedParentQuestNotify extends BasePacket {
|
||||
|
||||
public PacketFinishedParentQuestNotify(Player player) {
|
||||
super(PacketOpcodes.FinishedParentQuestNotify, true);
|
||||
|
||||
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
|
||||
|
||||
for (GameMainQuest mainQuest : player.getQuestManager().getQuests().values()) {
|
||||
proto.addParentQuestList(mainQuest.toProto());
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
|
||||
|
||||
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
|
||||
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
|
||||
|
||||
FinishedParentQuestUpdateNotify proto = FinishedParentQuestUpdateNotify.newBuilder()
|
||||
.addParentQuestList(quest.toProto())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.GetWidgetSlotRspOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotDataOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotTagOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketGetWidgetSlotRsp extends BasePacket {
|
||||
|
||||
public PacketGetWidgetSlotRsp(Player player) {
|
||||
super(PacketOpcodes.GetWidgetSlotRsp);
|
||||
|
||||
GetWidgetSlotRspOuterClass.GetWidgetSlotRsp.Builder proto =
|
||||
GetWidgetSlotRspOuterClass.GetWidgetSlotRsp.newBuilder();
|
||||
|
||||
if (player.getWidgetId() == null) {
|
||||
proto.addAllSlotList(List.of());
|
||||
} else {
|
||||
proto.addSlotList(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setIsActive(true)
|
||||
.setMaterialId(player.getWidgetId())
|
||||
.build()
|
||||
);
|
||||
|
||||
proto.addSlotList(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setTag(WidgetSlotTagOuterClass.WidgetSlotTag.WIDGET_SLOT_ATTACH_AVATAR)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
GetWidgetSlotRspOuterClass.GetWidgetSlotRsp protoData = proto.build();
|
||||
|
||||
this.setData(protoData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeChooseModuleRspOuterClass;
|
||||
|
||||
public class PacketHomeChooseModuleRsp extends BasePacket {
|
||||
|
||||
public PacketHomeChooseModuleRsp(int moduleId) {
|
||||
super(PacketOpcodes.HomeChooseModuleRsp);
|
||||
|
||||
HomeChooseModuleRspOuterClass.HomeChooseModuleRsp proto = HomeChooseModuleRspOuterClass.HomeChooseModuleRsp.newBuilder()
|
||||
.setRetcode(0)
|
||||
.setModuleId(moduleId)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeComfortInfoNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeModuleComfortInfoOuterClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketHomeComfortInfoNotify extends BasePacket {
|
||||
|
||||
public PacketHomeComfortInfoNotify(Player player) {
|
||||
super(PacketOpcodes.HomeComfortInfoNotify);
|
||||
|
||||
if (player.getRealmList() == null) {
|
||||
// Do not send
|
||||
return;
|
||||
}
|
||||
|
||||
List<HomeModuleComfortInfoOuterClass.HomeModuleComfortInfo> comfortInfoList = new ArrayList<>();
|
||||
|
||||
for (int moduleId : player.getRealmList()) {
|
||||
comfortInfoList.add(
|
||||
HomeModuleComfortInfoOuterClass.HomeModuleComfortInfo.newBuilder()
|
||||
.setModuleId(moduleId)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
HomeComfortInfoNotifyOuterClass.HomeComfortInfoNotify proto = HomeComfortInfoNotifyOuterClass.HomeComfortInfoNotify
|
||||
.newBuilder()
|
||||
.addAllModuleInfoList(comfortInfoList)
|
||||
.build();
|
||||
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import java.util.*;
|
||||
|
||||
public class PacketMarkMapRsp extends BasePacket {
|
||||
|
||||
public PacketMarkMapRsp(Player player, HashMap<String, MapMark> mapMarks) {
|
||||
public PacketMarkMapRsp(HashMap<String, MapMark> mapMarks) {
|
||||
super(PacketOpcodes.MarkMapRsp);
|
||||
|
||||
MarkMapRspOuterClass.MarkMapRsp.Builder proto = MarkMapRspOuterClass.MarkMapRsp.newBuilder();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerHomeCompInfoNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.PlayerHomeCompInfoOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketPlayerHomeCompInfoNotify extends BasePacket {
|
||||
|
||||
public PacketPlayerHomeCompInfoNotify(Player player) {
|
||||
super(PacketOpcodes.PlayerHomeCompInfoNotify);
|
||||
|
||||
if (player.getRealmList() == null) {
|
||||
// Do not send
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerHomeCompInfoNotifyOuterClass.PlayerHomeCompInfoNotify proto = PlayerHomeCompInfoNotifyOuterClass.PlayerHomeCompInfoNotify.newBuilder()
|
||||
.setCompInfo(
|
||||
PlayerHomeCompInfoOuterClass.PlayerHomeCompInfo.newBuilder()
|
||||
.addAllUnlockedModuleIdList(player.getRealmList())
|
||||
.addAllLevelupRewardGotLevelList(List.of(1)) // Hardcoded
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,10 @@ import emu.grasscutter.net.proto.PlayerLoginRspOuterClass.PlayerLoginRsp;
|
||||
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass;
|
||||
import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.http.dispatch.RegionHandler;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
|
||||
import static emu.grasscutter.Configuration.*;
|
||||
|
||||
@@ -32,24 +30,14 @@ public class PacketPlayerLoginRsp extends BasePacket {
|
||||
if (SERVER.runMode == ServerRunMode.GAME_ONLY) {
|
||||
if (regionCache == null) {
|
||||
try {
|
||||
File file = new File(DATA("query_cur_region.txt"));
|
||||
String query_cur_region = "";
|
||||
if (file.exists()) {
|
||||
query_cur_region = new String(FileUtils.read(file));
|
||||
} else {
|
||||
Grasscutter.getLogger().warn("query_cur_region not found! Using default current region.");
|
||||
}
|
||||
|
||||
byte[] decodedCurRegion = Base64.getDecoder().decode(query_cur_region);
|
||||
QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.parseFrom(decodedCurRegion);
|
||||
|
||||
RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder()
|
||||
// todo: we might want to push custom config to client
|
||||
RegionInfo serverRegion = RegionInfo.newBuilder()
|
||||
.setGateserverIp(lr(GAME_INFO.accessAddress, GAME_INFO.bindAddress))
|
||||
.setGateserverPort(lr(GAME_INFO.accessPort, GAME_INFO.bindPort))
|
||||
.setSecretKey(ByteString.copyFrom(FileUtils.read(KEYS_FOLDER + "/dispatchSeed.bin")))
|
||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||
.build();
|
||||
|
||||
regionCache = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
|
||||
regionCache = QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.newBuilder().setRegionInfo(serverRegion).build();
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error while initializing region cache!", e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.QuestManager;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestListNotifyOuterClass.QuestListNotify;
|
||||
|
||||
public class PacketQuestListNotify extends BasePacket {
|
||||
|
||||
public PacketQuestListNotify(Player player) {
|
||||
super(PacketOpcodes.QuestListNotify, true);
|
||||
|
||||
QuestListNotify.Builder proto = QuestListNotify.newBuilder();
|
||||
|
||||
player.getQuestManager().forEachQuest(quest -> {
|
||||
proto.addQuestList(quest.toProto());
|
||||
});
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestListUpdateNotifyOuterClass.QuestListUpdateNotify;
|
||||
|
||||
public class PacketQuestListUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketQuestListUpdateNotify(GameQuest quest) {
|
||||
super(PacketOpcodes.QuestListUpdateNotify);
|
||||
|
||||
QuestListUpdateNotify proto = QuestListUpdateNotify.newBuilder()
|
||||
.addQuestList(quest.toProto())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestProgressUpdateNotifyOuterClass.QuestProgressUpdateNotify;
|
||||
|
||||
public class PacketQuestProgressUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketQuestProgressUpdateNotify(GameQuest quest) {
|
||||
super(PacketOpcodes.QuestProgressUpdateNotify);
|
||||
|
||||
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getQuestId());
|
||||
|
||||
if (quest.getFinishProgressList() != null) {
|
||||
for (int i : quest.getFinishProgressList()) {
|
||||
proto.addFinishProgressList(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (quest.getFailProgressList() != null) {
|
||||
for (int i : quest.getFailProgressList()) {
|
||||
proto.addFailProgressList(i);
|
||||
}
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ServerCondMeetQuestListUpdateNotifyOuterClass.ServerCondMeetQuestListUpdateNotify;
|
||||
|
||||
public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketServerCondMeetQuestListUpdateNotify(Player player) {
|
||||
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||
|
||||
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
|
||||
|
||||
player.getQuestManager().forEachQuest(quest -> {
|
||||
if (quest.getState().getValue() <= 2) {
|
||||
proto.addAddQuestIdList(quest.getQuestId());
|
||||
}
|
||||
});
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketServerCondMeetQuestListUpdateNotify(GameQuest quest) {
|
||||
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||
|
||||
ServerCondMeetQuestListUpdateNotify proto = ServerCondMeetQuestListUpdateNotify.newBuilder()
|
||||
.addAddQuestIdList(quest.getQuestId())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetWidgetSlotRspOuterClass;
|
||||
|
||||
public class PacketSetWidgetSlotRsp extends BasePacket {
|
||||
|
||||
public PacketSetWidgetSlotRsp(int materialId) {
|
||||
super(PacketOpcodes.SetWidgetSlotRsp);
|
||||
|
||||
SetWidgetSlotRspOuterClass.SetWidgetSlotRsp proto = SetWidgetSlotRspOuterClass.SetWidgetSlotRsp.newBuilder()
|
||||
.setMaterialId(materialId)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||
import emu.grasscutter.net.proto.TryEnterHomeRspOuterClass;
|
||||
|
||||
public class PacketTryEnterHomeRsp extends BasePacket {
|
||||
|
||||
public PacketTryEnterHomeRsp() {
|
||||
super(PacketOpcodes.TryEnterHomeRsp);
|
||||
|
||||
TryEnterHomeRspOuterClass.TryEnterHomeRsp proto = TryEnterHomeRspOuterClass.TryEnterHomeRsp.newBuilder()
|
||||
.setRetcode(RetcodeOuterClass.Retcode.RET_SVR_ERROR_VALUE)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketTryEnterHomeRsp(int uid) {
|
||||
super(PacketOpcodes.TryEnterHomeRsp);
|
||||
|
||||
TryEnterHomeRspOuterClass.TryEnterHomeRsp proto = TryEnterHomeRspOuterClass.TryEnterHomeRsp.newBuilder()
|
||||
.setRetcode(0)
|
||||
.setTargetUid(uid)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.VehicleStaminaNotifyOuterClass.VehicleStaminaNotify;
|
||||
|
||||
public class PacketVehicleStaminaNotify extends BasePacket {
|
||||
|
||||
public PacketVehicleStaminaNotify(int vehicleId, float newStamina) {
|
||||
super(PacketOpcodes.VehicleStaminaNotify);
|
||||
VehicleStaminaNotify.Builder proto = VehicleStaminaNotify.newBuilder();
|
||||
|
||||
proto.setEntityId(vehicleId);
|
||||
proto.setCurStamina(newStamina);
|
||||
|
||||
this.setData(proto.build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WidgetCoolDownDataOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetCoolDownNotifyOuterClass;
|
||||
|
||||
public class PacketWidgetCoolDownNotify extends BasePacket {
|
||||
|
||||
public PacketWidgetCoolDownNotify(int id, long coolDownTime, boolean isSuccess) {
|
||||
super(PacketOpcodes.WidgetCoolDownNotify);
|
||||
|
||||
WidgetCoolDownNotifyOuterClass.WidgetCoolDownNotify proto = WidgetCoolDownNotifyOuterClass.WidgetCoolDownNotify.newBuilder()
|
||||
.addGroupCoolDownDataList(
|
||||
WidgetCoolDownDataOuterClass.WidgetCoolDownData.newBuilder()
|
||||
.setId(id)
|
||||
.setCoolDownTime(coolDownTime)
|
||||
.setIsSuccess(isSuccess)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WidgetDoBagRspOuterClass;
|
||||
|
||||
public class PacketWidgetDoBagRsp extends BasePacket {
|
||||
|
||||
public PacketWidgetDoBagRsp(int materialId) {
|
||||
super(PacketOpcodes.WidgetDoBagRsp);
|
||||
|
||||
WidgetDoBagRspOuterClass.WidgetDoBagRsp proto = WidgetDoBagRspOuterClass.WidgetDoBagRsp.newBuilder()
|
||||
.setMaterialId(materialId)
|
||||
.setRetcode(0)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketWidgetDoBagRsp() {
|
||||
super(PacketOpcodes.WidgetDoBagRsp);
|
||||
|
||||
WidgetDoBagRspOuterClass.WidgetDoBagRsp proto = WidgetDoBagRspOuterClass.WidgetDoBagRsp.newBuilder()
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WidgetGadgetAllDataNotifyOuterClass.WidgetGadgetAllDataNotify;
|
||||
|
||||
public class PacketWidgetGadgetAllDataNotify extends BasePacket {
|
||||
|
||||
public PacketWidgetGadgetAllDataNotify() {
|
||||
super(PacketOpcodes.AllWidgetDataNotify);
|
||||
|
||||
WidgetGadgetAllDataNotify proto = WidgetGadgetAllDataNotify.newBuilder().build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WidgetGadgetDataNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetGadgetDataOuterClass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketWidgetGadgetDataNotify extends BasePacket {
|
||||
public PacketWidgetGadgetDataNotify(int gadgetId, List<Integer> gadgetEntityIdList) throws IOException {
|
||||
super(PacketOpcodes.WidgetGadgetDataNotify);
|
||||
|
||||
WidgetGadgetDataNotifyOuterClass.WidgetGadgetDataNotify proto = WidgetGadgetDataNotifyOuterClass.WidgetGadgetDataNotify.newBuilder()
|
||||
.setWidgetGadgetData(
|
||||
WidgetGadgetDataOuterClass.WidgetGadgetData.newBuilder()
|
||||
.setGadgetId(gadgetId)
|
||||
.addAllGadgetEntityIdList(gadgetEntityIdList)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.WidgetSlotChangeNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotDataOuterClass;
|
||||
import emu.grasscutter.net.proto.WidgetSlotOpOuterClass;
|
||||
|
||||
public class PacketWidgetSlotChangeNotify extends BasePacket {
|
||||
|
||||
public PacketWidgetSlotChangeNotify(WidgetSlotChangeNotifyOuterClass.WidgetSlotChangeNotify proto) {
|
||||
super(PacketOpcodes.WidgetSlotChangeNotify);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketWidgetSlotChangeNotify(WidgetSlotOpOuterClass.WidgetSlotOp op) {
|
||||
super(PacketOpcodes.WidgetSlotChangeNotify);
|
||||
|
||||
WidgetSlotChangeNotifyOuterClass.WidgetSlotChangeNotify proto = WidgetSlotChangeNotifyOuterClass.WidgetSlotChangeNotify.newBuilder()
|
||||
.setOp(op)
|
||||
.setSlot(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setIsActive(true)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketWidgetSlotChangeNotify(int materialId) {
|
||||
super(PacketOpcodes.WidgetSlotChangeNotify);
|
||||
|
||||
WidgetSlotChangeNotifyOuterClass.WidgetSlotChangeNotify proto = WidgetSlotChangeNotifyOuterClass.WidgetSlotChangeNotify.newBuilder()
|
||||
.setSlot(
|
||||
WidgetSlotDataOuterClass.WidgetSlotData.newBuilder()
|
||||
.setIsActive(true)
|
||||
.setMaterialId(materialId)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user