mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-22 21:56:09 +00:00
Merge branch 'development' of https://github.com/Melledy/Grasscutter
This commit is contained in:
commit
cb104ac79a
68
proxy.py
68
proxy.py
@ -21,43 +21,45 @@
|
||||
##
|
||||
|
||||
from mitmproxy import http
|
||||
from proxy_config import REMOTE_HOST
|
||||
|
||||
class MlgmXyysd_Genshin_Impact_Proxy:
|
||||
|
||||
LIST_DOMAINS = [
|
||||
"api-os-takumi.mihoyo.com",
|
||||
"hk4e-api-os-static.mihoyo.com",
|
||||
"hk4e-sdk-os.mihoyo.com",
|
||||
"dispatchosglobal.yuanshen.com",
|
||||
"osusadispatch.yuanshen.com",
|
||||
"account.mihoyo.com",
|
||||
"log-upload-os.mihoyo.com",
|
||||
"dispatchcntest.yuanshen.com",
|
||||
"devlog-upload.mihoyo.com",
|
||||
"webstatic.mihoyo.com",
|
||||
"log-upload.mihoyo.com",
|
||||
"hk4e-sdk.mihoyo.com",
|
||||
"api-beta-sdk.mihoyo.com",
|
||||
"api-beta-sdk-os.mihoyo.com",
|
||||
"cnbeta01dispatch.yuanshen.com",
|
||||
"dispatchcnglobal.yuanshen.com",
|
||||
"cnbeta02dispatch.yuanshen.com",
|
||||
"sdk-os-static.mihoyo.com",
|
||||
"webstatic-sea.mihoyo.com",
|
||||
"webstatic-sea.hoyoverse.com",
|
||||
"hk4e-sdk-os-static.hoyoverse.com",
|
||||
"sdk-os-static.hoyoverse.com",
|
||||
"api-account-os.hoyoverse.com",
|
||||
"hk4e-sdk-os.hoyoverse.com",
|
||||
"overseauspider.yuanshen.com",
|
||||
"gameapi-account.mihoyo.com",
|
||||
"minor-api.mihoyo.com",
|
||||
"public-data-api.mihoyo.com",
|
||||
"uspider.yuanshen.com",
|
||||
"sdk-static.mihoyo.com"
|
||||
]
|
||||
|
||||
def request(self, flow: http.HTTPFlow) -> None:
|
||||
|
||||
# This can also be replaced with another IP address.
|
||||
REMOTE_HOST = "localhost"
|
||||
|
||||
LIST_DOMAINS = [
|
||||
"api-os-takumi.mihoyo.com",
|
||||
"hk4e-api-os-static.mihoyo.com",
|
||||
"hk4e-sdk-os.mihoyo.com",
|
||||
"dispatchosglobal.yuanshen.com",
|
||||
"osusadispatch.yuanshen.com",
|
||||
"account.mihoyo.com",
|
||||
"log-upload-os.mihoyo.com",
|
||||
"dispatchcntest.yuanshen.com",
|
||||
"devlog-upload.mihoyo.com",
|
||||
"webstatic.mihoyo.com",
|
||||
"log-upload.mihoyo.com",
|
||||
"hk4e-sdk.mihoyo.com",
|
||||
"api-beta-sdk.mihoyo.com",
|
||||
"api-beta-sdk-os.mihoyo.com",
|
||||
"cnbeta01dispatch.yuanshen.com",
|
||||
"dispatchcnglobal.yuanshen.com",
|
||||
"cnbeta02dispatch.yuanshen.com",
|
||||
"sdk-os-static.mihoyo.com",
|
||||
"webstatic-sea.mihoyo.com",
|
||||
"webstatic-sea.hoyoverse.com",
|
||||
"hk4e-sdk-os-static.hoyoverse.com",
|
||||
"sdk-os-static.hoyoverse.com",
|
||||
"api-account-os.hoyoverse.com",
|
||||
"hk4e-sdk-os.hoyoverse.com",
|
||||
"overseauspider.yuanshen.com"
|
||||
]
|
||||
|
||||
if flow.request.host in LIST_DOMAINS:
|
||||
if flow.request.host in self.LIST_DOMAINS:
|
||||
flow.request.host = REMOTE_HOST
|
||||
|
||||
addons = [
|
||||
|
2
proxy_config.py
Normal file
2
proxy_config.py
Normal file
@ -0,0 +1,2 @@
|
||||
# This can also be replaced with another IP address.
|
||||
REMOTE_HOST = "localhost"
|
@ -16,10 +16,12 @@ import emu.grasscutter.game.entity.EntityMonster;
|
||||
import emu.grasscutter.game.inventory.GenshinItem;
|
||||
import emu.grasscutter.game.inventory.Inventory;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.props.ClimateType;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
|
||||
@ -455,32 +457,111 @@ public final class PlayerCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(label = "sethealth", aliases = {"sethp"},
|
||||
usage = "sethealth <hp>", execution = Command.Execution.PLAYER, description = "Sets your health to the specified value",
|
||||
permission = "player.sethealth")
|
||||
public static class SetHealthCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@Command(label = "setstats", aliases = {"stats"},
|
||||
usage = "Usage: setstats|stats <hp|def|atk|em|er|crate|cdmg> <value>", execution = Command.Execution.PLAYER)
|
||||
public static class SetStatsCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(GenshinPlayer player, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(null, "Usage: sethealth <hp>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int health = Integer.parseInt(args.get(0));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
if (entity == null)
|
||||
String stat = args.get(0);
|
||||
switch(stat){
|
||||
default:
|
||||
CommandHandler.sendMessage(player, "Usage: setstats|stats <hp|def|atk|em|er|crate|cdmg> <value>");
|
||||
return;
|
||||
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
|
||||
entity.getWorld().broadcastPacket(
|
||||
new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||
player.dropMessage("Health set to " + health + ".");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid health value.");
|
||||
case "hp":
|
||||
try {
|
||||
int health = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||
player.dropMessage("HP set to " + health + ".");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid HP value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "def":
|
||||
try {
|
||||
int def = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, def);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE));
|
||||
player.dropMessage("DEF set to " + def + ".");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid DEF value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "atk":
|
||||
try {
|
||||
int atk = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, atk);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_ATTACK));
|
||||
player.dropMessage("ATK set to " + atk + ".");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid ATK value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "em":
|
||||
try {
|
||||
int em = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_ELEMENT_MASTERY, em);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_ELEMENT_MASTERY));
|
||||
player.dropMessage("Elemental Mastery set to " + em + ".");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid EM value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "er":
|
||||
try {
|
||||
float er = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
float erecharge = er / 10000;
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, erecharge);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY));
|
||||
float iger = erecharge * 100;
|
||||
player.dropMessage("Energy recharge set to " + iger + "%.");
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid ER value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "crate":
|
||||
try {
|
||||
float cr = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
float crate = cr / 10000;
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL, crate);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL));
|
||||
float igcrate = crate * 100;
|
||||
player.dropMessage("Crit Rate set to " + igcrate + "%.");
|
||||
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid Crit Rate value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "cdmg":
|
||||
try {
|
||||
float cdmg = Integer.parseInt(args.get(1));
|
||||
EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
|
||||
float cdamage = cdmg / 10000;
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, cdamage);
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL_HURT));
|
||||
float igcdmg = cdamage * 100;
|
||||
player.dropMessage("Crit DMG set to " + igcdmg + "%");
|
||||
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, "Invalid Crit DMG value.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(label = "setworldlevel", aliases = {"setworldlvl"}, usage = "setworldlevel <level>",
|
||||
@ -573,6 +654,42 @@ public final class PlayerCommands {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(label = "pos",
|
||||
usage = "Usage: pos", description = "Get coordinates.",
|
||||
execution = Command.Execution.PLAYER)
|
||||
public static class CordCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(GenshinPlayer player, List<String> args) {
|
||||
player.dropMessage(String.format("Coord: %.3f, %.3f, %.3f", player.getPos().getX(), player.getPos().getY(), player.getPos().getZ()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(label = "weather", aliases = {"weather", "w"},
|
||||
usage = "weather <weather id>", description = "Changes the weather.",
|
||||
execution = Command.Execution.PLAYER, permission = "player.weather"
|
||||
)
|
||||
public static class ChangeWeatherCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(GenshinPlayer player, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(player, "Usage: weather <weather id>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int weatherId = Integer.parseInt(args.get(0));
|
||||
|
||||
ClimateType climate = ClimateType.getTypeByValue(weatherId);
|
||||
|
||||
player.getScene().setClimate(climate);
|
||||
player.getScene().broadcastPacket(new PacketSceneAreaWeatherNotify(player));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(player, "Invalid weather ID.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(label = "restart", usage = "Usage: restart", description = "Restarts the current session", execution = Command.Execution.PLAYER, permission = "player.restart")
|
||||
public static class RestartCommand implements CommandHandler {
|
||||
|
@ -38,6 +38,7 @@ import emu.grasscutter.server.packet.send.PacketAvatarAddNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarDataNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarGainCostumeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarGainFlycloakNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketClientAbilityInitFinishNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketCombatInvocationsNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
|
||||
@ -104,6 +105,7 @@ public class GenshinPlayer {
|
||||
@Transient private final Int2ObjectMap<CoopRequest> coopRequests;
|
||||
@Transient private final InvokeHandler<CombatInvokeEntry> combatInvokeHandler;
|
||||
@Transient private final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler;
|
||||
@Transient private final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler;
|
||||
|
||||
@Deprecated @SuppressWarnings({ "rawtypes", "unchecked" }) // Morphia only!
|
||||
public GenshinPlayer() {
|
||||
@ -126,6 +128,7 @@ public class GenshinPlayer {
|
||||
this.coopRequests = new Int2ObjectOpenHashMap<>();
|
||||
this.combatInvokeHandler = new InvokeHandler(PacketCombatInvocationsNotify.class);
|
||||
this.abilityInvokeHandler = new InvokeHandler(PacketAbilityInvocationsNotify.class);
|
||||
this.clientAbilityInitFinishHandler = new InvokeHandler(PacketClientAbilityInitFinishNotify.class);
|
||||
}
|
||||
|
||||
// On player creation
|
||||
@ -389,6 +392,10 @@ public class GenshinPlayer {
|
||||
return this.abilityInvokeHandler;
|
||||
}
|
||||
|
||||
public InvokeHandler<AbilityInvokeEntry> getClientAbilityInitFinishHandler() {
|
||||
return clientAbilityInitFinishHandler;
|
||||
}
|
||||
|
||||
public void setMpSetting(MpSettingType mpSetting) {
|
||||
this.mpSetting = mpSetting;
|
||||
}
|
||||
|
@ -226,18 +226,22 @@ public final class DispatchServer {
|
||||
Account account = DatabaseHelper.getAccountByName(requestData.account);
|
||||
|
||||
// Check if account exists, else create a new one.
|
||||
if (account == null && Grasscutter.getConfig().ServerOptions.AutomaticallyCreateAccounts) {
|
||||
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
||||
account = DatabaseHelper.createAccountWithId(requestData.account, 0);
|
||||
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
} else if (!Grasscutter.getConfig().ServerOptions.AutomaticallyCreateAccounts) {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = "Username not found.";
|
||||
if (account == null) {
|
||||
// Account doesnt exist, so we can either auto create it if the config value is set
|
||||
if (Grasscutter.getConfig().ServerOptions.AutomaticallyCreateAccounts) {
|
||||
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
||||
account = DatabaseHelper.createAccountWithId(requestData.account, 0);
|
||||
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
} else {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = "Username not found.";
|
||||
}
|
||||
} else {
|
||||
// Account was found, log the player in
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
|
@ -154,7 +154,7 @@ public final class GameServer extends MihoyoKcpServer {
|
||||
|
||||
public Account getAccountByName(String username) {
|
||||
Optional<GenshinPlayer> playerOpt = getPlayers().values().stream().filter(player -> player.getAccount().getUsername().equals(username)).findFirst();
|
||||
if (playerOpt.get() != null) {
|
||||
if (playerOpt.isPresent()) {
|
||||
return playerOpt.get().getAccount();
|
||||
}
|
||||
return DatabaseHelper.getAccountByName(username);
|
||||
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||
import emu.grasscutter.net.proto.ClientAbilityInitFinishNotifyOuterClass.ClientAbilityInitFinishNotify;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ClientAbilityInitFinishNotify)
|
||||
public class HandlerClientAbilityInitFinishNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ClientAbilityInitFinishNotify notif = ClientAbilityInitFinishNotify.parseFrom(payload);
|
||||
|
||||
for (AbilityInvokeEntry entry : notif.getInvokesList()) {
|
||||
session.getPlayer().getClientAbilityInitFinishHandler().addEntry(entry.getForwardType(), entry);
|
||||
}
|
||||
|
||||
if (notif.getInvokesList().size() > 0) {
|
||||
session.getPlayer().getClientAbilityInitFinishHandler().update(session.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.inventory.GenshinItem;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.NpcTalkReqOuterClass.NpcTalkReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketNpcTalkRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.NpcTalkReq)
|
||||
public class HandlerNpcTalkReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
NpcTalkReq req = NpcTalkReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
@ -10,7 +11,15 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
// Skip if there is no one to broadcast it too
|
||||
if (session.getPlayer().getScene().getPlayerCount() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
GenshinPacket packet = new GenshinPacket(PacketOpcodes.SetEntityClientDataNotify, true);
|
||||
packet.setData(payload);
|
||||
|
||||
session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), packet);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||
import emu.grasscutter.net.proto.ClientAbilityInitFinishNotifyOuterClass.ClientAbilityInitFinishNotify;
|
||||
|
||||
public class PacketClientAbilityInitFinishNotify extends GenshinPacket {
|
||||
|
||||
public PacketClientAbilityInitFinishNotify(List<AbilityInvokeEntry> entries) {
|
||||
super(PacketOpcodes.ClientAbilityInitFinishNotify, true);
|
||||
|
||||
int entityId = 0;
|
||||
|
||||
if (entries.size() > 0) {
|
||||
AbilityInvokeEntry entry = entries.get(0);
|
||||
entityId = entry.getEntityId();
|
||||
}
|
||||
|
||||
ClientAbilityInitFinishNotify proto = ClientAbilityInitFinishNotify.newBuilder()
|
||||
.setEntityId(entityId)
|
||||
.addAllInvokes(entries)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.GenshinPacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.NpcTalkRspOuterClass.NpcTalkRsp;
|
||||
|
||||
public class PacketNpcTalkRsp extends GenshinPacket {
|
||||
public PacketNpcTalkRsp(int npcEntityId, int curTalkId, int entityId) {
|
||||
super(PacketOpcodes.NpcTalkRsp);
|
||||
|
||||
NpcTalkRsp p = NpcTalkRsp.newBuilder()
|
||||
.setNpcEntityId(npcEntityId)
|
||||
.setCurTalkId(curTalkId)
|
||||
.setEntityId(entityId)
|
||||
.build();
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user