Merge branch 'development' into java-16

This commit is contained in:
Melledy 2022-04-22 19:23:32 -07:00
commit 17abf321a2
75 changed files with 4185 additions and 626 deletions

24
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: "Build"
on:
push:
branches:
- "stable"
jobs:
Build-Server-Jar:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: '8'
- name: Run Gradle
run: .\gradlew.bat && .\gradlew jar
- name: Upload build
uses: actions/upload-artifact@v3
with:
name: Grasscutter
path: grasscutter.jar

1
.gitignore vendored
View File

@ -47,6 +47,7 @@ tmp/
# Grasscutter # Grasscutter
resources/* resources/*
logs/*
data/AbilityEmbryos.json data/AbilityEmbryos.json
data/OpenConfig.json data/OpenConfig.json
proto/auto/ proto/auto/

View File

@ -12,6 +12,9 @@ A WIP server reimplementation for *some anime game* 2.3-2.6
* Friends list * Friends list
* Co-op *partially* work * Co-op *partially* work
# Quick setup guide # Quick setup guide
### Note
* If you update from an older version, delete `config.json` for regeneration
### Prerequisites ### Prerequisites
* JDK-8u202 ([mirror link](https://mirrors.huaweicloud.com/java/jdk/8u202-b08/) since Oracle required an account to download old builds) * JDK-8u202 ([mirror link](https://mirrors.huaweicloud.com/java/jdk/8u202-b08/) since Oracle required an account to download old builds)
* Mongodb (recommended 4.0+) * Mongodb (recommended 4.0+)
@ -26,7 +29,7 @@ A WIP server reimplementation for *some anime game* 2.3-2.6
### Connecting with the client ### Connecting with the client
½. Create an account using *server console command* below ½. Create an account using *server console command* below
1. Run a proxy daemon: (choose either one) 1. Run a proxy daemon: (choose either one)
- mitmdump: `mitmdump -s proxy.py --ssl-insecure` - mitmdump: `mitmdump -s proxy.py -k`
- Fiddler Classic: Run Fiddler Classic, turn on `Decrypt https traffic` in setting and change the default port there (Tools -> Options -> Connections) to anything other than `8888`, and load [this script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Run Fiddler Classic, turn on `Decrypt https traffic` in setting and change the default port there (Tools -> Options -> Connections) to anything other than `8888`, and load [this script](https://github.lunatic.moe/fiddlerscript).
- [Hosts file](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Hosts file](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map)
2. Trust CA certificate: 2. Trust CA certificate:
@ -37,32 +40,33 @@ A WIP server reimplementation for *some anime game* 2.3-2.6
* or you can use `run.cmd` to start Server & Proxy daemon with one click * or you can use `run.cmd` to start Server & Proxy daemon with one click
# Grasscutter commands # Grasscutter commands
### Server console commands There is a dummy user named "Server" in every player's friends list that you can message to use commands. Commands also work in other chat rooms, such as private/team chats.
`account create [username] {playerid}` - Creates an account with the specified username and the in-game uid for that account. The playerid parameter is optional and will be auto generated if not set. `account create [username] {playerid}` - Creates an account with the specified username and the in-game uid for that account. The playerid parameter is optional and will be auto generated if not set.
### In-Game commands `spawn [monster id] [level] [amount]`
There is a dummy user named "Server" in every player's friends list that you can message to use commands. Commands also work in other chat rooms, such as private/team chats.
`!spawn [monster id] [level] [amount]` `give [item id] [amount]`
`!give [item id] [amount]` `givechar [avatar id] [level]`
`!givechar [avatar id] [level]` `drop [item id] [amount]`
`!drop [item id] [amount]` `killall`
`!killall` `setworldlevel [level]` - Relog to see effects properly
`!setworldlevel [level]` - Relog to see effects properly `godmode` - Prevents you from taking damage
`!godmode` - Prevents you from taking damage `resetconst` - Resets the constellation level on your current active character, will need to relog after using the command to see any changes.
`!resetconst` - Resets the constellation level on your current active character, will need to relog after using the command to see any changes. `setstats [stats] [amount]` - Changes the current character's specified stat.
`!sethp [hp]` `clearartifacts` - Deletes all unequipped and unlocked level 0 artifacts, **including yellow rarity ones** from your inventory
`!clearartifacts` - Deletes all unequipped and unlocked level 0 artifacts, **including yellow rarity ones** from your inventory `pos` - Gets your current coordinate.
`weather [weather id] [climate id]` - Changes the current weather.
*More commands will be updated in the [wiki](https://github.com/Melledy/Grasscutter/wiki/).* *More commands will be updated in the [wiki](https://github.com/Melledy/Grasscutter/wiki/).*

View File

@ -19,7 +19,7 @@
"bannerType": "EVENT", "bannerType": "EVENT",
"prefabPath": "GachaShowPanel_A079", "prefabPath": "GachaShowPanel_A079",
"previewPrefabPath": "UI_Tab_GachaShowPanel_A079", "previewPrefabPath": "UI_Tab_GachaShowPanel_A079",
"titlePath": "UI_GACHA_SHOW_PANEL_A079_TITLE", "titlePath": "UI_GACHA_SHOW_PANEL_A048_TITLE",
"costItem": 223, "costItem": 223,
"beginTime": 0, "beginTime": 0,
"endTime": 1924992000, "endTime": 1924992000,
@ -34,7 +34,7 @@
"bannerType": "WEAPON", "bannerType": "WEAPON",
"prefabPath": "GachaShowPanel_A080", "prefabPath": "GachaShowPanel_A080",
"previewPrefabPath": "UI_Tab_GachaShowPanel_A080", "previewPrefabPath": "UI_Tab_GachaShowPanel_A080",
"titlePath": "UI_GACHA_SHOW_PANEL_A080_TITLE", "titlePath": "UI_GACHA_SHOW_PANEL_A021_TITLE",
"costItem": 223, "costItem": 223,
"beginTime": 0, "beginTime": 0,
"endTime": 1924992000, "endTime": 1924992000,

View File

@ -16,12 +16,14 @@
# - mitmdump from mitmproxy # - mitmdump from mitmproxy
# #
# @author MlgmXyysd # @author MlgmXyysd
# @version 1.0 # @version 1.1
# #
## ##
from mitmproxy import http from mitmproxy import http
from proxy_config import USE_SSL
from proxy_config import REMOTE_HOST from proxy_config import REMOTE_HOST
from proxy_config import REMOTE_PORT
class MlgmXyysd_Genshin_Impact_Proxy: class MlgmXyysd_Genshin_Impact_Proxy:
@ -55,12 +57,19 @@ class MlgmXyysd_Genshin_Impact_Proxy:
"minor-api.mihoyo.com", "minor-api.mihoyo.com",
"public-data-api.mihoyo.com", "public-data-api.mihoyo.com",
"uspider.yuanshen.com", "uspider.yuanshen.com",
"sdk-static.mihoyo.com" "sdk-static.mihoyo.com",
"abtest-api-data-sg.hoyoverse.com",
"log-upload-os.hoyoverse.com"
] ]
def request(self, flow: http.HTTPFlow) -> None: def request(self, flow: http.HTTPFlow) -> None:
if flow.request.host in self.LIST_DOMAINS: if flow.request.host in self.LIST_DOMAINS:
if USE_SSL:
flow.request.scheme = "https"
else:
flow.request.scheme = "http"
flow.request.host = REMOTE_HOST flow.request.host = REMOTE_HOST
flow.request.port = REMOTE_PORT
addons = [ addons = [
MlgmXyysd_Genshin_Impact_Proxy() MlgmXyysd_Genshin_Impact_Proxy()

View File

@ -1,2 +1,4 @@
# This can also be replaced with another IP address. # This can also be replaced with another IP address.
REMOTE_HOST = "localhost" USE_SSL = True
REMOTE_HOST = "127.0.0.1"
REMOTE_PORT = 443

115
run.cmd
View File

@ -1,115 +0,0 @@
@rem
@rem Copyright (C) 2002-2022 MlgmXyysd All Rights Reserved.
@rem
@if "%DEBUG%" == "" echo off
pushd %~dp0
title Grasscutter
call :LOG [INFO] Grasscutter
call :LOG [INFO] Initializing...
@rem This will not work if your java or mitmproxy is in a different location, plugin as necessary
@rem this just saves you from changing your PATH
set JAVA_PATH=C:\Program Files\Java\jdk1.8.0_202\
set MITMPROXY_PATH=%~dp0
set PROXY_SCRIPT=proxy
@rem TODO: MongoDB integration
set SERVER_PATH=%~dp0
@rem mitmproxy not found, server only
if not exist "%MITMPROXY_PATH%mitmdump.exe" (
call :LOG [WARN] mitmproxy not found, server only mode.
goto :SERVER
)
@rem proxy script not found, server only
if not exist "%PROXY_SCRIPT%.py" (
if not exist "%PROXY_SCRIPT%.pyc" (
call :LOG [WARN] Missing proxy script or compiled proxy script, server only mode.
goto :SERVER
) else set PROXY_SCRIPT=%PROXY_SCRIPT%.pyc
) else set PROXY_SCRIPT=%PROXY_SCRIPT%.py
:PROXY
@rem UAC Administrator privileges
>nul 2>&1 reg query "HKU\S-1-5-19" || (
call :LOG [WARN] Currently running with non Administrator privileges, raising...
echo set UAC = CreateObject^("Shell.Application"^) > "%temp%\UAC.vbs"
echo UAC.ShellExecute "%~f0", "%1", "", "runas", 1 >> "%temp%\UAC.vbs"
"%temp%\UAC.vbs"
del /f /q "%temp%\UAC.vbs" >nul 2>nul
exit /b
)
set PROXY=true
@rem Store original proxy settings
for /f "tokens=2*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable 2^>nul') do set "ORIG_PROXY_ENABLE=%%b"
for /f "tokens=2*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer 2^>nul') do set "ORIG_PROXY_SERVER=%%b"
call :LOG [INFO] Starting proxy daemon...
@rem TODO: External proxy when ORIG_PROXY_ENABLE == 0x1
start /min "" "%MITMPROXY_PATH%mitmdump.exe" -s %PROXY_SCRIPT% --ssl-insecure
@rem CA certificate for possible HTTPS scheme
call :LOG [INFO] Waiting for CA certificate generation...
set CA_CERT_FILE="%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer"
set /A TIMEOUT_COUNT=0
:CERT_CA_CHECK
if not exist %CA_CERT_FILE% (
timeout /T 1 >nul 2>nul
set /A TIMEOUT_COUNT+=1
goto CERT_CA_CHECK
)
:EXTRA_TIMEOUT
if %TIMEOUT_COUNT% LEQ 2 (
timeout /T 1 >nul 2>nul
set /A TIMEOUT_COUNT+=1
goto EXTRA_TIMEOUT
)
call :LOG [INFO] Adding CA certificate to store...
certutil -addstore root %CA_CERT_FILE% >nul 2>nul
call :LOG [INFO] Setting up network proxy...
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8080" /f >nul 2>nul
:SERVER
if not exist "%JAVA_PATH%bin\java.exe" (
call :LOG [ERROR] Java not found.
goto :EXIT
)
if not exist "%SERVER_PATH%grasscutter.jar" (
call :LOG [ERROR] Server jar not found.
goto :EXIT
)
call :LOG [INFO] Starting server...
"%JAVA_PATH%bin\java.exe" -jar "%SERVER_PATH%grasscutter.jar"
call :LOG [INFO] Server stopped
:EXIT
if "%PROXY%" == "" (
call :LOG [INFO] Proxy not started, no need to clean up.
) else (
call :LOG [INFO] Restoring network settings...
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d "%ORIG_PROXY_ENABLE%" /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "%ORIG_PROXY_SERVER%" /f >nul 2>nul
call :LOG [INFO] Shutting down proxy daemon...
taskkill /t /f /im mitmdump.exe >nul 2>nul
call :LOG [INFO] Removing CA certificate...
for /F "tokens=2" %%s in ('certutil -dump %CA_CERT_FILE% ^| findstr ^"^sha1^"') do (
set SERIAL=%%s
)
certutil -delstore root %SERIAL% >nul 2>nul
)
call :LOG [INFO] See you again :)
goto :EOF
:LOG
echo [%time:~0,8%] %*

View File

@ -1,19 +1,8 @@
package emu.grasscutter; package emu.grasscutter;
import java.util.ArrayList;
public final class Config { public final class Config {
public String DispatchServerIp = "127.0.0.1";
public String DispatchServerPublicIp = "";
public int DispatchServerPort = 443;
public String DispatchServerKeystorePath = "./keystore.p12";
public String DispatchServerKeystorePassword = "";
public Boolean UseSSL = true;
public String GameServerName = "Test";
public String GameServerIp = "127.0.0.1";
public String GameServerPublicIp = "";
public int GameServerPort = 22102;
public int UploadLogPort = 80;
public String DatabaseUrl = "mongodb://localhost:27017"; public String DatabaseUrl = "mongodb://localhost:27017";
public String DatabaseCollection = "grasscutter"; public String DatabaseCollection = "grasscutter";
@ -23,26 +12,55 @@ public final class Config {
public String PACKETS_FOLDER = "./packets/"; public String PACKETS_FOLDER = "./packets/";
public String DUMPS_FOLDER = "./dumps/"; public String DUMPS_FOLDER = "./dumps/";
public String KEY_FOLDER = "./keys/"; public String KEY_FOLDER = "./keys/";
public String RunMode = "HYBRID"; // HYBRID, DISPATCH_ONLY, GAME_ONLY
public GameServerOptions GameServer = new GameServerOptions();
public DispatchServerOptions DispatchServer = new DispatchServerOptions();
public GameServerOptions getGameServerOptions() {
return GameServer;
}
public DispatchServerOptions getDispatchOptions() { return DispatchServer; }
public static class DispatchServerOptions {
public String Ip = "0.0.0.0";
public String PublicIp = "127.0.0.1";
public int Port = 443;
public int PublicPort = 0;
public String KeystorePath = "./keystore.p12";
public String KeystorePassword = "";
public Boolean UseSSL = true;
public Boolean FrontHTTPS = true;
public boolean AutomaticallyCreateAccounts = false;
public RegionInfo[] GameServers = {};
public RegionInfo[] getGameServers() {
return GameServers;
}
public static class RegionInfo {
public String Name = "os_usa";
public String Title = "Test";
public String Ip = "127.0.0.1";
public int Port = 22102;
}
}
public static class GameServerOptions {
public String Name = "Test";
public String Ip = "0.0.0.0";
public String PublicIp = "127.0.0.1";
public int Port = 22102;
public int PublicPort = 0;
public String DispatchServerDatabaseUrl = "mongodb://localhost:27017";
public String DispatchServerDatabaseCollection = "grasscutter";
public boolean LOG_PACKETS = false; public boolean LOG_PACKETS = false;
public GameRates Game = new GameRates();
public ServerOptions ServerOptions = new ServerOptions();
public GameRates getGameRates() {
return Game;
}
public ServerOptions getServerOptions() {
return ServerOptions;
}
public static class GameRates {
public float ADVENTURE_EXP_RATE = 1.0f;
public float MORA_RATE = 1.0f;
public float DOMAIN_DROP_RATE = 1.0f;
}
public static class ServerOptions {
public int InventoryLimitWeapon = 2000; public int InventoryLimitWeapon = 2000;
public int InventoryLimitRelic = 2000; public int InventoryLimitRelic = 2000;
public int InventoryLimitMaterial = 2000; public int InventoryLimitMaterial = 2000;
@ -54,6 +72,15 @@ public final class Config {
public boolean WatchGacha = false; public boolean WatchGacha = false;
public int[] WelcomeEmotes = {2007, 1002, 4010}; public int[] WelcomeEmotes = {2007, 1002, 4010};
public String WelcomeMotd = "Welcome to Grasscutter emu"; public String WelcomeMotd = "Welcome to Grasscutter emu";
public boolean AutomaticallyCreateAccounts = false;
public GameRates Game = new GameRates();
public GameRates getGameRates() { return Game; }
public static class GameRates {
public float ADVENTURE_EXP_RATE = 1.0f;
public float MORA_RATE = 1.0f;
public float DOMAIN_DROP_RATE = 1.0f;
}
} }
} }

View File

@ -73,11 +73,26 @@ public final class Grasscutter {
DatabaseManager.initialize(); DatabaseManager.initialize();
// Start servers. // Start servers.
if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) {
dispatchServer = new DispatchServer(); dispatchServer = new DispatchServer();
dispatchServer.start(); dispatchServer.start();
gameServer = new GameServer(new InetSocketAddress(getConfig().GameServerIp, getConfig().GameServerPort)); gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port));
gameServer.start(); gameServer.start();
} else if(getConfig().RunMode.equalsIgnoreCase("DISPATCH_ONLY")) {
dispatchServer = new DispatchServer();
dispatchServer.start();
} else if(getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port));
gameServer.start();
} else {
getLogger().error("Invalid server run mode. " + getConfig().RunMode);
getLogger().error("Server run mode must be 'HYBRID', 'DISPATCH_ONLY', or 'GAME_ONLY'. Unable to start Grasscutter...");
getLogger().error("Shutting down...");
System.exit(1);
}
// Open console. // Open console.
startConsole(); startConsole();
@ -86,8 +101,10 @@ public final class Grasscutter {
public static void loadConfig() { public static void loadConfig() {
try (FileReader file = new FileReader(configFile)) { try (FileReader file = new FileReader(configFile)) {
config = gson.fromJson(file, Config.class); config = gson.fromJson(file, Config.class);
saveConfig();
} catch (Exception e) { } catch (Exception e) {
Grasscutter.config = new Config(); saveConfig(); Grasscutter.config = new Config();
saveConfig();
} }
} }
@ -104,9 +121,14 @@ public final class Grasscutter {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
while ((input = br.readLine()) != null) { while ((input = br.readLine()) != null) {
try { try {
if(getConfig().RunMode.equalsIgnoreCase("DISPATCH_ONLY")) {
getLogger().error("Commands are not supported in dispatch only mode");
return;
}
CommandMap.getInstance().invoke(null, input); CommandMap.getInstance().invoke(null, input);
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("Command error: " + e.getMessage()); Grasscutter.getLogger().error("Command error: ");
e.printStackTrace();
} }
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -46,7 +46,7 @@ public final class AccountCommand implements CommandHandler {
CommandHandler.sendMessage(null, "Account already exists."); CommandHandler.sendMessage(null, "Account already exists.");
return; return;
} else { } else {
CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerId() + "."); CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerUid() + ".");
account.addPermission("*"); // Grant the player superuser permissions. account.addPermission("*"); // Grant the player superuser permissions.
account.save(); // Save account to database. account.save(); // Save account to database.
} }

View File

@ -23,11 +23,17 @@ public final class ChangeSceneCommand implements CommandHandler {
try { try {
int sceneId = Integer.parseInt(args.get(0)); int sceneId = Integer.parseInt(args.get(0));
boolean result = sender.getWorld().transferPlayerToScene(sender, sceneId, sender.getPos());
if (sceneId == sender.getSceneId()) {
CommandHandler.sendMessage(sender, "You are already in that scene");
return;
}
boolean result = sender.getWorld().transferPlayerToScene(sender, sceneId, sender.getPos());
CommandHandler.sendMessage(sender, "Changed to scene " + sceneId); CommandHandler.sendMessage(sender, "Changed to scene " + sceneId);
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, "Scene does not exist or you are already in it"); CommandHandler.sendMessage(sender, "Scene does not exist");
} }
} catch (Exception e) { } catch (Exception e) {
CommandHandler.sendMessage(sender, "Usage: changescene <scene id>"); CommandHandler.sendMessage(sender, "Usage: changescene <scene id>");

View File

@ -95,18 +95,19 @@ public final class GiveCommand implements CommandHandler {
} }
private void item(GenshinPlayer player, ItemData itemData, int amount) { private void item(GenshinPlayer player, ItemData itemData, int amount) {
GenshinItem genshinItem = new GenshinItem(itemData);
if (itemData.isEquip()) { if (itemData.isEquip()) {
List<GenshinItem> items = new LinkedList<>(); List<GenshinItem> items = new LinkedList<>();
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
items.add(genshinItem); items.add(new GenshinItem(itemData));
} }
player.getInventory().addItems(items); player.getInventory().addItems(items);
player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop)); player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop));
} else { } else {
GenshinItem genshinItem = new GenshinItem(itemData);
genshinItem.setCount(amount); genshinItem.setCount(amount);
player.getInventory().addItem(genshinItem); player.getInventory().addItem(genshinItem);
player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.SubfieldDrop)); player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.SubfieldDrop));
} }
} }
} }

View File

@ -0,0 +1,36 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
import java.util.List;
@Command(label = "heal", usage = "heal|h",
description = "Heal all characters in your current team.", aliases = {"h"}, permission = "player.heal")
public class HealCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
}
sender.getTeamManager().getActiveTeam().forEach(entity -> {
boolean isAlive = entity.isAlive();
entity.setFightProperty(
FightProperty.FIGHT_PROP_CUR_HP,
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
);
entity.getWorld().broadcastPacket(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
if (!isAlive) {
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
}
});
CommandHandler.sendMessage(sender, "All characters are healed.");
}
}

View File

@ -22,7 +22,7 @@ public final class KickCommand implements CommandHandler {
} }
if (sender != null) { if (sender != null) {
CommandHandler.sendMessage(sender, String.format("Player [%s:%s] has kicked player [%s:%s]", sender.getAccount().getPlayerId(), sender.getAccount().getUsername(), target, targetPlayer.getAccount().getUsername())); CommandHandler.sendMessage(sender, String.format("Player [%s:%s] has kicked player [%s:%s]", sender.getAccount().getPlayerUid(), sender.getAccount().getUsername(), target, targetPlayer.getAccount().getUsername()));
} }
CommandHandler.sendMessage(sender, String.format("Kicking player [%s:%s]", target, targetPlayer.getAccount().getUsername())); CommandHandler.sendMessage(sender, String.format("Kicking player [%s:%s]", target, targetPlayer.getAccount().getUsername()));

View File

@ -0,0 +1,33 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import java.util.List;
import java.util.Map;
@Command(label = "list", description = "List online players")
public class ListCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
Map<Integer, GenshinPlayer> playersMap = Grasscutter.getGameServer().getPlayers();
CommandHandler.sendMessage(sender, String.format("There are %s player(s) online:", playersMap.size()));
if (playersMap.size() != 0) {
StringBuilder playerSet = new StringBuilder();
for (Map.Entry<Integer, GenshinPlayer> entry : playersMap.entrySet()) {
playerSet.append(entry.getValue().getNickname());
playerSet.append(", ");
}
String players = playerSet.toString();
CommandHandler.sendMessage(sender, players.substring(0, players.length() - 2));
}
}
}

View File

@ -10,7 +10,7 @@ import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import java.util.List; import java.util.List;
@Command(label = "setstats", usage = "setstats|stats <stat> <value>", @Command(label = "setstats", usage = "setstats|stats <stat> <value>",
aliases = {"stats"}) description = "Set fight property for your current active character", aliases = {"stats"}, permission = "player.setstats")
public final class SetStatsCommand implements CommandHandler { public final class SetStatsCommand implements CommandHandler {
@Override @Override
@ -20,6 +20,11 @@ public final class SetStatsCommand implements CommandHandler {
return; return;
} }
if (args.size() < 2){
CommandHandler.sendMessage(sender, "Usage: setstats|stats <stat> <value>");
return;
}
String stat = args.get(0); String stat = args.get(0);
switch (stat) { switch (stat) {
default: default:

View File

@ -0,0 +1,107 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.server.packet.send.PacketAvatarSkillChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarSkillUpgradeRsp;
import java.util.List;
@Command(label = "talent", usage = "talent <talentID> <value>",
description = "Set talent level for your current active character", permission = "player.settalent")
public class TalentCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
}
if (args.size() < 0 || args.size() < 1){
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return;
}
String cmdSwitch = args.get(0);
switch (cmdSwitch) {
default:
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return;
case "set":
try {
int skillId = Integer.parseInt(args.get(1));
int nextLevel = Integer.parseInt(args.get(2));
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
GenshinAvatar avatar = entity.getAvatar();
int skillIdNorAtk = avatar.getData().getSkillDepot().getSkills().get(0);
int skillIdE = avatar.getData().getSkillDepot().getSkills().get(1);
int skillIdQ = avatar.getData().getSkillDepot().getEnergySkill();
int currentLevelNorAtk = avatar.getSkillLevelMap().get(skillIdNorAtk);
int currentLevelE = avatar.getSkillLevelMap().get(skillIdE);
int currentLevelQ = avatar.getSkillLevelMap().get(skillIdQ);
if (args.size() < 2){
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return;
}
if (nextLevel > 16){
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
return;
}
if (skillId == skillIdNorAtk){
// Upgrade skill
avatar.getSkillLevelMap().put(skillIdNorAtk, nextLevel);
avatar.save();
// Packet
sender.sendPacket(new PacketAvatarSkillChangeNotify(avatar, skillIdNorAtk, currentLevelNorAtk, nextLevel));
sender.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, skillIdNorAtk, currentLevelNorAtk, nextLevel));
CommandHandler.sendMessage(sender, "Set talent Normal ATK to " + nextLevel + ".");
}
if (skillId == skillIdE){
// Upgrade skill
avatar.getSkillLevelMap().put(skillIdE, nextLevel);
avatar.save();
// Packet
sender.sendPacket(new PacketAvatarSkillChangeNotify(avatar, skillIdE, currentLevelE, nextLevel));
sender.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, skillIdE, currentLevelE, nextLevel));
CommandHandler.sendMessage(sender, "Set talent E to " + nextLevel + ".");
}
if (skillId == skillIdQ){
// Upgrade skill
avatar.getSkillLevelMap().put(skillIdQ, nextLevel);
avatar.save();
// Packet
sender.sendPacket(new PacketAvatarSkillChangeNotify(avatar, skillIdQ, currentLevelQ, nextLevel));
sender.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, skillIdQ, currentLevelQ, nextLevel));
CommandHandler.sendMessage(sender, "Set talent Q to " + nextLevel + ".");
}
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid skill ID.");
return;
}
break;
case "getid":
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
GenshinAvatar avatar = entity.getAvatar();
int skillIdNorAtk = avatar.getData().getSkillDepot().getSkills().get(0);
int skillIdE = avatar.getData().getSkillDepot().getSkills().get(1);
int skillIdQ = avatar.getData().getSkillDepot().getEnergySkill();
CommandHandler.sendMessage(sender, "Normal Attack ID " + skillIdNorAtk + ".");
CommandHandler.sendMessage(sender, "E skill ID " + skillIdE + ".");
CommandHandler.sendMessage(sender, "Q skill ID " + skillIdQ + ".");
break;
}
}
}

View File

@ -8,7 +8,7 @@ import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
import java.util.List; import java.util.List;
@Command(label = "weather", usage = "weather <weatherId>", @Command(label = "weather", usage = "weather <weatherId> [climateId]",
description = "Changes the weather.", aliases = {"w"}, permission = "player.weather") description = "Changes the weather.", aliases = {"w"}, permission = "player.weather")
public final class WeatherCommand implements CommandHandler { public final class WeatherCommand implements CommandHandler {
@ -20,20 +20,22 @@ public final class WeatherCommand implements CommandHandler {
} }
if (args.size() < 1) { if (args.size() < 1) {
CommandHandler.sendMessage(sender, "Usage: weather <weatherId>"); CommandHandler.sendMessage(sender, "Usage: weather <weatherId> [climateId]");
return; return;
} }
try { try {
int weatherId = Integer.parseInt(args.get(0)); int weatherId = Integer.parseInt(args.get(0));
int climateId = args.size() > 1 ? Integer.parseInt(args.get(1)) : 1;
ClimateType climate = ClimateType.getTypeByValue(weatherId); ClimateType climate = ClimateType.getTypeByValue(climateId);
sender.getScene().setWeather(weatherId);
sender.getScene().setClimate(climate); sender.getScene().setClimate(climate);
sender.getScene().broadcastPacket(new PacketSceneAreaWeatherNotify(sender)); sender.getScene().broadcastPacket(new PacketSceneAreaWeatherNotify(sender));
CommandHandler.sendMessage(sender, "Changed weather to " + weatherId); CommandHandler.sendMessage(sender, "Changed weather to " + weatherId + " with climate " + climateId);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid weather ID."); CommandHandler.sendMessage(sender, "Invalid ID.");
} }
} }
} }

View File

@ -1,7 +1,9 @@
package emu.grasscutter.data; package emu.grasscutter.data;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
@ -54,6 +56,10 @@ public class GenshinData {
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap = new Int2ObjectLinkedOpenHashMap<>(); private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>(); private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
// Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) { public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
Int2ObjectMap<?> map = null; Int2ObjectMap<?> map = null;
@ -221,4 +227,17 @@ public class GenshinData {
public static Int2ObjectMap<SceneData> getSceneDataMap() { public static Int2ObjectMap<SceneData> getSceneDataMap() {
return sceneDataMap; return sceneDataMap;
} }
public static Map<Integer, List<Integer>> getFetterDataEntries() {
if (fetters.isEmpty()) {
fetterDataMap.forEach((k, v) -> {
if (!fetters.containsKey(v.getAvatarId())) {
fetters.put(v.getAvatarId(), new ArrayList<>());
}
fetters.get(v.getAvatarId()).add(k);
});
}
return fetters;
}
} }

View File

@ -128,7 +128,13 @@ public class ResourceLoader {
private static void loadScenePoints() { private static void loadScenePoints() {
Pattern pattern = Pattern.compile("(?<=scene)(.*?)(?=_point.json)"); Pattern pattern = Pattern.compile("(?<=scene)(.*?)(?=_point.json)");
File folder = new File(Grasscutter.getConfig().RESOURCE_FOLDER + "BinOutPut/Scene/Point"); File folder = new File(Grasscutter.getConfig().RESOURCE_FOLDER + "BinOutput/Scene/Point");
if (!folder.isDirectory() || !folder.exists() || folder.listFiles() == null) {
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
return;
}
List<ScenePointEntry> scenePointList = new ArrayList<>(); List<ScenePointEntry> scenePointList = new ArrayList<>();
for (File file : folder.listFiles()) { for (File file : folder.listFiles()) {
ScenePointConfig config = null; ScenePointConfig config = null;

View File

@ -56,6 +56,8 @@ public class AvatarData extends GenshinResource {
private AvatarSkillDepotData skillDepot; private AvatarSkillDepotData skillDepot;
private IntList abilities; private IntList abilities;
private List<Integer> fetters;
@Override @Override
public int getId(){ public int getId(){
return this.Id; return this.Id;
@ -193,10 +195,17 @@ public class AvatarData extends GenshinResource {
return abilities; return abilities;
} }
public List<Integer> getFetters() {
return fetters;
}
@Override @Override
public void onLoad() { public void onLoad() {
this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId); this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId);
// Get fetters from GenshinData
this.fetters = GenshinData.getFetterDataEntries().get(this.Id);
int size = GenshinData.getAvatarCurveDataMap().size(); int size = GenshinData.getAvatarCurveDataMap().size();
this.hpGrowthCurve = new float[size]; this.hpGrowthCurve = new float[size];
this.attackGrowthCurve = new float[size]; this.attackGrowthCurve = new float[size];

View File

@ -0,0 +1,24 @@
package emu.grasscutter.data.def;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority;
@ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
public class FetterData extends GenshinResource {
private int AvatarId;
private int FetterId;
@Override
public int getId() {
return FetterId;
}
public int getAvatarId() {
return AvatarId;
}
@Override
public void onLoad() {
}
}

View File

@ -66,7 +66,7 @@ public final class DatabaseHelper {
} }
public static void saveAccount(Account account) { public static void saveAccount(Account account) {
DatabaseManager.getDatastore().save(account); DatabaseManager.getAccountDatastore().save(account);
} }
public static Account getAccountByName(String username) { public static Account getAccountByName(String username) {

View File

@ -1,5 +1,6 @@
package emu.grasscutter.database; package emu.grasscutter.database;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCommandException; import com.mongodb.MongoCommandException;
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
@ -18,7 +19,12 @@ import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.inventory.GenshinItem; import emu.grasscutter.game.inventory.GenshinItem;
public final class DatabaseManager { public final class DatabaseManager {
private static MongoClient mongoClient;
private static MongoClient dispatchMongoClient;
private static Datastore datastore; private static Datastore datastore;
private static Datastore dispatchDatastore;
private static final Class<?>[] mappedClasses = new Class<?>[] { private static final Class<?>[] mappedClasses = new Class<?>[] {
DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class
@ -32,6 +38,16 @@ public final class DatabaseManager {
return getDatastore().getDatabase(); return getDatastore().getDatabase();
} }
// Yes. I very dislike this method. However, this will be good for now.
// TODO: Add dispatch routes for player account management
public static Datastore getAccountDatastore() {
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
return dispatchDatastore;
} else {
return datastore;
}
}
public static void initialize() { public static void initialize() {
// Initialize // Initialize
MongoClient mongoClient = MongoClients.create(Grasscutter.getConfig().DatabaseUrl); MongoClient mongoClient = MongoClients.create(Grasscutter.getConfig().DatabaseUrl);
@ -60,6 +76,28 @@ public final class DatabaseManager {
datastore.ensureIndexes(); datastore.ensureIndexes();
} }
} }
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
dispatchMongoClient = MongoClients.create(Grasscutter.getConfig().getGameServerOptions().DispatchServerDatabaseUrl);
dispatchDatastore = Morphia.createDatastore(dispatchMongoClient, Grasscutter.getConfig().getGameServerOptions().DispatchServerDatabaseCollection);
// Ensure indexes for dispatch server
try {
dispatchDatastore.ensureIndexes();
} catch (MongoCommandException e) {
Grasscutter.getLogger().info("Mongo index error: ", e);
// Duplicate index error
if (e.getCode() == 85) {
// Drop all indexes and re add them
MongoIterable<String> collections = dispatchDatastore.getDatabase().listCollectionNames();
for (String name : collections) {
dispatchDatastore.getDatabase().getCollection(name).dropIndexes();
}
// Add back indexes
dispatchDatastore.ensureIndexes();
}
}
}
} }
public static synchronized int getNextId(Class<?> c) { public static synchronized int getNextId(Class<?> c) {

View File

@ -8,6 +8,10 @@ import emu.grasscutter.utils.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.bson.Document;
import com.mongodb.DBObject;
@Entity(value = "accounts", useDiscriminator = false) @Entity(value = "accounts", useDiscriminator = false)
public class Account { public class Account {
@Id private String id; @Id private String id;
@ -17,7 +21,7 @@ public class Account {
private String username; private String username;
private String password; // Unused for now private String password; // Unused for now
private int playerId; @AlsoLoad("playerUid") private int playerId;
private String email; private String email;
private String token; private String token;
@ -61,7 +65,7 @@ public class Account {
this.token = token; this.token = token;
} }
public int getPlayerId() { public int getPlayerUid() {
return this.playerId; return this.playerId;
} }
@ -118,12 +122,11 @@ public class Account {
DatabaseHelper.saveAccount(this); DatabaseHelper.saveAccount(this);
} }
// TODO: Find an implementation for this. Morphia 2.0 breaks this method for some reason? @PreLoad
// @PreLoad public void onLoad(Document document) {
// public void onLoad(DBObject object) { // Grant the superuser permissions to accounts created before the permissions update
// // Grant the superuser permissions to accounts created before the permissions update if (!document.containsKey("permissions")) {
// if (!object.containsField("permissions")) { this.addPermission("*");
// this.addPermission("*"); }
// } }
// }
} }

View File

@ -31,6 +31,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason; import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason;
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo; import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify; import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify;
@ -49,9 +50,11 @@ import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify; import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify; import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify;
import emu.grasscutter.server.packet.send.PacketPrivateChatNotify; import emu.grasscutter.server.packet.send.PacketPrivateChatNotify;
import emu.grasscutter.server.packet.send.PacketScenePlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketSetNameCardRsp; import emu.grasscutter.server.packet.send.PacketSetNameCardRsp;
import emu.grasscutter.server.packet.send.PacketStoreWeightLimitNotify; import emu.grasscutter.server.packet.send.PacketStoreWeightLimitNotify;
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify; import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify; import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
@ -101,6 +104,7 @@ public class GenshinPlayer {
@Transient private int enterSceneToken; @Transient private int enterSceneToken;
@Transient private SceneLoadState sceneState; @Transient private SceneLoadState sceneState;
@Transient private boolean hasSentAvatarDataNotify; @Transient private boolean hasSentAvatarDataNotify;
@Transient private long nextSendPlayerLocTime = 0;
@Transient private final Int2ObjectMap<CoopRequest> coopRequests; @Transient private final Int2ObjectMap<CoopRequest> coopRequests;
@Transient private final InvokeHandler<CombatInvokeEntry> combatInvokeHandler; @Transient private final InvokeHandler<CombatInvokeEntry> combatInvokeHandler;
@ -121,6 +125,12 @@ public class GenshinPlayer {
} }
this.properties.put(prop.getId(), 0); this.properties.put(prop.getId(), 0);
} }
this.gachaInfo = new PlayerGachaInfo();
this.nameCardList = new HashSet<>();
this.flyCloakList = new HashSet<>();
this.costumeList = new HashSet<>();
this.setSceneId(3); this.setSceneId(3);
this.setRegionId(1); this.setRegionId(1);
this.sceneState = SceneLoadState.NONE; this.sceneState = SceneLoadState.NONE;
@ -140,11 +150,6 @@ public class GenshinPlayer {
this.nickname = "Traveler"; this.nickname = "Traveler";
this.signature = ""; this.signature = "";
this.teamManager = new TeamManager(this); this.teamManager = new TeamManager(this);
this.gachaInfo = new PlayerGachaInfo();
this.playerProfile = new PlayerProfile(this);
this.nameCardList = new HashSet<>();
this.flyCloakList = new HashSet<>();
this.costumeList = new HashSet<>();
this.setProperty(PlayerProperty.PROP_PLAYER_LEVEL, 1); this.setProperty(PlayerProperty.PROP_PLAYER_LEVEL, 1);
this.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1); this.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1);
this.setProperty(PlayerProperty.PROP_SPRING_AUTO_USE_PERCENT, 50); this.setProperty(PlayerProperty.PROP_SPRING_AUTO_USE_PERCENT, 50);
@ -288,7 +293,7 @@ public class GenshinPlayer {
} }
private float getExpModifier() { private float getExpModifier() {
return Grasscutter.getConfig().getGameRates().ADVENTURE_EXP_RATE; return Grasscutter.getConfig().getGameServerOptions().getGameRates().ADVENTURE_EXP_RATE;
} }
// Affected by exp rate // Affected by exp rate
@ -347,7 +352,6 @@ public class GenshinPlayer {
public PlayerProfile getProfile() { public PlayerProfile getProfile() {
if (this.playerProfile == null) { if (this.playerProfile == null) {
this.playerProfile = new PlayerProfile(this); this.playerProfile = new PlayerProfile(this);
this.save();
} }
return playerProfile; return playerProfile;
} }
@ -654,6 +658,13 @@ public class GenshinPlayer {
return social; return social;
} }
public WorldPlayerLocationInfo getWorldPlayerLocationInfo() {
return WorldPlayerLocationInfo.newBuilder()
.setSceneId(this.getSceneId())
.setPlayerLoc(this.getPlayerLocationInfo())
.build();
}
public PlayerLocationInfo getPlayerLocationInfo() { public PlayerLocationInfo getPlayerLocationInfo() {
return PlayerLocationInfo.newBuilder() return PlayerLocationInfo.newBuilder()
.setUid(this.getUid()) .setUid(this.getUid())
@ -679,9 +690,22 @@ public class GenshinPlayer {
} }
// Ping // Ping
if (this.getWorld() != null) { if (this.getWorld() != null) {
this.sendPacket(new PacketWorldPlayerRTTNotify(this.getWorld())); // Player ping // RTT notify - very important to send this often
this.sendPacket(new PacketWorldPlayerRTTNotify(this.getWorld()));
// Update player locations if in multiplayer every 5 seconds
long time = System.currentTimeMillis();
if (this.getWorld().isMultiplayer() && this.getScene() != null && time > nextSendPlayerLocTime) {
this.sendPacket(new PacketWorldPlayerLocationNotify(this.getWorld()));
this.sendPacket(new PacketScenePlayerLocationNotify(this.getScene()));
this.resetSendPlayerLocTime();
} }
} }
}
public void resetSendPlayerLocTime() {
this.nextSendPlayerLocTime = System.currentTimeMillis() + 5000;
}
@PostLoad @PostLoad
private void onLoad() { private void onLoad() {
@ -696,12 +720,8 @@ public class GenshinPlayer {
// Make sure these exist // Make sure these exist
if (this.getTeamManager() == null) { if (this.getTeamManager() == null) {
this.teamManager = new TeamManager(this); this.teamManager = new TeamManager(this);
} if (this.getGachaInfo() == null) { } if (this.getProfile().getUid() == 0) {
this.gachaInfo = new PlayerGachaInfo(); this.getProfile().syncWithCharacter(this);
} if (this.nameCardList == null) {
this.nameCardList = new HashSet<>();
} if (this.costumeList == null) {
this.costumeList = new HashSet<>();
} }
// Check if player object exists in server // Check if player object exists in server

View File

@ -34,6 +34,7 @@ public class GenshinScene {
private int time; private int time;
private ClimateType climate; private ClimateType climate;
private int weather;
public GenshinScene(World world, SceneData sceneData) { public GenshinScene(World world, SceneData sceneData) {
this.world = world; this.world = world;
@ -89,10 +90,18 @@ public class GenshinScene {
return climate; return climate;
} }
public int getWeather() {
return weather;
}
public void setClimate(ClimateType climate) { public void setClimate(ClimateType climate) {
this.climate = climate; this.climate = climate;
} }
public void setWeather(int weather) {
this.weather = weather;
}
public boolean isInScene(GenshinEntity entity) { public boolean isInScene(GenshinEntity entity) {
return this.entities.containsKey(entity.getId()); return this.entities.containsKey(entity.getId());
} }

View File

@ -15,7 +15,7 @@ public class TeamInfo {
public TeamInfo() { public TeamInfo() {
this.name = ""; this.name = "";
this.avatars = new ArrayList<>(Grasscutter.getConfig().getServerOptions().MaxAvatarsInTeam); this.avatars = new ArrayList<>(Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam);
} }
public String getName() { public String getName() {
@ -39,7 +39,7 @@ public class TeamInfo {
} }
public boolean addAvatar(GenshinAvatar avatar) { public boolean addAvatar(GenshinAvatar avatar) {
if (size() >= Grasscutter.getConfig().getServerOptions().MaxAvatarsInTeam || contains(avatar)) { if (size() >= Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam || contains(avatar)) {
return false; return false;
} }
@ -59,7 +59,7 @@ public class TeamInfo {
} }
public void copyFrom(TeamInfo team) { public void copyFrom(TeamInfo team) {
copyFrom(team, Grasscutter.getConfig().getServerOptions().MaxAvatarsInTeam); copyFrom(team, Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam);
} }
public void copyFrom(TeamInfo team, int maxTeamSize) { public void copyFrom(TeamInfo team, int maxTeamSize) {

View File

@ -166,13 +166,13 @@ public class TeamManager {
public int getMaxTeamSize() { public int getMaxTeamSize() {
if (getPlayer().isInMultiplayer()) { if (getPlayer().isInMultiplayer()) {
int max = Grasscutter.getConfig().getServerOptions().MaxAvatarsInTeamMultiplayer; int max = Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeamMultiplayer;
if (getPlayer().getWorld().getHost() == this.getPlayer()) { if (getPlayer().getWorld().getHost() == this.getPlayer()) {
return Math.max(1, (int) Math.ceil(max / (double) getWorld().getPlayerCount())); return Math.max(1, (int) Math.ceil(max / (double) getWorld().getPlayerCount()));
} }
return Math.max(1, (int) Math.floor(max / (double) getWorld().getPlayerCount())); return Math.max(1, (int) Math.floor(max / (double) getWorld().getPlayerCount()));
} }
return Grasscutter.getConfig().getServerOptions().MaxAvatarsInTeam; return Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam;
} }
// Methods // Methods

View File

@ -207,13 +207,15 @@ public class World implements Iterable<GenshinPlayer> {
this.getScenes().remove(scene.getId()); this.getScenes().remove(scene.getId());
} }
public boolean forceTransferPlayerToScene(GenshinPlayer player, int sceneId, Position pos) { public boolean transferPlayerToScene(GenshinPlayer player, int sceneId, Position pos) {
// Forces the client to reload the scene map to prevent the player from falling off the map.
if (GenshinData.getSceneDataMap().get(sceneId) == null) { if (GenshinData.getSceneDataMap().get(sceneId) == null) {
return false; return false;
} }
Integer oldSceneId = null;
if (player.getScene() != null) { if (player.getScene() != null) {
oldSceneId = player.getScene().getId();
player.getScene().removePlayer(player); player.getScene().removePlayer(player);
} }
@ -222,25 +224,11 @@ public class World implements Iterable<GenshinPlayer> {
player.getPos().set(pos); player.getPos().set(pos);
// Teleport packet // Teleport packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TransPoint, sceneId, pos)); if (oldSceneId.equals(sceneId)) {
return true; player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterGoto, EnterReason.TransPoint, sceneId, pos));
} else {
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterJump, EnterReason.TransPoint, sceneId, pos));
} }
public boolean transferPlayerToScene(GenshinPlayer player, int sceneId, Position pos) {
if (player.getScene().getId() == sceneId || GenshinData.getSceneDataMap().get(sceneId) == null) {
return false;
}
if (player.getScene() != null) {
player.getScene().removePlayer(player);
}
GenshinScene scene = this.getSceneById(sceneId);
scene.addPlayer(player);
player.getPos().set(pos);
// Teleport packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TransPoint, sceneId, pos));
return true; return true;
} }

View File

@ -1,7 +1,9 @@
package emu.grasscutter.game.avatar; package emu.grasscutter.game.avatar;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -13,6 +15,7 @@ import dev.morphia.annotations.Indexed;
import dev.morphia.annotations.PostLoad; import dev.morphia.annotations.PostLoad;
import dev.morphia.annotations.PrePersist; import dev.morphia.annotations.PrePersist;
import dev.morphia.annotations.Transient; import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GenshinData; import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.custom.OpenConfigEntry; import emu.grasscutter.data.custom.OpenConfigEntry;
@ -38,10 +41,13 @@ import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.GenshinItem; import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.FetterState;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo; import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo; import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo;
import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify; import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify;
import emu.grasscutter.utils.ProtoHelper; import emu.grasscutter.utils.ProtoHelper;
@ -69,7 +75,9 @@ public class GenshinAvatar {
@Transient private final Int2ObjectMap<GenshinItem> equips; @Transient private final Int2ObjectMap<GenshinItem> equips;
@Transient private final Int2FloatOpenHashMap fightProp; @Transient private final Int2FloatOpenHashMap fightProp;
@Transient private final Set<String> bonusAbilityList; @Transient private Set<String> extraAbilityEmbryos;
private List<Integer> fetters;
private Map<Integer, Integer> skillLevelMap; // Talent levels private Map<Integer, Integer> skillLevelMap; // Talent levels
private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const) private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const)
@ -86,8 +94,9 @@ public class GenshinAvatar {
// Morhpia only! // Morhpia only!
this.equips = new Int2ObjectOpenHashMap<>(); this.equips = new Int2ObjectOpenHashMap<>();
this.fightProp = new Int2FloatOpenHashMap(); this.fightProp = new Int2FloatOpenHashMap();
this.bonusAbilityList = new HashSet<>(); this.extraAbilityEmbryos = new HashSet<>();
this.proudSkillBonusMap = new HashMap<>(); // TODO Move to genshin avatar this.proudSkillBonusMap = new HashMap<>();
this.fetters = new ArrayList<>(); // TODO Move to genshin avatar
} }
// On creation // On creation
@ -260,8 +269,16 @@ public class GenshinAvatar {
return proudSkillBonusMap; return proudSkillBonusMap;
} }
public Set<String> getBonusAbilityList() { public Set<String> getExtraAbilityEmbryos() {
return bonusAbilityList; return extraAbilityEmbryos;
}
public void setFetterList(List<Integer> fetterList) {
this.fetters = fetterList;
}
public List<Integer> getFetterList() {
return fetters;
} }
public float getCurrentHp() { public float getCurrentHp() {
@ -347,14 +364,14 @@ public class GenshinAvatar {
item.setEquipCharacter(this.getAvatarId()); item.setEquipCharacter(this.getAvatarId());
item.save(); item.save();
if (shouldRecalc) {
this.recalcStats();
}
if (this.getPlayer().hasSentAvatarDataNotify()) { if (this.getPlayer().hasSentAvatarDataNotify()) {
this.getPlayer().sendPacket(new PacketAvatarEquipChangeNotify(this, item)); this.getPlayer().sendPacket(new PacketAvatarEquipChangeNotify(this, item));
} }
if (shouldRecalc) {
this.recalcStats();
}
return true; return true;
} }
@ -371,11 +388,21 @@ public class GenshinAvatar {
} }
public void recalcStats() { public void recalcStats() {
recalcStats(false);
}
public void recalcStats(boolean forceSendAbilityChange) {
// Setup // Setup
AvatarData data = this.getAvatarData(); AvatarData data = this.getAvatarData();
AvatarPromoteData promoteData = GenshinData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel()); AvatarPromoteData promoteData = GenshinData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
Int2IntOpenHashMap setMap = new Int2IntOpenHashMap(); Int2IntOpenHashMap setMap = new Int2IntOpenHashMap();
this.getBonusAbilityList().clear();
// Extra ability embryos
Set<String> prevExtraAbilityEmbryos = this.getExtraAbilityEmbryos();
this.extraAbilityEmbryos = new HashSet<>();
// Fetters
this.setFetterList(data.getFetters());
// Get hp percent, set to 100% if none // Get hp percent, set to 100% if none
float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
@ -458,7 +485,7 @@ public class GenshinAvatar {
} }
// Add any skill strings from this affix // Add any skill strings from this affix
this.addToAbilityList(affix.getOpenConfig(), true); this.addToExtraAbilityEmbryos(affix.getOpenConfig(), true);
} else { } else {
break; break;
} }
@ -505,7 +532,7 @@ public class GenshinAvatar {
} }
// Add any skill strings from this affix // Add any skill strings from this affix
this.addToAbilityList(affix.getOpenConfig(), true); this.addToExtraAbilityEmbryos(affix.getOpenConfig(), true);
} }
} }
} }
@ -538,7 +565,7 @@ public class GenshinAvatar {
} }
// Add any skill strings from this proud skill // Add any skill strings from this proud skill
this.addToAbilityList(proudSkillData.getOpenConfig(), true); this.addToExtraAbilityEmbryos(proudSkillData.getOpenConfig(), true);
} }
// Constellations // Constellations
@ -550,7 +577,7 @@ public class GenshinAvatar {
} }
// Add any skill strings from this constellation // Add any skill strings from this constellation
this.addToAbilityList(avatarTalentData.getOpenConfig(), false); this.addToExtraAbilityEmbryos(avatarTalentData.getOpenConfig(), false);
} }
} }
@ -573,11 +600,17 @@ public class GenshinAvatar {
// Packet // Packet
if (getPlayer() != null && getPlayer().hasSentAvatarDataNotify()) { if (getPlayer() != null && getPlayer().hasSentAvatarDataNotify()) {
// Update stats for client
getPlayer().sendPacket(new PacketAvatarFightPropNotify(this)); getPlayer().sendPacket(new PacketAvatarFightPropNotify(this));
// Update client abilities
EntityAvatar entity = this.getAsEntity();
if (entity != null && (!this.getExtraAbilityEmbryos().equals(prevExtraAbilityEmbryos) || forceSendAbilityChange)) {
getPlayer().sendPacket(new PacketAbilityChangeNotify(entity));
}
} }
} }
public void addToAbilityList(String openConfig, boolean forceAdd) { public void addToExtraAbilityEmbryos(String openConfig, boolean forceAdd) {
if (openConfig == null || openConfig.length() == 0) { if (openConfig == null || openConfig.length() == 0) {
return; return;
} }
@ -586,14 +619,14 @@ public class GenshinAvatar {
if (entry == null) { if (entry == null) {
if (forceAdd) { if (forceAdd) {
// Add config string to ability skill list anyways // Add config string to ability skill list anyways
this.getBonusAbilityList().add(openConfig); this.getExtraAbilityEmbryos().add(openConfig);
} }
return; return;
} }
if (entry.getAddAbilities() != null) { if (entry.getAddAbilities() != null) {
for (String ability : entry.getAddAbilities()) { for (String ability : entry.getAddAbilities()) {
this.getBonusAbilityList().add(ability); this.getExtraAbilityEmbryos().add(ability);
} }
} }
} }
@ -668,6 +701,20 @@ public class GenshinAvatar {
} }
public AvatarInfo toProto() { public AvatarInfo toProto() {
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
.setExpLevel(10)
.setExpNumber(6325); // Highest Level
if (this.getFetterList() != null) {
for (int i = 0; i < this.getFetterList().size(); i++) {
avatarFetter.addFetterList(
FetterData.newBuilder()
.setFetterId(this.getFetterList().get(i))
.setFetterState(FetterState.FINISH.getValue())
);
}
}
AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder() AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder()
.setAvatarId(this.getAvatarId()) .setAvatarId(this.getAvatarId())
.setGuid(this.getGuid()) .setGuid(this.getGuid())
@ -681,7 +728,7 @@ public class GenshinAvatar {
.putAllProudSkillExtraLevel(getProudSkillBonusMap()) .putAllProudSkillExtraLevel(getProudSkillBonusMap())
.setAvatarType(1) .setAvatarType(1)
.setBornTime(this.getBornTime()) .setBornTime(this.getBornTime())
.setFetterInfo(AvatarFetterInfo.newBuilder().setExpLevel(1)) .setFetterInfo(avatarFetter)
.setWearingFlycloakId(this.getFlyCloak()) .setWearingFlycloakId(this.getFlyCloak())
.setCostumeId(this.getCostume()); .setCostumeId(this.getCostume());

View File

@ -223,8 +223,8 @@ public class EntityAvatar extends GenshinEntity {
} }
} }
// Add equip abilities // Add equip abilities
if (this.getAvatar().getBonusAbilityList().size() > 0) { if (this.getAvatar().getExtraAbilityEmbryos().size() > 0) {
for (String skill : this.getAvatar().getBonusAbilityList()) { for (String skill : this.getAvatar().getExtraAbilityEmbryos()) {
AbilityEmbryo emb = AbilityEmbryo.newBuilder() AbilityEmbryo emb = AbilityEmbryo.newBuilder()
.setAbilityId(++embryoId) .setAbilityId(++embryoId)
.setAbilityNameHash(Utils.abilityHash(skill)) .setAbilityNameHash(Utils.abilityHash(skill))

View File

@ -220,7 +220,7 @@ public class FriendsList {
friendship.setOwner(getPlayer()); friendship.setOwner(getPlayer());
// Check if friend is online // Check if friend is online
GenshinPlayer friend = getPlayer().getSession().getServer().getPlayerByUid(friendship.getFriendProfile().getId()); GenshinPlayer friend = getPlayer().getSession().getServer().getPlayerByUid(friendship.getFriendProfile().getUid());
if (friend != null) { if (friend != null) {
// Set friend to online mode // Set friend to online mode
friendship.setFriendProfile(friend); friendship.setFriendProfile(friend);

View File

@ -88,7 +88,7 @@ public class Friendship {
public FriendBrief toProto() { public FriendBrief toProto() {
FriendBrief proto = FriendBrief.newBuilder() FriendBrief proto = FriendBrief.newBuilder()
.setUid(getFriendProfile().getId()) .setUid(getFriendProfile().getUid())
.setNickname(getFriendProfile().getName()) .setNickname(getFriendProfile().getName())
.setLevel(getFriendProfile().getPlayerLevel()) .setLevel(getFriendProfile().getPlayerLevel())
.setAvatar(HeadImage.newBuilder().setAvatarId(getFriendProfile().getAvatarId())) .setAvatar(HeadImage.newBuilder().setAvatarId(getFriendProfile().getAvatarId()))

View File

@ -8,7 +8,7 @@ import emu.grasscutter.utils.Utils;
public class PlayerProfile { public class PlayerProfile {
@Transient private GenshinPlayer player; @Transient private GenshinPlayer player;
private int id; @AlsoLoad("id") private int uid;
private int nameCard; private int nameCard;
private int avatarId; private int avatarId;
private String name; private String name;
@ -23,12 +23,12 @@ public class PlayerProfile {
public PlayerProfile() { } public PlayerProfile() { }
public PlayerProfile(GenshinPlayer player) { public PlayerProfile(GenshinPlayer player) {
this.id = player.getUid(); this.uid = player.getUid();
this.syncWithCharacter(player); this.syncWithCharacter(player);
} }
public int getId() { public int getUid() {
return id; return uid;
} }
public GenshinPlayer getPlayer() { public GenshinPlayer getPlayer() {
@ -88,6 +88,7 @@ public class PlayerProfile {
return; return;
} }
this.uid = player.getUid();
this.name = player.getNickname(); this.name = player.getNickname();
this.avatarId = player.getHeadImage(); this.avatarId = player.getHeadImage();
this.signature = player.getSignature(); this.signature = player.getSignature();

View File

@ -92,7 +92,7 @@ public class GachaBanner {
} }
public GachaInfo toProto() { public GachaInfo toProto() {
String record = "http://" + (Grasscutter.getConfig().DispatchServerPublicIp.isEmpty() ? Grasscutter.getConfig().DispatchServerIp : Grasscutter.getConfig().DispatchServerPublicIp) + "/gacha"; String record = "http://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + "/gacha";
GachaInfo.Builder info = GachaInfo.newBuilder() GachaInfo.Builder info = GachaInfo.newBuilder()
.setGachaType(this.getGachaType()) .setGachaType(this.getGachaType())

View File

@ -218,7 +218,6 @@ public class GachaManager {
addStarglitter = 2; addStarglitter = 2;
// Add 1 const // Add 1 const
gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(constItem == null)); gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(constItem == null));
gachaItem.addTokenItemList(ItemParam.newBuilder().setItemId(constItemId).setCount(1));
player.getInventory().addItem(constItemId, 1); player.getInventory().addItem(constItemId, 1);
} else { } else {
// Is max const // Is max const
@ -300,7 +299,7 @@ public class GachaManager {
@Subscribe @Subscribe
public synchronized void watchBannerJson(GameServerTickEvent tickEvent) { public synchronized void watchBannerJson(GameServerTickEvent tickEvent) {
if(Grasscutter.getConfig().getServerOptions().WatchGacha) { if(Grasscutter.getConfig().getGameServerOptions().WatchGacha) {
try { try {
WatchKey watchKey = watchService.take(); WatchKey watchKey = watchService.take();

View File

@ -37,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> {
this.store = new Long2ObjectOpenHashMap<>(); this.store = new Long2ObjectOpenHashMap<>();
this.inventoryTypes = new Int2ObjectOpenHashMap<>(); this.inventoryTypes = new Int2ObjectOpenHashMap<>();
this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitWeapon)); this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitWeapon));
this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitRelic)); this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitRelic));
this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitMaterial)); this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitMaterial));
this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitFurniture)); this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitFurniture));
} }
public GenshinPlayer getPlayer() { public GenshinPlayer getPlayer() {

View File

@ -589,7 +589,6 @@ public class InventoryManager {
// Update proud skills // Update proud skills
AvatarSkillDepotData skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(avatar.getSkillDepotId()); AvatarSkillDepotData skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(avatar.getSkillDepotId());
boolean hasAddedProudSkill = false;
if (skillDepot != null && skillDepot.getInherentProudSkillOpens() != null) { if (skillDepot != null && skillDepot.getInherentProudSkillOpens() != null) {
for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) { for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) {
@ -599,7 +598,6 @@ public class InventoryManager {
if (openData.getNeedAvatarPromoteLevel() == avatar.getPromoteLevel()) { if (openData.getNeedAvatarPromoteLevel() == avatar.getPromoteLevel()) {
int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1; int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1;
if (GenshinData.getProudSkillDataMap().containsKey(proudSkillId)) { if (GenshinData.getProudSkillDataMap().containsKey(proudSkillId)) {
hasAddedProudSkill = true;
avatar.getProudSkillList().add(proudSkillId); avatar.getProudSkillList().add(proudSkillId);
player.sendPacket(new PacketProudSkillChangeNotify(avatar)); player.sendPacket(new PacketProudSkillChangeNotify(avatar));
} }
@ -607,20 +605,13 @@ public class InventoryManager {
} }
} }
// Racalc stats and save avatar
avatar.recalcStats();
avatar.save();
// Resend ability embryos if proud skill has been added
if (hasAddedProudSkill && avatar.getAsEntity() != null) {
player.sendPacket(new PacketAbilityChangeNotify(avatar.getAsEntity()));
}
// TODO Send entity prop update packet to world
// Packets // Packets
player.sendPacket(new PacketAvatarPropNotify(avatar)); player.sendPacket(new PacketAvatarPropNotify(avatar));
player.sendPacket(new PacketAvatarPromoteRsp(avatar)); player.sendPacket(new PacketAvatarPromoteRsp(avatar));
// TODO Send entity prop update packet to world
avatar.recalcStats(true);
avatar.save();
} }
public void upgradeAvatar(GenshinPlayer player, long guid, int itemId, int count) { public void upgradeAvatar(GenshinPlayer player, long guid, int itemId, int count) {
@ -827,25 +818,20 @@ public class InventoryManager {
// Apply + recalc // Apply + recalc
avatar.getTalentIdList().add(talentData.getId()); avatar.getTalentIdList().add(talentData.getId());
avatar.setCoreProudSkillLevel(currentTalentLevel + 1); avatar.setCoreProudSkillLevel(currentTalentLevel + 1);
avatar.recalcStats();
// Packet // Packet
player.sendPacket(new PacketAvatarUnlockTalentNotify(avatar, nextTalentId)); player.sendPacket(new PacketAvatarUnlockTalentNotify(avatar, nextTalentId));
player.sendPacket(new PacketUnlockAvatarTalentRsp(avatar, nextTalentId)); player.sendPacket(new PacketUnlockAvatarTalentRsp(avatar, nextTalentId));
// Proud skill bonus map // Proud skill bonus map (Extra skills)
OpenConfigEntry entry = GenshinData.getOpenConfigEntries().get(talentData.getOpenConfig()); OpenConfigEntry entry = GenshinData.getOpenConfigEntries().get(talentData.getOpenConfig());
if (entry != null && entry.getExtraTalentIndex() > 0) { if (entry != null && entry.getExtraTalentIndex() > 0) {
avatar.recalcProudSkillBonusMap(); avatar.recalcProudSkillBonusMap();
player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex())); player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex()));
} }
// Resend ability embryos // Recalc + save avatar
if (avatar.getAsEntity() != null) { avatar.recalcStats(true);
player.sendPacket(new PacketAbilityChangeNotify(avatar.getAsEntity()));
}
// Save avatar
avatar.save(); avatar.save();
} }

View File

@ -0,0 +1,42 @@
package emu.grasscutter.game.props;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public enum FetterState {
NONE(0),
NOT_OPEN(1),
OPEN(1),
FINISH(3);
private final int value;
private static final Int2ObjectMap<FetterState> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, FetterState> stringMap = new HashMap<>();
static {
Stream.of(values()).forEach(e -> {
map.put(e.getValue(), e);
stringMap.put(e.name(), e);
});
}
private FetterState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static FetterState getTypeByValue(int value) {
return map.getOrDefault(value, NONE);
}
public static FetterState getTypeByName(String name) {
return stringMap.getOrDefault(name, NONE);
}
}

View File

@ -0,0 +1,810 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: AvatarFetterDataNotify.proto
package emu.grasscutter.net.proto;
public final class AvatarFetterDataNotifyOuterClass {
private AvatarFetterDataNotifyOuterClass() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface AvatarFetterDataNotifyOrBuilder extends
// @@protoc_insertion_point(interface_extends:AvatarFetterDataNotify)
com.google.protobuf.MessageOrBuilder {
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
int getFetterInfoMapCount();
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
boolean containsFetterInfoMap(
long key);
/**
* Use {@link #getFetterInfoMapMap()} instead.
*/
@java.lang.Deprecated
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
getFetterInfoMap();
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
getFetterInfoMapMap();
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
/* nullable */
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrDefault(
long key,
/* nullable */
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo defaultValue);
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrThrow(
long key);
}
/**
* Protobuf type {@code AvatarFetterDataNotify}
*/
public static final class AvatarFetterDataNotify extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:AvatarFetterDataNotify)
AvatarFetterDataNotifyOrBuilder {
private static final long serialVersionUID = 0L;
// Use AvatarFetterDataNotify.newBuilder() to construct.
private AvatarFetterDataNotify(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private AvatarFetterDataNotify() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new AvatarFetterDataNotify();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private AvatarFetterDataNotify(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 10: {
if (!((mutable_bitField0_ & 0x00000001) != 0)) {
fetterInfoMap_ = com.google.protobuf.MapField.newMapField(
FetterInfoMapDefaultEntryHolder.defaultEntry);
mutable_bitField0_ |= 0x00000001;
}
com.google.protobuf.MapEntry<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
fetterInfoMap__ = input.readMessage(
FetterInfoMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
fetterInfoMap_.getMutableMap().put(
fetterInfoMap__.getKey(), fetterInfoMap__.getValue());
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_descriptor;
}
@SuppressWarnings({"rawtypes"})
@java.lang.Override
protected com.google.protobuf.MapField internalGetMapField(
int number) {
switch (number) {
case 1:
return internalGetFetterInfoMap();
default:
throw new RuntimeException(
"Invalid map field number: " + number);
}
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.class, emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.Builder.class);
}
public static final int FETTERINFOMAP_FIELD_NUMBER = 1;
private static final class FetterInfoMapDefaultEntryHolder {
static final com.google.protobuf.MapEntry<
java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> defaultEntry =
com.google.protobuf.MapEntry
.<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>newDefaultInstance(
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_descriptor,
com.google.protobuf.WireFormat.FieldType.UINT64,
0L,
com.google.protobuf.WireFormat.FieldType.MESSAGE,
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo.getDefaultInstance());
}
private com.google.protobuf.MapField<
java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> fetterInfoMap_;
private com.google.protobuf.MapField<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
internalGetFetterInfoMap() {
if (fetterInfoMap_ == null) {
return com.google.protobuf.MapField.emptyMapField(
FetterInfoMapDefaultEntryHolder.defaultEntry);
}
return fetterInfoMap_;
}
public int getFetterInfoMapCount() {
return internalGetFetterInfoMap().getMap().size();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public boolean containsFetterInfoMap(
long key) {
return internalGetFetterInfoMap().getMap().containsKey(key);
}
/**
* Use {@link #getFetterInfoMapMap()} instead.
*/
@java.lang.Override
@java.lang.Deprecated
public java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> getFetterInfoMap() {
return getFetterInfoMapMap();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> getFetterInfoMapMap() {
return internalGetFetterInfoMap().getMap();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrDefault(
long key,
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo defaultValue) {
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> map =
internalGetFetterInfoMap().getMap();
return map.containsKey(key) ? map.get(key) : defaultValue;
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrThrow(
long key) {
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> map =
internalGetFetterInfoMap().getMap();
if (!map.containsKey(key)) {
throw new java.lang.IllegalArgumentException();
}
return map.get(key);
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
com.google.protobuf.GeneratedMessageV3
.serializeLongMapTo(
output,
internalGetFetterInfoMap(),
FetterInfoMapDefaultEntryHolder.defaultEntry,
1);
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
for (java.util.Map.Entry<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> entry
: internalGetFetterInfoMap().getMap().entrySet()) {
com.google.protobuf.MapEntry<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
fetterInfoMap__ = FetterInfoMapDefaultEntryHolder.defaultEntry.newBuilderForType()
.setKey(entry.getKey())
.setValue(entry.getValue())
.build();
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, fetterInfoMap__);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify other = (emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify) obj;
if (!internalGetFetterInfoMap().equals(
other.internalGetFetterInfoMap())) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
if (!internalGetFetterInfoMap().getMap().isEmpty()) {
hash = (37 * hash) + FETTERINFOMAP_FIELD_NUMBER;
hash = (53 * hash) + internalGetFetterInfoMap().hashCode();
}
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code AvatarFetterDataNotify}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:AvatarFetterDataNotify)
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotifyOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_descriptor;
}
@SuppressWarnings({"rawtypes"})
protected com.google.protobuf.MapField internalGetMapField(
int number) {
switch (number) {
case 1:
return internalGetFetterInfoMap();
default:
throw new RuntimeException(
"Invalid map field number: " + number);
}
}
@SuppressWarnings({"rawtypes"})
protected com.google.protobuf.MapField internalGetMutableMapField(
int number) {
switch (number) {
case 1:
return internalGetMutableFetterInfoMap();
default:
throw new RuntimeException(
"Invalid map field number: " + number);
}
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.class, emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.Builder.class);
}
// Construct using emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
internalGetMutableFetterInfoMap().clear();
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.internal_static_AvatarFetterDataNotify_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify getDefaultInstanceForType() {
return emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify build() {
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify buildPartial() {
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify result = new emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify(this);
int from_bitField0_ = bitField0_;
result.fetterInfoMap_ = internalGetFetterInfoMap();
result.fetterInfoMap_.makeImmutable();
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify) {
return mergeFrom((emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify other) {
if (other == emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify.getDefaultInstance()) return this;
internalGetMutableFetterInfoMap().mergeFrom(
other.internalGetFetterInfoMap());
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
private com.google.protobuf.MapField<
java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> fetterInfoMap_;
private com.google.protobuf.MapField<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
internalGetFetterInfoMap() {
if (fetterInfoMap_ == null) {
return com.google.protobuf.MapField.emptyMapField(
FetterInfoMapDefaultEntryHolder.defaultEntry);
}
return fetterInfoMap_;
}
private com.google.protobuf.MapField<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
internalGetMutableFetterInfoMap() {
onChanged();;
if (fetterInfoMap_ == null) {
fetterInfoMap_ = com.google.protobuf.MapField.newMapField(
FetterInfoMapDefaultEntryHolder.defaultEntry);
}
if (!fetterInfoMap_.isMutable()) {
fetterInfoMap_ = fetterInfoMap_.copy();
}
return fetterInfoMap_;
}
public int getFetterInfoMapCount() {
return internalGetFetterInfoMap().getMap().size();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public boolean containsFetterInfoMap(
long key) {
return internalGetFetterInfoMap().getMap().containsKey(key);
}
/**
* Use {@link #getFetterInfoMapMap()} instead.
*/
@java.lang.Override
@java.lang.Deprecated
public java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> getFetterInfoMap() {
return getFetterInfoMapMap();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> getFetterInfoMapMap() {
return internalGetFetterInfoMap().getMap();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrDefault(
long key,
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo defaultValue) {
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> map =
internalGetFetterInfoMap().getMap();
return map.containsKey(key) ? map.get(key) : defaultValue;
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo getFetterInfoMapOrThrow(
long key) {
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> map =
internalGetFetterInfoMap().getMap();
if (!map.containsKey(key)) {
throw new java.lang.IllegalArgumentException();
}
return map.get(key);
}
public Builder clearFetterInfoMap() {
internalGetMutableFetterInfoMap().getMutableMap()
.clear();
return this;
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
public Builder removeFetterInfoMap(
long key) {
internalGetMutableFetterInfoMap().getMutableMap()
.remove(key);
return this;
}
/**
* Use alternate mutation accessors instead.
*/
@java.lang.Deprecated
public java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo>
getMutableFetterInfoMap() {
return internalGetMutableFetterInfoMap().getMutableMap();
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
public Builder putFetterInfoMap(
long key,
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo value) {
if (value == null) {
throw new NullPointerException("map value");
}
internalGetMutableFetterInfoMap().getMutableMap()
.put(key, value);
return this;
}
/**
* <code>map&lt;uint64, .AvatarFetterInfo&gt; fetterInfoMap = 1;</code>
*/
public Builder putAllFetterInfoMap(
java.util.Map<java.lang.Long, emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo> values) {
internalGetMutableFetterInfoMap().getMutableMap()
.putAll(values);
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:AvatarFetterDataNotify)
}
// @@protoc_insertion_point(class_scope:AvatarFetterDataNotify)
private static final emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify();
}
public static emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<AvatarFetterDataNotify>
PARSER = new com.google.protobuf.AbstractParser<AvatarFetterDataNotify>() {
@java.lang.Override
public AvatarFetterDataNotify parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new AvatarFetterDataNotify(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<AvatarFetterDataNotify> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<AvatarFetterDataNotify> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_AvatarFetterDataNotify_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_AvatarFetterDataNotify_fieldAccessorTable;
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n\034AvatarFetterDataNotify.proto\032\026AvatarFe" +
"tterInfo.proto\"\244\001\n\026AvatarFetterDataNotif" +
"y\022A\n\rfetterInfoMap\030\001 \003(\0132*.AvatarFetterD" +
"ataNotify.FetterInfoMapEntry\032G\n\022FetterIn" +
"foMapEntry\022\013\n\003key\030\001 \001(\004\022 \n\005value\030\002 \001(\0132\021" +
".AvatarFetterInfo:\0028\001B\033\n\031emu.grasscutter" +
".net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.getDescriptor(),
});
internal_static_AvatarFetterDataNotify_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_AvatarFetterDataNotify_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_AvatarFetterDataNotify_descriptor,
new java.lang.String[] { "FetterInfoMap", });
internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_descriptor =
internal_static_AvatarFetterDataNotify_descriptor.getNestedTypes().get(0);
internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_AvatarFetterDataNotify_FetterInfoMapEntry_descriptor,
new java.lang.String[] { "Key", "Value", });
emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.getDescriptor();
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -0,0 +1,610 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: AvatarFetterLevelRewardReq.proto
package emu.grasscutter.net.proto;
public final class AvatarFetterLevelRewardReqOuterClass {
private AvatarFetterLevelRewardReqOuterClass() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface AvatarFetterLevelRewardReqOrBuilder extends
// @@protoc_insertion_point(interface_extends:AvatarFetterLevelRewardReq)
com.google.protobuf.MessageOrBuilder {
/**
* <code>uint64 avatarGuid = 1;</code>
* @return The avatarGuid.
*/
long getAvatarGuid();
/**
* <code>uint32 fetterLevel = 2;</code>
* @return The fetterLevel.
*/
int getFetterLevel();
}
/**
* Protobuf type {@code AvatarFetterLevelRewardReq}
*/
public static final class AvatarFetterLevelRewardReq extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:AvatarFetterLevelRewardReq)
AvatarFetterLevelRewardReqOrBuilder {
private static final long serialVersionUID = 0L;
// Use AvatarFetterLevelRewardReq.newBuilder() to construct.
private AvatarFetterLevelRewardReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private AvatarFetterLevelRewardReq() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new AvatarFetterLevelRewardReq();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private AvatarFetterLevelRewardReq(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 8: {
avatarGuid_ = input.readUInt64();
break;
}
case 16: {
fetterLevel_ = input.readUInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.internal_static_AvatarFetterLevelRewardReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.internal_static_AvatarFetterLevelRewardReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.class, emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.Builder.class);
}
public static final int AVATARGUID_FIELD_NUMBER = 1;
private long avatarGuid_;
/**
* <code>uint64 avatarGuid = 1;</code>
* @return The avatarGuid.
*/
@java.lang.Override
public long getAvatarGuid() {
return avatarGuid_;
}
public static final int FETTERLEVEL_FIELD_NUMBER = 2;
private int fetterLevel_;
/**
* <code>uint32 fetterLevel = 2;</code>
* @return The fetterLevel.
*/
@java.lang.Override
public int getFetterLevel() {
return fetterLevel_;
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
if (avatarGuid_ != 0L) {
output.writeUInt64(1, avatarGuid_);
}
if (fetterLevel_ != 0) {
output.writeUInt32(2, fetterLevel_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (avatarGuid_ != 0L) {
size += com.google.protobuf.CodedOutputStream
.computeUInt64Size(1, avatarGuid_);
}
if (fetterLevel_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(2, fetterLevel_);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq other = (emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq) obj;
if (getAvatarGuid()
!= other.getAvatarGuid()) return false;
if (getFetterLevel()
!= other.getFetterLevel()) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
hash = (37 * hash) + AVATARGUID_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
getAvatarGuid());
hash = (37 * hash) + FETTERLEVEL_FIELD_NUMBER;
hash = (53 * hash) + getFetterLevel();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code AvatarFetterLevelRewardReq}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:AvatarFetterLevelRewardReq)
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReqOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.internal_static_AvatarFetterLevelRewardReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.internal_static_AvatarFetterLevelRewardReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.class, emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.Builder.class);
}
// Construct using emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
avatarGuid_ = 0L;
fetterLevel_ = 0;
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.internal_static_AvatarFetterLevelRewardReq_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq getDefaultInstanceForType() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq build() {
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq buildPartial() {
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq result = new emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq(this);
result.avatarGuid_ = avatarGuid_;
result.fetterLevel_ = fetterLevel_;
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq) {
return mergeFrom((emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq other) {
if (other == emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq.getDefaultInstance()) return this;
if (other.getAvatarGuid() != 0L) {
setAvatarGuid(other.getAvatarGuid());
}
if (other.getFetterLevel() != 0) {
setFetterLevel(other.getFetterLevel());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private long avatarGuid_ ;
/**
* <code>uint64 avatarGuid = 1;</code>
* @return The avatarGuid.
*/
@java.lang.Override
public long getAvatarGuid() {
return avatarGuid_;
}
/**
* <code>uint64 avatarGuid = 1;</code>
* @param value The avatarGuid to set.
* @return This builder for chaining.
*/
public Builder setAvatarGuid(long value) {
avatarGuid_ = value;
onChanged();
return this;
}
/**
* <code>uint64 avatarGuid = 1;</code>
* @return This builder for chaining.
*/
public Builder clearAvatarGuid() {
avatarGuid_ = 0L;
onChanged();
return this;
}
private int fetterLevel_ ;
/**
* <code>uint32 fetterLevel = 2;</code>
* @return The fetterLevel.
*/
@java.lang.Override
public int getFetterLevel() {
return fetterLevel_;
}
/**
* <code>uint32 fetterLevel = 2;</code>
* @param value The fetterLevel to set.
* @return This builder for chaining.
*/
public Builder setFetterLevel(int value) {
fetterLevel_ = value;
onChanged();
return this;
}
/**
* <code>uint32 fetterLevel = 2;</code>
* @return This builder for chaining.
*/
public Builder clearFetterLevel() {
fetterLevel_ = 0;
onChanged();
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:AvatarFetterLevelRewardReq)
}
// @@protoc_insertion_point(class_scope:AvatarFetterLevelRewardReq)
private static final emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq();
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<AvatarFetterLevelRewardReq>
PARSER = new com.google.protobuf.AbstractParser<AvatarFetterLevelRewardReq>() {
@java.lang.Override
public AvatarFetterLevelRewardReq parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new AvatarFetterLevelRewardReq(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<AvatarFetterLevelRewardReq> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<AvatarFetterLevelRewardReq> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_AvatarFetterLevelRewardReq_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_AvatarFetterLevelRewardReq_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n AvatarFetterLevelRewardReq.proto\"E\n\032Av" +
"atarFetterLevelRewardReq\022\022\n\navatarGuid\030\001" +
" \001(\004\022\023\n\013fetterLevel\030\002 \001(\rB\033\n\031emu.grasscu" +
"tter.net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_AvatarFetterLevelRewardReq_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_AvatarFetterLevelRewardReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_AvatarFetterLevelRewardReq_descriptor,
new java.lang.String[] { "AvatarGuid", "FetterLevel", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -0,0 +1,751 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: AvatarFetterLevelRewardRsp.proto
package emu.grasscutter.net.proto;
public final class AvatarFetterLevelRewardRspOuterClass {
private AvatarFetterLevelRewardRspOuterClass() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface AvatarFetterLevelRewardRspOrBuilder extends
// @@protoc_insertion_point(interface_extends:AvatarFetterLevelRewardRsp)
com.google.protobuf.MessageOrBuilder {
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
int getRetcode();
/**
* <code>uint64 avatarGuid = 2;</code>
* @return The avatarGuid.
*/
long getAvatarGuid();
/**
* <code>uint32 fetterLevel = 3;</code>
* @return The fetterLevel.
*/
int getFetterLevel();
/**
* <code>uint32 rewardId = 4;</code>
* @return The rewardId.
*/
int getRewardId();
}
/**
* Protobuf type {@code AvatarFetterLevelRewardRsp}
*/
public static final class AvatarFetterLevelRewardRsp extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:AvatarFetterLevelRewardRsp)
AvatarFetterLevelRewardRspOrBuilder {
private static final long serialVersionUID = 0L;
// Use AvatarFetterLevelRewardRsp.newBuilder() to construct.
private AvatarFetterLevelRewardRsp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private AvatarFetterLevelRewardRsp() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new AvatarFetterLevelRewardRsp();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private AvatarFetterLevelRewardRsp(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 8: {
retcode_ = input.readInt32();
break;
}
case 16: {
avatarGuid_ = input.readUInt64();
break;
}
case 24: {
fetterLevel_ = input.readUInt32();
break;
}
case 32: {
rewardId_ = input.readUInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.internal_static_AvatarFetterLevelRewardRsp_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.internal_static_AvatarFetterLevelRewardRsp_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.class, emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.Builder.class);
}
public static final int RETCODE_FIELD_NUMBER = 1;
private int retcode_;
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
@java.lang.Override
public int getRetcode() {
return retcode_;
}
public static final int AVATARGUID_FIELD_NUMBER = 2;
private long avatarGuid_;
/**
* <code>uint64 avatarGuid = 2;</code>
* @return The avatarGuid.
*/
@java.lang.Override
public long getAvatarGuid() {
return avatarGuid_;
}
public static final int FETTERLEVEL_FIELD_NUMBER = 3;
private int fetterLevel_;
/**
* <code>uint32 fetterLevel = 3;</code>
* @return The fetterLevel.
*/
@java.lang.Override
public int getFetterLevel() {
return fetterLevel_;
}
public static final int REWARDID_FIELD_NUMBER = 4;
private int rewardId_;
/**
* <code>uint32 rewardId = 4;</code>
* @return The rewardId.
*/
@java.lang.Override
public int getRewardId() {
return rewardId_;
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
if (retcode_ != 0) {
output.writeInt32(1, retcode_);
}
if (avatarGuid_ != 0L) {
output.writeUInt64(2, avatarGuid_);
}
if (fetterLevel_ != 0) {
output.writeUInt32(3, fetterLevel_);
}
if (rewardId_ != 0) {
output.writeUInt32(4, rewardId_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (retcode_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(1, retcode_);
}
if (avatarGuid_ != 0L) {
size += com.google.protobuf.CodedOutputStream
.computeUInt64Size(2, avatarGuid_);
}
if (fetterLevel_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(3, fetterLevel_);
}
if (rewardId_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(4, rewardId_);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp other = (emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp) obj;
if (getRetcode()
!= other.getRetcode()) return false;
if (getAvatarGuid()
!= other.getAvatarGuid()) return false;
if (getFetterLevel()
!= other.getFetterLevel()) return false;
if (getRewardId()
!= other.getRewardId()) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
hash = (37 * hash) + RETCODE_FIELD_NUMBER;
hash = (53 * hash) + getRetcode();
hash = (37 * hash) + AVATARGUID_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
getAvatarGuid());
hash = (37 * hash) + FETTERLEVEL_FIELD_NUMBER;
hash = (53 * hash) + getFetterLevel();
hash = (37 * hash) + REWARDID_FIELD_NUMBER;
hash = (53 * hash) + getRewardId();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code AvatarFetterLevelRewardRsp}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:AvatarFetterLevelRewardRsp)
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRspOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.internal_static_AvatarFetterLevelRewardRsp_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.internal_static_AvatarFetterLevelRewardRsp_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.class, emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.Builder.class);
}
// Construct using emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
retcode_ = 0;
avatarGuid_ = 0L;
fetterLevel_ = 0;
rewardId_ = 0;
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.internal_static_AvatarFetterLevelRewardRsp_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp getDefaultInstanceForType() {
return emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp build() {
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp buildPartial() {
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp result = new emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp(this);
result.retcode_ = retcode_;
result.avatarGuid_ = avatarGuid_;
result.fetterLevel_ = fetterLevel_;
result.rewardId_ = rewardId_;
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp) {
return mergeFrom((emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp other) {
if (other == emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp.getDefaultInstance()) return this;
if (other.getRetcode() != 0) {
setRetcode(other.getRetcode());
}
if (other.getAvatarGuid() != 0L) {
setAvatarGuid(other.getAvatarGuid());
}
if (other.getFetterLevel() != 0) {
setFetterLevel(other.getFetterLevel());
}
if (other.getRewardId() != 0) {
setRewardId(other.getRewardId());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int retcode_ ;
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
@java.lang.Override
public int getRetcode() {
return retcode_;
}
/**
* <code>int32 retcode = 1;</code>
* @param value The retcode to set.
* @return This builder for chaining.
*/
public Builder setRetcode(int value) {
retcode_ = value;
onChanged();
return this;
}
/**
* <code>int32 retcode = 1;</code>
* @return This builder for chaining.
*/
public Builder clearRetcode() {
retcode_ = 0;
onChanged();
return this;
}
private long avatarGuid_ ;
/**
* <code>uint64 avatarGuid = 2;</code>
* @return The avatarGuid.
*/
@java.lang.Override
public long getAvatarGuid() {
return avatarGuid_;
}
/**
* <code>uint64 avatarGuid = 2;</code>
* @param value The avatarGuid to set.
* @return This builder for chaining.
*/
public Builder setAvatarGuid(long value) {
avatarGuid_ = value;
onChanged();
return this;
}
/**
* <code>uint64 avatarGuid = 2;</code>
* @return This builder for chaining.
*/
public Builder clearAvatarGuid() {
avatarGuid_ = 0L;
onChanged();
return this;
}
private int fetterLevel_ ;
/**
* <code>uint32 fetterLevel = 3;</code>
* @return The fetterLevel.
*/
@java.lang.Override
public int getFetterLevel() {
return fetterLevel_;
}
/**
* <code>uint32 fetterLevel = 3;</code>
* @param value The fetterLevel to set.
* @return This builder for chaining.
*/
public Builder setFetterLevel(int value) {
fetterLevel_ = value;
onChanged();
return this;
}
/**
* <code>uint32 fetterLevel = 3;</code>
* @return This builder for chaining.
*/
public Builder clearFetterLevel() {
fetterLevel_ = 0;
onChanged();
return this;
}
private int rewardId_ ;
/**
* <code>uint32 rewardId = 4;</code>
* @return The rewardId.
*/
@java.lang.Override
public int getRewardId() {
return rewardId_;
}
/**
* <code>uint32 rewardId = 4;</code>
* @param value The rewardId to set.
* @return This builder for chaining.
*/
public Builder setRewardId(int value) {
rewardId_ = value;
onChanged();
return this;
}
/**
* <code>uint32 rewardId = 4;</code>
* @return This builder for chaining.
*/
public Builder clearRewardId() {
rewardId_ = 0;
onChanged();
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:AvatarFetterLevelRewardRsp)
}
// @@protoc_insertion_point(class_scope:AvatarFetterLevelRewardRsp)
private static final emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp();
}
public static emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<AvatarFetterLevelRewardRsp>
PARSER = new com.google.protobuf.AbstractParser<AvatarFetterLevelRewardRsp>() {
@java.lang.Override
public AvatarFetterLevelRewardRsp parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new AvatarFetterLevelRewardRsp(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<AvatarFetterLevelRewardRsp> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<AvatarFetterLevelRewardRsp> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_AvatarFetterLevelRewardRsp_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_AvatarFetterLevelRewardRsp_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n AvatarFetterLevelRewardRsp.proto\"h\n\032Av" +
"atarFetterLevelRewardRsp\022\017\n\007retcode\030\001 \001(" +
"\005\022\022\n\navatarGuid\030\002 \001(\004\022\023\n\013fetterLevel\030\003 \001" +
"(\r\022\020\n\010rewardId\030\004 \001(\rB\033\n\031emu.grasscutter." +
"net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_AvatarFetterLevelRewardRsp_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_AvatarFetterLevelRewardRsp_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_AvatarFetterLevelRewardRsp_descriptor,
new java.lang.String[] { "Retcode", "AvatarGuid", "FetterLevel", "RewardId", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -0,0 +1,743 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: WorldPlayerLocationInfo.proto
package emu.grasscutter.net.proto;
public final class WorldPlayerLocationInfoOuterClass {
private WorldPlayerLocationInfoOuterClass() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface WorldPlayerLocationInfoOrBuilder extends
// @@protoc_insertion_point(interface_extends:WorldPlayerLocationInfo)
com.google.protobuf.MessageOrBuilder {
/**
* <code>uint32 sceneId = 1;</code>
* @return The sceneId.
*/
int getSceneId();
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return Whether the playerLoc field is set.
*/
boolean hasPlayerLoc();
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return The playerLoc.
*/
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLoc();
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocOrBuilder();
}
/**
* Protobuf type {@code WorldPlayerLocationInfo}
*/
public static final class WorldPlayerLocationInfo extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:WorldPlayerLocationInfo)
WorldPlayerLocationInfoOrBuilder {
private static final long serialVersionUID = 0L;
// Use WorldPlayerLocationInfo.newBuilder() to construct.
private WorldPlayerLocationInfo(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private WorldPlayerLocationInfo() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new WorldPlayerLocationInfo();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private WorldPlayerLocationInfo(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 8: {
sceneId_ = input.readUInt32();
break;
}
case 18: {
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder subBuilder = null;
if (playerLoc_ != null) {
subBuilder = playerLoc_.toBuilder();
}
playerLoc_ = input.readMessage(emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.parser(), extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(playerLoc_);
playerLoc_ = subBuilder.buildPartial();
}
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.internal_static_WorldPlayerLocationInfo_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.internal_static_WorldPlayerLocationInfo_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.class, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder.class);
}
public static final int SCENEID_FIELD_NUMBER = 1;
private int sceneId_;
/**
* <code>uint32 sceneId = 1;</code>
* @return The sceneId.
*/
@java.lang.Override
public int getSceneId() {
return sceneId_;
}
public static final int PLAYERLOC_FIELD_NUMBER = 2;
private emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo playerLoc_;
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return Whether the playerLoc field is set.
*/
@java.lang.Override
public boolean hasPlayerLoc() {
return playerLoc_ != null;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return The playerLoc.
*/
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLoc() {
return playerLoc_ == null ? emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.getDefaultInstance() : playerLoc_;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocOrBuilder() {
return getPlayerLoc();
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
if (sceneId_ != 0) {
output.writeUInt32(1, sceneId_);
}
if (playerLoc_ != null) {
output.writeMessage(2, getPlayerLoc());
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (sceneId_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(1, sceneId_);
}
if (playerLoc_ != null) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(2, getPlayerLoc());
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo other = (emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo) obj;
if (getSceneId()
!= other.getSceneId()) return false;
if (hasPlayerLoc() != other.hasPlayerLoc()) return false;
if (hasPlayerLoc()) {
if (!getPlayerLoc()
.equals(other.getPlayerLoc())) return false;
}
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
hash = (37 * hash) + SCENEID_FIELD_NUMBER;
hash = (53 * hash) + getSceneId();
if (hasPlayerLoc()) {
hash = (37 * hash) + PLAYERLOC_FIELD_NUMBER;
hash = (53 * hash) + getPlayerLoc().hashCode();
}
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code WorldPlayerLocationInfo}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:WorldPlayerLocationInfo)
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.internal_static_WorldPlayerLocationInfo_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.internal_static_WorldPlayerLocationInfo_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.class, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder.class);
}
// Construct using emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
sceneId_ = 0;
if (playerLocBuilder_ == null) {
playerLoc_ = null;
} else {
playerLoc_ = null;
playerLocBuilder_ = null;
}
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.internal_static_WorldPlayerLocationInfo_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getDefaultInstanceForType() {
return emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo build() {
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo buildPartial() {
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo result = new emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo(this);
result.sceneId_ = sceneId_;
if (playerLocBuilder_ == null) {
result.playerLoc_ = playerLoc_;
} else {
result.playerLoc_ = playerLocBuilder_.build();
}
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo) {
return mergeFrom((emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo other) {
if (other == emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.getDefaultInstance()) return this;
if (other.getSceneId() != 0) {
setSceneId(other.getSceneId());
}
if (other.hasPlayerLoc()) {
mergePlayerLoc(other.getPlayerLoc());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int sceneId_ ;
/**
* <code>uint32 sceneId = 1;</code>
* @return The sceneId.
*/
@java.lang.Override
public int getSceneId() {
return sceneId_;
}
/**
* <code>uint32 sceneId = 1;</code>
* @param value The sceneId to set.
* @return This builder for chaining.
*/
public Builder setSceneId(int value) {
sceneId_ = value;
onChanged();
return this;
}
/**
* <code>uint32 sceneId = 1;</code>
* @return This builder for chaining.
*/
public Builder clearSceneId() {
sceneId_ = 0;
onChanged();
return this;
}
private emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo playerLoc_;
private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> playerLocBuilder_;
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return Whether the playerLoc field is set.
*/
public boolean hasPlayerLoc() {
return playerLocBuilder_ != null || playerLoc_ != null;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
* @return The playerLoc.
*/
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLoc() {
if (playerLocBuilder_ == null) {
return playerLoc_ == null ? emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.getDefaultInstance() : playerLoc_;
} else {
return playerLocBuilder_.getMessage();
}
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public Builder setPlayerLoc(emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo value) {
if (playerLocBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
playerLoc_ = value;
onChanged();
} else {
playerLocBuilder_.setMessage(value);
}
return this;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public Builder setPlayerLoc(
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder builderForValue) {
if (playerLocBuilder_ == null) {
playerLoc_ = builderForValue.build();
onChanged();
} else {
playerLocBuilder_.setMessage(builderForValue.build());
}
return this;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public Builder mergePlayerLoc(emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo value) {
if (playerLocBuilder_ == null) {
if (playerLoc_ != null) {
playerLoc_ =
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.newBuilder(playerLoc_).mergeFrom(value).buildPartial();
} else {
playerLoc_ = value;
}
onChanged();
} else {
playerLocBuilder_.mergeFrom(value);
}
return this;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public Builder clearPlayerLoc() {
if (playerLocBuilder_ == null) {
playerLoc_ = null;
onChanged();
} else {
playerLoc_ = null;
playerLocBuilder_ = null;
}
return this;
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder getPlayerLocBuilder() {
onChanged();
return getPlayerLocFieldBuilder().getBuilder();
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocOrBuilder() {
if (playerLocBuilder_ != null) {
return playerLocBuilder_.getMessageOrBuilder();
} else {
return playerLoc_ == null ?
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.getDefaultInstance() : playerLoc_;
}
}
/**
* <code>.PlayerLocationInfo playerLoc = 2;</code>
*/
private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder>
getPlayerLocFieldBuilder() {
if (playerLocBuilder_ == null) {
playerLocBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder>(
getPlayerLoc(),
getParentForChildren(),
isClean());
playerLoc_ = null;
}
return playerLocBuilder_;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:WorldPlayerLocationInfo)
}
// @@protoc_insertion_point(class_scope:WorldPlayerLocationInfo)
private static final emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo();
}
public static emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<WorldPlayerLocationInfo>
PARSER = new com.google.protobuf.AbstractParser<WorldPlayerLocationInfo>() {
@java.lang.Override
public WorldPlayerLocationInfo parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new WorldPlayerLocationInfo(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<WorldPlayerLocationInfo> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<WorldPlayerLocationInfo> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_WorldPlayerLocationInfo_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_WorldPlayerLocationInfo_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n\035WorldPlayerLocationInfo.proto\032\030PlayerL" +
"ocationInfo.proto\"R\n\027WorldPlayerLocation" +
"Info\022\017\n\007sceneId\030\001 \001(\r\022&\n\tplayerLoc\030\002 \001(\013" +
"2\023.PlayerLocationInfoB\033\n\031emu.grasscutter" +
".net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.getDescriptor(),
});
internal_static_WorldPlayerLocationInfo_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_WorldPlayerLocationInfo_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_WorldPlayerLocationInfo_descriptor,
new java.lang.String[] { "SceneId", "PlayerLoc", });
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.getDescriptor();
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -19,27 +19,27 @@ public final class WorldPlayerLocationNotifyOuterClass {
com.google.protobuf.MessageOrBuilder { com.google.protobuf.MessageOrBuilder {
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo>
getPlayerLocListList(); getPlayerLocListList();
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLocList(int index); emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getPlayerLocList(int index);
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
int getPlayerLocListCount(); int getPlayerLocListCount();
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
java.util.List<? extends emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> java.util.List<? extends emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder>
getPlayerLocListOrBuilderList(); getPlayerLocListOrBuilderList();
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocListOrBuilder( emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder getPlayerLocListOrBuilder(
int index); int index);
} }
/** /**
@ -89,13 +89,13 @@ public final class WorldPlayerLocationNotifyOuterClass {
case 0: case 0:
done = true; done = true;
break; break;
case 10: { case 18: {
if (!((mutable_bitField0_ & 0x00000001) != 0)) { if (!((mutable_bitField0_ & 0x00000001) != 0)) {
playerLocList_ = new java.util.ArrayList<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo>(); playerLocList_ = new java.util.ArrayList<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo>();
mutable_bitField0_ |= 0x00000001; mutable_bitField0_ |= 0x00000001;
} }
playerLocList_.add( playerLocList_.add(
input.readMessage(emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.parser(), extensionRegistry)); input.readMessage(emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.parser(), extensionRegistry));
break; break;
} }
default: { default: {
@ -133,42 +133,42 @@ public final class WorldPlayerLocationNotifyOuterClass {
emu.grasscutter.net.proto.WorldPlayerLocationNotifyOuterClass.WorldPlayerLocationNotify.class, emu.grasscutter.net.proto.WorldPlayerLocationNotifyOuterClass.WorldPlayerLocationNotify.Builder.class); emu.grasscutter.net.proto.WorldPlayerLocationNotifyOuterClass.WorldPlayerLocationNotify.class, emu.grasscutter.net.proto.WorldPlayerLocationNotifyOuterClass.WorldPlayerLocationNotify.Builder.class);
} }
public static final int PLAYERLOCLIST_FIELD_NUMBER = 1; public static final int PLAYERLOCLIST_FIELD_NUMBER = 2;
private java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> playerLocList_; private java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo> playerLocList_;
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> getPlayerLocListList() { public java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo> getPlayerLocListList() {
return playerLocList_; return playerLocList_;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public java.util.List<? extends emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> public java.util.List<? extends emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder>
getPlayerLocListOrBuilderList() { getPlayerLocListOrBuilderList() {
return playerLocList_; return playerLocList_;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public int getPlayerLocListCount() { public int getPlayerLocListCount() {
return playerLocList_.size(); return playerLocList_.size();
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLocList(int index) { public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getPlayerLocList(int index) {
return playerLocList_.get(index); return playerLocList_.get(index);
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocListOrBuilder( public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder getPlayerLocListOrBuilder(
int index) { int index) {
return playerLocList_.get(index); return playerLocList_.get(index);
} }
@ -188,7 +188,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
public void writeTo(com.google.protobuf.CodedOutputStream output) public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException { throws java.io.IOException {
for (int i = 0; i < playerLocList_.size(); i++) { for (int i = 0; i < playerLocList_.size(); i++) {
output.writeMessage(1, playerLocList_.get(i)); output.writeMessage(2, playerLocList_.get(i));
} }
unknownFields.writeTo(output); unknownFields.writeTo(output);
} }
@ -201,7 +201,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
size = 0; size = 0;
for (int i = 0; i < playerLocList_.size(); i++) { for (int i = 0; i < playerLocList_.size(); i++) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, playerLocList_.get(i)); .computeMessageSize(2, playerLocList_.get(i));
} }
size += unknownFields.getSerializedSize(); size += unknownFields.getSerializedSize();
memoizedSize = size; memoizedSize = size;
@ -515,22 +515,22 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
private int bitField0_; private int bitField0_;
private java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> playerLocList_ = private java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo> playerLocList_ =
java.util.Collections.emptyList(); java.util.Collections.emptyList();
private void ensurePlayerLocListIsMutable() { private void ensurePlayerLocListIsMutable() {
if (!((bitField0_ & 0x00000001) != 0)) { if (!((bitField0_ & 0x00000001) != 0)) {
playerLocList_ = new java.util.ArrayList<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo>(playerLocList_); playerLocList_ = new java.util.ArrayList<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo>(playerLocList_);
bitField0_ |= 0x00000001; bitField0_ |= 0x00000001;
} }
} }
private com.google.protobuf.RepeatedFieldBuilderV3< private com.google.protobuf.RepeatedFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> playerLocListBuilder_; emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder> playerLocListBuilder_;
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> getPlayerLocListList() { public java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo> getPlayerLocListList() {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
return java.util.Collections.unmodifiableList(playerLocList_); return java.util.Collections.unmodifiableList(playerLocList_);
} else { } else {
@ -538,7 +538,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public int getPlayerLocListCount() { public int getPlayerLocListCount() {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
@ -548,9 +548,9 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo getPlayerLocList(int index) { public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo getPlayerLocList(int index) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
return playerLocList_.get(index); return playerLocList_.get(index);
} else { } else {
@ -558,10 +558,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder setPlayerLocList( public Builder setPlayerLocList(
int index, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo value) { int index, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo value) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
@ -575,10 +575,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder setPlayerLocList( public Builder setPlayerLocList(
int index, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder builderForValue) { int index, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder builderForValue) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
ensurePlayerLocListIsMutable(); ensurePlayerLocListIsMutable();
playerLocList_.set(index, builderForValue.build()); playerLocList_.set(index, builderForValue.build());
@ -589,9 +589,9 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder addPlayerLocList(emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo value) { public Builder addPlayerLocList(emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo value) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
@ -605,10 +605,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder addPlayerLocList( public Builder addPlayerLocList(
int index, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo value) { int index, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo value) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
@ -622,10 +622,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder addPlayerLocList( public Builder addPlayerLocList(
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder builderForValue) { emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder builderForValue) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
ensurePlayerLocListIsMutable(); ensurePlayerLocListIsMutable();
playerLocList_.add(builderForValue.build()); playerLocList_.add(builderForValue.build());
@ -636,10 +636,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder addPlayerLocList( public Builder addPlayerLocList(
int index, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder builderForValue) { int index, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder builderForValue) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
ensurePlayerLocListIsMutable(); ensurePlayerLocListIsMutable();
playerLocList_.add(index, builderForValue.build()); playerLocList_.add(index, builderForValue.build());
@ -650,10 +650,10 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder addAllPlayerLocList( public Builder addAllPlayerLocList(
java.lang.Iterable<? extends emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo> values) { java.lang.Iterable<? extends emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo> values) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
ensurePlayerLocListIsMutable(); ensurePlayerLocListIsMutable();
com.google.protobuf.AbstractMessageLite.Builder.addAll( com.google.protobuf.AbstractMessageLite.Builder.addAll(
@ -665,7 +665,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder clearPlayerLocList() { public Builder clearPlayerLocList() {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
@ -678,7 +678,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public Builder removePlayerLocList(int index) { public Builder removePlayerLocList(int index) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
@ -691,16 +691,16 @@ public final class WorldPlayerLocationNotifyOuterClass {
return this; return this;
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder getPlayerLocListBuilder( public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder getPlayerLocListBuilder(
int index) { int index) {
return getPlayerLocListFieldBuilder().getBuilder(index); return getPlayerLocListFieldBuilder().getBuilder(index);
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder getPlayerLocListOrBuilder( public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder getPlayerLocListOrBuilder(
int index) { int index) {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
return playerLocList_.get(index); } else { return playerLocList_.get(index); } else {
@ -708,9 +708,9 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public java.util.List<? extends emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> public java.util.List<? extends emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder>
getPlayerLocListOrBuilderList() { getPlayerLocListOrBuilderList() {
if (playerLocListBuilder_ != null) { if (playerLocListBuilder_ != null) {
return playerLocListBuilder_.getMessageOrBuilderList(); return playerLocListBuilder_.getMessageOrBuilderList();
@ -719,33 +719,33 @@ public final class WorldPlayerLocationNotifyOuterClass {
} }
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder addPlayerLocListBuilder() { public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder addPlayerLocListBuilder() {
return getPlayerLocListFieldBuilder().addBuilder( return getPlayerLocListFieldBuilder().addBuilder(
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.getDefaultInstance()); emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.getDefaultInstance());
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder addPlayerLocListBuilder( public emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder addPlayerLocListBuilder(
int index) { int index) {
return getPlayerLocListFieldBuilder().addBuilder( return getPlayerLocListFieldBuilder().addBuilder(
index, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.getDefaultInstance()); index, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.getDefaultInstance());
} }
/** /**
* <code>repeated .PlayerLocationInfo playerLocList = 1;</code> * <code>repeated .WorldPlayerLocationInfo playerLocList = 2;</code>
*/ */
public java.util.List<emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder> public java.util.List<emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder>
getPlayerLocListBuilderList() { getPlayerLocListBuilderList() {
return getPlayerLocListFieldBuilder().getBuilderList(); return getPlayerLocListFieldBuilder().getBuilderList();
} }
private com.google.protobuf.RepeatedFieldBuilderV3< private com.google.protobuf.RepeatedFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder> emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder>
getPlayerLocListFieldBuilder() { getPlayerLocListFieldBuilder() {
if (playerLocListBuilder_ == null) { if (playerLocListBuilder_ == null) {
playerLocListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< playerLocListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo.Builder, emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfoOrBuilder>( emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo.Builder, emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfoOrBuilder>(
playerLocList_, playerLocList_,
((bitField0_ & 0x00000001) != 0), ((bitField0_ & 0x00000001) != 0),
getParentForChildren(), getParentForChildren(),
@ -821,16 +821,16 @@ public final class WorldPlayerLocationNotifyOuterClass {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\037WorldPlayerLocationNotify.proto\032\030Playe" + "\n\037WorldPlayerLocationNotify.proto\032\035World" +
"rLocationInfo.proto\"G\n\031WorldPlayerLocati" + "PlayerLocationInfo.proto\"L\n\031WorldPlayerL" +
"onNotify\022*\n\rplayerLocList\030\001 \003(\0132\023.Player" + "ocationNotify\022/\n\rplayerLocList\030\002 \003(\0132\030.W" +
"LocationInfoB\033\n\031emu.grasscutter.net.prot" + "orldPlayerLocationInfoB\033\n\031emu.grasscutte" +
"ob\006proto3" "r.net.protob\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] { new com.google.protobuf.Descriptors.FileDescriptor[] {
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.getDescriptor(), emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.getDescriptor(),
}); });
internal_static_WorldPlayerLocationNotify_descriptor = internal_static_WorldPlayerLocationNotify_descriptor =
getDescriptor().getMessageTypes().get(0); getDescriptor().getMessageTypes().get(0);
@ -838,7 +838,7 @@ public final class WorldPlayerLocationNotifyOuterClass {
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_WorldPlayerLocationNotify_descriptor, internal_static_WorldPlayerLocationNotify_descriptor,
new java.lang.String[] { "PlayerLocList", }); new java.lang.String[] { "PlayerLocList", });
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.getDescriptor(); emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.getDescriptor();
} }
// @@protoc_insertion_point(outer_class_scope) // @@protoc_insertion_point(outer_class_scope)

View File

@ -1,30 +1,14 @@
package emu.grasscutter.server.dispatch; 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.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer; import com.sun.net.httpserver.HttpsServer;
import emu.grasscutter.Config;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
@ -32,30 +16,34 @@ import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegio
import emu.grasscutter.net.proto.QueryRegionListHttpRspOuterClass.QueryRegionListHttpRsp; import emu.grasscutter.net.proto.QueryRegionListHttpRspOuterClass.QueryRegionListHttpRsp;
import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo; import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo;
import emu.grasscutter.net.proto.RegionSimpleInfoOuterClass.RegionSimpleInfo; import emu.grasscutter.net.proto.RegionSimpleInfoOuterClass.RegionSimpleInfo;
import emu.grasscutter.server.dispatch.json.ComboTokenReqJson; import emu.grasscutter.server.dispatch.json.*;
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.server.dispatch.json.ComboTokenReqJson.LoginTokenData;
import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import com.sun.net.httpserver.HttpServer; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URLDecoder;
import java.security.KeyStore;
import java.util.*;
public final class DispatchServer { public final class DispatchServer {
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_region_list = "";
public static String query_cur_region = ""; public static String query_cur_region = "";
private final InetSocketAddress address;
private final Gson gson;
private final String defaultServerName = "os_usa";
public String regionListBase64;
public HashMap<String, RegionData> regions;
public DispatchServer() { public DispatchServer() {
this.address = new InetSocketAddress(Grasscutter.getConfig().DispatchServerIp, Grasscutter.getConfig().DispatchServerPort); this.regions = new HashMap<String, RegionData>();
this.address = new InetSocketAddress(Grasscutter.getConfig().getDispatchOptions().Ip, Grasscutter.getConfig().getDispatchOptions().Port);
this.gson = new GsonBuilder().create(); this.gson = new GsonBuilder().create();
this.loadQueries(); this.loadQueries();
@ -71,7 +59,13 @@ public final class DispatchServer {
} }
public QueryCurrRegionHttpRsp getCurrRegion() { public QueryCurrRegionHttpRsp getCurrRegion() {
return currRegion; // Needs to be fixed by having the game servers connect to the dispatch server.
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) {
return regions.get(defaultServerName).parsedRegionQuery;
}
Grasscutter.getLogger().warn("[Dispatch] Unsupported run mode for getCurrRegion()");
return null;
} }
public void loadQueries() { public void loadQueries() {
@ -81,14 +75,14 @@ public final class DispatchServer {
if (file.exists()) { if (file.exists()) {
query_region_list = new String(FileUtils.read(file)); query_region_list = new String(FileUtils.read(file));
} else { } else {
Grasscutter.getLogger().warn("query_region_list not found! Using default region list."); Grasscutter.getLogger().warn("[Dispatch] query_region_list not found! Using default region list.");
} }
file = new File(Grasscutter.getConfig().DATA_FOLDER + "query_cur_region.txt"); file = new File(Grasscutter.getConfig().DATA_FOLDER + "query_cur_region.txt");
if (file.exists()) { if (file.exists()) {
query_cur_region = new String(FileUtils.read(file)); query_cur_region = new String(FileUtils.read(file));
} else { } else {
Grasscutter.getLogger().warn("query_cur_region not found! Using default current region."); Grasscutter.getLogger().warn("[Dispatch] query_cur_region not found! Using default current region.");
} }
} }
@ -100,52 +94,79 @@ public final class DispatchServer {
byte[] decoded2 = Base64.getDecoder().decode(query_cur_region); byte[] decoded2 = Base64.getDecoder().decode(query_cur_region);
QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(decoded2); QueryCurrRegionHttpRsp regionQuery = QueryCurrRegionHttpRsp.parseFrom(decoded2);
List<RegionSimpleInfo> servers = new ArrayList<RegionSimpleInfo>();
List<String> usedNames = new ArrayList<String>(); // List to check for potential naming conflicts
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in hybrid mode
RegionSimpleInfo server = RegionSimpleInfo.newBuilder() RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
.setName("os_usa") .setName("os_usa")
.setTitle(Grasscutter.getConfig().GameServerName) .setTitle(Grasscutter.getConfig().getGameServerOptions().Name)
.setType("DEV_PUBLIC") .setType("DEV_PUBLIC")
.setDispatchUrl("https://" + (Grasscutter.getConfig().DispatchServerPublicIp.isEmpty() ? Grasscutter.getConfig().DispatchServerIp : Grasscutter.getConfig().DispatchServerPublicIp) + ":" + getAddress().getPort() + "/query_cur_region") .setDispatchUrl("http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + ":" + (Grasscutter.getConfig().getDispatchOptions().PublicPort != 0 ? Grasscutter.getConfig().getDispatchOptions().PublicPort : Grasscutter.getConfig().getDispatchOptions().Port) + "/query_cur_region_" + defaultServerName)
.build();
usedNames.add(defaultServerName);
servers.add(server);
RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder()
.setIp((Grasscutter.getConfig().getGameServerOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getGameServerOptions().Ip : Grasscutter.getConfig().getGameServerOptions().PublicIp))
.setPort(Grasscutter.getConfig().getGameServerOptions().PublicPort != 0 ? Grasscutter.getConfig().getGameServerOptions().PublicPort : Grasscutter.getConfig().getGameServerOptions().Port)
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
.build(); .build();
RegionSimpleInfo serverTest2 = RegionSimpleInfo.newBuilder() QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
.setName("os_euro") regions.put(defaultServerName, new RegionData(parsedRegionQuery, Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray())));
.setTitle("Grasscutter")
} else {
if(Grasscutter.getConfig().getDispatchOptions().getGameServers().length == 0) {
Grasscutter.getLogger().error("[Dispatch] There are no game servers available. Exiting due to unplayable state.");
System.exit(1);
}
}
for (Config.DispatchServerOptions.RegionInfo regionInfo : Grasscutter.getConfig().getDispatchOptions().getGameServers()) {
if(usedNames.contains(regionInfo.Name)) {
Grasscutter.getLogger().error("Region name already in use.");
continue;
}
RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
.setName(regionInfo.Name)
.setTitle(regionInfo.Title)
.setType("DEV_PUBLIC") .setType("DEV_PUBLIC")
.setDispatchUrl("https://" + (Grasscutter.getConfig().DispatchServerPublicIp.isEmpty() ? Grasscutter.getConfig().DispatchServerIp : Grasscutter.getConfig().DispatchServerPublicIp) + ":" + getAddress().getPort() + "/query_cur_region") .setDispatchUrl("http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + ":" + getAddress().getPort() + "/query_cur_region_" + regionInfo.Name)
.build(); .build();
usedNames.add(regionInfo.Name);
servers.add(server);
RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder()
.setIp(regionInfo.Ip)
.setPort(regionInfo.Port)
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
.build();
QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
regions.put(regionInfo.Name, new RegionData(parsedRegionQuery, Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray())));
}
QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.newBuilder() QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.newBuilder()
.addServers(server) .addAllServers(servers)
.addServers(serverTest2)
.setClientSecretKey(rl.getClientSecretKey()) .setClientSecretKey(rl.getClientSecretKey())
.setClientCustomConfigEncrypted(rl.getClientCustomConfigEncrypted()) .setClientCustomConfigEncrypted(rl.getClientCustomConfigEncrypted())
.setEnableLoginPc(true) .setEnableLoginPc(true)
.build(); .build();
RegionInfo currentRegion = regionQuery.getRegionInfo().toBuilder()
.setIp((Grasscutter.getConfig().GameServerPublicIp.isEmpty() ? Grasscutter.getConfig().GameServerIp : Grasscutter.getConfig().GameServerPublicIp))
.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.regionListBase64 = Base64.getEncoder().encodeToString(regionList.toByteString().toByteArray());
this.regionCurrentBase64 = Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray());
this.currRegion = parsedRegionQuery;
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("Error while initializing region info!", e); Grasscutter.getLogger().error("[Dispatch] Error while initializing region info!", e);
} }
} }
public void start() throws Exception { public void start() throws Exception {
HttpServer server; HttpServer server;
if(Grasscutter.getConfig().UseSSL) { if (Grasscutter.getConfig().getDispatchOptions().UseSSL) {
HttpsServer httpsServer; HttpsServer httpsServer;
httpsServer = HttpsServer.create(getAddress(), 0); httpsServer = HttpsServer.create(getAddress(), 0);
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().DispatchServerKeystorePath)) { try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().getDispatchOptions().KeystorePath)) {
char[] keystorePassword = Grasscutter.getConfig().DispatchServerKeystorePassword.toCharArray(); char[] keystorePassword = Grasscutter.getConfig().getDispatchOptions().KeystorePassword.toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12"); KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(fis, keystorePassword); ks.load(fis, keystorePassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
@ -156,56 +177,39 @@ public final class DispatchServer {
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
server = httpsServer; server = httpsServer;
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("No SSL cert found!"); Grasscutter.getLogger().warn("[Dispatch] No SSL cert found! Falling back to HTTP server.");
return; Grasscutter.getConfig().getDispatchOptions().UseSSL = false;
server = HttpServer.create(getAddress(), 0);
} }
} else { } else {
server = HttpServer.create(getAddress(), 0); server = HttpServer.create(getAddress(), 0);
} }
server.createContext("/", t -> { server.createContext("/", t -> responseHTML(t, "Hello"));
//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 // Dispatch
server.createContext("/query_region_list", t -> { server.createContext("/query_region_list", t -> {
// Log // Log
Grasscutter.getLogger().info("Client request: query_region_list"); Grasscutter.getLogger().info(String.format("[Dispatch] Client %s request: query_region_list", t.getRemoteAddress()));
// Create a response form the request query parameters
String response = regionListBase64; responseHTML(t, 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", t -> {
for (String regionName : regions.keySet()) {
server.createContext("/query_cur_region_" + regionName, t -> {
String regionCurrentBase64 = regions.get(regionName).Base64;
// Log // Log
Grasscutter.getLogger().info("Client request: query_cur_region"); Grasscutter.getLogger().info(String.format("Client %s request: query_cur_region_%s", t.getRemoteAddress(), regionName));
// Create a response form the request query parameters // Create a response form the request query parameters
URI uri = t.getRequestURI(); URI uri = t.getRequestURI();
String response = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw=="; String response = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw==";
if (uri.getQuery() != null && uri.getQuery().length() > 0) { if (uri.getQuery() != null && uri.getQuery().length() > 0) {
response = regionCurrentBase64; response = regionCurrentBase64;
} }
// Set the response header status and length responseHTML(t, response);
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 // Login via account
server.createContext("/hk4e_global/mdk/shield/api/login", t -> { server.createContext("/hk4e_global/mdk/shield/api/login", t -> {
// Get post data // Get post data
@ -213,32 +217,44 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, LoginAccountRequestJson.class); requestData = getGsonFactory().fromJson(body, LoginAccountRequestJson.class);
} catch (Exception e) { } catch (Exception ignored) { }
}
// Create response json // Create response json
if (requestData == null) { if (requestData == null) {
return; return;
} }
LoginResultJson responseData = new LoginResultJson(); LoginResultJson responseData = new LoginResultJson();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s is trying to log in", t.getRemoteAddress()));
// Login // Login
Account account = DatabaseHelper.getAccountByName(requestData.account); Account account = DatabaseHelper.getAccountByName(requestData.account);
// Check if account exists, else create a new one. // Check if account exists, else create a new one.
if (account == null) { if (account == null) {
// Account doesnt exist, so we can either auto create it if the config value is set // Account doesnt exist, so we can either auto create it if the config value is set
if (Grasscutter.getConfig().ServerOptions.AutomaticallyCreateAccounts) { if (Grasscutter.getConfig().getDispatchOptions().AutomaticallyCreateAccounts) {
// This account has been created AUTOMATICALLY. There will be no permissions added. // This account has been created AUTOMATICALLY. There will be no permissions added.
account = DatabaseHelper.createAccountWithId(requestData.account, 0); account = DatabaseHelper.createAccountWithId(requestData.account, 0);
if (account != null) {
responseData.message = "OK"; responseData.message = "OK";
responseData.data.account.uid = account.getId(); responseData.data.account.uid = account.getId();
responseData.data.account.token = account.generateSessionKey(); responseData.data.account.token = account.generateSessionKey();
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account %s created", t.getRemoteAddress(), responseData.data.account.uid));
} else {
responseData.retcode = -201;
responseData.message = "Username not found, create failed.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account create failed", t.getRemoteAddress()));
}
} else { } else {
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Username not found."; responseData.message = "Username not found.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account no found", t.getRemoteAddress()));
} }
} else { } else {
// Account was found, log the player in // Account was found, log the player in
@ -246,17 +262,11 @@ public final class DispatchServer {
responseData.data.account.uid = account.getId(); responseData.data.account.uid = account.getId();
responseData.data.account.token = account.generateSessionKey(); responseData.data.account.token = account.generateSessionKey();
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", t.getRemoteAddress(), responseData.data.account.uid));
} }
// Create a response responseJSON(t, responseData);
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 // Login via token
server.createContext("/hk4e_global/mdk/shield/api/verify", t -> { server.createContext("/hk4e_global/mdk/shield/api/verify", t -> {
@ -265,14 +275,14 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, LoginTokenRequestJson.class); requestData = getGsonFactory().fromJson(body, LoginTokenRequestJson.class);
} catch (Exception e) { } catch (Exception ignored) { }
}
// Create response json // Create response json
if (requestData == null) { if (requestData == null) {
return; return;
} }
LoginResultJson responseData = new LoginResultJson(); LoginResultJson responseData = new LoginResultJson();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s is trying to log in via token", t.getRemoteAddress()));
// Login // Login
Account account = DatabaseHelper.getAccountById(requestData.uid); Account account = DatabaseHelper.getAccountById(requestData.uid);
@ -281,22 +291,18 @@ public final class DispatchServer {
if (account == null || !account.getSessionKey().equals(requestData.token)) { if (account == null || !account.getSessionKey().equals(requestData.token)) {
responseData.retcode = -111; responseData.retcode = -111;
responseData.message = "Game account cache information error"; responseData.message = "Game account cache information error";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in via token", t.getRemoteAddress()));
} else { } else {
responseData.message = "OK"; responseData.message = "OK";
responseData.data.account.uid = requestData.uid; responseData.data.account.uid = requestData.uid;
responseData.data.account.token = requestData.token; responseData.data.account.token = requestData.token;
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s", t.getRemoteAddress(), responseData.data.account.uid));
} }
// Create a response responseJSON(t, responseData);
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 // Exchange for combo token
server.createContext("/hk4e_global/combo/granter/login/v2/login", t -> { server.createContext("/hk4e_global/combo/granter/login/v2/login", t -> {
@ -305,9 +311,8 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, ComboTokenReqJson.class); requestData = getGsonFactory().fromJson(body, ComboTokenReqJson.class);
} catch (Exception e) { } catch (Exception ignored) { }
}
// Create response json // Create response json
if (requestData == null || requestData.data == null) { if (requestData == null || requestData.data == null) {
return; return;
@ -322,22 +327,18 @@ public final class DispatchServer {
if (account == null || !account.getSessionKey().equals(loginData.token)) { if (account == null || !account.getSessionKey().equals(loginData.token)) {
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Wrong session key."; responseData.message = "Wrong session key.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to exchange combo token", t.getRemoteAddress()));
} else { } else {
responseData.message = "OK"; responseData.message = "OK";
responseData.data.open_id = loginData.uid; responseData.data.open_id = loginData.uid;
responseData.data.combo_id = "157795300"; responseData.data.combo_id = "157795300";
responseData.data.combo_token = account.generateLoginToken(); responseData.data.combo_token = account.generateLoginToken();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s succeed to exchange combo token", t.getRemoteAddress()));
} }
// Create a response responseJSON(t, responseData);
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 // Agreement and Protocol
server.createContext( // hk4e-sdk-os.hoyoverse.com server.createContext( // hk4e-sdk-os.hoyoverse.com
@ -405,57 +406,67 @@ public final class DispatchServer {
"/perf/config/verify", "/perf/config/verify",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}")
); );
// Start server
server.start();
Grasscutter.getLogger().info("Dispatch server started on port " + getAddress().getPort());
// Logging servers // Logging servers
HttpServer overseaLogServer = HttpServer.create(new InetSocketAddress(Grasscutter.getConfig().DispatchServerIp, 8888), 0); server.createContext( // overseauspider.yuanshen.com
overseaLogServer.createContext( // overseauspider.yuanshen.com
"/log", "/log",
new DispatchHttpJsonHandler("{\"code\":0}") 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, Grasscutter.getConfig().UploadLogPort), 0); server.createContext( // log-upload-os.mihoyo.com
uploadLogServer.createContext( // log-upload-os.mihoyo.com
"/crash/dataUpload", "/crash/dataUpload",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}")
); );
uploadLogServer.createContext("/gacha", t -> { server.createContext("/gacha", t -> responseHTML(t, "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"));
//Create a response form the request query parameters
String response = "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"; // Start server
//Set the response header status and length server.start();
Grasscutter.getLogger().info("[Dispatch] Dispatch server started on port " + getAddress().getPort());
}
private void responseJSON(HttpExchange t, Object data) throws IOException {
// Create a response
String response = getGsonFactory().toJson(data);
// 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();
}
private void responseHTML(HttpExchange t, String response) throws IOException {
// Set the response header status and length
t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8")); t.getResponseHeaders().put("Content-Type", Collections.singletonList("text/html; charset=UTF-8"));
t.sendResponseHeaders(200, response.getBytes().length); t.sendResponseHeaders(200, response.getBytes().length);
//Write the response string //Write the response string
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
});
uploadLogServer.start();
Grasscutter.getLogger().info("Log server (log-upload-os) started on port " + Grasscutter.getConfig().UploadLogPort);
} }
private Map<String, String> parseQueryString(String qs) { private Map<String, String> parseQueryString(String qs) {
Map<String, String> result = new HashMap<>(); Map<String, String> result = new HashMap<>();
if (qs == null) if (qs == null) {
return result; return result;
}
int last = 0, next, l = qs.length(); int last = 0, next, l = qs.length();
while (last < l) { while (last < l) {
next = qs.indexOf('&', last); next = qs.indexOf('&', last);
if (next == -1) if (next == -1) {
next = l; next = l;
}
if (next > last) { if (next > last) {
int eqPos = qs.indexOf('=', last); int eqPos = qs.indexOf('=', last);
try { try {
if (eqPos < 0 || eqPos > next) if (eqPos < 0 || eqPos > next) {
result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), "");
else } else {
result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8"));
}
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java
} }
@ -464,4 +475,15 @@ public final class DispatchServer {
} }
return result; return result;
} }
public static class RegionData {
QueryCurrRegionHttpRsp parsedRegionQuery;
String Base64;
public RegionData(QueryCurrRegionHttpRsp prq, String b64) {
this.parsedRegionQuery = prq;
this.Base64 = b64;
}
}
} }

View File

@ -7,7 +7,7 @@ public class ComboTokenReqJson {
public String device; public String device;
public String sign; public String sign;
public class LoginTokenData { public static class LoginTokenData {
public String uid; public String uid;
public String token; public String token;
public boolean guest; public boolean guest;

View File

@ -5,7 +5,7 @@ public class ComboTokenResJson {
public int retcode; public int retcode;
public LoginData data = new LoginData(); public LoginData data = new LoginData();
public class LoginData { public static class LoginData {
public int account_type = 1; public int account_type = 1;
public boolean heartbeat; public boolean heartbeat;
public String combo_id; public String combo_id;

View File

@ -5,7 +5,7 @@ public class LoginResultJson {
public int retcode; public int retcode;
public VerifyData data = new VerifyData(); public VerifyData data = new VerifyData();
public class VerifyData { public static class VerifyData {
public VerifyAccountData account = new VerifyAccountData(); public VerifyAccountData account = new VerifyAccountData();
public boolean device_grant_required = false; public boolean device_grant_required = false;
public String realname_operation = "NONE"; public String realname_operation = "NONE";
@ -13,7 +13,7 @@ public class LoginResultJson {
public boolean safe_mobile_required = false; public boolean safe_mobile_required = false;
} }
public class VerifyAccountData { public static class VerifyAccountData {
public String uid; public String uid;
public String name = ""; public String name = "";
public String email; public String email;

View File

@ -87,7 +87,7 @@ public class GameServerPacketHandler {
} }
// Log unhandled packets // Log unhandled packets
if (Grasscutter.getConfig().LOG_PACKETS) { if (Grasscutter.getConfig().getGameServerOptions().LOG_PACKETS) {
//Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode)); //Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode));
} }
} }

View File

@ -165,7 +165,7 @@ public class GameSession extends MihoyoKcpChannel {
byte[] data = genshinPacket.build(); byte[] data = genshinPacket.build();
// Log // Log
if (Grasscutter.getConfig().LOG_PACKETS) { if (Grasscutter.getConfig().getGameServerOptions().LOG_PACKETS) {
logPacket(genshinPacket); logPacket(genshinPacket);
} }
@ -225,7 +225,7 @@ public class GameSession extends MihoyoKcpChannel {
} }
// Log packet // Log packet
if (Grasscutter.getConfig().LOG_PACKETS) { if (Grasscutter.getConfig().getGameServerOptions().LOG_PACKETS) {
Grasscutter.getLogger().info("RECV: " + PacketOpcodesUtil.getOpcodeName(opcode) + " (" + opcode + ")"); Grasscutter.getLogger().info("RECV: " + PacketOpcodesUtil.getOpcodeName(opcode) + " (" + opcode + ")");
System.out.println(Utils.bytesToHex(payload)); System.out.println(Utils.bytesToHex(payload));
} }

View File

@ -31,8 +31,11 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
// Locations // Locations
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
session.send(new PacketScenePlayerLocationNotify(session.getPlayer())); session.send(new PacketScenePlayerLocationNotify(session.getPlayer().getScene()));
session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld()));
// Reset timer for sending player locations
session.getPlayer().resetSendPlayerLocTime();
} }
} }

View File

@ -35,15 +35,15 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Has character // Has character
boolean doesPlayerExist = false; boolean doesPlayerExist = false;
if (account.getPlayerId() > 0) { if (account.getPlayerUid() > 0) {
// Set flag for player existing // Set flag for player existing
doesPlayerExist = DatabaseHelper.checkPlayerExists(account.getPlayerId()); doesPlayerExist = DatabaseHelper.checkPlayerExists(account.getPlayerUid());
} }
// Set reserve player id if account doesnt exist // Set reserve player id if account doesnt exist
if (!doesPlayerExist) { if (!doesPlayerExist) {
int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerId()); int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerUid());
if (id != session.getAccount().getPlayerId()) { if (id != session.getAccount().getPlayerUid()) {
session.getAccount().setPlayerId(id); session.getAccount().setPlayerId(id);
session.getAccount().save(); session.getAccount().save();
} }

View File

@ -30,7 +30,7 @@ public class HandlerPlayerLoginReq extends PacketHandler {
} }
// Load character from db // Load character from db
GenshinPlayer player = DatabaseHelper.getPlayerById(session.getAccount().getPlayerId()); GenshinPlayer player = DatabaseHelper.getPlayerById(session.getAccount().getPlayerUid());
if (player == null) { if (player == null) {
// Send packets // Send packets

View File

@ -1,11 +1,15 @@
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.custom.ScenePointEntry;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq; import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq;
import emu.grasscutter.net.proto.SceneTransToPointRspOuterClass.SceneTransToPointRsp;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSceneTransToPointRsp; import emu.grasscutter.server.packet.send.PacketSceneTransToPointRsp;
import emu.grasscutter.utils.Position;
@Opcodes(PacketOpcodes.SceneTransToPointReq) @Opcodes(PacketOpcodes.SceneTransToPointReq)
public class HandlerSceneTransToPointReq extends PacketHandler { public class HandlerSceneTransToPointReq extends PacketHandler {
@ -13,7 +17,20 @@ public class HandlerSceneTransToPointReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
SceneTransToPointReq req = SceneTransToPointReq.parseFrom(payload); SceneTransToPointReq req = SceneTransToPointReq.parseFrom(payload);
String code = req.getSceneId() + "_" + req.getPointId();
ScenePointEntry scenePointEntry = GenshinData.getScenePointEntries().get(code);
if (scenePointEntry != null) {
float x = scenePointEntry.getPointData().getTranPos().getX();
float y = scenePointEntry.getPointData().getTranPos().getY();
float z = scenePointEntry.getPointData().getTranPos().getZ();
session.getPlayer().getWorld().transferPlayerToScene(session.getPlayer(), req.getSceneId(), new Position(x, y, z));
session.send(new PacketSceneTransToPointRsp(session.getPlayer(), req.getPointId(), req.getSceneId())); session.send(new PacketSceneTransToPointRsp(session.getPlayer(), req.getPointId(), req.getSceneId()));
} else {
session.send(new PacketSceneTransToPointRsp());
}
} }
} }

View File

@ -3,6 +3,7 @@ package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SetEntityClientDataNotifyOuterClass.SetEntityClientDataNotify;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
@ -16,8 +17,11 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler {
return; return;
} }
// Make sure packet is a valid proto before replaying it to the other players
SetEntityClientDataNotify notif = SetEntityClientDataNotify.parseFrom(payload);
GenshinPacket packet = new GenshinPacket(PacketOpcodes.SetEntityClientDataNotify, true); GenshinPacket packet = new GenshinPacket(PacketOpcodes.SetEntityClientDataNotify, true);
packet.setData(payload); packet.setData(notif);
session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), packet); session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), packet);
} }

View File

@ -43,7 +43,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
try { try {
// Save to db // Save to db
DatabaseHelper.createPlayer(player, session.getAccount().getPlayerId()); DatabaseHelper.createPlayer(player, session.getAccount().getPlayerUid());
// Create avatar // Create avatar
if (player.getAvatars().getAvatarCount() == 0) { if (player.getAvatars().getAvatarCount() == 0) {

View File

@ -8,7 +8,7 @@ import emu.grasscutter.net.proto.AbilityChangeNotifyOuterClass.AbilityChangeNoti
public class PacketAbilityChangeNotify extends GenshinPacket { public class PacketAbilityChangeNotify extends GenshinPacket {
public PacketAbilityChangeNotify(EntityAvatar entity) { public PacketAbilityChangeNotify(EntityAvatar entity) {
super(PacketOpcodes.AbilityChangeNotify); super(PacketOpcodes.AbilityChangeNotify, true);
AbilityChangeNotify proto = AbilityChangeNotify.newBuilder() AbilityChangeNotify proto = AbilityChangeNotify.newBuilder()
.setEntityId(entity.getId()) .setEntityId(entity.getId())

View File

@ -23,7 +23,6 @@ public class PacketGetPlayerFriendListRsp extends GenshinPacket {
.setWorldLevel(0) .setWorldLevel(0)
.setSignature("") .setSignature("")
.setLastActiveTime((int) (System.currentTimeMillis() / 1000f)) .setLastActiveTime((int) (System.currentTimeMillis() / 1000f))
.setIsMpModeAvailable(true)
.setNameCardId(210001) .setNameCardId(210001)
.setOnlineState(FriendOnlineState.FRIEND_ONLINE) .setOnlineState(FriendOnlineState.FRIEND_ONLINE)
.setParam(1) .setParam(1)

View File

@ -16,7 +16,7 @@ public class PacketGetPlayerTokenRsp extends GenshinPacket {
this.setUseDispatchKey(true); this.setUseDispatchKey(true);
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder() GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
.setPlayerUid(session.getAccount().getPlayerId()) .setPlayerUid(session.getAccount().getPlayerUid())
.setAccountToken(session.getAccount().getToken()) .setAccountToken(session.getAccount().getToken())
.setAccountType(1) .setAccountType(1)
.setIsProficientPlayer(doesPlayerExist) // Not sure where this goes .setIsProficientPlayer(doesPlayerExist) // Not sure where this goes

View File

@ -52,7 +52,7 @@ public class PacketPlayerEnterSceneNotify extends GenshinPacket {
.setSceneId(newScene) .setSceneId(newScene)
.setPos(newPos.toProto()) .setPos(newPos.toProto())
.setSceneBeginTime(System.currentTimeMillis()) .setSceneBeginTime(System.currentTimeMillis())
.setType(EnterType.EnterSelf) .setType(type)
.setTargetUid(target.getUid()) .setTargetUid(target.getUid())
.setEnterSceneToken(player.getEnterSceneToken()) .setEnterSceneToken(player.getEnterSceneToken())
.setWorldLevel(target.getWorld().getWorldLevel()) .setWorldLevel(target.getWorld().getWorldLevel())

View File

@ -1,20 +1,60 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import com.google.protobuf.ByteString;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PlayerLoginRspOuterClass.PlayerLoginRsp; import emu.grasscutter.net.proto.PlayerLoginRspOuterClass.PlayerLoginRsp;
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass;
import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo; import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.utils.FileUtils;
import java.io.File;
import java.net.URL;
import java.util.Base64;
public class PacketPlayerLoginRsp extends GenshinPacket { public class PacketPlayerLoginRsp extends GenshinPacket {
private static QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp regionCache;
public PacketPlayerLoginRsp(GameSession session) { public PacketPlayerLoginRsp(GameSession session) {
super(PacketOpcodes.PlayerLoginRsp, 1); super(PacketOpcodes.PlayerLoginRsp, 1);
this.setUseDispatchKey(true); this.setUseDispatchKey(true);
RegionInfo info = Grasscutter.getDispatchServer().getCurrRegion().getRegionInfo(); RegionInfo info;
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
if (regionCache == null) {
try {
File file = new File(Grasscutter.getConfig().DATA_FOLDER + "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()
.setIp((Grasscutter.getConfig().getGameServerOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getGameServerOptions().Ip : Grasscutter.getConfig().getGameServerOptions().PublicIp))
.setPort(Grasscutter.getConfig().getGameServerOptions().PublicPort != 0 ? Grasscutter.getConfig().getGameServerOptions().PublicPort : Grasscutter.getConfig().getGameServerOptions().Port)
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
.build();
regionCache = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
} catch (Exception e) {
Grasscutter.getLogger().error("Error while initializing region cache!", e);
}
}
info = regionCache.getRegionInfo();
} else {
info = Grasscutter.getDispatchServer().getCurrRegion().getRegionInfo();
}
PlayerLoginRsp p = PlayerLoginRsp.newBuilder() PlayerLoginRsp p = PlayerLoginRsp.newBuilder()
.setIsUseAbilityHash(true) // true .setIsUseAbilityHash(true) // true

View File

@ -19,7 +19,7 @@ public class PacketPlayerStoreNotify extends GenshinPacket {
PlayerStoreNotify.Builder p = PlayerStoreNotify.newBuilder() PlayerStoreNotify.Builder p = PlayerStoreNotify.newBuilder()
.setStoreType(StoreType.StorePack) .setStoreType(StoreType.StorePack)
.setWeightLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitAll); .setWeightLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitAll);
for (GenshinItem item : player.getInventory()) { for (GenshinItem item : player.getInventory()) {
Item itemProto = item.toProto(); Item itemProto = item.toProto();

View File

@ -1,6 +1,6 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Config.ServerOptions; import emu.grasscutter.Config.GameServerOptions;
import emu.grasscutter.GenshinConstants; import emu.grasscutter.GenshinConstants;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
@ -14,7 +14,7 @@ public class PacketPullRecentChatRsp extends GenshinPacket {
public PacketPullRecentChatRsp(GenshinPlayer player) { public PacketPullRecentChatRsp(GenshinPlayer player) {
super(PacketOpcodes.PullRecentChatRsp); super(PacketOpcodes.PullRecentChatRsp);
ServerOptions serverOptions = Grasscutter.getConfig().getServerOptions(); GameServerOptions serverOptions = Grasscutter.getConfig().getGameServerOptions();
PullRecentChatRsp.Builder proto = PullRecentChatRsp.newBuilder(); PullRecentChatRsp.Builder proto = PullRecentChatRsp.newBuilder();
if (serverOptions.WelcomeEmotes != null && serverOptions.WelcomeEmotes.length > 0) { if (serverOptions.WelcomeEmotes != null && serverOptions.WelcomeEmotes.length > 0) {
@ -33,7 +33,7 @@ public class PacketPullRecentChatRsp extends GenshinPacket {
.setTime((int) (System.currentTimeMillis() / 1000)) .setTime((int) (System.currentTimeMillis() / 1000))
.setUid(GenshinConstants.SERVER_CONSOLE_UID) .setUid(GenshinConstants.SERVER_CONSOLE_UID)
.setToUid(player.getUid()) .setToUid(player.getUid())
.setText(Grasscutter.getConfig().getServerOptions().WelcomeMotd) .setText(Grasscutter.getConfig().getGameServerOptions().WelcomeMotd)
.build(); .build();
proto.addChatInfo(welcomeMotd); proto.addChatInfo(welcomeMotd);

View File

@ -12,7 +12,7 @@ public class PacketSceneAreaWeatherNotify extends GenshinPacket {
super(PacketOpcodes.SceneAreaWeatherNotify); super(PacketOpcodes.SceneAreaWeatherNotify);
SceneAreaWeatherNotify proto = SceneAreaWeatherNotify.newBuilder() SceneAreaWeatherNotify proto = SceneAreaWeatherNotify.newBuilder()
.setWeatherAreaId(1) .setWeatherAreaId(player.getScene().getWeather())
.setClimateType(player.getScene().getClimate().getValue()) .setClimateType(player.getScene().getClimate().getValue())
.build(); .build();

View File

@ -1,19 +1,20 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ScenePlayerLocationNotifyOuterClass.ScenePlayerLocationNotify; import emu.grasscutter.net.proto.ScenePlayerLocationNotifyOuterClass.ScenePlayerLocationNotify;
public class PacketScenePlayerLocationNotify extends GenshinPacket { public class PacketScenePlayerLocationNotify extends GenshinPacket {
public PacketScenePlayerLocationNotify(GenshinPlayer player) { public PacketScenePlayerLocationNotify(GenshinScene scene) {
super(PacketOpcodes.ScenePlayerLocationNotify); super(PacketOpcodes.ScenePlayerLocationNotify);
ScenePlayerLocationNotify.Builder proto = ScenePlayerLocationNotify.newBuilder() ScenePlayerLocationNotify.Builder proto = ScenePlayerLocationNotify.newBuilder()
.setSceneId(player.getSceneId()); .setSceneId(scene.getId());
for (GenshinPlayer p : player.getWorld().getPlayers()) { for (GenshinPlayer p : scene.getPlayers()) {
proto.addPlayerLocList(p.getPlayerLocationInfo()); proto.addPlayerLocList(p.getPlayerLocationInfo());
} }

View File

@ -13,17 +13,6 @@ public class PacketSceneTransToPointRsp extends GenshinPacket {
public PacketSceneTransToPointRsp(GenshinPlayer player, int pointId, int sceneId) { public PacketSceneTransToPointRsp(GenshinPlayer player, int pointId, int sceneId) {
super(PacketOpcodes.SceneTransToPointRsp); super(PacketOpcodes.SceneTransToPointRsp);
String code = sceneId + "_" + pointId;
ScenePointEntry scenePointEntry = GenshinData.getScenePointEntries().get(code);
float x = scenePointEntry.getPointData().getTranPos().getX();
float y = scenePointEntry.getPointData().getTranPos().getY();
float z = scenePointEntry.getPointData().getTranPos().getZ();
player.getPos().set(new Position(x, y, z));
player.getWorld().forceTransferPlayerToScene(player, sceneId, player.getPos());
SceneTransToPointRsp proto = SceneTransToPointRsp.newBuilder() SceneTransToPointRsp proto = SceneTransToPointRsp.newBuilder()
.setRetcode(0) .setRetcode(0)
.setPointId(pointId) .setPointId(pointId)
@ -32,4 +21,14 @@ public class PacketSceneTransToPointRsp extends GenshinPacket {
this.setData(proto); this.setData(proto);
} }
public PacketSceneTransToPointRsp() {
super(PacketOpcodes.SceneTransToPointRsp);
SceneTransToPointRsp proto = SceneTransToPointRsp.newBuilder()
.setRetcode(1) // Internal server error
.build();
this.setData(proto);
}
} }

View File

@ -12,8 +12,8 @@ public class PacketSceneUnlockInfoNotify extends GenshinPacket {
SceneUnlockInfoNotify proto = SceneUnlockInfoNotify.newBuilder() SceneUnlockInfoNotify proto = SceneUnlockInfoNotify.newBuilder()
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(1)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(1))
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(3)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(3).addSceneTagIdList(102).addSceneTagIdList(113).addSceneTagIdList(117))
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(4)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(4).addSceneTagIdList(106).addSceneTagIdList(109))
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(5)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(5))
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(6)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(6))
.addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(7)) .addUnlockInfos(SceneUnlockInfo.newBuilder().setSceneId(7))

View File

@ -13,11 +13,11 @@ public class PacketStoreWeightLimitNotify extends GenshinPacket {
StoreWeightLimitNotify p = StoreWeightLimitNotify.newBuilder() StoreWeightLimitNotify p = StoreWeightLimitNotify.newBuilder()
.setStoreType(StoreType.StorePack) .setStoreType(StoreType.StorePack)
.setWeightLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitAll) .setWeightLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitAll)
.setWeaponCountLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitWeapon) .setWeaponCountLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitWeapon)
.setReliquaryCountLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitRelic) .setReliquaryCountLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitRelic)
.setMaterialCountLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitMaterial) .setMaterialCountLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitMaterial)
.setFurnitureCountLimit(Grasscutter.getConfig().getServerOptions().InventoryLimitFurniture) .setFurnitureCountLimit(Grasscutter.getConfig().getGameServerOptions().InventoryLimitFurniture)
.build(); .build();
this.setData(p); this.setData(p);

View File

@ -14,7 +14,7 @@ public class PacketWorldPlayerLocationNotify extends GenshinPacket {
WorldPlayerLocationNotify.Builder proto = WorldPlayerLocationNotify.newBuilder(); WorldPlayerLocationNotify.Builder proto = WorldPlayerLocationNotify.newBuilder();
for (GenshinPlayer p : world.getPlayers()) { for (GenshinPlayer p : world.getPlayers()) {
proto.addPlayerLocList(p.getPlayerLocationInfo()); proto.addPlayerLocList(p.getWorldPlayerLocationInfo());
} }
this.setData(proto); this.setData(proto);

View File

@ -1,8 +1,13 @@
package emu.grasscutter.tools; package emu.grasscutter.tools;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
@ -30,13 +35,13 @@ public final class Tools {
ResourceLoader.loadResources(); ResourceLoader.loadResources();
Map<Long, String> map; Map<Long, String> map;
try (FileReader fileReader = new FileReader(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMapEN.json"))) { try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMapEN.json")), StandardCharsets.UTF_8)) {
map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType()); map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
} }
List<Integer> list; List<Integer> list;
String fileName = "./GM Handbook.txt"; String fileName = "./GM Handbook.txt";
try (FileWriter fileWriter = new FileWriter(fileName); PrintWriter writer = new PrintWriter(fileWriter)) { try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();

View File

@ -158,7 +158,7 @@ public final class Utils {
// Check for GenshinData. // Check for GenshinData.
if(!fileExists(resourcesFolder + "BinOutput") || if(!fileExists(resourcesFolder + "BinOutput") ||
!fileExists(resourcesFolder + "ExcelBinOutput")) { !fileExists(resourcesFolder + "ExcelBinOutput")) {
logger.info("Place a copy of 'GenshinData' in the resources folder."); logger.info("Place a copy of 'BinOutput' and 'ExcelBinOutput' in the resources folder.");
exit = true; exit = true;
} }

View File

@ -4,8 +4,19 @@
<pattern>[%d{HH:mm:ss}] [%highlight(%level)] %msg%n</pattern> <pattern>[%d{HH:mm:ss}] [%highlight(%level)] %msg%n</pattern>
</encoder> </encoder>
</appender> </appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/latest.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/log.%d{yyyy-MM-dd}_%d{HH}.log.tar.gz</fileNamePattern>
<maxHistory>24</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss'Z'} - %m%n</pattern>
</encoder>
</appender>
<logger name="org.reflections" level="OFF"/> <logger name="org.reflections" level="OFF"/>
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root> </root>
</Configuration> </Configuration>

164
start.cmd Normal file
View File

@ -0,0 +1,164 @@
@rem
@rem Copyright (C) 2002-2022 MlgmXyysd All Rights Reserved.
@rem
@if "%DEBUG%" == "" echo off
pushd %~dp0
set CUR_PATH=%~dp0
title Grasscutter
call :LOG [INFO] Welcome to Grasscutter
call :LOG [INFO] To proper exit this console, use [Ctrl + C] and enter N not Y.
call :LOG [INFO]
call :LOG [INFO] Initializing...
set CONFIG=start_config
set JAVA_PATH=DO_NOT_CHECK_PATH
set MITMDUMP_PATH=DO_NOT_CHECK_PATH
set MONGODB_PATH=DO_NOT_CHECK_PATH
set SERVER_JAR_PATH=%CUR_PATH%
set DATABASE_STORAGE_PATH=%CUR_PATH%resources\Database
set SERVER_JAR_NAME=grasscutter.jar
set PROXY_SCRIPT_NAME=proxy
if exist "%CUR_PATH%%CONFIG%.cmd" (
call "%CUR_PATH%%CONFIG%.cmd" >nul 2>nul
)
if not "%JAVA_PATH%" == "DO_NOT_CHECK_PATH" (
if not exist "%JAVA_PATH%java.exe" (
call :LOG [ERROR] Java not found.
goto :EXIT
)
) else set JAVA_PATH=
if not exist "%SERVER_PATH%grasscutter.jar" (
call :LOG [ERROR] Server jar not found.
goto :EXIT
)
@rem mitmproxy not found, server only
if not "%MITMDUMP_PATH%" == "DO_NOT_CHECK_PATH" (
if not exist "%MITMDUMP_PATH%mitmdump.exe" (
call :LOG [WARN] mitmdump not found, server only mode.
goto :SERVER
)
) else set MITMDUMP_PATH=
@rem proxy script not found, server only
if not exist "%PROXY_SCRIPT_NAME%.py" (
if not exist "%PROXY_SCRIPT_NAME%.pyc" (
call :LOG [WARN] Missing proxy script or compiled proxy script, server only mode.
goto :SERVER
) else set PROXY_SCRIPT_NAME=%PROXY_SCRIPT_NAME%.pyc
) else set PROXY_SCRIPT_NAME=%PROXY_SCRIPT_NAME%.py
:PROXY
@rem UAC Administrator privileges
>nul 2>&1 reg query "HKU\S-1-5-19" || (
call :LOG [WARN] Currently running with non Administrator privileges, raising...
echo set UAC = CreateObject^("Shell.Application"^) > "%temp%\UAC.vbs"
echo UAC.ShellExecute "%~f0","%1","","runas",1 >> "%temp%\UAC.vbs"
"%temp%\UAC.vbs"
del /f /q "%temp%\UAC.vbs" >nul 2>nul
exit /b
)
call :LOG [INFO] Starting proxy daemon...
set PROXY=true
@rem Store original proxy settings
for /f "tokens=2*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable 2^>nul') do set "ORIG_PROXY_ENABLE=%%b"
for /f "tokens=2*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer 2^>nul') do set "ORIG_PROXY_SERVER=%%b"
@rem TODO: External proxy when ORIG_PROXY_ENABLE == 0x1
echo set ws = createobject("wscript.shell") > "%temp%\proxy.vbs"
if not "%MITMDUMP_PATH%" == "" (
echo ws.currentdirectory = "%MITMDUMP_PATH%" >> "%temp%\proxy.vbs"
)
echo ws.run "cmd /c mitmdump.exe -s "^&chr(34)^&"%PROXY_SCRIPT_NAME%"^&chr(34)^&" -k",0 >> "%temp%\proxy.vbs"
"%temp%\proxy.vbs"
del /f /q "%temp%\proxy.vbs" >nul 2>nul
@rem CA certificate for HTTPS scheme
call :LOG [INFO] Waiting for CA certificate generation...
set CA_CERT_FILE="%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer"
set /a TIMEOUT_COUNT=0
:CERT_CA_CHECK
if not exist %CA_CERT_FILE% (
timeout /t 1 >nul 2>nul
set /a TIMEOUT_COUNT+=1
goto CERT_CA_CHECK
)
:EXTRA_TIMEOUT
if %TIMEOUT_COUNT% LEQ 2 (
timeout /t 1 >nul 2>nul
set /a TIMEOUT_COUNT+=1
goto EXTRA_TIMEOUT
)
call :LOG [INFO] Adding CA certificate to store...
certutil -addstore root %CA_CERT_FILE% >nul 2>nul
call :LOG [INFO] Setting up network proxy...
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8080" /f >nul 2>nul
:SERVER
if not "%MONGODB_PATH%" == "DO_NOT_CHECK_PATH" (
if not exist "%MONGODB_PATH%mongod.exe" (
call :LOG [WARN] MongoDB daemon not found, server only mode.
goto :GAME
)
) else set MONGODB_PATH=
call :LOG [INFO] Starting MongoDB daemon...
set DATABASE=true
mkdir "%DATABASE_STORAGE_PATH%" >nul 2>nul
echo set ws = createobject("wscript.shell") > "%temp%\db.vbs"
if not "%MONGODB_PATH%" == "" (
echo ws.currentdirectory = "%MONGODB_PATH%" >> "%temp%\db.vbs"
)
echo ws.run "cmd /c mongod.exe --dbpath "^&chr(34)^&"%DATABASE_STORAGE_PATH%"^&chr(34)^&"",0 >> "%temp%\db.vbs"
"%temp%\db.vbs"
del /f /q "%temp%\db.vbs" >nul 2>nul
:GAME
call :LOG [INFO] Starting server...
"%JAVA_PATH%java.exe" -jar "%SERVER_PATH%grasscutter.jar"
call :LOG [INFO] Server stopped
:EXIT
if "%DATABASE%" == "" (
call :LOG [INFO] MongoDB daemon not started, no need to clean up.
) else (
call :LOG [INFO] Shutting down MongoDB daemon...
taskkill /t /f /im mongod.exe >nul 2>nul
)
if "%PROXY%" == "" (
call :LOG [INFO] Proxy daemon not started, no need to clean up.
) else (
call :LOG [INFO] Restoring network settings...
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d "%ORIG_PROXY_ENABLE%" /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "%ORIG_PROXY_SERVER%" /f >nul 2>nul
call :LOG [INFO] Shutting down proxy daemon...
taskkill /t /f /im mitmdump.exe >nul 2>nul
call :LOG [INFO] Removing CA certificate...
for /F "tokens=2" %%s in ('certutil -dump %CA_CERT_FILE% ^| findstr ^"^sha1^"') do (
set SERIAL=%%s
)
certutil -delstore root %SERIAL% >nul 2>nul
)
call :LOG [INFO] See you again :)
goto :EOF
:LOG
echo [%time:~0,8%] %*

25
start_config.cmd Normal file
View File

@ -0,0 +1,25 @@
@rem
@rem Copyright (C) 2002-2022 MlgmXyysd All Rights Reserved.
@rem
@echo off
pushd %~dp0
set CUR_PATH=%~dp0
@rem This will not work if your java or mitmproxy is in a different location, plugin as necessary
@rem this just saves you from changing your PATH
@rem Executable Path
@rem Note: Fill DO_NOT_CHECK_PATH if you need to run it from PATH
@rem without detecting whether the executable file exists
set JAVA_PATH=C:\Program Files\Java\jdk1.8.0_202\bin\
set MITMDUMP_PATH=%CUR_PATH%
set MONGODB_PATH=%CUR_PATH%
@rem Utility Path
set SERVER_JAR_PATH=%CUR_PATH%
set DATABASE_STORAGE_PATH=%CUR_PATH%resources\Database
@rem Utility Name
set SERVER_JAR_NAME=grasscutter.jar
set PROXY_SCRIPT_NAME=proxy