Commit dce13cf6 authored by Magix's avatar Magix Committed by GitHub
Browse files

Merge branch 'development' into plugin-system

parents 832c460a b6fedcf2
......@@ -197,8 +197,8 @@ public final class SetStatsCommand implements CommandHandler {
float eelec = Integer.parseInt(args.get(1));
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
float elec = eelec / 10000;
entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, elec);
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL_HURT));
entity.setFightProperty(FightProperty.FIGHT_PROP_ELEC_ADD_HURT, elec);
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_ELEC_ADD_HURT));
float igelec = elec * 100;
CommandHandler.sendMessage(sender, "Electro DMG Bonus set to " + igelec + "%");
} catch (NumberFormatException ignored) {
......
......@@ -2,6 +2,7 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.def.AvatarSkillDepotData;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar;
......@@ -21,8 +22,9 @@ public class TalentCommand implements CommandHandler {
return;
}
if (args.size() < 0 || args.size() < 1){
if (args.size() < 1){
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "Another way to set talent level: /talent <n or e or q> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return;
}
......@@ -31,6 +33,7 @@ public class TalentCommand implements CommandHandler {
switch (cmdSwitch) {
default:
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "Another way to set talent level: /talent <n or e or q> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return;
case "set":
......@@ -90,6 +93,45 @@ public class TalentCommand implements CommandHandler {
return;
}
break;
case "n": case "e": case "q":
try {
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
GenshinAvatar avatar = entity.getAvatar();
AvatarSkillDepotData SkillDepot = avatar.getData().getSkillDepot();
int skillId;
switch (cmdSwitch) {
default:
skillId = SkillDepot.getSkills().get(0);
break;
case "e":
skillId = SkillDepot.getSkills().get(1);
break;
case "q":
skillId = SkillDepot.getEnergySkill();
break;
}
int nextLevel = Integer.parseInt(args.get(1));
int currentLevel = avatar.getSkillLevelMap().get(skillId);
if (args.size() < 1){
CommandHandler.sendMessage(sender, "To set talent level: /talent <n or e or q> <value>");
return;
}
if (nextLevel > 16){
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
return;
}
// Upgrade skill
avatar.getSkillLevelMap().put(skillId, nextLevel);
avatar.save();
// Packet
sender.sendPacket(new PacketAvatarSkillChangeNotify(avatar, skillId, currentLevel, nextLevel));
sender.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, skillId, currentLevel, nextLevel));
CommandHandler.sendMessage(sender, "Set this talent to " + nextLevel + ".");
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid talent level.");
return;
}
break;
case "getid":
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
......
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.utils.Position;
import java.util.List;
@Command(label = "teleport", usage = "teleport <x> <y> <z>", aliases = {"tp"},
description = "Change the player's position.", permission = "player.teleport")
public class TelePortCommand 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() < 3){
CommandHandler.sendMessage(sender, "Usage: /tp <x> <y> <z> [scene id]");
return;
}
try {
float x = 0f;
float y = 0f;
float z = 0f;
if (args.get(0).contains("~")) {
if (args.get(0).equals("~")) {
x = sender.getPos().getX();
} else {
x = Float.parseFloat(args.get(0).replace("~", "")) + sender.getPos().getX();
}
} else {
x = Float.parseFloat(args.get(0));
}
if (args.get(1).contains("~")) {
if (args.get(1).equals("~")) {
y = sender.getPos().getY();
} else {
y = Float.parseFloat(args.get(1).replace("~", "")) + sender.getPos().getY();
}
} else {
y = Float.parseFloat(args.get(1));
}
if (args.get(2).contains("~")) {
if (args.get(2).equals("~")) {
z = sender.getPos().getZ();
} else {
z = Float.parseFloat(args.get(2).replace("~", "")) + sender.getPos().getZ();
}
} else {
z = Float.parseFloat(args.get(2));
}
int sceneId = sender.getSceneId();
if (args.size() == 4){
sceneId = Integer.parseInt(args.get(3));
}
Position target = new Position(x, y, z);
boolean result = sender.getWorld().transferPlayerToScene(sender, sceneId, target);
if (!result) {
CommandHandler.sendMessage(sender, "Invalid position.");
}
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid position.");
}
}
}
......@@ -31,6 +31,7 @@ public class GenshinData {
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>();
......@@ -57,6 +58,8 @@ public class GenshinData {
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
// Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
......@@ -114,6 +117,14 @@ public class GenshinData {
return playerLevelDataMap;
}
public static Int2ObjectMap<AvatarFetterLevelData> getAvatarFetterLevelDataMap() {
return avatarFetterLevelDataMap;
}
public static Int2ObjectMap<FetterCharacterCardData> getFetterCharacterCardDataMap() {
return fetterCharacterCardDataMap;
}
public static Int2ObjectMap<AvatarLevelData> getAvatarLevelDataMap() {
return avatarLevelDataMap;
}
......@@ -176,6 +187,11 @@ public class GenshinData {
return levelData != null ? levelData.getExp() : 0;
}
public static int getAvatarFetterLevelExpRequired(int level) {
AvatarFetterLevelData levelData = avatarFetterLevelDataMap.get(level);
return levelData != null ? levelData.getExp() : 0;
}
public static Int2ObjectMap<ProudSkillData> getProudSkillDataMap() {
return proudSkillDataMap;
}
......@@ -228,6 +244,10 @@ public class GenshinData {
return sceneDataMap;
}
public static Int2ObjectMap<RewardData> getRewardDataMap() {
return rewardDataMap;
}
public static Map<Integer, List<Integer>> getFetterDataEntries() {
if (fetters.isEmpty()) {
fetterDataMap.forEach((k, v) -> {
......
package emu.grasscutter.data.common;
import java.util.List;
public class OpenCondData {
private String CondType;
private List<Integer> ParamList;
public String getCondType() {
return CondType;
}
public void setCondType(String condType) {
CondType = condType;
}
public List<Integer> getParamList() {
return ParamList;
}
public void setParamList(List<Integer> paramList) {
ParamList = paramList;
}
}
package emu.grasscutter.data.common;
public class RewardItemData {
private int ItemId;
private int ItemCount;
public int getItemId() {
return ItemId;
}
public void setItemId(int itemId) {
ItemId = itemId;
}
public int getItemCount() {
return ItemCount;
}
public void setItemCount(int itemCount) {
ItemCount = itemCount;
}
}
......@@ -57,6 +57,8 @@ public class AvatarData extends GenshinResource {
private IntList abilities;
private List<Integer> fetters;
private int nameCardRewardId;
private int nameCardId;
@Override
public int getId(){
......@@ -199,6 +201,14 @@ public class AvatarData extends GenshinResource {
return fetters;
}
public int getNameCardRewardId() {
return nameCardRewardId;
}
public int getNameCardId() {
return nameCardId;
}
@Override
public void onLoad() {
this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId);
......@@ -206,6 +216,14 @@ public class AvatarData extends GenshinResource {
// Get fetters from GenshinData
this.fetters = GenshinData.getFetterDataEntries().get(this.Id);
if (GenshinData.getFetterCharacterCardDataMap().get(this.Id) != null) {
this.nameCardRewardId = GenshinData.getFetterCharacterCardDataMap().get(this.Id).getRewardId();
}
if (GenshinData.getRewardDataMap().get(this.nameCardRewardId) != null) {
this.nameCardId = GenshinData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
}
int size = GenshinData.getAvatarCurveDataMap().size();
this.hpGrowthCurve = new float[size];
this.attackGrowthCurve = new float[size];
......
package emu.grasscutter.data.def;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
public class AvatarFetterLevelData extends GenshinResource {
private int FetterLevel;
private int NeedExp;
@Override
public int getId() {
return this.FetterLevel;
}
public int getLevel() {
return FetterLevel;
}
public int getExp() {
return NeedExp;
}
}
package emu.grasscutter.data.def;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority;
@ResourceType(name = "FetterCharacterCardExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
public class FetterCharacterCardData extends GenshinResource {
private int AvatarId;
private int RewardId;
@Override
public int getId() {
return AvatarId;
}
public int getRewardId() {
return RewardId;
}
@Override
public void onLoad() {
}
}
package emu.grasscutter.data.def;
import java.util.List;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.OpenCondData;
@ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
public class FetterData extends GenshinResource {
private int AvatarId;
private int FetterId;
private List<OpenCondData> OpenCond;
@Override
public int getId() {
......@@ -18,6 +22,10 @@ public class FetterData extends GenshinResource {
return AvatarId;
}
public List<OpenCondData> getOpenConds() {
return OpenCond;
}
@Override
public void onLoad() {
}
......
package emu.grasscutter.data.def;
import java.util.List;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.RewardItemData;
@ResourceType(name = "RewardExcelConfigData.json")
public class RewardData extends GenshinResource {
public int RewardId;
public List<RewardItemData> RewardItemList;
@Override
public int getId() {
return RewardId;
}
public List<RewardItemData> getRewardItemList() {
return RewardItemList;
}
@Override
public void onLoad() {
}
}
......@@ -101,7 +101,7 @@ public final class DatabaseManager {
}
public static synchronized int getNextId(Class<?> c) {
DatabaseCounter counter = getDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getName())).first();
DatabaseCounter counter = getDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getSimpleName())).first();
if (counter == null) {
counter = new DatabaseCounter(c.getSimpleName());
}
......
package emu.grasscutter.game;
import java.util.*;
import dev.morphia.annotations.*;
import emu.grasscutter.GenshinConstants;
import emu.grasscutter.Grasscutter;
......@@ -23,7 +21,6 @@ import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday;
import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
import emu.grasscutter.net.proto.HeadImageOuterClass.HeadImage;
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
......@@ -35,33 +32,13 @@ 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.GameSession;
import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify;
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;
import emu.grasscutter.server.packet.send.PacketOpenStateUpdateNotify;
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpResultNotify;
import emu.grasscutter.server.packet.send.PacketPlayerDataNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify;
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.PacketStoreWeightLimitNotify;
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.*;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.*;
@Entity(value = "players", useDiscriminator = false)
public class GenshinPlayer {
@Id private int id;
......@@ -96,6 +73,7 @@ public class GenshinPlayer {
private MpSettingType mpSetting = MpSettingType.MpSettingEnterAfterApply;
private boolean showAvatar;
private ArrayList<AvatarProfileData> shownAvatars;
private Set<Integer> rewardedLevels;
private int sceneId;
private int regionId;
......@@ -113,7 +91,8 @@ public class GenshinPlayer {
@Transient private final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler;
@Transient private final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler;
@Deprecated @SuppressWarnings({ "rawtypes", "unchecked" }) // Morphia only!
@Deprecated
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
public GenshinPlayer() {
this.inventory = new Inventory(this);
this.avatars = new AvatarStorage(this);
......@@ -143,6 +122,7 @@ public class GenshinPlayer {
this.clientAbilityInitFinishHandler = new InvokeHandler(PacketClientAbilityInitFinishNotify.class);
this.birthday = new PlayerBirthday();
this.rewardedLevels = new HashSet<>();
}
// On player creation
......@@ -581,6 +561,7 @@ public class GenshinPlayer {
/**
* Sends a message to another player.
*
* @param sender The sender of the message.
* @param message The message to send.
*/
......@@ -647,7 +628,7 @@ public class GenshinPlayer {
return onlineInfo.build();
}
public PlayerBirthday getBirthday(){
public PlayerBirthday getBirthday() {
return this.birthday;
}
......@@ -656,6 +637,18 @@ public class GenshinPlayer {
this.updateProfile();
}
public boolean hasBirthday() {
return this.birthday.getDay() > 0;
}
public Set<Integer> getRewardedLevels() {
return rewardedLevels;
}
public void setRewardedLevels(Set<Integer> rewardedLevels) {
this.rewardedLevels = rewardedLevels;
}
public SocialDetail.Builder getSocialDetail() {
SocialDetail.Builder social = SocialDetail.newBuilder()
.setUid(this.getUid())
......@@ -734,7 +727,8 @@ public class GenshinPlayer {
// Make sure these exist
if (this.getTeamManager() == null) {
this.teamManager = new TeamManager(this);
} if (this.getProfile().getUid() == 0) {
}
if (this.getProfile().getUid() == 0) {
this.getProfile().syncWithCharacter(this);
}
......@@ -773,6 +767,7 @@ public class GenshinPlayer {
session.send(new PacketAvatarDataNotify(this));
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
session.send(new PacketOpenStateUpdateNotify());
// First notify packets sent
......@@ -798,7 +793,7 @@ public class GenshinPlayer {
}
public enum SceneLoadState {
NONE (0), LOADING (1), INIT (2), LOADED (3);
NONE(0), LOADING(1), INIT(2), LOADED(3);
private final int value;
......
......@@ -90,6 +90,12 @@ public class GenshinAvatar {
private int costume;
private int bornTime;
private int fetterLevel = 1;
private int fetterExp;
private int nameCardRewardId;
private int nameCardId;
public GenshinAvatar() {
// Morhpia only!
this.equips = new Int2ObjectOpenHashMap<>();
......@@ -107,6 +113,8 @@ public class GenshinAvatar {
public GenshinAvatar(AvatarData data) {
this();
this.avatarId = data.getId();
this.nameCardRewardId = data.getNameCardRewardId();
this.nameCardId = data.getNameCardId();
this.data = data;
this.bornTime = (int) (System.currentTimeMillis() / 1000);
this.flyCloak = 140001;
......@@ -169,6 +177,14 @@ public class GenshinAvatar {
this.satiation = satiation;
}
public int getNameCardRewardId() {
return nameCardRewardId;
}
public void setNameCardRewardId(int nameCardRewardId) {
this.nameCardRewardId = nameCardRewardId;
}
public int getSatiationPenalty() {
return satiationPenalty;
}
......@@ -281,6 +297,30 @@ public class GenshinAvatar {
return fetters;
}
public int getFetterLevel() {
return fetterLevel;
}
public void setFetterLevel(int fetterLevel) {
this.fetterLevel = fetterLevel;
}
public int getFetterExp() {
return fetterExp;
}
public void setFetterExp(int fetterExp) {
this.fetterExp = fetterExp;
}
public int getNameCardId() {
return nameCardId;
}
public void setNameCardId(int nameCardId) {
this.nameCardId = nameCardId;
}
public float getCurrentHp() {
return currentHp;
}
......@@ -403,6 +443,8 @@ public class GenshinAvatar {
// Fetters
this.setFetterList(data.getFetters());
this.setNameCardRewardId(data.getNameCardRewardId());
this.setNameCardId(data.getNameCardId());
// 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);
......@@ -701,9 +743,14 @@ public class GenshinAvatar {
}
public AvatarInfo toProto() {
int fetterLevel = this.getFetterLevel();
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
.setExpLevel(10)
.setExpNumber(6325); // Highest Level
.setExpLevel(fetterLevel);
if (fetterLevel != 10) {
avatarFetter.setExpNumber(this.getFetterExp());
}
if (this.getFetterList() != null) {
for (int i = 0; i < this.getFetterList().size(); i++) {
......@@ -715,6 +762,12 @@ public class GenshinAvatar {
}
}
int cardId = this.getNameCardId();
if (this.getPlayer().getNameCardList().contains(cardId)) {
avatarFetter.addRewardedFetterLevelList(10);
}
AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder()
.setAvatarId(this.getAvatarId())
.setGuid(this.getGuid())
......
......@@ -90,7 +90,7 @@ public class GenshinItem {
// Equip data
if (getItemType() == ItemType.ITEM_WEAPON) {
this.level = 1;
this.level = this.count > 1 ? this.count : 1;
this.affixes = new ArrayList<>(2);
if (getItemData().getSkillAffix() != null) {
for (int skillAffix : getItemData().getSkillAffix()) {
......
......@@ -711,6 +711,31 @@ public class InventoryManager {
player.sendPacket(new PacketAvatarUpgradeRsp(avatar, oldLevel, oldPropMap));
}
public void upgradeAvatarFetterLevel(GenshinPlayer player, GenshinAvatar avatar, int expGain) {
// May work. Not test.
int maxLevel = 10; // Keep it until I think of a more "elegant" way
int level = avatar.getFetterLevel();
int exp = avatar.getFetterExp();
int reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
while (expGain > 0 && reqExp > 0 && level < maxLevel) {
int toGain = Math.min(expGain, reqExp - exp);
exp += toGain;
expGain -= toGain;
if (exp >= reqExp) {
exp = 0;
level += 1;
reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
}
}
avatar.setFetterLevel(level);
avatar.setFetterExp(exp);
avatar.save();
player.sendPacket(new PacketAvatarPropNotify(avatar));
}
public void upgradeAvatarSkill(GenshinPlayer player, long guid, int skillId) {
// Sanity checks
GenshinAvatar avatar = player.getAvatars().getAvatarByGuid(guid);
......
package emu.grasscutter.game.player;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday;
@Entity
public class PlayerBirthday {
private int day;
private int month;
......
......@@ -64,9 +64,8 @@ public class MihoyoKcpServer extends Thread {
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception exception) {
Grasscutter.getLogger().error("Unable to start game server.", exception);
} finally {
// Close
finish();
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.RewardData;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarDataNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFetterLevelRewardRsp;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
import emu.grasscutter.net.packet.PacketHandler;
@Opcodes(PacketOpcodes.AvatarFetterLevelRewardReq)
public class HandlerAvatarFetterLevelRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
AvatarFetterLevelRewardReq req = AvatarFetterLevelRewardReq.parseFrom(payload);
if (req.getFetterLevel() < 10) {
// You don't have a full level of fetter level, why do you want to get a divorce certificate?
session.send(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel()));
} else {
long avatarGuid = req.getAvatarGuid();
GenshinAvatar avatar = session
.getPlayer()
.getAvatars()
.getAvatarByGuid(avatarGuid);
int rewardId = avatar.getNameCardRewardId();
RewardData card = GenshinData.getRewardDataMap().get(rewardId);
int cardId = card.getRewardItemList().get(0).getItemId();
if (session.getPlayer().getNameCardList().contains(cardId)) {
// Already got divorce certificate.
session.getPlayer().sendPacket(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel(), rewardId));
return;
}
GenshinItem item = new GenshinItem(cardId);
session.getPlayer().getInventory().addItem(item);
session.getPlayer().sendPacket(new PacketItemAddHintNotify(item, ActionReason.FetterLevelReward));
session.getPlayer().sendPacket(new PacketUnlockNameCardNotify(cardId));
session.send(new PacketAvatarFetterDataNotify(avatar));
session.send(new PacketAvatarDataNotify(avatar.getPlayer()));
session.send(new PacketAvatarFetterLevelRewardRsp(avatarGuid, req.getFetterLevel(), rewardId));
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment