Commit 6e81dc39 authored by Magix's avatar Magix Committed by GitHub
Browse files

Update Grasscutter to v1.0.0

Merge development into stable (and all the support hell that comes with it).
parents 1456cd99 4e1ea6ab
...@@ -7,7 +7,7 @@ import emu.grasscutter.utils.Utils; ...@@ -7,7 +7,7 @@ import emu.grasscutter.utils.Utils;
public class PlayerProfile { public class PlayerProfile {
@Transient private GenshinPlayer player; @Transient private GenshinPlayer player;
private int id; @AlsoLoad("id") private int uid;
private int nameCard; private int nameCard;
private int avatarId; private int avatarId;
private String name; private String name;
...@@ -22,12 +22,12 @@ public class PlayerProfile { ...@@ -22,12 +22,12 @@ public class PlayerProfile {
public PlayerProfile() { } public PlayerProfile() { }
public PlayerProfile(GenshinPlayer player) { public PlayerProfile(GenshinPlayer player) {
this.id = player.getUid(); this.uid = player.getUid();
this.syncWithCharacter(player); this.syncWithCharacter(player);
} }
public int getId() { public int getUid() {
return id; return uid;
} }
public GenshinPlayer getPlayer() { public GenshinPlayer getPlayer() {
...@@ -87,6 +87,7 @@ public class PlayerProfile { ...@@ -87,6 +87,7 @@ public class PlayerProfile {
return; return;
} }
this.uid = player.getUid();
this.name = player.getNickname(); this.name = player.getNickname();
this.avatarId = player.getHeadImage(); this.avatarId = player.getHeadImage();
this.signature = player.getSignature(); this.signature = player.getSignature();
......
...@@ -92,7 +92,7 @@ public class GachaBanner { ...@@ -92,7 +92,7 @@ public class GachaBanner {
} }
public GachaInfo toProto() { public GachaInfo toProto() {
String record = "http://" + (Grasscutter.getConfig().DispatchServerPublicIp.isEmpty() ? Grasscutter.getConfig().DispatchServerIp : Grasscutter.getConfig().DispatchServerPublicIp) + "/gacha"; String record = "http://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + "/gacha";
GachaInfo.Builder info = GachaInfo.newBuilder() GachaInfo.Builder info = GachaInfo.newBuilder()
.setGachaType(this.getGachaType()) .setGachaType(this.getGachaType())
......
package emu.grasscutter.game.gacha; package emu.grasscutter.game.gacha;
import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.nio.file.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
...@@ -8,6 +10,7 @@ import java.util.concurrent.ThreadLocalRandom; ...@@ -8,6 +10,7 @@ import java.util.concurrent.ThreadLocalRandom;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.sun.nio.file.SensitivityWatchEventModifier;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GenshinData; import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.def.ItemData;
...@@ -21,17 +24,20 @@ import emu.grasscutter.net.proto.GachaTransferItemOuterClass.GachaTransferItem; ...@@ -21,17 +24,20 @@ import emu.grasscutter.net.proto.GachaTransferItemOuterClass.GachaTransferItem;
import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp; import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam; import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.game.GameServerTickEvent;
import emu.grasscutter.server.packet.send.PacketDoGachaRsp; import emu.grasscutter.server.packet.send.PacketDoGachaRsp;
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 it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import org.greenrobot.eventbus.Subscribe;
public class GachaManager { public class GachaManager {
private final GameServer server; private final GameServer server;
private final Int2ObjectMap<GachaBanner> gachaBanners; private final Int2ObjectMap<GachaBanner> gachaBanners;
private GetGachaInfoRsp cachedProto; private GetGachaInfoRsp cachedProto;
WatchService watchService;
private int[] yellowAvatars = new int[] {1003, 1016, 1042, 1035, 1041}; private int[] yellowAvatars = new int[] {1003, 1016, 1042, 1035, 1041};
private int[] yellowWeapons = new int[] {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; private int[] yellowWeapons = new int[] {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
private int[] purpleAvatars = new int[] {1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064}; private int[] purpleAvatars = new int[] {1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064};
...@@ -40,11 +46,12 @@ public class GachaManager { ...@@ -40,11 +46,12 @@ public class GachaManager {
private static int starglitterId = 221; private static int starglitterId = 221;
private static int stardustId = 222; private static int stardustId = 222;
public GachaManager(GameServer server) { public GachaManager(GameServer server) {
this.server = server; this.server = server;
this.gachaBanners = new Int2ObjectOpenHashMap<>(); this.gachaBanners = new Int2ObjectOpenHashMap<>();
this.load(); this.load();
this.startWatcher(server);
} }
public GameServer getServer() { public GameServer getServer() {
...@@ -65,9 +72,16 @@ public class GachaManager { ...@@ -65,9 +72,16 @@ public class GachaManager {
public synchronized void load() { public synchronized void load() {
try (FileReader fileReader = new FileReader(Grasscutter.getConfig().DATA_FOLDER + "Banners.json")) { try (FileReader fileReader = new FileReader(Grasscutter.getConfig().DATA_FOLDER + "Banners.json")) {
getGachaBanners().clear();
List<GachaBanner> banners = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, GachaBanner.class).getType()); List<GachaBanner> banners = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, GachaBanner.class).getType());
for (GachaBanner banner : banners) { if(banners.size() > 0) {
getGachaBanners().put(banner.getGachaType(), banner); for (GachaBanner banner : banners) {
getGachaBanners().put(banner.getGachaType(), banner);
}
Grasscutter.getLogger().info("Banners successfully loaded.");
this.cachedProto = createProto();
} else {
Grasscutter.getLogger().error("Unable to load banners. Banners size is 0.");
} }
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
...@@ -204,7 +218,6 @@ public class GachaManager { ...@@ -204,7 +218,6 @@ public class GachaManager {
addStarglitter = 2; addStarglitter = 2;
// Add 1 const // Add 1 const
gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(constItem == null)); gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(constItem == null));
gachaItem.addTokenItemList(ItemParam.newBuilder().setItemId(constItemId).setCount(1));
player.getInventory().addItem(constItemId, 1); player.getInventory().addItem(constItemId, 1);
} else { } else {
// Is max const // Is max const
...@@ -266,6 +279,48 @@ public class GachaManager { ...@@ -266,6 +279,48 @@ public class GachaManager {
// Packets // Packets
player.sendPacket(new PacketDoGachaRsp(banner, list)); player.sendPacket(new PacketDoGachaRsp(banner, list));
} }
private synchronized void startWatcher(GameServer server) {
if(this.watchService == null) {
try {
this.watchService = FileSystems.getDefault().newWatchService();
Path path = new File(Grasscutter.getConfig().DATA_FOLDER).toPath();
path.register(watchService, new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY}, SensitivityWatchEventModifier.HIGH);
server.OnGameServerTick.register(this);
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload");
e.printStackTrace();
}
} else {
Grasscutter.getLogger().error("Cannot reinitialise watcher ");
}
}
@Subscribe
public synchronized void watchBannerJson(GameServerTickEvent tickEvent) {
if(Grasscutter.getConfig().getGameServerOptions().WatchGacha) {
try {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
final Path changed = (Path) event.context();
if (changed.endsWith("Banners.json")) {
Grasscutter.getLogger().info("Change detected with banners.json. Reloading gacha config");
this.load();
}
}
boolean valid = watchKey.reset();
if (!valid) {
Grasscutter.getLogger().error("Unable to reset Gacha Manager Watch Key. Auto-reload of banners.json will no longer work.");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private synchronized GetGachaInfoRsp createProto() { private synchronized GetGachaInfoRsp createProto() {
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345); GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
......
...@@ -37,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> { ...@@ -37,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> {
this.store = new Long2ObjectOpenHashMap<>(); this.store = new Long2ObjectOpenHashMap<>();
this.inventoryTypes = new Int2ObjectOpenHashMap<>(); this.inventoryTypes = new Int2ObjectOpenHashMap<>();
this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitWeapon)); this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitWeapon));
this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitRelic)); this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitRelic));
this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitMaterial)); this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitMaterial));
this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitFurniture)); this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(Grasscutter.getConfig().getGameServerOptions().InventoryLimitFurniture));
} }
public GenshinPlayer getPlayer() { public GenshinPlayer getPlayer() {
......
package emu.grasscutter.game.managers; package emu.grasscutter.game.managers;
import emu.grasscutter.commands.CommandMap; import emu.grasscutter.command.CommandMap;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
......
...@@ -589,7 +589,6 @@ public class InventoryManager { ...@@ -589,7 +589,6 @@ public class InventoryManager {
// Update proud skills // Update proud skills
AvatarSkillDepotData skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(avatar.getSkillDepotId()); AvatarSkillDepotData skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(avatar.getSkillDepotId());
boolean hasAddedProudSkill = false;
if (skillDepot != null && skillDepot.getInherentProudSkillOpens() != null) { if (skillDepot != null && skillDepot.getInherentProudSkillOpens() != null) {
for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) { for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) {
...@@ -599,7 +598,6 @@ public class InventoryManager { ...@@ -599,7 +598,6 @@ public class InventoryManager {
if (openData.getNeedAvatarPromoteLevel() == avatar.getPromoteLevel()) { if (openData.getNeedAvatarPromoteLevel() == avatar.getPromoteLevel()) {
int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1; int proudSkillId = (openData.getProudSkillGroupId() * 100) + 1;
if (GenshinData.getProudSkillDataMap().containsKey(proudSkillId)) { if (GenshinData.getProudSkillDataMap().containsKey(proudSkillId)) {
hasAddedProudSkill = true;
avatar.getProudSkillList().add(proudSkillId); avatar.getProudSkillList().add(proudSkillId);
player.sendPacket(new PacketProudSkillChangeNotify(avatar)); player.sendPacket(new PacketProudSkillChangeNotify(avatar));
} }
...@@ -607,20 +605,13 @@ public class InventoryManager { ...@@ -607,20 +605,13 @@ public class InventoryManager {
} }
} }
// Racalc stats and save avatar
avatar.recalcStats();
avatar.save();
// Resend ability embryos if proud skill has been added
if (hasAddedProudSkill && avatar.getAsEntity() != null) {
player.sendPacket(new PacketAbilityChangeNotify(avatar.getAsEntity()));
}
// TODO Send entity prop update packet to world
// Packets // Packets
player.sendPacket(new PacketAvatarPropNotify(avatar)); player.sendPacket(new PacketAvatarPropNotify(avatar));
player.sendPacket(new PacketAvatarPromoteRsp(avatar)); player.sendPacket(new PacketAvatarPromoteRsp(avatar));
// TODO Send entity prop update packet to world
avatar.recalcStats(true);
avatar.save();
} }
public void upgradeAvatar(GenshinPlayer player, long guid, int itemId, int count) { public void upgradeAvatar(GenshinPlayer player, long guid, int itemId, int count) {
...@@ -827,25 +818,20 @@ public class InventoryManager { ...@@ -827,25 +818,20 @@ public class InventoryManager {
// Apply + recalc // Apply + recalc
avatar.getTalentIdList().add(talentData.getId()); avatar.getTalentIdList().add(talentData.getId());
avatar.setCoreProudSkillLevel(currentTalentLevel + 1); avatar.setCoreProudSkillLevel(currentTalentLevel + 1);
avatar.recalcStats();
// Packet // Packet
player.sendPacket(new PacketAvatarUnlockTalentNotify(avatar, nextTalentId)); player.sendPacket(new PacketAvatarUnlockTalentNotify(avatar, nextTalentId));
player.sendPacket(new PacketUnlockAvatarTalentRsp(avatar, nextTalentId)); player.sendPacket(new PacketUnlockAvatarTalentRsp(avatar, nextTalentId));
// Proud skill bonus map // Proud skill bonus map (Extra skills)
OpenConfigEntry entry = GenshinData.getOpenConfigEntries().get(talentData.getOpenConfig()); OpenConfigEntry entry = GenshinData.getOpenConfigEntries().get(talentData.getOpenConfig());
if (entry != null && entry.getExtraTalentIndex() > 0) { if (entry != null && entry.getExtraTalentIndex() > 0) {
avatar.recalcProudSkillBonusMap(); avatar.recalcProudSkillBonusMap();
player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex())); player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex()));
} }
// Resend ability embryos // Recalc + save avatar
if (avatar.getAsEntity() != null) { avatar.recalcStats(true);
player.sendPacket(new PacketAbilityChangeNotify(avatar.getAsEntity()));
}
// Save avatar
avatar.save(); avatar.save();
} }
......
package emu.grasscutter.game.props;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public enum FetterState {
NONE(0),
NOT_OPEN(1),
OPEN(1),
FINISH(3);
private final int value;
private static final Int2ObjectMap<FetterState> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, FetterState> stringMap = new HashMap<>();
static {
Stream.of(values()).forEach(e -> {
map.put(e.getValue(), e);
stringMap.put(e.name(), e);
});
}
private FetterState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static FetterState getTypeByValue(int value) {
return map.getOrDefault(value, NONE);
}
public static FetterState getTypeByName(String name) {
return stringMap.getOrDefault(name, NONE);
}
}
...@@ -7,7 +7,7 @@ public class ComboTokenReqJson { ...@@ -7,7 +7,7 @@ public class ComboTokenReqJson {
public String device; public String device;
public String sign; public String sign;
public class LoginTokenData { public static class LoginTokenData {
public String uid; public String uid;
public String token; public String token;
public boolean guest; public boolean guest;
......
...@@ -5,7 +5,7 @@ public class ComboTokenResJson { ...@@ -5,7 +5,7 @@ public class ComboTokenResJson {
public int retcode; public int retcode;
public LoginData data = new LoginData(); public LoginData data = new LoginData();
public class LoginData { public static class LoginData {
public int account_type = 1; public int account_type = 1;
public boolean heartbeat; public boolean heartbeat;
public String combo_id; public String combo_id;
......
...@@ -5,7 +5,7 @@ public class LoginResultJson { ...@@ -5,7 +5,7 @@ public class LoginResultJson {
public int retcode; public int retcode;
public VerifyData data = new VerifyData(); public VerifyData data = new VerifyData();
public class VerifyData { public static class VerifyData {
public VerifyAccountData account = new VerifyAccountData(); public VerifyAccountData account = new VerifyAccountData();
public boolean device_grant_required = false; public boolean device_grant_required = false;
public String realname_operation = "NONE"; public String realname_operation = "NONE";
...@@ -13,7 +13,7 @@ public class LoginResultJson { ...@@ -13,7 +13,7 @@ public class LoginResultJson {
public boolean safe_mobile_required = false; public boolean safe_mobile_required = false;
} }
public class VerifyAccountData { public static class VerifyAccountData {
public String uid; public String uid;
public String name = ""; public String name = "";
public String email; public String email;
......
...@@ -87,7 +87,7 @@ public class GameServerPacketHandler { ...@@ -87,7 +87,7 @@ public class GameServerPacketHandler {
} }
// Log unhandled packets // Log unhandled packets
if (Grasscutter.getConfig().LOG_PACKETS) { if (Grasscutter.getConfig().getGameServerOptions().LOG_PACKETS) {
//Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode)); //Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode));
} }
} }
......
package emu.grasscutter.server.game;
public class GameServerStartFinishEvent {
// Placeholder class for now, probably will get used later
}
package emu.grasscutter.server.game;
public class GameServerStopEvent {
// Placeholder class for now, probably will get used later
}
package emu.grasscutter.server.game;
public class GameServerTickEvent {
// Placeholder class for now, probably will get used later
}
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