mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-06-26 18:14:50 +08:00
Compare commits
No commits in common. "ac3214f10a523d2ee4c8e76506274342d5cd0962" and "00bd23873fca3b56056d6521e82e233e64a23c74" have entirely different histories.
ac3214f10a
...
00bd23873f
@ -1,12 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option java_package = "emu.grasscutter.net.proto";
|
|
||||||
|
|
||||||
// CmdId: 1706
|
|
||||||
// EnetChannelId: 0
|
|
||||||
// EnetIsReliable: true
|
|
||||||
// IsAllowClient: true
|
|
||||||
message AvatarChangeElementTypeReq {
|
|
||||||
uint32 scene_id = 15;
|
|
||||||
uint32 area_id = 4;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option java_package = "emu.grasscutter.net.proto";
|
|
||||||
|
|
||||||
// CmdId: 1708
|
|
||||||
// EnetChannelId: 0
|
|
||||||
// EnetIsReliable: true
|
|
||||||
message AvatarChangeElementTypeRsp {
|
|
||||||
int32 retcode = 15;
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option java_package = "emu.grasscutter.net.proto";
|
|
||||||
|
|
||||||
// CmdId: 1037
|
|
||||||
// EnetChannelId: 0
|
|
||||||
// EnetIsReliable: true
|
|
||||||
message AvatarSkillDepotChangeNotify {
|
|
||||||
uint64 avatar_guid = 2;
|
|
||||||
uint32 entity_id = 8;
|
|
||||||
uint32 skill_depot_id = 9;
|
|
||||||
repeated uint32 talent_id_list = 1;
|
|
||||||
repeated uint32 proud_skill_list = 5;
|
|
||||||
uint32 core_proud_skill_level = 4;
|
|
||||||
map<uint32, uint32> skill_level_map = 10;
|
|
||||||
map<uint32, uint32> proud_skill_extra_level_map = 11;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option java_package = "emu.grasscutter.net.proto";
|
|
||||||
|
|
||||||
// CmdId: 1532
|
|
||||||
// EnetChannelId: 0
|
|
||||||
// EnetIsReliable: true
|
|
||||||
// IsAllowClient: true
|
|
||||||
message GachaWishReq {
|
|
||||||
uint32 gacha_type = 2;
|
|
||||||
uint32 gacha_schedule_id = 4;
|
|
||||||
uint32 item_id = 14;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option java_package = "emu.grasscutter.net.proto";
|
|
||||||
|
|
||||||
// CmdId: 1517
|
|
||||||
// EnetChannelId: 0
|
|
||||||
// EnetIsReliable: true
|
|
||||||
message GachaWishRsp {
|
|
||||||
int32 retcode = 7;
|
|
||||||
uint32 gacha_type = 14;
|
|
||||||
uint32 gacha_schedule_id = 15;
|
|
||||||
uint32 wish_item_id = 3;
|
|
||||||
uint32 wish_progress = 12;
|
|
||||||
uint32 wish_max_progress = 10;
|
|
||||||
}
|
|
@ -6,10 +6,8 @@ import java.util.Calendar;
|
|||||||
import emu.grasscutter.auth.AuthenticationSystem;
|
import emu.grasscutter.auth.AuthenticationSystem;
|
||||||
import emu.grasscutter.auth.DefaultAuthentication;
|
import emu.grasscutter.auth.DefaultAuthentication;
|
||||||
import emu.grasscutter.command.CommandMap;
|
import emu.grasscutter.command.CommandMap;
|
||||||
import emu.grasscutter.command.DefaultPermissionHandler;
|
import emu.grasscutter.game.managers.EnergyManager.EnergyManager;
|
||||||
import emu.grasscutter.command.PermissionHandler;
|
import emu.grasscutter.game.managers.StaminaManager.StaminaManager;
|
||||||
import emu.grasscutter.game.managers.energy.EnergyManager;
|
|
||||||
import emu.grasscutter.game.managers.stamina.StaminaManager;
|
|
||||||
import emu.grasscutter.plugin.PluginManager;
|
import emu.grasscutter.plugin.PluginManager;
|
||||||
import emu.grasscutter.plugin.api.ServerHook;
|
import emu.grasscutter.plugin.api.ServerHook;
|
||||||
import emu.grasscutter.scripts.ScriptLoader;
|
import emu.grasscutter.scripts.ScriptLoader;
|
||||||
@ -60,7 +58,6 @@ public final class Grasscutter {
|
|||||||
private static GameServer gameServer;
|
private static GameServer gameServer;
|
||||||
private static PluginManager pluginManager;
|
private static PluginManager pluginManager;
|
||||||
private static AuthenticationSystem authenticationSystem;
|
private static AuthenticationSystem authenticationSystem;
|
||||||
private static PermissionHandler permissionHandler;
|
|
||||||
|
|
||||||
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
||||||
public static ConfigContainer config;
|
public static ConfigContainer config;
|
||||||
@ -117,9 +114,8 @@ public final class Grasscutter {
|
|||||||
// Initialize database.
|
// Initialize database.
|
||||||
DatabaseManager.initialize();
|
DatabaseManager.initialize();
|
||||||
|
|
||||||
// Initialize the default systems.
|
// Initialize the default authentication system.
|
||||||
authenticationSystem = new DefaultAuthentication();
|
authenticationSystem = new DefaultAuthentication();
|
||||||
permissionHandler = new DefaultPermissionHandler();
|
|
||||||
|
|
||||||
// Create server instances.
|
// Create server instances.
|
||||||
httpServer = new HttpServer();
|
httpServer = new HttpServer();
|
||||||
@ -291,10 +287,6 @@ public final class Grasscutter {
|
|||||||
return authenticationSystem;
|
return authenticationSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PermissionHandler getPermissionHandler() {
|
|
||||||
return permissionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCurrentDayOfWeek() {
|
public static int getCurrentDayOfWeek() {
|
||||||
return day;
|
return day;
|
||||||
}
|
}
|
||||||
@ -354,14 +346,6 @@ public final class Grasscutter {
|
|||||||
Grasscutter.authenticationSystem = authenticationSystem;
|
Grasscutter.authenticationSystem = authenticationSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the permission handler for the server.
|
|
||||||
* @param permissionHandler The permission handler to use.
|
|
||||||
*/
|
|
||||||
public static void setPermissionHandler(PermissionHandler permissionHandler) {
|
|
||||||
Grasscutter.permissionHandler = permissionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enums for the configuration.
|
* Enums for the configuration.
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,6 @@ public final class CommandMap {
|
|||||||
private final Map<String, Command> annotations = new HashMap<>();
|
private final Map<String, Command> annotations = new HashMap<>();
|
||||||
private final Map<String, Integer> targetPlayerIds = new HashMap<>();
|
private final Map<String, Integer> targetPlayerIds = new HashMap<>();
|
||||||
private static final String consoleId = "console";
|
private static final String consoleId = "console";
|
||||||
|
|
||||||
public CommandMap() {
|
public CommandMap() {
|
||||||
this(false);
|
this(false);
|
||||||
}
|
}
|
||||||
@ -203,9 +202,21 @@ public final class CommandMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for permissions.
|
// Check for permission.
|
||||||
if (!Grasscutter.getPermissionHandler().checkPermission(player, targetPlayer, this.annotations.get(label).permission(), this.annotations.get(label).permissionTargeted())) {
|
if (player != null) {
|
||||||
return;
|
String permissionNode = this.annotations.get(label).permission();
|
||||||
|
String permissionNodeTargeted = this.annotations.get(label).permissionTargeted();
|
||||||
|
Account account = player.getAccount();
|
||||||
|
if (player != targetPlayer) { // Additional permission required for targeting another player
|
||||||
|
if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) {
|
||||||
|
CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) {
|
||||||
|
CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if command has unfulfilled constraints on targetPlayer
|
// Check if command has unfulfilled constraints on targetPlayer
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package emu.grasscutter.command;
|
|
||||||
|
|
||||||
import emu.grasscutter.game.Account;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
|
|
||||||
public class DefaultPermissionHandler implements PermissionHandler {
|
|
||||||
@Override
|
|
||||||
public boolean EnablePermissionCommand() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkPermission(Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted) {
|
|
||||||
if(player == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Account account = player.getAccount();
|
|
||||||
if (player != targetPlayer) { // Additional permission required for targeting another player
|
|
||||||
if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) {
|
|
||||||
CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) {
|
|
||||||
CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package emu.grasscutter.command;
|
|
||||||
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
|
|
||||||
public interface PermissionHandler {
|
|
||||||
public boolean EnablePermissionCommand();
|
|
||||||
public boolean checkPermission(Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted);
|
|
||||||
}
|
|
@ -20,11 +20,6 @@ public final class PermissionCommand implements CommandHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Grasscutter.getPermissionHandler().EnablePermissionCommand()) {
|
|
||||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.permission_error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String action = args.get(0);
|
String action = args.get(0);
|
||||||
String permission = args.get(1);
|
String permission = args.get(1);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import emu.grasscutter.command.Command;
|
|||||||
import emu.grasscutter.command.CommandHandler;
|
import emu.grasscutter.command.CommandHandler;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.entity.EntityAvatar;
|
import emu.grasscutter.game.entity.EntityAvatar;
|
||||||
import emu.grasscutter.game.managers.energy.EnergyManager;
|
import emu.grasscutter.game.managers.EnergyManager.EnergyManager;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.player.TeamManager;
|
import emu.grasscutter.game.player.TeamManager;
|
||||||
import emu.grasscutter.game.props.ElementType;
|
import emu.grasscutter.game.props.ElementType;
|
||||||
|
@ -77,7 +77,6 @@ public class GameData {
|
|||||||
private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
||||||
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
|
||||||
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
@ -320,10 +319,6 @@ public class GameData {
|
|||||||
|
|
||||||
public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList(){return codexReliquaryArrayList;}
|
public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList(){return codexReliquaryArrayList;}
|
||||||
|
|
||||||
public static Int2ObjectMap<WorldAreaData> getWorldAreaDataMap() {
|
|
||||||
return worldAreaDataMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Int2ObjectMap<WorldLevelData> getWorldLevelDataMap() {
|
public static Int2ObjectMap<WorldLevelData> getWorldLevelDataMap() {
|
||||||
return worldLevelDataMap;
|
return worldLevelDataMap;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package emu.grasscutter.data;
|
package emu.grasscutter.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.danilopianini.util.FlexibleQuadTree;
|
import org.danilopianini.util.FlexibleQuadTree;
|
||||||
import org.danilopianini.util.SpatialIndex;
|
import org.danilopianini.util.SpatialIndex;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
|
||||||
import emu.grasscutter.data.ResourceLoader.AvatarConfigAbility;
|
|
||||||
import emu.grasscutter.data.excels.ReliquaryAffixData;
|
import emu.grasscutter.data.excels.ReliquaryAffixData;
|
||||||
import emu.grasscutter.data.excels.ReliquaryMainPropData;
|
import emu.grasscutter.data.excels.ReliquaryMainPropData;
|
||||||
import emu.grasscutter.game.world.SpawnDataEntry;
|
import emu.grasscutter.game.world.SpawnDataEntry;
|
||||||
@ -23,7 +19,6 @@ public class GameDepot {
|
|||||||
private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicMainPropDepot = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicMainPropDepot = new Int2ObjectOpenHashMap<>();
|
||||||
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
|
||||||
private static Int2ObjectMap<SpatialIndex<SpawnGroupEntry>> spawnLists = new Int2ObjectOpenHashMap<>();
|
private static Int2ObjectMap<SpatialIndex<SpawnGroupEntry>> spawnLists = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
@ -66,12 +61,4 @@ public class GameDepot {
|
|||||||
public static SpatialIndex<SpawnGroupEntry> getSpawnListById(int sceneId) {
|
public static SpatialIndex<SpawnGroupEntry> getSpawnListById(int sceneId) {
|
||||||
return getSpawnLists().computeIfAbsent(sceneId, id -> new FlexibleQuadTree<>());
|
return getSpawnLists().computeIfAbsent(sceneId, id -> new FlexibleQuadTree<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, AvatarConfig> getPlayerAbilities() {
|
|
||||||
return playerAbilities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setPlayerAbilities(Map<String, AvatarConfig> playerAbilities) {
|
|
||||||
GameDepot.playerAbilities = playerAbilities;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,37 @@ public class ResourceLoader {
|
|||||||
loadQuests();
|
loadQuests();
|
||||||
// Load scene points - must be done AFTER resources are loaded
|
// Load scene points - must be done AFTER resources are loaded
|
||||||
loadScenePoints();
|
loadScenePoints();
|
||||||
|
// Custom - TODO move this somewhere else
|
||||||
|
try {
|
||||||
|
GameData.getAvatarSkillDepotDataMap().get(504).setAbilities(
|
||||||
|
new AbilityEmbryoEntry(
|
||||||
|
"",
|
||||||
|
new String[] {
|
||||||
|
"Avatar_PlayerBoy_ExtraAttack_Wind",
|
||||||
|
"Avatar_Player_UziExplode_Mix",
|
||||||
|
"Avatar_Player_UziExplode",
|
||||||
|
"Avatar_Player_UziExplode_Strike_01",
|
||||||
|
"Avatar_Player_UziExplode_Strike_02",
|
||||||
|
"Avatar_Player_WindBreathe",
|
||||||
|
"Avatar_Player_WindBreathe_CameraController"
|
||||||
|
}
|
||||||
|
));
|
||||||
|
GameData.getAvatarSkillDepotDataMap().get(704).setAbilities(
|
||||||
|
new AbilityEmbryoEntry(
|
||||||
|
"",
|
||||||
|
new String[] {
|
||||||
|
"Avatar_PlayerGirl_ExtraAttack_Wind",
|
||||||
|
"Avatar_Player_UziExplode_Mix",
|
||||||
|
"Avatar_Player_UziExplode",
|
||||||
|
"Avatar_Player_UziExplode_Strike_01",
|
||||||
|
"Avatar_Player_UziExplode_Strike_02",
|
||||||
|
"Avatar_Player_WindBreathe",
|
||||||
|
"Avatar_Player_WindBreathe_CameraController"
|
||||||
|
}
|
||||||
|
));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("Error loading abilities", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadResources() {
|
public static void loadResources() {
|
||||||
@ -213,16 +244,6 @@ public class ResourceLoader {
|
|||||||
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
||||||
embryoList.add(al);
|
embryoList.add(al);
|
||||||
}
|
}
|
||||||
|
|
||||||
File playerElementsFile = new File(Utils.toFilePath(RESOURCE("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json")));
|
|
||||||
|
|
||||||
if (playerElementsFile.exists()) {
|
|
||||||
try (FileReader fileReader = new FileReader(playerElementsFile)) {
|
|
||||||
GameDepot.setPlayerAbilities(Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<String, AvatarConfig>>(){}.getType()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (embryoList == null || embryoList.isEmpty()) {
|
if (embryoList == null || embryoList.isEmpty()) {
|
||||||
@ -396,15 +417,14 @@ public class ResourceLoader {
|
|||||||
|
|
||||||
// BinOutput configs
|
// BinOutput configs
|
||||||
|
|
||||||
public static class AvatarConfig {
|
private static class AvatarConfig {
|
||||||
@SerializedName(value="abilities", alternate={"targetAbilities"})
|
|
||||||
public ArrayList<AvatarConfigAbility> abilities;
|
public ArrayList<AvatarConfigAbility> abilities;
|
||||||
}
|
|
||||||
|
private static class AvatarConfigAbility {
|
||||||
public static class AvatarConfigAbility {
|
public String abilityName;
|
||||||
public String abilityName;
|
public String toString() {
|
||||||
public String toString() {
|
return abilityName;
|
||||||
return abilityName;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,7 @@ package emu.grasscutter.data.excels;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.GameDepot;
|
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
|
||||||
import emu.grasscutter.data.ResourceLoader.AvatarConfigAbility;
|
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
||||||
@ -98,21 +95,12 @@ public class AvatarSkillDepotData extends GameResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
// Set energy skill data
|
|
||||||
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
|
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
|
||||||
if (getEnergySkillData() != null) {
|
if (getEnergySkillData() != null) {
|
||||||
this.elementType = getEnergySkillData().getCostElemType();
|
this.elementType = getEnergySkillData().getCostElemType();
|
||||||
} else {
|
} else {
|
||||||
this.elementType = ElementType.None;
|
this.elementType = ElementType.None;
|
||||||
}
|
}
|
||||||
// Set embryo abilities (if player skill depot)
|
|
||||||
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
|
|
||||||
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
|
|
||||||
|
|
||||||
if (config != null) {
|
|
||||||
this.setAbilities(new AbilityEmbryoEntry(getSkillDepotAbilityGroup(), config.abilities.stream().map(Object::toString).toArray(String[]::new)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InherentProudSkillOpens {
|
public static class InherentProudSkillOpens {
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package emu.grasscutter.data.excels;
|
|
||||||
|
|
||||||
import emu.grasscutter.data.GameResource;
|
|
||||||
import emu.grasscutter.data.ResourceType;
|
|
||||||
import emu.grasscutter.game.props.ElementType;
|
|
||||||
|
|
||||||
@ResourceType(name = "WorldAreaConfigData.json")
|
|
||||||
public class WorldAreaData extends GameResource {
|
|
||||||
private int ID;
|
|
||||||
private int AreaID1;
|
|
||||||
private int AreaID2;
|
|
||||||
private int SceneID;
|
|
||||||
private ElementType elementType;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return (this.AreaID2 << 16) + this.AreaID1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSceneID() {
|
|
||||||
return this.SceneID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ElementType getElementType() {
|
|
||||||
return this.elementType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,5 @@
|
|||||||
package emu.grasscutter.game.gacha;
|
package emu.grasscutter.game.gacha;
|
||||||
|
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
|
||||||
import emu.grasscutter.game.Account;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
||||||
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
|
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
@ -47,7 +44,6 @@ public class GachaBanner {
|
|||||||
private int[] rateUpItems2 = {};
|
private int[] rateUpItems2 = {};
|
||||||
private int eventChance = -1;
|
private int eventChance = -1;
|
||||||
private int costItem = 0;
|
private int costItem = 0;
|
||||||
private int wishMaxProgress = 2;
|
|
||||||
|
|
||||||
public int getGachaType() {
|
public int getGachaType() {
|
||||||
return gachaType;
|
return gachaType;
|
||||||
@ -112,11 +108,6 @@ public class GachaBanner {
|
|||||||
public boolean getRemoveC6FromPool() {return removeC6FromPool;}
|
public boolean getRemoveC6FromPool() {return removeC6FromPool;}
|
||||||
public boolean getAutoStripRateUpFromFallback() {return autoStripRateUpFromFallback;}
|
public boolean getAutoStripRateUpFromFallback() {return autoStripRateUpFromFallback;}
|
||||||
|
|
||||||
public int getWishMaxProgress() {return wishMaxProgress;}
|
|
||||||
|
|
||||||
public boolean hasEpitomized() {
|
|
||||||
return bannerType.equals(BannerType.WEAPON);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeight(int rarity, int pity) {
|
public int getWeight(int rarity, int pity) {
|
||||||
return switch(rarity) {
|
return switch(rarity) {
|
||||||
@ -138,11 +129,13 @@ public class GachaBanner {
|
|||||||
default -> (eventChance > -1) ? eventChance : eventChance5;
|
default -> (eventChance > -1) ? eventChance : eventChance5;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public GachaInfo toProto() {
|
||||||
|
return toProto("");
|
||||||
|
}
|
||||||
|
|
||||||
public GachaInfo toProto(Player player) {
|
public GachaInfo toProto(String sessionKey) {
|
||||||
// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
|
|
||||||
String sessionKey = player.getAccount().getSessionKey();
|
|
||||||
|
|
||||||
String record = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
String record = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
||||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
||||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
||||||
@ -173,15 +166,6 @@ public class GachaBanner {
|
|||||||
.setLeftGachaTimes(Integer.MAX_VALUE)
|
.setLeftGachaTimes(Integer.MAX_VALUE)
|
||||||
.setGachaTimesLimit(Integer.MAX_VALUE)
|
.setGachaTimesLimit(Integer.MAX_VALUE)
|
||||||
.setGachaSortId(this.getSortId());
|
.setGachaSortId(this.getSortId());
|
||||||
|
|
||||||
if(hasEpitomized()) {
|
|
||||||
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
|
|
||||||
|
|
||||||
info.setWishItemId(gachaInfo.getWishItemId())
|
|
||||||
.setWishProgress(gachaInfo.getFailedChosenItemPulls())
|
|
||||||
.setWishMaxProgress(this.getWishMaxProgress());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getTitlePath() != null) {
|
if (this.getTitlePath() != null) {
|
||||||
info.setTitleTextmap(this.getTitlePath());
|
info.setTitleTextmap(this.getTitlePath());
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
|||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import emu.grasscutter.server.game.GameServerTickEvent;
|
import emu.grasscutter.server.game.GameServerTickEvent;
|
||||||
import emu.grasscutter.server.packet.send.PacketDoGachaRsp;
|
import emu.grasscutter.server.packet.send.PacketDoGachaRsp;
|
||||||
import emu.grasscutter.server.packet.send.PacketGachaWishRsp;
|
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
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;
|
||||||
@ -48,7 +47,8 @@ import static emu.grasscutter.Configuration.*;
|
|||||||
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 WatchService watchService;
|
private GetGachaInfoRsp cachedProto;
|
||||||
|
WatchService watchService;
|
||||||
|
|
||||||
private static final int starglitterId = 221;
|
private static final int starglitterId = 221;
|
||||||
private static final int stardustId = 222;
|
private static final int stardustId = 222;
|
||||||
@ -87,6 +87,9 @@ public class GachaManager {
|
|||||||
getGachaBanners().put(banner.getScheduleId(), banner);
|
getGachaBanners().put(banner.getScheduleId(), banner);
|
||||||
}
|
}
|
||||||
Grasscutter.getLogger().info("Banners successfully loaded.");
|
Grasscutter.getLogger().info("Banners successfully loaded.");
|
||||||
|
|
||||||
|
|
||||||
|
this.cachedProto = createProto();
|
||||||
} else {
|
} else {
|
||||||
Grasscutter.getLogger().error("Unable to load banners. Banners size is 0.");
|
Grasscutter.getLogger().error("Unable to load banners. Banners size is 0.");
|
||||||
}
|
}
|
||||||
@ -179,59 +182,38 @@ public class GachaManager {
|
|||||||
return 0; // This should only be reachable if total==0
|
return 0; // This should only be reachable if total==0
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized int doFallbackRarePull(int[] fallback1, int[] fallback2, int rarity, GachaBanner banner, PlayerGachaBannerInfo gachaInfo) {
|
|
||||||
if (fallback1.length < 1) {
|
|
||||||
if (fallback2.length < 1) {
|
|
||||||
return getRandom((rarity==5)? fallbackItems5Pool2Default : fallbackItems4Pool2Default);
|
|
||||||
} else {
|
|
||||||
return getRandom(fallback2);
|
|
||||||
}
|
|
||||||
} else if (fallback2.length < 1) {
|
|
||||||
return getRandom(fallback1);
|
|
||||||
} else { // Both pools are possible, use the pool balancer
|
|
||||||
int pityPool1 = banner.getPoolBalanceWeight(rarity, gachaInfo.getPityPool(rarity, 1));
|
|
||||||
int pityPool2 = banner.getPoolBalanceWeight(rarity, gachaInfo.getPityPool(rarity, 2));
|
|
||||||
int chosenPool = switch ((pityPool1 >= pityPool2)? 1 : 0) { // Larger weight must come first for the hard cutoff to function correctly
|
|
||||||
case 1 -> 1 + drawRoulette(new int[] {pityPool1, pityPool2}, 10000);
|
|
||||||
default -> 2 - drawRoulette(new int[] {pityPool2, pityPool1}, 10000);
|
|
||||||
};
|
|
||||||
return switch (chosenPool) {
|
|
||||||
case 1:
|
|
||||||
gachaInfo.setPityPool(rarity, 1, 0);
|
|
||||||
yield getRandom(fallback1);
|
|
||||||
default:
|
|
||||||
gachaInfo.setPityPool(rarity, 2, 0);
|
|
||||||
yield getRandom(fallback2);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized int doRarePull(int[] featured, int[] fallback1, int[] fallback2, int rarity, GachaBanner banner, PlayerGachaBannerInfo gachaInfo) {
|
private synchronized int doRarePull(int[] featured, int[] fallback1, int[] fallback2, int rarity, GachaBanner banner, PlayerGachaBannerInfo gachaInfo) {
|
||||||
int itemId = 0;
|
int itemId = 0;
|
||||||
boolean epitomized = (banner.hasEpitomized()) && (rarity == 5) && (gachaInfo.getWishItemId() != 0);
|
boolean pullFeatured = (gachaInfo.getFailedFeaturedItemPulls(rarity) >= 1) // Lost previous coinflip
|
||||||
boolean pityEpitomized = (gachaInfo.getFailedChosenItemPulls() >= banner.getWishMaxProgress()); // Maximum fate points reached
|
|| (this.randomRange(1, 100) <= banner.getEventChance(rarity)); // Won this coinflip
|
||||||
boolean pityFeatured = (gachaInfo.getFailedFeaturedItemPulls(rarity) >= 1); // Lost previous coinflip
|
if (pullFeatured && (featured.length > 0)) {
|
||||||
boolean rollFeatured = (this.randomRange(1, 100) <= banner.getEventChance(rarity)); // Won this coinflip
|
itemId = getRandom(featured);
|
||||||
boolean pullFeatured = pityFeatured || rollFeatured;
|
gachaInfo.setFailedFeaturedItemPulls(rarity, 0);
|
||||||
|
|
||||||
if (epitomized && pityEpitomized) { // Auto pick item when epitomized points reached
|
|
||||||
gachaInfo.setFailedFeaturedItemPulls(rarity, 0); // Epitomized item will always be a featured one
|
|
||||||
itemId = gachaInfo.getWishItemId();
|
|
||||||
} else {
|
} else {
|
||||||
if (pullFeatured && (featured.length > 0)) {
|
gachaInfo.addFailedFeaturedItemPulls(rarity, 1);
|
||||||
gachaInfo.setFailedFeaturedItemPulls(rarity, 0);
|
if (fallback1.length < 1) {
|
||||||
itemId = getRandom(featured);
|
if (fallback2.length < 1) {
|
||||||
} else {
|
itemId = getRandom((rarity==5)? fallbackItems5Pool2Default : fallbackItems4Pool2Default);
|
||||||
gachaInfo.addFailedFeaturedItemPulls(rarity, 1); // This could be moved into doFallbackRarePull but having it here makes it clearer
|
} else {
|
||||||
itemId = doFallbackRarePull(fallback1, fallback2, rarity, banner, gachaInfo);
|
itemId = getRandom(fallback2);
|
||||||
}
|
}
|
||||||
}
|
} else if (fallback2.length < 1) {
|
||||||
|
itemId = getRandom(fallback1);
|
||||||
if (epitomized) {
|
} else { // Both pools are possible, use the pool balancer
|
||||||
if(itemId == gachaInfo.getWishItemId()) { // Reset epitomized points when got wished item
|
int pityPool1 = banner.getPoolBalanceWeight(rarity, gachaInfo.getPityPool(rarity, 1));
|
||||||
gachaInfo.setFailedChosenItemPulls(0);
|
int pityPool2 = banner.getPoolBalanceWeight(rarity, gachaInfo.getPityPool(rarity, 2));
|
||||||
} else { // Add epitomized points if not get wished item
|
int chosenPool = switch ((pityPool1 >= pityPool2)? 1 : 0) { // Larger weight must come first for the hard cutoff to function correctly
|
||||||
gachaInfo.addFailedChosenItemPulls(1);
|
case 1 -> 1 + drawRoulette(new int[] {pityPool1, pityPool2}, 10000);
|
||||||
|
default -> 2 - drawRoulette(new int[] {pityPool2, pityPool1}, 10000);
|
||||||
|
};
|
||||||
|
itemId = switch (chosenPool) {
|
||||||
|
case 1:
|
||||||
|
gachaInfo.setPityPool(rarity, 1, 0);
|
||||||
|
yield getRandom(fallback1);
|
||||||
|
default:
|
||||||
|
gachaInfo.setPityPool(rarity, 2, 0);
|
||||||
|
yield getRandom(fallback2);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return itemId;
|
return itemId;
|
||||||
@ -374,7 +356,7 @@ public class GachaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Packets
|
// Packets
|
||||||
player.sendPacket(new PacketDoGachaRsp(banner, list, gachaInfo));
|
player.sendPacket(new PacketDoGachaRsp(banner, list));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startWatcher(GameServer server) {
|
private synchronized void startWatcher(GameServer server) {
|
||||||
@ -417,7 +399,18 @@ public class GachaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized GetGachaInfoRsp createProto(Player player) {
|
@Deprecated
|
||||||
|
private synchronized GetGachaInfoRsp createProto() {
|
||||||
|
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
||||||
|
|
||||||
|
for (GachaBanner banner : getGachaBanners().values()) {
|
||||||
|
proto.addGachaInfoList(banner.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized GetGachaInfoRsp createProto(String sessionKey) {
|
||||||
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis() / 1000L;
|
long currentTime = System.currentTimeMillis() / 1000L;
|
||||||
@ -425,14 +418,22 @@ public class GachaManager {
|
|||||||
for (GachaBanner banner : getGachaBanners().values()) {
|
for (GachaBanner banner : getGachaBanners().values()) {
|
||||||
if ((banner.getEndTime() >= currentTime && banner.getBeginTime() <= currentTime) || (banner.getBannerType() == BannerType.STANDARD))
|
if ((banner.getEndTime() >= currentTime && banner.getBeginTime() <= currentTime) || (banner.getBannerType() == BannerType.STANDARD))
|
||||||
{
|
{
|
||||||
proto.addGachaInfoList(banner.toProto(player));
|
proto.addGachaInfoList(banner.toProto(sessionKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return proto.build();
|
return proto.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public GetGachaInfoRsp toProto() {
|
||||||
|
if (this.cachedProto == null) {
|
||||||
|
this.cachedProto = createProto();
|
||||||
|
}
|
||||||
|
return this.cachedProto;
|
||||||
|
}
|
||||||
|
|
||||||
public GetGachaInfoRsp toProto(Player player) {
|
public GetGachaInfoRsp toProto(String sessionKey) {
|
||||||
return createProto(player);
|
return createProto(sessionKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,6 @@ public class PlayerGachaBannerInfo {
|
|||||||
private int pity5Pool2 = 0;
|
private int pity5Pool2 = 0;
|
||||||
private int pity4Pool1 = 0;
|
private int pity4Pool1 = 0;
|
||||||
private int pity4Pool2 = 0;
|
private int pity4Pool2 = 0;
|
||||||
|
|
||||||
private int failedChosenItemPulls = 0;
|
|
||||||
private int wishItemId = 0;
|
|
||||||
|
|
||||||
public int getPity5() {
|
public int getPity5() {
|
||||||
return pity5;
|
return pity5;
|
||||||
@ -39,26 +36,6 @@ public class PlayerGachaBannerInfo {
|
|||||||
public void addPity4(int amount) {
|
public void addPity4(int amount) {
|
||||||
this.pity4 += amount;
|
this.pity4 += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWishItemId() {
|
|
||||||
return wishItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWishItemId(int wishItemId) {
|
|
||||||
this.wishItemId = wishItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFailedChosenItemPulls() {
|
|
||||||
return failedChosenItemPulls;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFailedChosenItemPulls(int amount) {
|
|
||||||
failedChosenItemPulls = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFailedChosenItemPulls(int amount) {
|
|
||||||
failedChosenItemPulls += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFailedFeaturedItemPulls(int rarity) {
|
public int getFailedFeaturedItemPulls(int rarity) {
|
||||||
return switch (rarity) {
|
return switch (rarity) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.chat;
|
package emu.grasscutter.game.managers.ChatManager;
|
||||||
|
|
||||||
import emu.grasscutter.command.CommandMap;
|
import emu.grasscutter.command.CommandMap;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.chat;
|
package emu.grasscutter.game.managers.ChatManager;
|
||||||
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
@ -1,91 +1,91 @@
|
|||||||
package emu.grasscutter.game.managers.deforestation;
|
package emu.grasscutter.game.managers.DeforestationManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.game.entity.EntityItem;
|
import emu.grasscutter.game.entity.EntityItem;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.net.proto.HitTreeNotifyOuterClass;
|
import emu.grasscutter.net.proto.HitTreeNotifyOuterClass;
|
||||||
import emu.grasscutter.net.proto.VectorOuterClass;
|
import emu.grasscutter.net.proto.VectorOuterClass;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
|
|
||||||
public class DeforestationManager {
|
public class DeforestationManager {
|
||||||
final static int RECORD_EXPIRED_SECONDS = 60*5; // 5 min
|
final static int RECORD_EXPIRED_SECONDS = 60*5; // 5 min
|
||||||
final static int RECORD_MAX_TIMES = 3; // max number of wood
|
final static int RECORD_MAX_TIMES = 3; // max number of wood
|
||||||
final static int RECORD_MAX_TIMES_OTHER_HIT_TREE = 10; // if hit 10 times other trees, reset wood
|
final static int RECORD_MAX_TIMES_OTHER_HIT_TREE = 10; // if hit 10 times other trees, reset wood
|
||||||
|
|
||||||
@Transient private final Player player;
|
@Transient private final Player player;
|
||||||
@Transient private final ArrayList<HitTreeRecord> currentRecord;
|
@Transient private final ArrayList<HitTreeRecord> currentRecord;
|
||||||
@Transient private final static HashMap<Integer, Integer> ColliderTypeToWoodItemID = new HashMap<>();
|
@Transient private final static HashMap<Integer, Integer> ColliderTypeToWoodItemID = new HashMap<>();
|
||||||
static {
|
static {
|
||||||
/* define wood types which reflected to item id*/
|
/* define wood types which reflected to item id*/
|
||||||
ColliderTypeToWoodItemID.put(1,101301);
|
ColliderTypeToWoodItemID.put(1,101301);
|
||||||
ColliderTypeToWoodItemID.put(2,101302);
|
ColliderTypeToWoodItemID.put(2,101302);
|
||||||
ColliderTypeToWoodItemID.put(3,101303);
|
ColliderTypeToWoodItemID.put(3,101303);
|
||||||
ColliderTypeToWoodItemID.put(4,101304);
|
ColliderTypeToWoodItemID.put(4,101304);
|
||||||
ColliderTypeToWoodItemID.put(5,101305);
|
ColliderTypeToWoodItemID.put(5,101305);
|
||||||
ColliderTypeToWoodItemID.put(6,101306);
|
ColliderTypeToWoodItemID.put(6,101306);
|
||||||
ColliderTypeToWoodItemID.put(7,101307);
|
ColliderTypeToWoodItemID.put(7,101307);
|
||||||
ColliderTypeToWoodItemID.put(8,101308);
|
ColliderTypeToWoodItemID.put(8,101308);
|
||||||
ColliderTypeToWoodItemID.put(9,101309);
|
ColliderTypeToWoodItemID.put(9,101309);
|
||||||
ColliderTypeToWoodItemID.put(10,101310);
|
ColliderTypeToWoodItemID.put(10,101310);
|
||||||
ColliderTypeToWoodItemID.put(11,101311);
|
ColliderTypeToWoodItemID.put(11,101311);
|
||||||
ColliderTypeToWoodItemID.put(12,101312);
|
ColliderTypeToWoodItemID.put(12,101312);
|
||||||
}
|
}
|
||||||
public DeforestationManager(Player player){
|
public DeforestationManager(Player player){
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.currentRecord = new ArrayList<>();
|
this.currentRecord = new ArrayList<>();
|
||||||
}
|
}
|
||||||
public void resetWood(){
|
public void resetWood(){
|
||||||
synchronized (currentRecord) {
|
synchronized (currentRecord) {
|
||||||
currentRecord.clear();
|
currentRecord.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onDeforestationInvoke(HitTreeNotifyOuterClass.HitTreeNotify hit){
|
public void onDeforestationInvoke(HitTreeNotifyOuterClass.HitTreeNotify hit){
|
||||||
synchronized (currentRecord) {
|
synchronized (currentRecord) {
|
||||||
//Grasscutter.getLogger().info("onDeforestationInvoke! Wood records {}", currentRecord);
|
//Grasscutter.getLogger().info("onDeforestationInvoke! Wood records {}", currentRecord);
|
||||||
VectorOuterClass.Vector hitPosition = hit.getHitPostion();
|
VectorOuterClass.Vector hitPosition = hit.getHitPostion();
|
||||||
int woodType = hit.getWoodType();
|
int woodType = hit.getWoodType();
|
||||||
if (ColliderTypeToWoodItemID.containsKey(woodType)) {// is a available wood type
|
if (ColliderTypeToWoodItemID.containsKey(woodType)) {// is a available wood type
|
||||||
Scene scene = player.getScene();
|
Scene scene = player.getScene();
|
||||||
int itemId = ColliderTypeToWoodItemID.get(woodType);
|
int itemId = ColliderTypeToWoodItemID.get(woodType);
|
||||||
int positionHash = hitPosition.hashCode();
|
int positionHash = hitPosition.hashCode();
|
||||||
HitTreeRecord record = searchRecord(positionHash);
|
HitTreeRecord record = searchRecord(positionHash);
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
record = new HitTreeRecord(positionHash);
|
record = new HitTreeRecord(positionHash);
|
||||||
}else{
|
}else{
|
||||||
currentRecord.remove(record);// move it to last position
|
currentRecord.remove(record);// move it to last position
|
||||||
}
|
}
|
||||||
currentRecord.add(record);
|
currentRecord.add(record);
|
||||||
if(currentRecord.size()>RECORD_MAX_TIMES_OTHER_HIT_TREE){
|
if(currentRecord.size()>RECORD_MAX_TIMES_OTHER_HIT_TREE){
|
||||||
currentRecord.remove(0);
|
currentRecord.remove(0);
|
||||||
}
|
}
|
||||||
if(record.record()) {
|
if(record.record()) {
|
||||||
EntityItem entity = new EntityItem(scene,
|
EntityItem entity = new EntityItem(scene,
|
||||||
null,
|
null,
|
||||||
GameData.getItemDataMap().get(itemId),
|
GameData.getItemDataMap().get(itemId),
|
||||||
new Position(hitPosition.getX(), hitPosition.getY(), hitPosition.getZ()),
|
new Position(hitPosition.getX(), hitPosition.getY(), hitPosition.getZ()),
|
||||||
1,
|
1,
|
||||||
false);
|
false);
|
||||||
scene.addEntity(entity);
|
scene.addEntity(entity);
|
||||||
}
|
}
|
||||||
//record.record()=false : too many wood they have deforested, no more wood dropped!
|
//record.record()=false : too many wood they have deforested, no more wood dropped!
|
||||||
} else {
|
} else {
|
||||||
Grasscutter.getLogger().warn("No wood type {} found.", woodType);
|
Grasscutter.getLogger().warn("No wood type {} found.", woodType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// unknown wood type
|
// unknown wood type
|
||||||
}
|
}
|
||||||
private HitTreeRecord searchRecord(int id){
|
private HitTreeRecord searchRecord(int id){
|
||||||
for (HitTreeRecord record : currentRecord) {
|
for (HitTreeRecord record : currentRecord) {
|
||||||
if (record.getUnique() == id) {
|
if (record.getUnique() == id) {
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,57 +1,57 @@
|
|||||||
package emu.grasscutter.game.managers.deforestation;
|
package emu.grasscutter.game.managers.DeforestationManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class HitTreeRecord {
|
public class HitTreeRecord {
|
||||||
private final int unique;
|
private final int unique;
|
||||||
private short count; // hit this tree times
|
private short count; // hit this tree times
|
||||||
private long time; // last available hitting time
|
private long time; // last available hitting time
|
||||||
HitTreeRecord(int unique){
|
HitTreeRecord(int unique){
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.time = 0;
|
this.time = 0;
|
||||||
this.unique = unique;
|
this.unique = unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset hit time
|
* reset hit time
|
||||||
*/
|
*/
|
||||||
private void resetTime(){
|
private void resetTime(){
|
||||||
this.time = System.currentTimeMillis();
|
this.time = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* commit hit behavior
|
* commit hit behavior
|
||||||
*/
|
*/
|
||||||
public boolean record(){
|
public boolean record(){
|
||||||
if (this.count < DeforestationManager.RECORD_MAX_TIMES) {
|
if (this.count < DeforestationManager.RECORD_MAX_TIMES) {
|
||||||
this.count++;
|
this.count++;
|
||||||
resetTime();
|
resetTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// check expired
|
// check expired
|
||||||
boolean isWaiting = System.currentTimeMillis() - this.time < DeforestationManager.RECORD_EXPIRED_SECONDS * 1000L;
|
boolean isWaiting = System.currentTimeMillis() - this.time < DeforestationManager.RECORD_EXPIRED_SECONDS * 1000L;
|
||||||
if(isWaiting){
|
if(isWaiting){
|
||||||
return false;
|
return false;
|
||||||
}else{
|
}else{
|
||||||
this.count = 1;
|
this.count = 1;
|
||||||
resetTime();
|
resetTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* get unique id
|
* get unique id
|
||||||
*/
|
*/
|
||||||
public int getUnique(){
|
public int getUnique(){
|
||||||
return unique;
|
return unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "HitTreeRecord{" +
|
return "HitTreeRecord{" +
|
||||||
"unique=" + unique +
|
"unique=" + unique +
|
||||||
", count=" + count +
|
", count=" + count +
|
||||||
", time=" + time +
|
", time=" + time +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.energy;
|
package emu.grasscutter.game.managers.EnergyManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.energy;
|
package emu.grasscutter.game.managers.EnergyManager;
|
||||||
|
|
||||||
public class EnergyDropInfo {
|
public class EnergyDropInfo {
|
||||||
private int ballId;
|
private int ballId;
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.energy;
|
package emu.grasscutter.game.managers.EnergyManager;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.energy;
|
package emu.grasscutter.game.managers.EnergyManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.energy;
|
package emu.grasscutter.game.managers.EnergyManager;
|
||||||
|
|
||||||
public class SkillParticleGenerationInfo {
|
public class SkillParticleGenerationInfo {
|
||||||
private int value;
|
private int value;
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.forging;
|
package emu.grasscutter.game.managers.ForgingManager;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
@ -1,4 +1,4 @@
|
|||||||
package emu.grasscutter.game.managers.forging;
|
package emu.grasscutter.game.managers.ForgingManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
@ -1,66 +1,66 @@
|
|||||||
package emu.grasscutter.game.managers.mapmark;
|
package emu.grasscutter.game.managers.MapMarkManager;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.net.proto.MapMarkFromTypeOuterClass.MapMarkFromType;
|
import emu.grasscutter.net.proto.MapMarkFromTypeOuterClass.MapMarkFromType;
|
||||||
import emu.grasscutter.net.proto.MapMarkPointOuterClass.MapMarkPoint;
|
import emu.grasscutter.net.proto.MapMarkPointOuterClass.MapMarkPoint;
|
||||||
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class MapMark {
|
public class MapMark {
|
||||||
private int sceneId;
|
private int sceneId;
|
||||||
private String name;
|
private String name;
|
||||||
private Position position;
|
private Position position;
|
||||||
private MapMarkPointType mapMarkPointType;
|
private MapMarkPointType mapMarkPointType;
|
||||||
private int monsterId;
|
private int monsterId;
|
||||||
private MapMarkFromType mapMarkFromType;
|
private MapMarkFromType mapMarkFromType;
|
||||||
private int questId;
|
private int questId;
|
||||||
|
|
||||||
@Deprecated // Morhpia
|
@Deprecated // Morhpia
|
||||||
public MapMark() {
|
public MapMark() {
|
||||||
this.mapMarkPointType = MapMarkPointType.MAP_MARK_POINT_TYPE_MONSTER;
|
this.mapMarkPointType = MapMarkPointType.MAP_MARK_POINT_TYPE_MONSTER;
|
||||||
this.mapMarkFromType = MapMarkFromType.MAP_MARK_FROM_TYPE_MONSTER;
|
this.mapMarkFromType = MapMarkFromType.MAP_MARK_FROM_TYPE_MONSTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMark(MapMarkPoint mapMarkPoint) {
|
public MapMark(MapMarkPoint mapMarkPoint) {
|
||||||
this.sceneId = mapMarkPoint.getSceneId();
|
this.sceneId = mapMarkPoint.getSceneId();
|
||||||
this.name = mapMarkPoint.getName();
|
this.name = mapMarkPoint.getName();
|
||||||
this.position = new Position(
|
this.position = new Position(
|
||||||
mapMarkPoint.getPos().getX(),
|
mapMarkPoint.getPos().getX(),
|
||||||
mapMarkPoint.getPos().getY(),
|
mapMarkPoint.getPos().getY(),
|
||||||
mapMarkPoint.getPos().getZ()
|
mapMarkPoint.getPos().getZ()
|
||||||
);
|
);
|
||||||
this.mapMarkPointType = mapMarkPoint.getPointType();
|
this.mapMarkPointType = mapMarkPoint.getPointType();
|
||||||
this.monsterId = mapMarkPoint.getMonsterId();
|
this.monsterId = mapMarkPoint.getMonsterId();
|
||||||
this.mapMarkFromType = mapMarkPoint.getFromType();
|
this.mapMarkFromType = mapMarkPoint.getFromType();
|
||||||
this.questId = mapMarkPoint.getQuestId();
|
this.questId = mapMarkPoint.getQuestId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSceneId() {
|
public int getSceneId() {
|
||||||
return this.sceneId;
|
return this.sceneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Position getPosition() {
|
public Position getPosition() {
|
||||||
return this.position;
|
return this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMarkPointType getMapMarkPointType() {
|
public MapMarkPointType getMapMarkPointType() {
|
||||||
return this.mapMarkPointType;
|
return this.mapMarkPointType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMonsterId() {
|
public int getMonsterId() {
|
||||||
return this.monsterId;
|
return this.monsterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMarkFromType getMapMarkFromType() {
|
public MapMarkFromType getMapMarkFromType() {
|
||||||
return this.mapMarkFromType;
|
return this.mapMarkFromType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQuestId() {
|
public int getQuestId() {
|
||||||
return this.questId;
|
return this.questId;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,90 +1,90 @@
|
|||||||
package emu.grasscutter.game.managers.mapmark;
|
package emu.grasscutter.game.managers.MapMarkManager;
|
||||||
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
||||||
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
|
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
|
||||||
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq.Operation;
|
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq.Operation;
|
||||||
import emu.grasscutter.server.packet.send.PacketMarkMapRsp;
|
import emu.grasscutter.server.packet.send.PacketMarkMapRsp;
|
||||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class MapMarksManager {
|
public class MapMarksManager {
|
||||||
public static final int mapMarkMaxCount = 150;
|
public static final int mapMarkMaxCount = 150;
|
||||||
private HashMap<String, MapMark> mapMarks;
|
private HashMap<String, MapMark> mapMarks;
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
|
||||||
public MapMarksManager(Player player) {
|
public MapMarksManager(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.mapMarks = player.getMapMarks();
|
this.mapMarks = player.getMapMarks();
|
||||||
if (this.mapMarks == null) { this.mapMarks = new HashMap<>(); }
|
if (this.mapMarks == null) { this.mapMarks = new HashMap<>(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleMapMarkReq(MarkMapReq req) {
|
public void handleMapMarkReq(MarkMapReq req) {
|
||||||
Operation op = req.getOp();
|
Operation op = req.getOp();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OPERATION_ADD -> {
|
case OPERATION_ADD -> {
|
||||||
MapMark createMark = new MapMark(req.getMark());
|
MapMark createMark = new MapMark(req.getMark());
|
||||||
// keep teleporting functionality on fishhook mark.
|
// keep teleporting functionality on fishhook mark.
|
||||||
if (createMark.getMapMarkPointType() == MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) {
|
if (createMark.getMapMarkPointType() == MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) {
|
||||||
teleport(player, createMark);
|
teleport(player, createMark);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addMapMark(createMark);
|
addMapMark(createMark);
|
||||||
}
|
}
|
||||||
case OPERATION_MOD -> {
|
case OPERATION_MOD -> {
|
||||||
MapMark oldMark = new MapMark(req.getOld());
|
MapMark oldMark = new MapMark(req.getOld());
|
||||||
removeMapMark(oldMark.getPosition());
|
removeMapMark(oldMark.getPosition());
|
||||||
MapMark newMark = new MapMark(req.getMark());
|
MapMark newMark = new MapMark(req.getMark());
|
||||||
addMapMark(newMark);
|
addMapMark(newMark);
|
||||||
}
|
}
|
||||||
case OPERATION_DEL -> {
|
case OPERATION_DEL -> {
|
||||||
MapMark deleteMark = new MapMark(req.getMark());
|
MapMark deleteMark = new MapMark(req.getMark());
|
||||||
removeMapMark(deleteMark.getPosition());
|
removeMapMark(deleteMark.getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (op != Operation.OPERATION_GET) {
|
if (op != Operation.OPERATION_GET) {
|
||||||
saveMapMarks();
|
saveMapMarks();
|
||||||
}
|
}
|
||||||
player.getSession().send(new PacketMarkMapRsp(getMapMarks()));
|
player.getSession().send(new PacketMarkMapRsp(getMapMarks()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, MapMark> getMapMarks() {
|
public HashMap<String, MapMark> getMapMarks() {
|
||||||
return mapMarks;
|
return mapMarks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMapMarkKey(Position position) {
|
public String getMapMarkKey(Position position) {
|
||||||
return "x" + (int)position.getX()+ "z" + (int)position.getZ();
|
return "x" + (int)position.getX()+ "z" + (int)position.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeMapMark(Position position) {
|
public void removeMapMark(Position position) {
|
||||||
mapMarks.remove(getMapMarkKey(position));
|
mapMarks.remove(getMapMarkKey(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMapMark(MapMark mapMark) {
|
public void addMapMark(MapMark mapMark) {
|
||||||
if (mapMarks.size() < mapMarkMaxCount) {
|
if (mapMarks.size() < mapMarkMaxCount) {
|
||||||
mapMarks.put(getMapMarkKey(mapMark.getPosition()), mapMark);
|
mapMarks.put(getMapMarkKey(mapMark.getPosition()), mapMark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveMapMarks() {
|
private void saveMapMarks() {
|
||||||
player.setMapMarks(mapMarks);
|
player.setMapMarks(mapMarks);
|
||||||
player.save();
|
player.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void teleport(Player player, MapMark mapMark) {
|
private void teleport(Player player, MapMark mapMark) {
|
||||||
float y;
|
float y;
|
||||||
try {
|
try {
|
||||||
y = (float)Integer.parseInt(mapMark.getName());
|
y = (float)Integer.parseInt(mapMark.getName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
y = 300;
|
y = 300;
|
||||||
}
|
}
|
||||||
Position pos = mapMark.getPosition();
|
Position pos = mapMark.getPosition();
|
||||||
player.getPos().set(pos.getX(), y, pos.getZ());
|
player.getPos().set(pos.getX(), y, pos.getZ());
|
||||||
if (mapMark.getSceneId() != player.getSceneId()) {
|
if (mapMark.getSceneId() != player.getSceneId()) {
|
||||||
player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(), player.getPos());
|
player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(), player.getPos());
|
||||||
}
|
}
|
||||||
player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
|
player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,12 @@
|
|||||||
package emu.grasscutter.game.managers.stamina;
|
package emu.grasscutter.game.managers.StaminaManager;
|
||||||
|
|
||||||
public interface AfterUpdateStaminaListener {
|
public interface AfterUpdateStaminaListener {
|
||||||
/**
|
/**
|
||||||
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
||||||
* This gives listeners a chance to intercept this update.
|
* This gives listeners a chance to intercept this update.
|
||||||
*
|
*
|
||||||
* @param reason Why updating stamina.
|
* @param reason Why updating stamina.
|
||||||
* @param newStamina New Stamina value.
|
* @param newStamina New Stamina value.
|
||||||
*/
|
*/
|
||||||
void onAfterUpdateStamina(String reason, int newStamina, boolean isCharacterStamina);
|
void onAfterUpdateStamina(String reason, int newStamina, boolean isCharacterStamina);
|
||||||
}
|
}
|
@ -1,20 +1,20 @@
|
|||||||
package emu.grasscutter.game.managers.stamina;
|
package emu.grasscutter.game.managers.StaminaManager;
|
||||||
|
|
||||||
public interface BeforeUpdateStaminaListener {
|
public interface BeforeUpdateStaminaListener {
|
||||||
/**
|
/**
|
||||||
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
||||||
* This gives listeners a chance to intercept this update.
|
* This gives listeners a chance to intercept this update.
|
||||||
* @param reason Why updating stamina.
|
* @param reason Why updating stamina.
|
||||||
* @param newStamina New ABSOLUTE stamina value.
|
* @param newStamina New ABSOLUTE stamina value.
|
||||||
* @return true if you want to cancel this update, otherwise false.
|
* @return true if you want to cancel this update, otherwise false.
|
||||||
*/
|
*/
|
||||||
int onBeforeUpdateStamina(String reason, int newStamina, boolean isCharacterStamina);
|
int onBeforeUpdateStamina(String reason, int newStamina, boolean isCharacterStamina);
|
||||||
/**
|
/**
|
||||||
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
* onBeforeUpdateStamina() will be called before StaminaManager attempt to update the player's current stamina.
|
||||||
* This gives listeners a chance to intercept this update.
|
* This gives listeners a chance to intercept this update.
|
||||||
* @param reason Why updating stamina.
|
* @param reason Why updating stamina.
|
||||||
* @param consumption ConsumptionType and RELATIVE stamina change amount.
|
* @param consumption ConsumptionType and RELATIVE stamina change amount.
|
||||||
* @return true if you want to cancel this update, otherwise false.
|
* @return true if you want to cancel this update, otherwise false.
|
||||||
*/
|
*/
|
||||||
Consumption onBeforeUpdateStamina(String reason, Consumption consumption, boolean isCharacterStamina);
|
Consumption onBeforeUpdateStamina(String reason, Consumption consumption, boolean isCharacterStamina);
|
||||||
}
|
}
|
@ -1,18 +1,18 @@
|
|||||||
package emu.grasscutter.game.managers.stamina;
|
package emu.grasscutter.game.managers.StaminaManager;
|
||||||
|
|
||||||
public class Consumption {
|
public class Consumption {
|
||||||
public ConsumptionType type = ConsumptionType.None;
|
public ConsumptionType type = ConsumptionType.None;
|
||||||
public int amount = 0;
|
public int amount = 0;
|
||||||
|
|
||||||
public Consumption(ConsumptionType type, int amount) {
|
public Consumption(ConsumptionType type, int amount) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumption(ConsumptionType type) {
|
public Consumption(ConsumptionType type) {
|
||||||
this(type, type.amount);
|
this(type, type.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumption() {
|
public Consumption() {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,37 +1,37 @@
|
|||||||
package emu.grasscutter.game.managers.stamina;
|
package emu.grasscutter.game.managers.StaminaManager;
|
||||||
|
|
||||||
public enum ConsumptionType {
|
public enum ConsumptionType {
|
||||||
None(0),
|
None(0),
|
||||||
|
|
||||||
// consume
|
// consume
|
||||||
CLIMBING(-150),
|
CLIMBING(-150),
|
||||||
CLIMB_START(-500),
|
CLIMB_START(-500),
|
||||||
CLIMB_JUMP(-2500),
|
CLIMB_JUMP(-2500),
|
||||||
DASH(-360),
|
DASH(-360),
|
||||||
FIGHT(0), // See StaminaManager.getFightConsumption()
|
FIGHT(0), // See StaminaManager.getFightConsumption()
|
||||||
FLY(-60),
|
FLY(-60),
|
||||||
// Slow swimming is handled per movement, not per second.
|
// Slow swimming is handled per movement, not per second.
|
||||||
// Arm movement frequency depends on gender/age/height.
|
// Arm movement frequency depends on gender/age/height.
|
||||||
// TODO: Instead of cost -80 per tick, find a proper way to calculate cost.
|
// TODO: Instead of cost -80 per tick, find a proper way to calculate cost.
|
||||||
SKIFF_DASH(-204),
|
SKIFF_DASH(-204),
|
||||||
SPRINT(-1800),
|
SPRINT(-1800),
|
||||||
SWIM_DASH_START(-2000),
|
SWIM_DASH_START(-2000),
|
||||||
SWIM_DASH(-204), // -10.2 per second, 5Hz = -204 each tick
|
SWIM_DASH(-204), // -10.2 per second, 5Hz = -204 each tick
|
||||||
SWIMMING(-80),
|
SWIMMING(-80),
|
||||||
TALENT_DASH(-300), // -1500 per second, 5Hz = -300 each tick
|
TALENT_DASH(-300), // -1500 per second, 5Hz = -300 each tick
|
||||||
TALENT_DASH_START(-1000),
|
TALENT_DASH_START(-1000),
|
||||||
|
|
||||||
// restore
|
// restore
|
||||||
POWERED_FLY(500),
|
POWERED_FLY(500),
|
||||||
POWERED_SKIFF(500),
|
POWERED_SKIFF(500),
|
||||||
RUN(500),
|
RUN(500),
|
||||||
SKIFF(500),
|
SKIFF(500),
|
||||||
STANDBY(500),
|
STANDBY(500),
|
||||||
WALK(500);
|
WALK(500);
|
||||||
|
|
||||||
public final int amount;
|
public final int amount;
|
||||||
|
|
||||||
ConsumptionType(int amount) {
|
ConsumptionType(int amount) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,73 +1,73 @@
|
|||||||
# Stamina Manager
|
# Stamina Manager
|
||||||
|
|
||||||
---
|
---
|
||||||
## UpdateStamina
|
## UpdateStamina
|
||||||
```java
|
```java
|
||||||
// will use consumption.consumptionType as reason
|
// will use consumption.consumptionType as reason
|
||||||
public int updateStaminaRelative(GameSession session, Consumption consumption);
|
public int updateStaminaRelative(GameSession session, Consumption consumption);
|
||||||
```
|
```
|
||||||
```java
|
```java
|
||||||
public int updateStaminaAbsolute(GameSession session, String reason, int newStamina)
|
public int updateStaminaAbsolute(GameSession session, String reason, int newStamina)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
## Pause and Resume
|
## Pause and Resume
|
||||||
```java
|
```java
|
||||||
public void startSustainedStaminaHandler()
|
public void startSustainedStaminaHandler()
|
||||||
```
|
```
|
||||||
```java
|
```java
|
||||||
public void stopSustainedStaminaHandler()
|
public void stopSustainedStaminaHandler()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
## Stamina change listeners and intercepting
|
## Stamina change listeners and intercepting
|
||||||
### BeforeUpdateStaminaListener
|
### BeforeUpdateStaminaListener
|
||||||
```java
|
```java
|
||||||
|
|
||||||
import emu.grasscutter.game.managers.StaminaManager.BeforeUpdateStaminaListener;
|
import emu.grasscutter.game.managers.StaminaManager.BeforeUpdateStaminaListener;
|
||||||
|
|
||||||
// Listener sample: plugin disable CLIMB_JUMP stamina cost.
|
// Listener sample: plugin disable CLIMB_JUMP stamina cost.
|
||||||
private class MyClass implements BeforeUpdateStaminaListener {
|
private class MyClass implements BeforeUpdateStaminaListener {
|
||||||
// Make your class implement the listener, and pass in your class as a listener.
|
// Make your class implement the listener, and pass in your class as a listener.
|
||||||
|
|
||||||
public MyClass() {
|
public MyClass() {
|
||||||
getStaminaManager().registerBeforeUpdateStaminaListener("myClass", this);
|
getStaminaManager().registerBeforeUpdateStaminaListener("myClass", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onBeforeUpdateStamina(String reason, int newStamina) {
|
public boolean onBeforeUpdateStamina(String reason, int newStamina) {
|
||||||
// do not intercept this update
|
// do not intercept this update
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onBeforeUpdateStamina(String reason, Consumption consumption) {
|
public boolean onBeforeUpdateStamina(String reason, Consumption consumption) {
|
||||||
// Try to intercept if this update is CLIMB_JUMP
|
// Try to intercept if this update is CLIMB_JUMP
|
||||||
if (consumption.consumptionType == ConsumptionType.CLIMB_JUMP) {
|
if (consumption.consumptionType == ConsumptionType.CLIMB_JUMP) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// If it is not CLIMB_JUMP, do not intercept.
|
// If it is not CLIMB_JUMP, do not intercept.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### AfterUpdateStaminaListener
|
### AfterUpdateStaminaListener
|
||||||
```java
|
```java
|
||||||
|
|
||||||
import emu.grasscutter.game.managers.StaminaManager.AfterUpdateStaminaListener;
|
import emu.grasscutter.game.managers.StaminaManager.AfterUpdateStaminaListener;
|
||||||
|
|
||||||
// Listener sample: plugin listens for changes already made.
|
// Listener sample: plugin listens for changes already made.
|
||||||
private class MyClass implements AfterUpdateStaminaListener {
|
private class MyClass implements AfterUpdateStaminaListener {
|
||||||
// Make your class implement the listener, and pass in your class as a listener.
|
// Make your class implement the listener, and pass in your class as a listener.
|
||||||
|
|
||||||
public MyClass() {
|
public MyClass() {
|
||||||
registerAfterUpdateStaminaListener("myClass", this);
|
registerAfterUpdateStaminaListener("myClass", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAfterUpdateStamina(String reason, int newStamina) {
|
public void onAfterUpdateStamina(String reason, int newStamina) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ import emu.grasscutter.game.avatar.AvatarProfileData;
|
|||||||
import emu.grasscutter.game.avatar.AvatarStorage;
|
import emu.grasscutter.game.avatar.AvatarStorage;
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
import emu.grasscutter.game.entity.EntityVehicle;
|
import emu.grasscutter.game.entity.EntityVehicle;
|
||||||
|
import emu.grasscutter.game.managers.DeforestationManager.DeforestationManager;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
import emu.grasscutter.game.entity.EntityItem;
|
import emu.grasscutter.game.entity.EntityItem;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
@ -27,19 +28,18 @@ import emu.grasscutter.game.mail.Mail;
|
|||||||
import emu.grasscutter.game.mail.MailHandler;
|
import emu.grasscutter.game.mail.MailHandler;
|
||||||
import emu.grasscutter.game.managers.InsectCaptureManager;
|
import emu.grasscutter.game.managers.InsectCaptureManager;
|
||||||
import emu.grasscutter.game.managers.ResinManager;
|
import emu.grasscutter.game.managers.ResinManager;
|
||||||
import emu.grasscutter.game.managers.deforestation.DeforestationManager;
|
import emu.grasscutter.game.managers.StaminaManager.StaminaManager;
|
||||||
import emu.grasscutter.game.managers.energy.EnergyManager;
|
|
||||||
import emu.grasscutter.game.managers.forging.ActiveForgeData;
|
|
||||||
import emu.grasscutter.game.managers.forging.ForgingManager;
|
|
||||||
import emu.grasscutter.game.managers.mapmark.*;
|
|
||||||
import emu.grasscutter.game.managers.stamina.StaminaManager;
|
|
||||||
import emu.grasscutter.game.managers.SotSManager;
|
import emu.grasscutter.game.managers.SotSManager;
|
||||||
|
import emu.grasscutter.game.managers.EnergyManager.EnergyManager;
|
||||||
|
import emu.grasscutter.game.managers.ForgingManager.ActiveForgeData;
|
||||||
|
import emu.grasscutter.game.managers.ForgingManager.ForgingManager;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityType;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.props.SceneType;
|
import emu.grasscutter.game.props.SceneType;
|
||||||
import emu.grasscutter.game.quest.QuestManager;
|
import emu.grasscutter.game.quest.QuestManager;
|
||||||
import emu.grasscutter.game.shop.ShopLimit;
|
import emu.grasscutter.game.shop.ShopLimit;
|
||||||
|
import emu.grasscutter.game.managers.MapMarkManager.*;
|
||||||
import emu.grasscutter.game.tower.TowerData;
|
import emu.grasscutter.game.tower.TowerData;
|
||||||
import emu.grasscutter.game.tower.TowerManager;
|
import emu.grasscutter.game.tower.TowerManager;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
@ -10,14 +10,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||||||
|
|
||||||
public enum ElementType {
|
public enum ElementType {
|
||||||
None (0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
|
None (0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
|
||||||
Fire (1, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10101, "TeamResonance_Fire_Lv2", 2),
|
Fire (1, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10101, "TeamResonance_Fire_Lv2"),
|
||||||
Water (2, FightProperty.FIGHT_PROP_CUR_WATER_ENERGY, FightProperty.FIGHT_PROP_MAX_WATER_ENERGY, 10201, "TeamResonance_Water_Lv2", 3),
|
Water (2, FightProperty.FIGHT_PROP_CUR_WATER_ENERGY, FightProperty.FIGHT_PROP_MAX_WATER_ENERGY, 10201, "TeamResonance_Water_Lv2"),
|
||||||
Grass (3, FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY, FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY),
|
Grass (3, FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY, FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY),
|
||||||
Electric (4, FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY, FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY, 10401, "TeamResonance_Electric_Lv2", 7),
|
Electric (4, FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY, FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY, 10401, "TeamResonance_Electric_Lv2"),
|
||||||
Ice (5, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY, 10601, "TeamResonance_Ice_Lv2", 5),
|
Ice (5, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY, 10601, "TeamResonance_Ice_Lv2"),
|
||||||
Frozen (6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY),
|
Frozen (6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY),
|
||||||
Wind (7, FightProperty.FIGHT_PROP_CUR_WIND_ENERGY, FightProperty.FIGHT_PROP_MAX_WIND_ENERGY, 10301, "TeamResonance_Wind_Lv2", 4),
|
Wind (7, FightProperty.FIGHT_PROP_CUR_WIND_ENERGY, FightProperty.FIGHT_PROP_MAX_WIND_ENERGY, 10301, "TeamResonance_Wind_Lv2"),
|
||||||
Rock (8, FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY, FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY, 10701, "TeamResonance_Rock_Lv2", 6),
|
Rock (8, FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY, FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY, 10701, "TeamResonance_Rock_Lv2"),
|
||||||
AntiFire (9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
|
AntiFire (9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
|
||||||
Default (255, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10801, "TeamResonance_AllDifferent");
|
Default (255, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10801, "TeamResonance_AllDifferent");
|
||||||
|
|
||||||
@ -25,7 +25,6 @@ public enum ElementType {
|
|||||||
private final int teamResonanceId;
|
private final int teamResonanceId;
|
||||||
private final FightProperty curEnergyProp;
|
private final FightProperty curEnergyProp;
|
||||||
private final FightProperty maxEnergyProp;
|
private final FightProperty maxEnergyProp;
|
||||||
private int depotValue;
|
|
||||||
private final int configHash;
|
private final int configHash;
|
||||||
private static final Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Map<String, ElementType> stringMap = new HashMap<>();
|
private static final Map<String, ElementType> stringMap = new HashMap<>();
|
||||||
@ -52,11 +51,6 @@ public enum ElementType {
|
|||||||
this.configHash = 0;
|
this.configHash = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ElementType(int value, FightProperty curEnergyProp, FightProperty maxEnergyProp, int teamResonanceId, String configName, int depotValue) {
|
|
||||||
this(value, curEnergyProp, maxEnergyProp, teamResonanceId, configName);
|
|
||||||
this.depotValue = depotValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
public int getValue() {
|
||||||
return value;
|
return value;
|
||||||
@ -70,10 +64,6 @@ public enum ElementType {
|
|||||||
return maxEnergyProp;
|
return maxEnergyProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDepotValue() {
|
|
||||||
return depotValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTeamResonanceId() {
|
public int getTeamResonanceId() {
|
||||||
return teamResonanceId;
|
return teamResonanceId;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import emu.grasscutter.Grasscutter;
|
|||||||
import emu.grasscutter.auth.AuthenticationSystem;
|
import emu.grasscutter.auth.AuthenticationSystem;
|
||||||
import emu.grasscutter.command.Command;
|
import emu.grasscutter.command.Command;
|
||||||
import emu.grasscutter.command.CommandHandler;
|
import emu.grasscutter.command.CommandHandler;
|
||||||
import emu.grasscutter.command.PermissionHandler;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import emu.grasscutter.server.http.HttpServer;
|
import emu.grasscutter.server.http.HttpServer;
|
||||||
@ -98,12 +97,4 @@ public final class ServerHook {
|
|||||||
public void setAuthSystem(AuthenticationSystem authSystem) {
|
public void setAuthSystem(AuthenticationSystem authSystem) {
|
||||||
Grasscutter.setAuthenticationSystem(authSystem);
|
Grasscutter.setAuthenticationSystem(authSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the server's permission handler.
|
|
||||||
* @param permHandler An instance of the permission handler.
|
|
||||||
*/
|
|
||||||
public void setPermissionHandler(PermissionHandler permHandler) {
|
|
||||||
Grasscutter.setPermissionHandler(permHandler);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -10,10 +10,10 @@ import emu.grasscutter.game.drop.DropManager;
|
|||||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
import emu.grasscutter.game.dungeons.DungeonManager;
|
||||||
import emu.grasscutter.game.expedition.ExpeditionManager;
|
import emu.grasscutter.game.expedition.ExpeditionManager;
|
||||||
import emu.grasscutter.game.gacha.GachaManager;
|
import emu.grasscutter.game.gacha.GachaManager;
|
||||||
|
import emu.grasscutter.game.managers.ChatManager.ChatManager;
|
||||||
|
import emu.grasscutter.game.managers.ChatManager.ChatManagerHandler;
|
||||||
import emu.grasscutter.game.managers.InventoryManager;
|
import emu.grasscutter.game.managers.InventoryManager;
|
||||||
import emu.grasscutter.game.managers.MultiplayerManager;
|
import emu.grasscutter.game.managers.MultiplayerManager;
|
||||||
import emu.grasscutter.game.managers.chat.ChatManager;
|
|
||||||
import emu.grasscutter.game.managers.chat.ChatManagerHandler;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.ServerQuestHandler;
|
import emu.grasscutter.game.quest.ServerQuestHandler;
|
||||||
import emu.grasscutter.game.shop.ShopManager;
|
import emu.grasscutter.game.shop.ShopManager;
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
|
||||||
|
|
||||||
import emu.grasscutter.GameConstants;
|
|
||||||
import emu.grasscutter.data.GameData;
|
|
||||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
|
||||||
import emu.grasscutter.data.excels.WorldAreaData;
|
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
|
||||||
import emu.grasscutter.game.entity.EntityAvatar;
|
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.AvatarChangeElementTypeReqOuterClass.AvatarChangeElementTypeReq;
|
|
||||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
|
||||||
import emu.grasscutter.server.game.GameSession;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketAvatarChangeElementTypeRsp;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketAvatarSkillDepotChangeNotify;
|
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.AvatarChangeElementTypeReq)
|
|
||||||
public class HandlerAvatarChangeElementTypeReq extends PacketHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
|
||||||
AvatarChangeElementTypeReq req = AvatarChangeElementTypeReq.parseFrom(payload);
|
|
||||||
|
|
||||||
WorldAreaData area = GameData.getWorldAreaDataMap().get(req.getAreaId());
|
|
||||||
|
|
||||||
if (area == null || area.getElementType() == null || area.getElementType().getDepotValue() <= 0) {
|
|
||||||
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current avatar, should be one of the main characters
|
|
||||||
EntityAvatar mainCharacterEntity = session.getPlayer().getTeamManager().getCurrentAvatarEntity();
|
|
||||||
|
|
||||||
int intialSkillDepotId = 0;
|
|
||||||
if (mainCharacterEntity.getAvatar().getAvatarId() == GameConstants.MAIN_CHARACTER_MALE) {
|
|
||||||
intialSkillDepotId = 500;
|
|
||||||
} else if (mainCharacterEntity.getAvatar().getAvatarId() == GameConstants.MAIN_CHARACTER_FEMALE) {
|
|
||||||
intialSkillDepotId = 700;
|
|
||||||
} else {
|
|
||||||
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
intialSkillDepotId += area.getElementType().getDepotValue();
|
|
||||||
|
|
||||||
// Sanity checks for skill depots
|
|
||||||
Avatar mainCharacter = mainCharacterEntity.getAvatar();
|
|
||||||
AvatarSkillDepotData skillDepot = GameData.getAvatarSkillDepotDataMap().get(intialSkillDepotId);
|
|
||||||
if (skillDepot == null || skillDepot.getId() == mainCharacter.getSkillDepotId()) {
|
|
||||||
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
session.send(new PacketAvatarChangeElementTypeRsp());
|
|
||||||
|
|
||||||
// Set skill depot
|
|
||||||
mainCharacter.setSkillDepotData(skillDepot);
|
|
||||||
|
|
||||||
// Ability change packet
|
|
||||||
session.send(new PacketAvatarSkillDepotChangeNotify(mainCharacter));
|
|
||||||
session.send(new PacketAbilityChangeNotify(mainCharacterEntity));
|
|
||||||
session.send(new PacketAvatarFightPropNotify(mainCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
|
||||||
|
|
||||||
import emu.grasscutter.game.gacha.GachaBanner;
|
|
||||||
import emu.grasscutter.game.gacha.PlayerGachaBannerInfo;
|
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.GachaWishReqOuterClass.GachaWishReq;
|
|
||||||
import emu.grasscutter.server.game.GameSession;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketGachaWishRsp;
|
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.GachaWishReq)
|
|
||||||
public class HandlerGachaWishReq extends PacketHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
|
||||||
GachaWishReq req = GachaWishReq.parseFrom(payload);
|
|
||||||
|
|
||||||
GachaBanner banner = session.getServer().getGachaManager().getGachaBanners().get(req.getGachaScheduleId());
|
|
||||||
PlayerGachaBannerInfo gachaInfo = session.getPlayer().getGachaInfo().getBannerInfo(banner);
|
|
||||||
|
|
||||||
gachaInfo.setFailedChosenItemPulls(0);
|
|
||||||
gachaInfo.setWishItemId(req.getItemId());
|
|
||||||
|
|
||||||
session.send(new PacketGachaWishRsp(req.getGachaType(), req.getGachaScheduleId(), req.getItemId(), 0, banner.getWishMaxProgress()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +1,9 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
import emu.grasscutter.game.gacha.GachaBanner;
|
|
||||||
import emu.grasscutter.game.gacha.PlayerGachaBannerInfo;
|
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketGachaWishRsp;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketGetGachaInfoRsp;
|
import emu.grasscutter.server.packet.send.PacketGetGachaInfoRsp;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.GetGachaInfoReq)
|
@Opcodes(PacketOpcodes.GetGachaInfoReq)
|
||||||
@ -14,7 +11,10 @@ public class HandlerGetGachaInfoReq 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 PacketGetGachaInfoRsp(session.getServer().getGachaManager(), session.getPlayer()));
|
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaManager(),
|
||||||
|
// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
|
||||||
|
session.getPlayer().getAccount().getSessionKey())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
|
||||||
|
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.AvatarChangeElementTypeRspOuterClass.AvatarChangeElementTypeRsp;
|
|
||||||
|
|
||||||
public class PacketAvatarChangeElementTypeRsp extends BasePacket {
|
|
||||||
|
|
||||||
public PacketAvatarChangeElementTypeRsp() {
|
|
||||||
super(PacketOpcodes.AvatarChangeElementTypeRsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PacketAvatarChangeElementTypeRsp(int retcode) {
|
|
||||||
super(PacketOpcodes.AvatarChangeElementTypeRsp);
|
|
||||||
|
|
||||||
if (retcode > 0) {
|
|
||||||
AvatarChangeElementTypeRsp proto = AvatarChangeElementTypeRsp.newBuilder()
|
|
||||||
.setRetcode(retcode)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.setData(proto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
|
||||||
|
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.AvatarSkillDepotChangeNotifyOuterClass.AvatarSkillDepotChangeNotify;
|
|
||||||
|
|
||||||
public class PacketAvatarSkillDepotChangeNotify extends BasePacket {
|
|
||||||
|
|
||||||
public PacketAvatarSkillDepotChangeNotify(Avatar avatar) {
|
|
||||||
super(PacketOpcodes.AvatarSkillDepotChangeNotify);
|
|
||||||
|
|
||||||
AvatarSkillDepotChangeNotify proto = AvatarSkillDepotChangeNotify.newBuilder()
|
|
||||||
.setAvatarGuid(avatar.getGuid())
|
|
||||||
.setEntityId(avatar.getEntityId())
|
|
||||||
.setSkillDepotId(avatar.getSkillDepotId())
|
|
||||||
.setCoreProudSkillLevel(avatar.getCoreProudSkillLevel())
|
|
||||||
.addAllTalentIdList(avatar.getTalentIdList())
|
|
||||||
.addAllProudSkillList(avatar.getProudSkillList())
|
|
||||||
.putAllSkillLevelMap(avatar.getSkillLevelMap())
|
|
||||||
.putAllProudSkillExtraLevelMap(avatar.getProudSkillBonusMap())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.setData(proto);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.game.gacha.GachaBanner;
|
import emu.grasscutter.game.gacha.GachaBanner;
|
||||||
import emu.grasscutter.game.gacha.PlayerGachaBannerInfo;
|
|
||||||
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.DoGachaRspOuterClass.DoGachaRsp;
|
import emu.grasscutter.net.proto.DoGachaRspOuterClass.DoGachaRsp;
|
||||||
@ -14,12 +13,12 @@ import emu.grasscutter.net.proto.RetcodeOuterClass;
|
|||||||
|
|
||||||
public class PacketDoGachaRsp extends BasePacket {
|
public class PacketDoGachaRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketDoGachaRsp(GachaBanner banner, List<GachaItem> list, PlayerGachaBannerInfo gachaInfo) {
|
public PacketDoGachaRsp(GachaBanner banner, List<GachaItem> list) {
|
||||||
super(PacketOpcodes.DoGachaRsp);
|
super(PacketOpcodes.DoGachaRsp);
|
||||||
|
|
||||||
ItemParamData costItem = banner.getCost(1);
|
ItemParamData costItem = banner.getCost(1);
|
||||||
ItemParamData costItem10 = banner.getCost(10);
|
ItemParamData costItem10 = banner.getCost(10);
|
||||||
DoGachaRsp.Builder rsp = DoGachaRsp.newBuilder()
|
DoGachaRsp p = DoGachaRsp.newBuilder()
|
||||||
.setGachaType(banner.getGachaType())
|
.setGachaType(banner.getGachaType())
|
||||||
.setGachaScheduleId(banner.getScheduleId())
|
.setGachaScheduleId(banner.getScheduleId())
|
||||||
.setGachaTimes(list.size())
|
.setGachaTimes(list.size())
|
||||||
@ -29,15 +28,10 @@ public class PacketDoGachaRsp extends BasePacket {
|
|||||||
.setCostItemNum(costItem.getCount())
|
.setCostItemNum(costItem.getCount())
|
||||||
.setTenCostItemId(costItem10.getId())
|
.setTenCostItemId(costItem10.getId())
|
||||||
.setTenCostItemNum(costItem10.getCount())
|
.setTenCostItemNum(costItem10.getCount())
|
||||||
.addAllGachaItemList(list);
|
.addAllGachaItemList(list)
|
||||||
|
.build();
|
||||||
if(banner.hasEpitomized()) {
|
|
||||||
rsp.setWishItemId(gachaInfo.getWishItemId())
|
|
||||||
.setWishProgress(gachaInfo.getFailedChosenItemPulls())
|
|
||||||
.setWishMaxProgress(banner.getWishMaxProgress());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setData(rsp.build());
|
this.setData(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketDoGachaRsp() {
|
public PacketDoGachaRsp() {
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
|
||||||
|
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.GachaWishRspOuterClass.GachaWishRsp;
|
|
||||||
|
|
||||||
public class PacketGachaWishRsp extends BasePacket {
|
|
||||||
|
|
||||||
public PacketGachaWishRsp(int gachaType, int scheduleId, int itemId, int progress, int maxProgress) {
|
|
||||||
super(PacketOpcodes.GachaWishRsp);
|
|
||||||
|
|
||||||
GachaWishRsp proto = GachaWishRsp.newBuilder()
|
|
||||||
.setGachaType(gachaType)
|
|
||||||
.setGachaScheduleId(scheduleId)
|
|
||||||
.setWishItemId(itemId)
|
|
||||||
.setWishProgress(progress)
|
|
||||||
.setWishMaxProgress(maxProgress)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.setData(proto);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +1,22 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.gacha.GachaManager;
|
import emu.grasscutter.game.gacha.GachaManager;
|
||||||
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;
|
||||||
|
|
||||||
public class PacketGetGachaInfoRsp extends BasePacket {
|
public class PacketGetGachaInfoRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketGetGachaInfoRsp(GachaManager manager, Player player) {
|
@Deprecated
|
||||||
|
public PacketGetGachaInfoRsp(GachaManager manager) {
|
||||||
super(PacketOpcodes.GetGachaInfoRsp);
|
super(PacketOpcodes.GetGachaInfoRsp);
|
||||||
|
|
||||||
this.setData(manager.toProto(player));
|
this.setData(manager.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketGetGachaInfoRsp(GachaManager manager, String sessionKey) {
|
||||||
|
super(PacketOpcodes.GetGachaInfoRsp);
|
||||||
|
|
||||||
|
this.setData(manager.toProto(sessionKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.game.managers.mapmark.MapMark;
|
import emu.grasscutter.game.managers.MapMarkManager.MapMark;
|
||||||
import emu.grasscutter.game.player.Player;
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user