Fix new avatar weapons being null

This commit is contained in:
KingRainbow44 2023-05-31 21:04:38 -04:00
parent bcf54dd6ba
commit 73c23707b4
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
7 changed files with 82 additions and 51 deletions

View File

@ -1,34 +1,21 @@
package emu.grasscutter.game.avatar; package emu.grasscutter.game.avatar;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import dev.morphia.annotations.*; import dev.morphia.annotations.*;
import emu.grasscutter.GameConstants; import emu.grasscutter.GameConstants;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.OpenConfigEntry; import emu.grasscutter.data.binout.OpenConfigEntry;
import emu.grasscutter.data.binout.OpenConfigEntry.SkillPointModifier; import emu.grasscutter.data.binout.OpenConfigEntry.SkillPointModifier;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.excels.EquipAffixData; import emu.grasscutter.data.excels.*;
import emu.grasscutter.data.excels.ItemData.WeaponProperty; import emu.grasscutter.data.excels.ItemData.WeaponProperty;
import emu.grasscutter.data.excels.ProudSkillData; import emu.grasscutter.data.excels.avatar.*;
import emu.grasscutter.data.excels.avatar.AvatarData;
import emu.grasscutter.data.excels.avatar.AvatarSkillData;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData.InherentProudSkillOpens; import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData.InherentProudSkillOpens;
import emu.grasscutter.data.excels.avatar.AvatarTalentData; import emu.grasscutter.data.excels.reliquary.*;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryLevelData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.data.excels.reliquary.ReliquarySetData;
import emu.grasscutter.data.excels.trial.TrialAvatarTemplateData; import emu.grasscutter.data.excels.trial.TrialAvatarTemplateData;
import emu.grasscutter.data.excels.weapon.WeaponCurveData; import emu.grasscutter.data.excels.weapon.*;
import emu.grasscutter.data.excels.weapon.WeaponPromoteData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.entity.EntityWeapon; import emu.grasscutter.game.inventory.*;
import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*; import emu.grasscutter.game.props.*;
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo; import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
@ -43,15 +30,14 @@ import emu.grasscutter.net.proto.TrialAvatarInfoOuterClass.TrialAvatarInfo;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.helpers.ProtoHelper; import emu.grasscutter.utils.helpers.ProtoHelper;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import org.bson.types.ObjectId;
import javax.annotation.*;
import java.util.*; import java.util.*;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.val;
import org.bson.types.ObjectId;
@Entity(value = "avatars", useDiscriminator = false) @Entity(value = "avatars", useDiscriminator = false)
public class Avatar { public class Avatar {
@ -241,10 +227,22 @@ public class Avatar {
return this.getEquips().get(slotId); return this.getEquips().get(slotId);
} }
/**
* @return The avatar's equipped weapon.
*/
@Nullable
public GameItem getWeapon() { public GameItem getWeapon() {
return this.getEquipBySlot(EquipType.EQUIP_WEAPON); return this.getEquipBySlot(EquipType.EQUIP_WEAPON);
} }
/**
* @return The avatar's equipped weapon.
* @throws NullPointerException If the avatar does not have a weapon.
*/
public GameItem getWeaponNotNull() {
return Objects.requireNonNull(this.getWeapon(), "Avatar does not have a weapon.");
}
protected void setSkillDepot(AvatarSkillDepotData skillDepot) { protected void setSkillDepot(AvatarSkillDepotData skillDepot) {
if (this.skillDepot != null) return; if (this.skillDepot != null) return;
this.skillDepot = skillDepot; // Used while loading this from the database this.skillDepot = skillDepot; // Used while loading this from the database

View File

@ -129,6 +129,8 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
} }
public void loadFromDatabase() { public void loadFromDatabase() {
if (this.isLoaded()) return;
List<Avatar> avatars = DatabaseHelper.getAvatars(getPlayer()); List<Avatar> avatars = DatabaseHelper.getAvatars(getPlayer());
for (Avatar avatar : avatars) { for (Avatar avatar : avatars) {
@ -156,6 +158,8 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
this.avatars.put(avatar.getAvatarId(), avatar); this.avatars.put(avatar.getAvatarId(), avatar);
this.avatarsGuid.put(avatar.getGuid(), avatar); this.avatarsGuid.put(avatar.getGuid(), avatar);
} }
this.setLoaded(true);
} }
public void postLoad() { public void postLoad() {

View File

@ -1,31 +1,24 @@
package emu.grasscutter.game.inventory; package emu.grasscutter.game.inventory;
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.*;
import emu.grasscutter.game.avatar.AvatarStorage; import emu.grasscutter.game.player.*;
import emu.grasscutter.game.player.BasePlayerManager; import emu.grasscutter.game.props.*;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.ItemUseAction.UseItemParams; import emu.grasscutter.game.props.ItemUseAction.UseItemParams;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.game.quest.enums.QuestContent; import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam; import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.*;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Iterator; import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
import java.util.List;
public class Inventory extends BasePlayerManager implements Iterable<GameItem> { public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
private final Long2ObjectMap<GameItem> store; private final Long2ObjectMap<GameItem> store;
@ -535,6 +528,11 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
} }
public void loadFromDatabase() { public void loadFromDatabase() {
if (this.isLoaded()) return;
// Wait for avatars to load.
Utils.waitFor(this.getPlayer().getAvatars()::isLoaded);
List<GameItem> items = DatabaseHelper.getInventoryItems(getPlayer()); List<GameItem> items = DatabaseHelper.getInventoryItems(getPlayer());
for (GameItem item : items) { for (GameItem item : items) {
@ -575,6 +573,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
// Load avatars after inventory. // Load avatars after inventory.
this.getPlayer().getAvatars().postLoad(); this.getPlayer().getAvatars().postLoad();
this.setLoaded(true);
} }
@Override @Override

View File

@ -1,9 +1,12 @@
package emu.grasscutter.game.player; package emu.grasscutter.game.player;
import lombok.NonNull; import lombok.*;
public abstract class BasePlayerManager { public abstract class BasePlayerManager {
protected final transient Player player; protected final transient Player player;
@Getter
@Setter(AccessLevel.PROTECTED)
protected boolean loaded = false;
public BasePlayerManager(@NonNull Player player) { public BasePlayerManager(@NonNull Player player) {
this.player = player; this.player = player;

View File

@ -1325,11 +1325,20 @@ public class Player implements PlayerHook, FieldFetch {
runner.submit(this::loadBattlePassManager); runner.submit(this::loadBattlePassManager);
// Wait for all tasks to finish.
Utils.waitFor(() ->
this.getAvatars().isLoaded() &&
this.getInventory().isLoaded());
this.getPlayerProgress().setPlayer(this); // Add reference to the player. this.getPlayerProgress().setPlayer(this); // Add reference to the player.
} }
/**
* Invoked when the player selects their avatar.
*/
public void onPlayerBorn() { public void onPlayerBorn() {
getQuestManager().onPlayerBorn(); Grasscutter.getThreadPool().submit(
this.getQuestManager()::onPlayerBorn);
} }
public void onLogin() { public void onLogin() {

View File

@ -22,7 +22,7 @@ public class PacketSceneTeamUpdateNotify extends BasePacket {
.setSceneId(p.getSceneId()) .setSceneId(p.getSceneId())
.setEntityId(entityAvatar.getId()) .setEntityId(entityAvatar.getId())
.setSceneEntityInfo(entityAvatar.toProto()) .setSceneEntityInfo(entityAvatar.toProto())
.setWeaponGuid(entityAvatar.getAvatar().getWeapon().getGuid()) .setWeaponGuid(entityAvatar.getAvatar().getWeaponNotNull().getGuid())
.setWeaponEntityId(entityAvatar.getWeaponEntityId()) .setWeaponEntityId(entityAvatar.getWeaponEntityId())
.setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar) .setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
.setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar) .setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)

View File

@ -1,15 +1,16 @@
package emu.grasscutter.utils; package emu.grasscutter.utils;
import static emu.grasscutter.utils.FileUtils.getResourcePath;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.config.ConfigContainer; import emu.grasscutter.config.ConfigContainer;
import emu.grasscutter.data.DataLoader; import emu.grasscutter.data.DataLoader;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import emu.grasscutter.utils.objects.Returnable;
import io.javalin.http.Context; import io.javalin.http.Context;
import io.netty.buffer.*; import io.netty.buffer.*;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import org.slf4j.Logger;
import javax.annotation.Nullable;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.*; import java.nio.file.*;
@ -17,8 +18,9 @@ import java.time.*;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
import java.util.*; import java.util.*;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
import org.slf4j.Logger; import static emu.grasscutter.utils.FileUtils.getResourcePath;
import static emu.grasscutter.utils.lang.Language.translate;
@SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"}) @SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
public final class Utils { public final class Utils {
@ -477,4 +479,20 @@ public final class Utils {
// Return the request IP. // Return the request IP.
return ctx.ip(); return ctx.ip();
} }
/**
* Waits for the task to return true.
* This will halt the thread until the task returns true.
*
* @param runnable The task to run.
*/
public static void waitFor(Returnable<Boolean> runnable) {
while (!runnable.invoke()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} }