Commit dc9cef8a authored by Luke H-W's avatar Luke H-W Committed by GitHub
Browse files

Refactoring (#1660)



* Refactor a couple of iterators

* Use side-effect instead of second iterator

* Make World::onTick return shouldDelete instead of success

* Replace Shop iterator with side effects

* Scene

* Clean up Expeditions

* Refactor Expeditions

* Clean up Expeditions, Player

* Limit Expeditions by AR

* Lombokify props
Co-authored-by: default avatarAnimeGitB <AnimeGitB@bigblueball.in>
parent bccf516c
...@@ -2,32 +2,20 @@ package emu.grasscutter.data.excels; ...@@ -2,32 +2,20 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.Getter;
@ResourceType(name = "PlayerLevelExcelConfigData.json") @ResourceType(name = "PlayerLevelExcelConfigData.json")
@Getter
public class PlayerLevelData extends GameResource { public class PlayerLevelData extends GameResource {
private int level; private int level;
private int exp; private int exp;
private int rewardId; private int rewardId;
private int expeditionLimitAdd = 0;
private int unlockWorldLevel; private int unlockWorldLevel;
private long unlockDescTextMapHash;
@Override @Override
public int getId() { public int getId() {
return this.level; return this.level;
} }
public int getLevel() {
return level;
}
public int getExp() {
return exp;
}
public int getRewardId() {
return rewardId;
}
public int getUnlockWorldLevel() {
return unlockWorldLevel;
}
} }
package emu.grasscutter.game.expedition; package emu.grasscutter.game.expedition;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.AvatarExpeditionInfoOuterClass.AvatarExpeditionInfo;
import lombok.Getter;
import lombok.Setter;
@Entity @Entity
@Getter @Setter
public class ExpeditionInfo { public class ExpeditionInfo {
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public int getExpId() {
return expId;
}
public void setExpId(int expId) {
this.expId = expId;
}
public int getHourTime() {
return hourTime;
}
public void setHourTime(int hourTime) {
this.hourTime = hourTime;
}
public int getStartTime() {
return startTime;
}
public void setStartTime(int startTime) {
this.startTime = startTime;
}
private int state; private int state;
private int expId; private int expId;
private int hourTime; private int hourTime;
private int startTime; private int startTime;
public AvatarExpeditionInfo toProto() {
return AvatarExpeditionInfo.newBuilder()
.setStateValue(this.getState())
.setExpId(this.getExpId())
.setHourTime(this.getHourTime())
.setStartTime(this.getStartTime())
.build();
}
} }
package emu.grasscutter.game.expedition; package emu.grasscutter.game.expedition;
public class ExpeditionRewardData { import emu.grasscutter.game.inventory.GameItem;
private int itemId; import emu.grasscutter.utils.Utils;
private int minCount; import lombok.Getter;
private int maxCount;
public int getItemId() {
return itemId;
}
public int getMinCount() { return minCount; } public class ExpeditionRewardData {
@Getter private int itemId;
@Getter private int minCount;
@Getter private int maxCount;
public int getMaxCount() { public GameItem getReward() {
return maxCount; return new GameItem(itemId, Utils.randomRange(minCount, maxCount));
} }
} }
package emu.grasscutter.game.expedition; package emu.grasscutter.game.expedition;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import emu.grasscutter.game.inventory.GameItem;
import lombok.Getter;
public class ExpeditionRewardDataList { public class ExpeditionRewardDataList {
public int getHourTime() { @Getter private int hourTime;
return hourTime; @Getter private List<ExpeditionRewardData> expeditionRewardData;
public List<GameItem> getRewards() {
List<GameItem> rewards = new ArrayList<>();
if (expeditionRewardData != null) {
expeditionRewardData.forEach(data -> rewards.add(data.getReward()));
} }
public List<ExpeditionRewardData> getExpeditionRewardData() { return rewards;
return expeditionRewardData;
} }
private int hourTime;
private List<ExpeditionRewardData> expeditionRewardData;
} }
...@@ -2,15 +2,9 @@ package emu.grasscutter.game.expedition; ...@@ -2,15 +2,9 @@ package emu.grasscutter.game.expedition;
import java.util.List; import java.util.List;
public class ExpeditionRewardInfo { import lombok.Getter;
public int getExpId() {
return expId;
}
public List<ExpeditionRewardDataList> getExpeditionRewardDataList() {
return expeditionRewardDataList;
}
private int expId; public class ExpeditionRewardInfo {
private List<ExpeditionRewardDataList> expeditionRewardDataList; @Getter private int expId;
@Getter private List<ExpeditionRewardDataList> expeditionRewardDataList;
} }
...@@ -88,33 +88,33 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -88,33 +88,33 @@ import java.util.concurrent.LinkedBlockingQueue;
public class Player { public class Player {
@Id private int id; @Id private int id;
@Indexed(options = @IndexOptions(unique = true)) private String accountId; @Indexed(options = @IndexOptions(unique = true)) private String accountId;
private transient Account account; @Setter private transient Account account;
private transient GameSession session; @Getter @Setter private transient GameSession session;
private String nickname; @Getter private String nickname;
private String signature; @Getter private String signature;
private int headImage; @Getter private int headImage;
private int nameCardId = 210001; @Getter private int nameCardId = 210001;
private Position position; @Getter private Position position;
private Position rotation; @Getter private Position rotation;
private PlayerBirthday birthday; @Getter private PlayerBirthday birthday;
private PlayerCodex codex; @Getter private PlayerCodex codex;
private boolean showAvatars; @Getter @Setter private boolean showAvatars;
private List<Integer> showAvatarList; @Getter @Setter private List<Integer> showAvatarList;
private Map<Integer, Integer> properties; @Getter private Map<Integer, Integer> properties;
private int currentRealmId; @Getter @Setter private int currentRealmId;
private int widgetId; @Getter @Setter private int widgetId;
private int sceneId; @Getter @Setter private int sceneId;
private int regionId; @Getter @Setter private int regionId;
private int mainCharacterId; @Getter private int mainCharacterId;
private boolean godmode; @Setter private boolean godmode; // Getter is inGodmode
private boolean stamina; private boolean stamina; // Getter is getUnlimitedStamina, Setter is setUnlimitedStamina
@Getter private Set<Integer> nameCardList; @Getter private Set<Integer> nameCardList;
@Getter private Set<Integer> flyCloakList; @Getter private Set<Integer> flyCloakList;
@Getter private Set<Integer> costumeList; @Getter private Set<Integer> costumeList;
@Getter private Set<Integer> rewardedLevels; @Getter private Set<Integer> rewardedLevels;
@Getter private Set<Integer> realmList; @Getter @Setter private Set<Integer> realmList;
@Getter private Set<Integer> unlockedForgingBlueprints; @Getter private Set<Integer> unlockedForgingBlueprints;
@Getter private Set<Integer> unlockedCombines; @Getter private Set<Integer> unlockedCombines;
@Getter private Set<Integer> unlockedFurniture; @Getter private Set<Integer> unlockedFurniture;
...@@ -128,9 +128,9 @@ public class Player { ...@@ -128,9 +128,9 @@ public class Player {
@Getter @Setter private Map<Integer, List<Integer>> unlockedScenePoints; @Getter @Setter private Map<Integer, List<Integer>> unlockedScenePoints;
@Transient private long nextGuid = 0; @Transient private long nextGuid = 0;
@Transient private int peerId; @Transient @Getter @Setter private int peerId;
@Transient private World world; @Transient private World world; // Synchronized getter and setter
@Transient private Scene scene; @Transient private Scene scene; // Synchronized getter and setter
@Transient @Getter private int weatherId = 0; @Transient @Getter private int weatherId = 0;
@Transient @Getter private ClimateType climate = ClimateType.CLIMATE_SUNNY; @Transient @Getter private ClimateType climate = ClimateType.CLIMATE_SUNNY;
...@@ -139,9 +139,9 @@ public class Player { ...@@ -139,9 +139,9 @@ public class Player {
@Getter private transient Inventory inventory; @Getter private transient Inventory inventory;
@Getter private transient FriendsList friendsList; @Getter private transient FriendsList friendsList;
@Getter private transient MailHandler mailHandler; @Getter private transient MailHandler mailHandler;
@Getter private transient MessageHandler messageHandler; @Getter @Setter private transient MessageHandler messageHandler;
@Getter private transient AbilityManager abilityManager; @Getter private transient AbilityManager abilityManager;
@Getter private transient QuestManager questManager; @Getter @Setter private transient QuestManager questManager;
@Getter private transient TowerManager towerManager; @Getter private transient TowerManager towerManager;
@Getter private transient SotSManager sotsManager; @Getter private transient SotSManager sotsManager;
@Getter private transient MapMarksManager mapMarksManager; @Getter private transient MapMarksManager mapMarksManager;
...@@ -158,36 +158,37 @@ public class Player { ...@@ -158,36 +158,37 @@ public class Player {
@Getter private transient PlayerProgressManager progressManager; @Getter private transient PlayerProgressManager progressManager;
// Manager data (Save-able to the database) // Manager data (Save-able to the database)
private PlayerProfile playerProfile; private PlayerProfile playerProfile; // Getter has null-check
private TeamManager teamManager; @Getter private TeamManager teamManager;
private TowerData towerData; private TowerData towerData; // Getter has null-check
private PlayerGachaInfo gachaInfo; @Getter private PlayerGachaInfo gachaInfo;
private PlayerCollectionRecords collectionRecordStore; private PlayerCollectionRecords collectionRecordStore; // Getter has null-check
private ArrayList<ShopLimit> shopLimit; @Getter private ArrayList<ShopLimit> shopLimit;
@Getter private transient GameHome home; @Getter private transient GameHome home;
private boolean moonCard; @Setter private boolean moonCard; // Getter is inMoonCard
private Date moonCardStartTime; @Getter @Setter private Date moonCardStartTime;
private int moonCardDuration; @Getter @Setter private int moonCardDuration;
private Set<Date> moonCardGetTimes; @Getter @Setter private Set<Date> moonCardGetTimes;
@Transient private boolean paused; @Transient @Getter private boolean paused;
@Transient private int enterSceneToken; @Transient @Getter @Setter private int enterSceneToken;
@Transient private SceneLoadState sceneState; @Transient @Getter @Setter private SceneLoadState sceneLoadState = SceneLoadState.NONE;
@Transient private boolean hasSentLoginPackets; @Transient private boolean hasSentLoginPackets;
@Transient private long nextSendPlayerLocTime = 0; @Transient private long nextSendPlayerLocTime = 0;
private transient final Int2ObjectMap<CoopRequest> coopRequests; private transient final Int2ObjectMap<CoopRequest> coopRequests; // Synchronized getter
private transient final Queue<AttackResult> attackResults; @Getter private transient final Queue<AttackResult> attackResults;
@Getter private transient final InvokeHandler<CombatInvokeEntry> combatInvokeHandler; @Getter private transient final InvokeHandler<CombatInvokeEntry> combatInvokeHandler;
@Getter private transient final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler; @Getter private transient final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler;
@Getter private transient final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler; @Getter private transient final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler;
private long springLastUsed; @Getter @Setter private long springLastUsed;
private HashMap<String, MapMark> mapMarks; private HashMap<String, MapMark> mapMarks; // Getter makes an empty hashmap - maybe do this elsewhere?
private int nextResinRefresh; @Getter @Setter private int nextResinRefresh;
private int lastDailyReset; @Getter @Setter private int lastDailyReset;
@Getter private transient MpSettingType mpSetting = MpSettingType.MP_SETTING_TYPE_ENTER_AFTER_APPLY; // TODO
@Deprecated @Deprecated
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only! @SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
...@@ -228,7 +229,6 @@ public class Player { ...@@ -228,7 +229,6 @@ public class Player {
this.openStates = new HashMap<>(); this.openStates = new HashMap<>();
this.unlockedSceneAreas = new HashMap<>(); this.unlockedSceneAreas = new HashMap<>();
this.unlockedScenePoints = new HashMap<>(); this.unlockedScenePoints = new HashMap<>();
this.sceneState = SceneLoadState.NONE;
this.attackResults = new LinkedBlockingQueue<>(); this.attackResults = new LinkedBlockingQueue<>();
this.coopRequests = new Int2ObjectOpenHashMap<>(); this.coopRequests = new Int2ObjectOpenHashMap<>();
...@@ -308,18 +308,6 @@ public class Player { ...@@ -308,18 +308,6 @@ public class Player {
return this.account; return this.account;
} }
public void setAccount(Account account) {
this.account = account;
}
public GameSession getSession() {
return session;
}
public void setSession(GameSession session) {
this.session = session;
}
public boolean isOnline() { public boolean isOnline() {
return this.getSession() != null && this.getSession().isActive(); return this.getSession() != null && this.getSession().isActive();
} }
...@@ -366,45 +354,21 @@ public class Player { ...@@ -366,45 +354,21 @@ public class Player {
this.session.send(new PacketSceneAreaWeatherNotify(this)); this.session.send(new PacketSceneAreaWeatherNotify(this));
} }
public String getNickname() {
return nickname;
}
public void setNickname(String nickName) { public void setNickname(String nickName) {
this.nickname = nickName; this.nickname = nickName;
this.updateProfile(); this.updateProfile();
} }
public int getHeadImage() {
return headImage;
}
public void setHeadImage(int picture) { public void setHeadImage(int picture) {
this.headImage = picture; this.headImage = picture;
this.updateProfile(); this.updateProfile();
} }
public String getSignature() {
return signature;
}
public void setSignature(String signature) { public void setSignature(String signature) {
this.signature = signature; this.signature = signature;
this.updateProfile(); this.updateProfile();
} }
public Integer getWidgetId() {
return widgetId;
}
public void setWidgetId(Integer widgetId) {
this.widgetId = widgetId;
}
public void setRealmList(Set<Integer> realmList) {
this.realmList = realmList;
}
public void addRealmList(int realmId) { public void addRealmList(int realmId) {
if (this.realmList == null) { if (this.realmList == null) {
this.realmList = new HashSet<>(); this.realmList = new HashSet<>();
...@@ -414,20 +378,16 @@ public class Player { ...@@ -414,20 +378,16 @@ public class Player {
this.realmList.add(realmId); this.realmList.add(realmId);
} }
public int getCurrentRealmId() { public int getExpeditionLimit() {
return currentRealmId; final int CONST_VALUE_EXPEDITION_INIT_LIMIT = 2; // TODO: pull from ConstValueExcelConfigData.json
} int expeditionLimit = CONST_VALUE_EXPEDITION_INIT_LIMIT;
var levelMap = GameData.getPlayerLevelDataMap();
public void setCurrentRealmId(int currentRealmId) { for (int i = 1; i <= this.getLevel(); i++) { // 1-indexed
this.currentRealmId = currentRealmId; var data = levelMap.get(i);
} if (data != null)
expeditionLimit += data.getExpeditionLimitAdd();
public Position getPosition() {
return position;
} }
return expeditionLimit;
public Position getRotation() {
return rotation;
} }
public int getLevel() { public int getLevel() {
...@@ -576,10 +536,6 @@ public class Player { ...@@ -576,10 +536,6 @@ public class Player {
return !this.hasSentLoginPackets; return !this.hasSentLoginPackets;
} }
public TeamManager getTeamManager() {
return this.teamManager;
}
public TowerData getTowerData() { public TowerData getTowerData() {
if (towerData == null) { if (towerData == null) {
// because of mistake, null may be saved as storage at some machine, this if can be removed in future // because of mistake, null may be saved as storage at some machine, this if can be removed in future
...@@ -588,10 +544,6 @@ public class Player { ...@@ -588,10 +544,6 @@ public class Player {
return towerData; return towerData;
} }
public void setQuestManager(QuestManager questManager) {
this.questManager = questManager;
}
public void onEnterRegion(SceneRegion region) { public void onEnterRegion(SceneRegion region) {
getQuestManager().forEachActiveQuest(quest -> { getQuestManager().forEachActiveQuest(quest -> {
if(quest.getTriggers().containsKey("ENTER_REGION_"+ String.valueOf(region.config_id))) { if(quest.getTriggers().containsKey("ENTER_REGION_"+ String.valueOf(region.config_id))) {
...@@ -615,10 +567,6 @@ public class Player { ...@@ -615,10 +567,6 @@ public class Player {
} }
} }
}); });
}
public PlayerGachaInfo getGachaInfo() {
return gachaInfo;
} }
public PlayerProfile getProfile() { public PlayerProfile getProfile() {
...@@ -628,12 +576,6 @@ public class Player { ...@@ -628,12 +576,6 @@ public class Player {
return playerProfile; return playerProfile;
} }
// TODO: Based on the proto, property value could be int or float.
// Although there's no float value at this moment, our code should be prepared for float values.
public Map<Integer, Integer> getProperties() {
return properties;
}
public boolean setProperty(PlayerProperty prop, int value) { public boolean setProperty(PlayerProperty prop, int value) {
return setPropertyWithSanityCheck(prop, value, true); return setPropertyWithSanityCheck(prop, value, true);
} }
...@@ -646,39 +588,15 @@ public class Player { ...@@ -646,39 +588,15 @@ public class Player {
return getProperties().get(prop.getId()); return getProperties().get(prop.getId());
} }
public MpSettingType getMpSetting() {
return MpSettingType.MP_SETTING_TYPE_ENTER_AFTER_APPLY; // TEMP
}
public Queue<AttackResult> getAttackResults() {
return this.attackResults;
}
public synchronized Int2ObjectMap<CoopRequest> getCoopRequests() { public synchronized Int2ObjectMap<CoopRequest> getCoopRequests() {
return coopRequests; return coopRequests;
} }
public int getEnterSceneToken() {
return enterSceneToken;
}
public void setEnterSceneToken(int enterSceneToken) {
this.enterSceneToken = enterSceneToken;
}
public int getNameCardId() {
return nameCardId;
}
public void setNameCardId(int nameCardId) { public void setNameCardId(int nameCardId) {
this.nameCardId = nameCardId; this.nameCardId = nameCardId;
this.updateProfile(); this.updateProfile();
} }
public int getMainCharacterId() {
return mainCharacterId;
}
public void setMainCharacterId(int mainCharacterId) { public void setMainCharacterId(int mainCharacterId) {
if (this.mainCharacterId != 0) { if (this.mainCharacterId != 0) {
return; return;
...@@ -686,14 +604,6 @@ public class Player { ...@@ -686,14 +604,6 @@ public class Player {
this.mainCharacterId = mainCharacterId; this.mainCharacterId = mainCharacterId;
} }
public int getPeerId() {
return peerId;
}
public void setPeerId(int peerId) {
this.peerId = peerId;
}
public int getClientTime() { public int getClientTime() {
return session.getClientTime(); return session.getClientTime();
} }
...@@ -702,10 +612,6 @@ public class Player { ...@@ -702,10 +612,6 @@ public class Player {
return session.getLastPingTime(); return session.getLastPingTime();
} }
public boolean isPaused() {
return paused;
}
public void setPaused(boolean newPauseState) { public void setPaused(boolean newPauseState) {
boolean oldPauseState = this.paused; boolean oldPauseState = this.paused;
this.paused = newPauseState; this.paused = newPauseState;
...@@ -717,110 +623,18 @@ public class Player { ...@@ -717,110 +623,18 @@ public class Player {
} }
} }
public long getSpringLastUsed() {
return springLastUsed;
}
public void setSpringLastUsed(long val) {
springLastUsed = val;
}
public int getNextResinRefresh() {
return nextResinRefresh;
}
public void setNextResinRefresh(int value) {
this.nextResinRefresh = value;
}
public SceneLoadState getSceneLoadState() {
return sceneState;
}
public void setSceneLoadState(SceneLoadState sceneState) {
this.sceneState = sceneState;
}
public boolean isInMultiplayer() { public boolean isInMultiplayer() {
return this.getWorld() != null && this.getWorld().isMultiplayer(); return this.getWorld() != null && this.getWorld().isMultiplayer();
} }
public int getSceneId() {
return sceneId;
}
public void setSceneId(int sceneId) {
this.sceneId = sceneId;
}
public int getRegionId() {
return regionId;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
public void setShowAvatars(boolean showAvatars) {
this.showAvatars = showAvatars;
}
public boolean isShowAvatars() {
return showAvatars;
}
public void setShowAvatarList(List<Integer> showAvatarList) {
this.showAvatarList = showAvatarList;
}
public List<Integer> getShowAvatarList() {
return showAvatarList;
}
public int getLastDailyReset() {
return this.lastDailyReset;
}
public void setLastDailyReset(int value) {
this.lastDailyReset = value;
}
public boolean inMoonCard() { public boolean inMoonCard() {
return moonCard; return moonCard;
} }
public void setMoonCard(boolean moonCard) {
this.moonCard = moonCard;
}
public void addMoonCardDays(int days) { public void addMoonCardDays(int days) {
this.moonCardDuration += days; this.moonCardDuration += days;
} }
public int getMoonCardDuration() {
return moonCardDuration;
}
public void setMoonCardDuration(int moonCardDuration) {
this.moonCardDuration = moonCardDuration;
}
public Date getMoonCardStartTime() {
return moonCardStartTime;
}
public void setMoonCardStartTime(Date moonCardStartTime) {
this.moonCardStartTime = moonCardStartTime;
}
public Set<Date> getMoonCardGetTimes() {
return moonCardGetTimes;
}
public void setMoonCardGetTimes(Set<Date> moonCardGetTimes) {
this.moonCardGetTimes = moonCardGetTimes;
}
public int getMoonCardRemainDays() { public int getMoonCardRemainDays() {
Calendar remainCalendar = Calendar.getInstance(); Calendar remainCalendar = Calendar.getInstance();
remainCalendar.setTime(moonCardStartTime); remainCalendar.setTime(moonCardStartTime);
...@@ -869,25 +683,21 @@ public class Player { ...@@ -869,25 +683,21 @@ public class Player {
session.send(new PacketCardProductRewardNotify(getMoonCardRemainDays())); session.send(new PacketCardProductRewardNotify(getMoonCardRemainDays()));
} }
public void addExpeditionInfo(long avaterGuid, int expId, int hourTime, int startTime) { public void addExpeditionInfo(long avatarGuid, int expId, int hourTime, int startTime) {
ExpeditionInfo exp = new ExpeditionInfo(); ExpeditionInfo exp = new ExpeditionInfo();
exp.setExpId(expId); exp.setExpId(expId);
exp.setHourTime(hourTime); exp.setHourTime(hourTime);
exp.setState(1); exp.setState(1);
exp.setStartTime(startTime); exp.setStartTime(startTime);
expeditionInfo.put(avaterGuid, exp); expeditionInfo.put(avatarGuid, exp);
}
public void removeExpeditionInfo(long avaterGuid) {
expeditionInfo.remove(avaterGuid);
} }
public ExpeditionInfo getExpeditionInfo(long avaterGuid) { public void removeExpeditionInfo(long avatarGuid) {
return expeditionInfo.get(avaterGuid); expeditionInfo.remove(avatarGuid);
} }
public List<ShopLimit> getShopLimit() { public ExpeditionInfo getExpeditionInfo(long avatarGuid) {
return shopLimit; return expeditionInfo.get(avatarGuid);
} }
public ShopLimit getGoodsLimit(int goodsId) { public ShopLimit getGoodsLimit(int goodsId) {
...@@ -913,20 +723,19 @@ public class Player { ...@@ -913,20 +723,19 @@ public class Player {
} }
this.save(); this.save();
} }
public boolean getUnlimitedStamina() { public boolean getUnlimitedStamina() {
return stamina; return stamina;
} }
public void setUnlimitedStamina(boolean stamina) { public void setUnlimitedStamina(boolean stamina) {
this.stamina = stamina; this.stamina = stamina;
} }
public boolean inGodmode() { public boolean inGodmode() {
return godmode; return godmode;
} }
public void setGodmode(boolean godmode) {
this.godmode = godmode;
}
public boolean hasSentLoginPackets() { public boolean hasSentLoginPackets() {
return hasSentLoginPackets; return hasSentLoginPackets;
} }
...@@ -1067,10 +876,6 @@ public class Player { ...@@ -1067,10 +876,6 @@ public class Player {
return onlineInfo.build(); return onlineInfo.build();
} }
public PlayerBirthday getBirthday() {
return this.birthday;
}
public void setBirthday(int d, int m) { public void setBirthday(int d, int m) {
this.birthday = new PlayerBirthday(d, m); this.birthday = new PlayerBirthday(d, m);
this.updateProfile(); this.updateProfile();
...@@ -1080,10 +885,6 @@ public class Player { ...@@ -1080,10 +885,6 @@ public class Player {
return this.birthday.getDay() > 0; return this.birthday.getDay() > 0;
} }
public PlayerCodex getCodex() {
return this.codex;
}
public void setRewardedLevels(Set<Integer> rewardedLevels) { public void setRewardedLevels(Set<Integer> rewardedLevels) {
this.rewardedLevels = rewardedLevels; this.rewardedLevels = rewardedLevels;
} }
...@@ -1200,6 +1001,15 @@ public class Player { ...@@ -1200,6 +1001,15 @@ public class Player {
return mapMarks; return mapMarks;
} }
private boolean expireCoopRequest(CoopRequest req) {
if (!req.isExpired()) return false;
req.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(
this,
false,
PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.REASON_SYSTEM_JUDGE));
return true;
}
public synchronized void onTick() { public synchronized void onTick() {
// Check ping // Check ping
if (this.getLastPingTime() > System.currentTimeMillis() + 60000) { if (this.getLastPingTime() > System.currentTimeMillis() + 60000) {
...@@ -1207,17 +1017,7 @@ public class Player { ...@@ -1207,17 +1017,7 @@ public class Player {
return; return;
} }
// Check co-op requests // Check co-op requests
Iterator<CoopRequest> it = this.getCoopRequests().values().iterator(); this.getCoopRequests().values().removeIf(this::expireCoopRequest);
while (it.hasNext()) {
CoopRequest req = it.next();
if (req.isExpired()) {
req.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(
this,
false,
PlayerApplyEnterMpResultNotifyOuterClass.PlayerApplyEnterMpResultNotify.Reason.REASON_SYSTEM_JUDGE));
it.remove();
}
}
// Handle buff // Handle buff
this.getBuffManager().onTick(); this.getBuffManager().onTick();
// Ping // Ping
...@@ -1240,8 +1040,7 @@ public class Player { ...@@ -1240,8 +1040,7 @@ public class Player {
// Expedition // Expedition
var timeNow = Utils.getCurrentSeconds(); var timeNow = Utils.getCurrentSeconds();
var needNotify = false; var needNotify = false;
for (Long key : expeditionInfo.keySet()) { for (ExpeditionInfo e : expeditionInfo.values()) {
ExpeditionInfo e = expeditionInfo.get(key);
if (e.getState() == 1) { if (e.getState() == 1) {
if (timeNow - e.getStartTime() >= e.getHourTime() * 60 * 60) { if (timeNow - e.getStartTime() >= e.getHourTime() * 60 * 60) {
e.setState(2); e.setState(2);
...@@ -1251,7 +1050,7 @@ public class Player { ...@@ -1251,7 +1050,7 @@ public class Player {
} }
if (needNotify) { if (needNotify) {
this.save(); this.save();
this.sendPacket(new PacketAvatarExpeditionDataNotify(this)); this.sendPacket(new PacketAvatarExpeditionDataNotify(this.getExpeditionInfo()));
} }
// Send updated forge queue data, if necessary. // Send updated forge queue data, if necessary.
...@@ -1474,23 +1273,15 @@ public class Player { ...@@ -1474,23 +1273,15 @@ public class Player {
public enum SceneLoadState { public enum SceneLoadState {
NONE(0), LOADING(1), INIT(2), LOADED(3); NONE(0), LOADING(1), INIT(2), LOADED(3);
private final int value; @Getter private final int value;
private SceneLoadState(int value) { private SceneLoadState(int value) {
this.value = value; this.value = value;
} }
public int getValue() {
return this.value;
}
}
public void setMessageHandler(MessageHandler messageHandler) {
this.messageHandler = messageHandler;
} }
public int getPropertyMin(PlayerProperty prop) { public int getPropertyMin(PlayerProperty prop) {
if (prop.getDynamicRange()) { if (prop.isDynamicRange()) {
return switch (prop) { return switch (prop) {
default -> 0; default -> 0;
}; };
...@@ -1500,7 +1291,7 @@ public class Player { ...@@ -1500,7 +1291,7 @@ public class Player {
} }
public int getPropertyMax(PlayerProperty prop) { public int getPropertyMax(PlayerProperty prop) {
if (prop.getDynamicRange()) { if (prop.isDynamicRange()) {
return switch (prop) { return switch (prop) {
case PROP_CUR_SPRING_VOLUME -> getProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME); case PROP_CUR_SPRING_VOLUME -> getProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME);
case PROP_CUR_PERSIST_STAMINA -> getProperty(PlayerProperty.PROP_MAX_STAMINA); case PROP_CUR_PERSIST_STAMINA -> getProperty(PlayerProperty.PROP_MAX_STAMINA);
......
...@@ -4,6 +4,7 @@ import java.util.stream.Stream; ...@@ -4,6 +4,7 @@ import java.util.stream.Stream;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
public enum PlayerProperty { public enum PlayerProperty {
PROP_NONE (0), PROP_NONE (0),
...@@ -53,8 +54,8 @@ public enum PlayerProperty { ...@@ -53,8 +54,8 @@ public enum PlayerProperty {
PROP_PLAYER_WAIT_SUB_HOME_COIN (10043); PROP_PLAYER_WAIT_SUB_HOME_COIN (10043);
private static final int inf = Integer.MAX_VALUE; // Maybe this should be something else? private static final int inf = Integer.MAX_VALUE; // Maybe this should be something else?
private final int id, min, max; @Getter private final int id, min, max;
private final boolean dynamicRange; @Getter private final boolean dynamicRange;
private static final Int2ObjectMap<PlayerProperty> map = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<PlayerProperty> map = new Int2ObjectOpenHashMap<>();
static { static {
...@@ -84,22 +85,6 @@ public enum PlayerProperty { ...@@ -84,22 +85,6 @@ public enum PlayerProperty {
this(id, Integer.MIN_VALUE, inf, dynamicRange); this(id, Integer.MIN_VALUE, inf, dynamicRange);
} }
public int getId() {
return this.id;
}
public int getMin() {
return this.min;
}
public int getMax() {
return this.max;
}
public boolean getDynamicRange() {
return dynamicRange;
}
public static PlayerProperty getPropById(int value) { public static PlayerProperty getPropById(int value) {
return map.getOrDefault(value, null); return map.getOrDefault(value, null);
} }
......
...@@ -2,26 +2,28 @@ package emu.grasscutter.game.shop; ...@@ -2,26 +2,28 @@ package emu.grasscutter.game.shop;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.ShopGoodsData; import emu.grasscutter.data.excels.ShopGoodsData;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ShopInfo { public class ShopInfo {
private int goodsId = 0; @Getter @Setter private int goodsId = 0;
private ItemParamData goodsItem; @Getter @Setter private ItemParamData goodsItem;
private int scoin = 0; @Getter @Setter private int scoin = 0;
private List<ItemParamData> costItemList; @Getter @Setter private List<ItemParamData> costItemList;
private int boughtNum = 0; @Getter @Setter private int boughtNum = 0;
private int buyLimit = 0; @Getter @Setter private int buyLimit = 0;
private int beginTime = 0; @Getter @Setter private int beginTime = 0;
private int endTime = 1924992000; @Getter @Setter private int endTime = 1924992000;
private int minLevel = 0; @Getter @Setter private int minLevel = 0;
private int maxLevel = 61; @Getter @Setter private int maxLevel = 61;
private List<Integer> preGoodsIdList = new ArrayList<>(); @Getter @Setter private List<Integer> preGoodsIdList = new ArrayList<>();
private int mcoin = 0; @Getter @Setter private int mcoin = 0;
private int hcoin = 0; @Getter @Setter private int hcoin = 0;
private int disableType = 0; @Getter @Setter private int disableType = 0;
private int secondarySheetId = 0; @Getter @Setter private int secondarySheetId = 0;
private String refreshType; private String refreshType;
...@@ -41,8 +43,8 @@ public class ShopInfo { ...@@ -41,8 +43,8 @@ public class ShopInfo {
} }
} }
private transient ShopRefreshType shopRefreshType; @Setter private transient ShopRefreshType shopRefreshType;
private int shopRefreshParam; @Getter @Setter private int shopRefreshParam;
public ShopInfo(ShopGoodsData sgd) { public ShopInfo(ShopGoodsData sgd) {
this.goodsId = sgd.getGoodsId(); this.goodsId = sgd.getGoodsId();
...@@ -60,126 +62,6 @@ public class ShopInfo { ...@@ -60,126 +62,6 @@ public class ShopInfo {
this.shopRefreshParam = sgd.getRefreshParam(); this.shopRefreshParam = sgd.getRefreshParam();
} }
public int getHcoin() {
return hcoin;
}
public void setHcoin(int hcoin) {
this.hcoin = hcoin;
}
public List<Integer> getPreGoodsIdList() {
return preGoodsIdList;
}
public void setPreGoodsIdList(List<Integer> preGoodsIdList) {
this.preGoodsIdList = preGoodsIdList;
}
public int getMcoin() {
return mcoin;
}
public void setMcoin(int mcoin) {
this.mcoin = mcoin;
}
public int getDisableType() {
return disableType;
}
public void setDisableType(int disableType) {
this.disableType = disableType;
}
public int getSecondarySheetId() {
return secondarySheetId;
}
public void setSecondarySheetId(int secondarySheetId) {
this.secondarySheetId = secondarySheetId;
}
public int getGoodsId() {
return goodsId;
}
public void setGoodsId(int goodsId) {
this.goodsId = goodsId;
}
public ItemParamData getGoodsItem() {
return goodsItem;
}
public void setGoodsItem(ItemParamData goodsItem) {
this.goodsItem = goodsItem;
}
public int getScoin() {
return scoin;
}
public void setScoin(int scoin) {
this.scoin = scoin;
}
public List<ItemParamData> getCostItemList() {
return costItemList;
}
public void setCostItemList(List<ItemParamData> costItemList) {
this.costItemList = costItemList;
}
public int getBoughtNum() {
return boughtNum;
}
public void setBoughtNum(int boughtNum) {
this.boughtNum = boughtNum;
}
public int getBuyLimit() {
return buyLimit;
}
public void setBuyLimit(int buyLimit) {
this.buyLimit = buyLimit;
}
public int getBeginTime() {
return beginTime;
}
public void setBeginTime(int beginTime) {
this.beginTime = beginTime;
}
public int getEndTime() {
return endTime;
}
public void setEndTime(int endTime) {
this.endTime = endTime;
}
public int getMinLevel() {
return minLevel;
}
public void setMinLevel(int minLevel) {
this.minLevel = minLevel;
}
public int getMaxLevel() {
return maxLevel;
}
public void setMaxLevel(int maxLevel) {
this.maxLevel = maxLevel;
}
public ShopRefreshType getShopRefreshType() { public ShopRefreshType getShopRefreshType() {
if (refreshType == null) if (refreshType == null)
return ShopRefreshType.NONE; return ShopRefreshType.NONE;
...@@ -191,15 +73,16 @@ public class ShopInfo { ...@@ -191,15 +73,16 @@ public class ShopInfo {
}; };
} }
public void setShopRefreshType(ShopRefreshType shopRefreshType) { private boolean evaluateVirtualCost(ItemParamData item) {
this.shopRefreshType = shopRefreshType; return switch (item.getId()) {
} case 201 -> {this.hcoin += item.getCount(); yield true;}
case 203 -> {this.mcoin += item.getCount(); yield true;}
public int getShopRefreshParam() { default -> false;
return shopRefreshParam; };
} }
public void setShopRefreshParam(int shopRefreshParam) { public void removeVirtualCosts() {
this.shopRefreshParam = shopRefreshParam; if (this.costItemList != null)
this.costItemList.removeIf(item -> evaluateVirtualCost(item));
} }
} }
...@@ -3,7 +3,6 @@ package emu.grasscutter.game.shop; ...@@ -3,7 +3,6 @@ package emu.grasscutter.game.shop;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.DataLoader; import emu.grasscutter.data.DataLoader;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.ShopGoodsData; import emu.grasscutter.data.excels.ShopGoodsData;
import emu.grasscutter.server.game.BaseGameSystem; import emu.grasscutter.server.game.BaseGameSystem;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
...@@ -14,7 +13,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ...@@ -14,7 +13,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import static emu.grasscutter.config.Configuration.*; import static emu.grasscutter.config.Configuration.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class ShopSystem extends BaseGameSystem { public class ShopSystem extends BaseGameSystem {
...@@ -60,22 +58,7 @@ public class ShopSystem extends BaseGameSystem { ...@@ -60,22 +58,7 @@ public class ShopSystem extends BaseGameSystem {
List<ShopTable> banners = DataLoader.loadList("Shop.json", ShopTable.class); List<ShopTable> banners = DataLoader.loadList("Shop.json", ShopTable.class);
if (banners.size() > 0) { if (banners.size() > 0) {
for (ShopTable shopTable : banners) { for (ShopTable shopTable : banners) {
for (ShopInfo cost : shopTable.getItems()) { shopTable.getItems().forEach(ShopInfo::removeVirtualCosts);
if (cost.getCostItemList() != null) {
Iterator<ItemParamData> iterator = cost.getCostItemList().iterator();
while (iterator.hasNext()) {
ItemParamData ipd = iterator.next();
if (ipd.getId() == 201) {
cost.setHcoin(cost.getHcoin() + ipd.getCount());
iterator.remove();
}
if (ipd.getId() == 203) {
cost.setMcoin(cost.getMcoin() + ipd.getCount());
iterator.remove();
}
}
}
}
getShopData().put(shopTable.getShopId(), shopTable.getItems()); getShopData().put(shopTable.getShopId(), shopTable.getItems());
} }
Grasscutter.getLogger().debug("Shop data successfully loaded."); Grasscutter.getLogger().debug("Shop data successfully loaded.");
......
...@@ -28,6 +28,7 @@ import emu.grasscutter.utils.Position; ...@@ -28,6 +28,7 @@ import emu.grasscutter.utils.Position;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
public class Scene { public class Scene {
private final World world; private final World world;
...@@ -261,12 +262,11 @@ public class Scene { ...@@ -261,12 +262,11 @@ public class Scene {
} }
} }
private void removePlayerAvatars(Player player) { private synchronized void removePlayerAvatars(Player player) {
Iterator<EntityAvatar> it = player.getTeamManager().getActiveTeam().iterator(); var team = player.getTeamManager().getActiveTeam();
while (it.hasNext()) { // removeEntities(team, VisionType.VISION_TYPE_REMOVE); // List<SubType> isn't cool apparently :(
this.removeEntity(it.next(), VisionType.VISION_TYPE_REMOVE); team.forEach(e -> removeEntity(e, VisionType.VISION_TYPE_REMOVE));
it.remove(); team.clear();
}
} }
public void spawnPlayer(Player player) { public void spawnPlayer(Player player) {
...@@ -567,40 +567,40 @@ public class Scene { ...@@ -567,40 +567,40 @@ public class Scene {
return SceneIndexManager.queryNeighbors(getScriptManager().getBlocksIndex(), return SceneIndexManager.queryNeighbors(getScriptManager().getBlocksIndex(),
player.getPosition().toXZDoubleArray(), Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange); player.getPosition().toXZDoubleArray(), Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange);
} }
public void checkBlocks() {
Set<SceneBlock> visible = new HashSet<>();
for (Player player : this.getPlayers()) {
var blocks = getPlayerActiveBlocks(player);
visible.addAll(blocks);
}
Iterator<SceneBlock> it = this.getLoadedBlocks().iterator(); private boolean unloadBlockIfNotVisible(Collection<SceneBlock> visible, SceneBlock block) {
while (it.hasNext()) { if (visible.contains(block)) return false;
SceneBlock block = it.next(); this.onUnloadBlock(block);
return true;
if (!visible.contains(block)) {
it.remove();
onUnloadBlock(block);
} }
private synchronized boolean loadBlock(SceneBlock block) {
if (this.loadedBlocks.contains(block)) return false;
this.onLoadBlock(block, this.players);
this.loadedBlocks.add(block);
return true;
} }
for (var block : visible) { public synchronized void checkBlocks() {
if (!this.getLoadedBlocks().contains(block)) { Set<SceneBlock> visible = this.players.stream()
this.onLoadBlock(block, this.getPlayers()); .map(player -> this.getPlayerActiveBlocks(player))
this.getLoadedBlocks().add(block); .flatMap(Collection::stream)
}else { .collect(Collectors.toSet());
this.loadedBlocks.removeIf(block -> unloadBlockIfNotVisible(visible, block));
visible.stream()
.filter(block -> !this.loadBlock(block))
.forEach(block -> {
// dynamic load the groups for players in a loaded block // dynamic load the groups for players in a loaded block
var toLoad = this.getPlayers().stream() var toLoad = this.players.stream()
.filter(p -> block.contains(p.getPosition())) .filter(p -> block.contains(p.getPosition()))
.map(p -> playerMeetGroups(p, block)) .map(p -> this.playerMeetGroups(p, block))
.flatMap(Collection::stream) .flatMap(Collection::stream)
.toList(); .toList();
onLoadGroup(toLoad); this.onLoadGroup(toLoad);
} });
} }
}
public List<SceneGroup> playerMeetGroups(Player player, SceneBlock block) { public List<SceneGroup> playerMeetGroups(Player player, SceneBlock block) {
List<SceneGroup> sceneGroups = SceneIndexManager.queryNeighbors(block.sceneGroupIndex, player.getPosition().toDoubleArray(), List<SceneGroup> sceneGroups = SceneIndexManager.queryNeighbors(block.sceneGroupIndex, player.getPosition().toDoubleArray(),
Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange); Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange);
......
...@@ -330,10 +330,11 @@ public class World implements Iterable<Player> { ...@@ -330,10 +330,11 @@ public class World implements Iterable<Player> {
} }
} }
public void onTick() { // Returns true if the world should be deleted
for (Scene scene : this.getScenes().values()) { public boolean onTick() {
scene.onTick(); if (this.getPlayerCount() == 0) return true;
} this.scenes.forEach((k, scene) -> scene.onTick());
return false;
} }
public void close() { public void close() {
......
...@@ -218,21 +218,10 @@ public final class GameServer extends KcpServer { ...@@ -218,21 +218,10 @@ public final class GameServer extends KcpServer {
var tickStart = Instant.now(); var tickStart = Instant.now();
// Tick worlds. // Tick worlds.
Iterator<World> it = this.getWorlds().iterator(); this.worlds.removeIf(World::onTick);
while (it.hasNext()) {
World world = it.next();
if (world.getPlayerCount() == 0) {
it.remove();
}
world.onTick();
}
// Tick players. // Tick players.
for (Player player : this.getPlayers().values()) { this.players.values().forEach(Player::onTick);
player.onTick();
}
// Tick scheduler. // Tick scheduler.
this.getScheduler().runTasks(); this.getScheduler().runTasks();
......
...@@ -10,6 +10,7 @@ import emu.grasscutter.server.packet.send.PacketAvatarExpeditionAllDataRsp; ...@@ -10,6 +10,7 @@ import emu.grasscutter.server.packet.send.PacketAvatarExpeditionAllDataRsp;
public class HandlerAvatarExpeditionAllDataReq extends PacketHandler { public class HandlerAvatarExpeditionAllDataReq 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 {
session.send(new PacketAvatarExpeditionAllDataRsp(session.getPlayer())); var player = session.getPlayer();
session.send(new PacketAvatarExpeditionAllDataRsp(player.getExpeditionInfo(), player.getExpeditionLimit()));
} }
} }
...@@ -6,20 +6,19 @@ import emu.grasscutter.net.packet.PacketOpcodes; ...@@ -6,20 +6,19 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarExpeditionCallBackReqOuterClass.AvatarExpeditionCallBackReq; import emu.grasscutter.net.proto.AvatarExpeditionCallBackReqOuterClass.AvatarExpeditionCallBackReq;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarExpeditionCallBackRsp; import emu.grasscutter.server.packet.send.PacketAvatarExpeditionCallBackRsp;
import emu.grasscutter.server.packet.send.PacketAvatarExpeditionStartRsp;
import emu.grasscutter.utils.Utils;
@Opcodes(PacketOpcodes.AvatarExpeditionCallBackReq) @Opcodes(PacketOpcodes.AvatarExpeditionCallBackReq)
public class HandlerAvatarExpeditionCallBackReq extends PacketHandler { public class HandlerAvatarExpeditionCallBackReq 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 {
AvatarExpeditionCallBackReq req = AvatarExpeditionCallBackReq.parseFrom(payload); AvatarExpeditionCallBackReq req = AvatarExpeditionCallBackReq.parseFrom(payload);
var player = session.getPlayer();
for (int i = 0; i < req.getAvatarGuidCount(); i++) { for (int i = 0; i < req.getAvatarGuidCount(); i++) {
session.getPlayer().removeExpeditionInfo(req.getAvatarGuid(i)); player.removeExpeditionInfo(req.getAvatarGuid(i));
} }
session.getPlayer().save(); player.save();
session.send(new PacketAvatarExpeditionCallBackRsp(session.getPlayer())); session.send(new PacketAvatarExpeditionCallBackRsp(player.getExpeditionInfo()));
} }
} }
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.drop.DropData;
import emu.grasscutter.game.expedition.ExpeditionInfo; import emu.grasscutter.game.expedition.ExpeditionInfo;
import emu.grasscutter.game.expedition.ExpeditionRewardData;
import emu.grasscutter.game.expedition.ExpeditionRewardDataList; import emu.grasscutter.game.expedition.ExpeditionRewardDataList;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarExpeditionGetRewardReqOuterClass.AvatarExpeditionGetRewardReq; import emu.grasscutter.net.proto.AvatarExpeditionGetRewardReqOuterClass.AvatarExpeditionGetRewardReq;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarExpeditionCallBackRsp;
import emu.grasscutter.server.packet.send.PacketAvatarExpeditionGetRewardRsp; import emu.grasscutter.server.packet.send.PacketAvatarExpeditionGetRewardRsp;
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify; import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.utils.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List; import java.util.List;
@Opcodes(PacketOpcodes.AvatarExpeditionGetRewardReq) @Opcodes(PacketOpcodes.AvatarExpeditionGetRewardReq)
...@@ -29,33 +20,25 @@ public class HandlerAvatarExpeditionGetRewardReq extends PacketHandler { ...@@ -29,33 +20,25 @@ public class HandlerAvatarExpeditionGetRewardReq 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 {
AvatarExpeditionGetRewardReq req = AvatarExpeditionGetRewardReq.parseFrom(payload); AvatarExpeditionGetRewardReq req = AvatarExpeditionGetRewardReq.parseFrom(payload);
var player = session.getPlayer();
ExpeditionInfo expInfo = session.getPlayer().getExpeditionInfo(req.getAvatarGuid()); ExpeditionInfo expInfo = player.getExpeditionInfo(req.getAvatarGuid());
List<GameItem> items = new ArrayList<>();
List<ExpeditionRewardDataList> expeditionRewardDataLists = session.getServer().getExpeditionSystem().getExpeditionRewardDataList().get(expInfo.getExpId());
List<GameItem> items = new LinkedList<>(); if (expeditionRewardDataLists != null) {
expeditionRewardDataLists.stream()
if (session.getServer().getExpeditionSystem().getExpeditionRewardDataList().containsKey(expInfo.getExpId())) { .filter(r -> r.getHourTime() == expInfo.getHourTime())
for (ExpeditionRewardDataList RewardDataList : session.getServer().getExpeditionSystem().getExpeditionRewardDataList().get(expInfo.getExpId())) { .map(ExpeditionRewardDataList::getRewards)
if (RewardDataList.getHourTime() == expInfo.getHourTime()) { .forEach(items::addAll);
if (!RewardDataList.getExpeditionRewardData().isEmpty()) {
for (ExpeditionRewardData RewardData :RewardDataList.getExpeditionRewardData()) {
int num = RewardData.getMinCount();
if (RewardData.getMinCount() != RewardData.getMaxCount()) {
num = Utils.randomRange(RewardData.getMinCount(), RewardData.getMaxCount());
}
items.add(new GameItem(RewardData.getItemId(), num));
}
}
}
}
} }
session.getPlayer().getInventory().addItems(items); player.getInventory().addItems(items);
session.getPlayer().sendPacket(new PacketItemAddHintNotify(items, ActionReason.ExpeditionReward)); player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.ExpeditionReward));
session.getPlayer().removeExpeditionInfo(req.getAvatarGuid()); player.removeExpeditionInfo(req.getAvatarGuid());
session.getPlayer().save(); player.save();
session.send(new PacketAvatarExpeditionGetRewardRsp(session.getPlayer(), items)); session.send(new PacketAvatarExpeditionGetRewardRsp(player.getExpeditionInfo(), items));
} }
} }
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
...@@ -14,10 +13,11 @@ public class HandlerAvatarExpeditionStartReq extends PacketHandler { ...@@ -14,10 +13,11 @@ public class HandlerAvatarExpeditionStartReq 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 {
AvatarExpeditionStartReq req = AvatarExpeditionStartReq.parseFrom(payload); AvatarExpeditionStartReq req = AvatarExpeditionStartReq.parseFrom(payload);
var player = session.getPlayer();
int startTime = Utils.getCurrentSeconds(); int startTime = Utils.getCurrentSeconds();
session.getPlayer().addExpeditionInfo(req.getAvatarGuid(), req.getExpId(), req.getHourTime(), startTime); player.addExpeditionInfo(req.getAvatarGuid(), req.getExpId(), req.getHourTime(), startTime);
session.getPlayer().save(); player.save();
session.send(new PacketAvatarExpeditionStartRsp(session.getPlayer())); session.send(new PacketAvatarExpeditionStartRsp(player.getExpeditionInfo()));
} }
} }
...@@ -33,7 +33,7 @@ public class PacketAllWidgetDataNotify extends BasePacket { ...@@ -33,7 +33,7 @@ public class PacketAllWidgetDataNotify extends BasePacket {
// Good luck, my boy. // Good luck, my boy.
.addAllNormalCoolDownDataList(List.of()); .addAllNormalCoolDownDataList(List.of());
if (player.getWidgetId() == null) { if (player.getWidgetId() == 0) { // TODO: check this logic later, it was null-checking an int before which made it dead code
proto.addAllSlotList(List.of()); proto.addAllSlotList(List.of());
} else { } else {
proto.addSlotList( proto.addSlotList(
......
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.expedition.ExpeditionInfo; import emu.grasscutter.game.expedition.ExpeditionInfo;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarExpeditionAllDataRspOuterClass.AvatarExpeditionAllDataRsp; import emu.grasscutter.net.proto.AvatarExpeditionAllDataRspOuterClass.AvatarExpeditionAllDataRsp;
import emu.grasscutter.net.proto.AvatarExpeditionInfoOuterClass.AvatarExpeditionInfo;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class PacketAvatarExpeditionAllDataRsp extends BasePacket { public class PacketAvatarExpeditionAllDataRsp extends BasePacket {
public PacketAvatarExpeditionAllDataRsp(Player player) { public PacketAvatarExpeditionAllDataRsp(Map<Long, ExpeditionInfo> expeditionInfo, int expeditionCountLimit) {
super(PacketOpcodes.AvatarExpeditionAllDataRsp); super(PacketOpcodes.AvatarExpeditionAllDataRsp);
List<Integer> openExpeditionList = new ArrayList<>(List.of(306,305,304,303,302,301,206,105,204,104,203,103,202,101,102,201,106,205)); List<Integer> openExpeditionList = new ArrayList<>(List.of(306,305,304,303,302,301,206,105,204,104,203,103,202,101,102,201,106,205));
Map<Long, AvatarExpeditionInfo> avatarExpeditionInfoList = new HashMap<Long, AvatarExpeditionInfo>();
var expeditionInfo = player.getExpeditionInfo(); this.setData(AvatarExpeditionAllDataRsp.newBuilder()
for (Long key : player.getExpeditionInfo().keySet()) {
ExpeditionInfo e = expeditionInfo.get(key);
avatarExpeditionInfoList.put(key, AvatarExpeditionInfo.newBuilder().setStateValue(e.getState()).setExpId(e.getExpId()).setHourTime(e.getHourTime()).setStartTime(e.getStartTime()).build());
};
AvatarExpeditionAllDataRsp.Builder proto = AvatarExpeditionAllDataRsp.newBuilder()
.addAllOpenExpeditionList(openExpeditionList) .addAllOpenExpeditionList(openExpeditionList)
.setExpeditionCountLimit(5) .setExpeditionCountLimit(expeditionCountLimit)
.putAllExpeditionInfoMap(avatarExpeditionInfoList); .putAllExpeditionInfoMap(
expeditionInfo.entrySet().stream()
this.setData(proto.build()); .collect(Collectors.toMap(
e -> e.getKey(),
e -> e.getValue().toProto())))
.build());
} }
} }
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import java.util.Map;
import emu.grasscutter.game.expedition.ExpeditionInfo; import emu.grasscutter.game.expedition.ExpeditionInfo;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarExpeditionCallBackRspOuterClass.AvatarExpeditionCallBackRsp; import emu.grasscutter.net.proto.AvatarExpeditionCallBackRspOuterClass.AvatarExpeditionCallBackRsp;
import emu.grasscutter.net.proto.AvatarExpeditionInfoOuterClass.AvatarExpeditionInfo;
public class PacketAvatarExpeditionCallBackRsp extends BasePacket { public class PacketAvatarExpeditionCallBackRsp extends BasePacket {
public PacketAvatarExpeditionCallBackRsp(Player player) { public PacketAvatarExpeditionCallBackRsp(Map<Long, ExpeditionInfo> expeditionInfo) {
super(PacketOpcodes.AvatarExpeditionCallBackRsp); super(PacketOpcodes.AvatarExpeditionCallBackRsp);
AvatarExpeditionCallBackRsp.Builder proto = AvatarExpeditionCallBackRsp.newBuilder(); AvatarExpeditionCallBackRsp.Builder proto = AvatarExpeditionCallBackRsp.newBuilder();
var expeditionInfo = player.getExpeditionInfo(); expeditionInfo.forEach((key, e) -> proto.putExpeditionInfoMap(key, e.toProto()));
for (Long key : player.getExpeditionInfo().keySet()) {
ExpeditionInfo e = expeditionInfo.get(key);
proto.putExpeditionInfoMap(key, AvatarExpeditionInfo.newBuilder().setStateValue(e.getState()).setExpId(e.getExpId()).setHourTime(e.getHourTime()).setStartTime(e.getStartTime()).build());
};
this.setData(proto.build()); this.setData(proto.build());
} }
......
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.expedition.ExpeditionInfo; import emu.grasscutter.game.expedition.ExpeditionInfo;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarExpeditionDataNotifyOuterClass.AvatarExpeditionDataNotify; import emu.grasscutter.net.proto.AvatarExpeditionDataNotifyOuterClass.AvatarExpeditionDataNotify;
import emu.grasscutter.net.proto.AvatarExpeditionInfoOuterClass.AvatarExpeditionInfo;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class PacketAvatarExpeditionDataNotify extends BasePacket { public class PacketAvatarExpeditionDataNotify extends BasePacket {
public PacketAvatarExpeditionDataNotify(Player player) { public PacketAvatarExpeditionDataNotify(Map<Long, ExpeditionInfo> expeditionInfo) {
super(PacketOpcodes.AvatarExpeditionDataNotify); super(PacketOpcodes.AvatarExpeditionDataNotify);
Map<Long, AvatarExpeditionInfo> avatarExpeditionInfoList = new HashMap<Long, AvatarExpeditionInfo>(); this.setData(AvatarExpeditionDataNotify.newBuilder()
.putAllExpeditionInfoMap(
var expeditionInfo = player.getExpeditionInfo(); expeditionInfo.entrySet().stream()
for (Long key : player.getExpeditionInfo().keySet()) { .collect(Collectors.toMap(
ExpeditionInfo e = expeditionInfo.get(key); e -> e.getKey(),
avatarExpeditionInfoList.put(key, AvatarExpeditionInfo.newBuilder().setStateValue(e.getState()).setExpId(e.getExpId()).setHourTime(e.getHourTime()).setStartTime(e.getStartTime()).build()); e -> e.getValue().toProto())))
}; .build()
);
AvatarExpeditionDataNotify.Builder proto = AvatarExpeditionDataNotify.newBuilder()
.putAllExpeditionInfoMap(avatarExpeditionInfoList);
this.setData(proto.build());
} }
} }
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