mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-06-26 01:54:51 +08:00
Compare commits
4 Commits
8b114cf964
...
3a39545e34
Author | SHA1 | Date | |
---|---|---|---|
|
3a39545e34 | ||
|
e433b46ef5 | ||
|
0e2fc3850e | ||
|
d73c7f7233 |
65
README.md
65
README.md
@ -98,72 +98,11 @@ chmod +x gradlew
|
||||
|
||||
You can find the output jar in the root of the project folder.
|
||||
|
||||
## Commands
|
||||
|
||||
You might want to use this command (`java -jar grasscutter.jar -handbook`) in a cmd that is in the grasscutter folder. It will create a handbook file (GM Handbook.txt) where you can find the item IDs for stuff you want
|
||||
|
||||
You may want to use this command (`java -jar grasscutter.jar -gachamap`) to generate a mapping file for the gacha record subsystem. The file will be generated to `GRASSCUTTER_RESOURCE/gcstatic` folder. Otherwise you may only see number IDs in the gacha record page.
|
||||
|
||||
There is a dummy user named "Server" in every player's friends list that you can message to use commands. Commands also work in other chat rooms, such as private/team chats. to run commands ingame, you need to add prefix `/` or `!` such as `/pos`
|
||||
|
||||
### Targeting
|
||||
1. For commands that target a Player, you can specify a target UID with `@UID` as an argument in any position to the command.
|
||||
2. If you message a valid command at another player (instead of at the "Server" virtual player), they will be the target for that command if you didn't set one above.
|
||||
3. If none of the above, it will default to a persistent target player you previously set using the command `/target <UID>`.
|
||||
4. If none of the above, you will be the target of the command. If you are entering the command from the Server console, **it will not work!**
|
||||
|
||||
Note that performing commands on other players will usually require different a permission to the base permission node. e.g. `player.give` becomes `player.give.others` if used on another player.
|
||||
|
||||
| Commands | Description | Alias | Targeting | Usage | Permission node |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------- | ------------------ | ------------- | --------------------------------------------------------------------------- | ------------------------- |
|
||||
| account | Creates an account with the specified username, and the in-game UID if specified. | | Server only | account \<create\|delete> \<username> [UID] | |
|
||||
| broadcast | Sends a message to all the players. | b | None | broadcast \<message> | server.broadcast |
|
||||
| coop | Forces someone to join the world of others. | | Online Player | coop [host UID (default self)] | server.coop |
|
||||
| changescene | Switch scenes by scene ID. | scene | Online Player | changescene \<scene id> | player.changescene |
|
||||
| clear | Deletes all unequipped and unlocked lvl0 artifacts(art)/weapons(wp)/material(mat) from inventory. | | Online Player | clear \<all\|wp\|art\|mat> | player.clearinv |
|
||||
| drop | Drops an item around you. | d dropitem | Online Player | drop \<itemID\|itemName> [amount] | server.drop |
|
||||
| enterdungeon | Enter a dungeon by dungeon ID. | | Online Player | enterdungeon \<dungeon id> | player.enterdungeon |
|
||||
| give | Gives item(s) to you or the specified player. | g item giveitem | Online Player | give \<itemId\|itemName> [amount] [level] [refinement] | player.give |
|
||||
| giveall | Gives all items. | givea | Online Player | giveall [amount] | player.giveall |
|
||||
| giveart | Gives the player a specified artifact. | gart | Online Player | giveart \<artifactId> \<mainPropId> [\<appendPropId>[,\<times>]]... [level] | player.giveart |
|
||||
| givechar | Gives the player a specified character. | givec | Online Player | givechar \<avatarId> | player.givechar |
|
||||
| godmode | Prevents you from taking damage. | | Online Player | godmode | player.godmode |
|
||||
| heal | Heals all characters in your current team. | h | Online Player | heal | player.heal |
|
||||
| help | Sends the help message or shows information about a specified command. | | None | help [command] | |
|
||||
| kick | Kicks the specified player from the server. | k | Online Player | kick | server.kick |
|
||||
| killall | Kills all entities in the current scene or specified scene of the corresponding player. | | Online Player | killall [sceneId] | server.killall |
|
||||
| list | Lists online players. | | None | list | |
|
||||
| permission | Grants or removes a permission for a user. | | Online Player | permission \<add\|remove> \<permission> | permission |
|
||||
| position | Sends your current coordinates. | pos | Online Player | position | |
|
||||
| reload | Reloads the server config. | | None | reload | server.reload |
|
||||
| resetconst | Resets currently selected (or all) character(s) to C0. Relog to see proper effects. | resetconstellation | Online Player | resetconst [all] | player.resetconstellation |
|
||||
| restart | Restarts the current session. | | None | restart | |
|
||||
| sendmessage | Sends a message to a player as the server. | say | Online Player | say \<message> | server.sendmessage |
|
||||
| setfetterlevel | Sets the friendship level for your currently selected character. | setfetterlvl | Online Player | setfetterlevel \<level> | player.setfetterlevel |
|
||||
| setstats | Sets a stat for your currently selected character. | stats | Online Player | setstats \<stat> \<value> | player.setstats |
|
||||
| setworldlevel | Sets your world level. Relog to see proper effects. | setworldlvl | Online Player | setworldlevel \<level> | player.setworldlevel |
|
||||
| spawn | Spawns some entities around you. | | Online Player | spawn \<entityId> [amount] [level(monster only)] | server.spawn |
|
||||
| stop | Stops the server. | | None | stop | server.stop |
|
||||
| talent | Sets talent level for your currently selected character | | Online Player | talent \<talentID> \<value> | player.settalent |
|
||||
| team | Add, remove, or swap avatars in your current team. Index start from 1. | | Online Player | team \<add\|remove\|set> [avatarId,...] [index|first|last|index-index,...] | player.team |
|
||||
| teleport | Change the player's position. | tp | Online Player | teleport \<x> \<y> \<z> [sceneId] | player.teleport |
|
||||
| tpall | Teleports all players in your world to your position. | | Online Player | tpall | player.tpall |
|
||||
| unlocktower | Unlock the all floors of abyss. | ut | Online Player | ut | player.tower |
|
||||
| weather | Changes the weather. | w | Online Player | weather \<weatherID> \<climateID> | player.weather |
|
||||
|
||||
### Bonus
|
||||
|
||||
- Teleporting
|
||||
- When you want to teleport to somewhere, use the in-game marking function on Map.
|
||||
- Mark a point on the map using the fish hook marking (the last one.)
|
||||
- (Optional) rename the map marker to a number to override the default Y coordinate (height, default 300.)
|
||||
- Confirm and close the map.
|
||||
- You will see your character falling from a very high destination, exact location that you marked.
|
||||
### Commands have moved to the [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)!
|
||||
|
||||
# Quick Troubleshooting
|
||||
|
||||
* If compiling wasn't successful, please check your JDK installation (JDK 17 and validated JDK's bin PATH variable)
|
||||
* My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using
|
||||
Fiddler make sure it running on another port except 8888
|
||||
|
||||
* Startup sequence: Mongodb > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Game
|
||||
* Startup sequence: MongoDB > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Game
|
||||
|
16
proto/QueryCodexMonsterBeKilledNumReq.proto
Normal file
16
proto/QueryCodexMonsterBeKilledNumReq.proto
Normal file
@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QueryCodexMonsterBeKilledNumReq {
|
||||
enum CmdId {
|
||||
option allow_alias = true;
|
||||
ENET_CHANNEL_ID = 0;
|
||||
NONE = 0;
|
||||
ENET_IS_RELIABLE = 1;
|
||||
IS_ALLOW_CLIENT = 1;
|
||||
CMD_ID = 4201;
|
||||
}
|
||||
|
||||
repeated uint32 codex_id_list = 1;
|
||||
}
|
18
proto/QueryCodexMonsterBeKilledNumRsp.proto
Normal file
18
proto/QueryCodexMonsterBeKilledNumRsp.proto
Normal file
@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QueryCodexMonsterBeKilledNumRsp {
|
||||
enum CmdId {
|
||||
option allow_alias = true;
|
||||
NONE = 0;
|
||||
ENET_CHANNEL_ID = 0;
|
||||
ENET_IS_RELIABLE = 1;
|
||||
CMD_ID = 4210;
|
||||
}
|
||||
|
||||
int32 retcode = 1;
|
||||
repeated uint32 codex_id_list = 2;
|
||||
repeated uint32 be_killed_num_list = 3;
|
||||
repeated uint32 be_killed_num_empty_list = 4;
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
|
||||
|
||||
@ -11,7 +9,6 @@ import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
import static emu.grasscutter.Configuration.*;
|
||||
|
||||
@Command(label = "team", usage = "team <add|remove|set> [avatarId,...] [index|first|last|index-index,...]",
|
||||
@ -22,7 +19,7 @@ public final class TeamCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.usage");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -40,8 +37,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
break;
|
||||
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.invalid_usage"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.usage");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -51,8 +48,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
|
||||
private boolean addCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.invalid_usage"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.add_usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -62,7 +59,7 @@ public final class TeamCommand implements CommandHandler {
|
||||
index = Integer.parseInt(args.get(2)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.invalid_index"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_index");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -71,28 +68,22 @@ public final class TeamCommand implements CommandHandler {
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
if (currentTeamAvatars.size() + avatarIds.length > GAME_OPTIONS.avatarLimits.singlePlayerTeam) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var avatarId: avatarIds) {
|
||||
try {
|
||||
int id = Integer.parseInt(avatarId);
|
||||
var ret = addAvatar(sender, targetPlayer, id, index);
|
||||
if (index > 0) ++index;
|
||||
if (!ret) continue;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.failed_to_add_avatar", avatarId));
|
||||
continue;
|
||||
}
|
||||
int id = Integer.parseInt(avatarId);
|
||||
var success = addAvatar(sender, targetPlayer, id, index);
|
||||
if (index > 0) ++index;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean removeCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.invalid_usage"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.remove_usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.remove_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -106,7 +97,7 @@ public final class TeamCommand implements CommandHandler {
|
||||
// step 1: parse metaIndex to indexes
|
||||
var subIndexes = transformToIndexes(metaIndex, avatarCount);
|
||||
if (subIndexes == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.failed_to_parse_index", metaIndex));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", metaIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -123,13 +114,13 @@ public final class TeamCommand implements CommandHandler {
|
||||
|
||||
// step 3: check if user remove all of the avatar
|
||||
if (indexes.size() >= avatarCount) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.remove_too_much"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.remove_too_much");
|
||||
return false;
|
||||
}
|
||||
|
||||
// step 4: hint user for ignore index
|
||||
if (!ignoreList.isEmpty()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.ignore_index", ignoreList));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.ignore_index", ignoreList);
|
||||
}
|
||||
|
||||
// step 5: remove
|
||||
@ -139,8 +130,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
|
||||
private boolean setCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.invalid_usage"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.set_usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.set_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -151,12 +142,12 @@ public final class TeamCommand implements CommandHandler {
|
||||
index = Integer.parseInt(args.get(1)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch(Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.failed_to_parse_index", args.get(1)));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + 1 > currentTeamAvatars.size()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.index_out_of_range"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.index_out_of_range");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -164,7 +155,7 @@ public final class TeamCommand implements CommandHandler {
|
||||
try {
|
||||
avatarId = Integer.parseInt(args.get(2));
|
||||
} catch(Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.failed_parse_avatar_id", args.get(2)));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_parse_avatar_id", args.get(2));
|
||||
return false;
|
||||
}
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
@ -172,12 +163,12 @@ public final class TeamCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.avatar_already_in_team", avatarId));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.avatar_not_found", avatarId));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -191,11 +182,11 @@ public final class TeamCommand implements CommandHandler {
|
||||
}
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.avatar_already_in_team", avatarId));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (!sender.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.team.avatar_not_found", avatarId));
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (index < 0) {
|
||||
|
@ -64,8 +64,16 @@ public class GameData {
|
||||
|
||||
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuest> codexQuestMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuest> codexQuestIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexAnimalData> codexAnimalDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
||||
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -294,9 +302,17 @@ public class GameData {
|
||||
return fetters;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<CodexQuest> getCodexQuestMap(){return codexQuestMap;}
|
||||
public static Int2ObjectMap<CodexQuestData> getCodexQuestDataIdMap(){return codexQuestDataIdMap;}
|
||||
|
||||
public static Int2ObjectMap<CodexQuest> getCodexQuestIdMap(){return codexQuestIdMap;}
|
||||
public static Int2ObjectMap<CodexAnimalData> getCodexAnimalDataMap(){return codexAnimalDataMap;}
|
||||
|
||||
public static Int2ObjectMap<CodexWeaponData> getCodexWeaponDataIdMap(){return codexWeaponDataIdMap;}
|
||||
|
||||
public static Int2ObjectMap<CodexMaterialData> getCodexMaterialDataIdMap(){return codexMaterialDataIdMap;}
|
||||
|
||||
public static Int2ObjectMap<CodexReliquaryData> getcodexReliquaryIdMap(){return codexReliquaryDataIdMap;}
|
||||
|
||||
public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList(){return codexReliquaryArrayList;}
|
||||
|
||||
public static Int2ObjectMap<WorldLevelData> getWorldLevelDataMap() {
|
||||
return worldLevelDataMap;
|
||||
|
39
src/main/java/emu/grasscutter/data/def/CodexAnimalData.java
Normal file
39
src/main/java/emu/grasscutter/data/def/CodexAnimalData.java
Normal file
@ -0,0 +1,39 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"AnimalCodexExcelConfigData.json"})
|
||||
public class CodexAnimalData extends GameResource {
|
||||
private int Id;
|
||||
private String Type;
|
||||
private int DescribeId;
|
||||
private int SortOrder;
|
||||
private CodexAnimalUnlockCondition BAINKHIIMJE;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return Type;
|
||||
}
|
||||
|
||||
public int getDescribeId() {
|
||||
return DescribeId;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
return SortOrder;
|
||||
}
|
||||
|
||||
public CodexAnimalUnlockCondition getUnlockCondition() {
|
||||
return BAINKHIIMJE;
|
||||
}
|
||||
|
||||
public enum CodexAnimalUnlockCondition {
|
||||
CODEX_COUNT_TYPE_KILL,
|
||||
CODEX_COUNT_TYPE_CAPTURE
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"MaterialCodexExcelConfigData.json"})
|
||||
public class CodexMaterialData extends GameResource {
|
||||
private int Id;
|
||||
private int MaterialId;
|
||||
private int SortOrder;
|
||||
|
||||
public int getSortOrder() {
|
||||
return SortOrder;
|
||||
}
|
||||
|
||||
public int getMaterialId() {
|
||||
return MaterialId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this);
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"QuestCodexExcelConfigData.json"}, loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
public class CodexQuest extends GameResource {
|
||||
@ResourceType(name = {"QuestCodexExcelConfigData.json"})
|
||||
public class CodexQuestData extends GameResource {
|
||||
private int Id;
|
||||
private int ParentQuestId;
|
||||
private int ChapterId;
|
||||
@ -36,7 +35,7 @@ public class CodexQuest extends GameResource {
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if(!this.getIsDisuse()) {
|
||||
GameData.getCodexQuestIdMap().put(this.getParentQuestId(), this);
|
||||
GameData.getCodexQuestDataIdMap().put(this.getParentQuestId(), this);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"ReliquaryCodexExcelConfigData.json"})
|
||||
public class CodexReliquaryData extends GameResource {
|
||||
private int Id;
|
||||
private int SuitId;
|
||||
private int Level;
|
||||
private int CupId;
|
||||
private int LeatherId;
|
||||
private int CapId;
|
||||
private int FlowerId;
|
||||
private int SandId;
|
||||
private int SortOrder;
|
||||
|
||||
public int getSortOrder() {
|
||||
return SortOrder;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public int getSuitId() {
|
||||
return SuitId;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return Level;
|
||||
}
|
||||
|
||||
public int getCupId() {
|
||||
return CupId;
|
||||
}
|
||||
|
||||
public int getLeatherId() {
|
||||
return LeatherId;
|
||||
}
|
||||
|
||||
public int getCapId() {
|
||||
return CapId;
|
||||
}
|
||||
|
||||
public int getFlowerId() {
|
||||
return FlowerId;
|
||||
}
|
||||
|
||||
public int getSandId() {
|
||||
return SandId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getcodexReliquaryArrayList().add(this);
|
||||
GameData.getcodexReliquaryIdMap().put(getSuitId(), this);
|
||||
}
|
||||
}
|
29
src/main/java/emu/grasscutter/data/def/CodexWeaponData.java
Normal file
29
src/main/java/emu/grasscutter/data/def/CodexWeaponData.java
Normal file
@ -0,0 +1,29 @@
|
||||
package emu.grasscutter.data.def;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"WeaponCodexExcelConfigData.json"})
|
||||
public class CodexWeaponData extends GameResource {
|
||||
private int Id;
|
||||
private int WeaponId;
|
||||
private int SortOrder;
|
||||
|
||||
public int getSortOrder() {
|
||||
return SortOrder;
|
||||
}
|
||||
|
||||
public int getWeaponId() {
|
||||
return WeaponId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getCodexWeaponDataIdMap().put(this.getWeaponId(), this);
|
||||
}
|
||||
}
|
@ -240,6 +240,7 @@ public class Inventory implements Iterable<GameItem> {
|
||||
}
|
||||
|
||||
private synchronized void putItem(GameItem item, InventoryTab tab) {
|
||||
getPlayer().getCodex().checkAddedItem(item);
|
||||
// Set owner and guid FIRST!
|
||||
item.setOwner(getPlayer());
|
||||
// Put in item store
|
||||
|
@ -2,7 +2,6 @@ package emu.grasscutter.game.player;
|
||||
|
||||
import dev.morphia.annotations.*;
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.def.PlayerLevelData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
@ -30,8 +29,6 @@ import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.game.quest.QuestManager;
|
||||
import emu.grasscutter.game.shop.ShopLimit;
|
||||
import emu.grasscutter.game.managers.MapMarkManager.*;
|
||||
@ -80,6 +77,7 @@ public class Player {
|
||||
private Position pos;
|
||||
private Position rotation;
|
||||
private PlayerBirthday birthday;
|
||||
private PlayerCodex codex;
|
||||
|
||||
private Map<Integer, Integer> properties;
|
||||
private Set<Integer> nameCardList;
|
||||
@ -189,6 +187,7 @@ public class Player {
|
||||
this.birthday = new PlayerBirthday();
|
||||
this.rewardedLevels = new HashSet<>();
|
||||
this.moonCardGetTimes = new HashSet<>();
|
||||
this.codex = new PlayerCodex();
|
||||
|
||||
this.shopLimit = new ArrayList<>();
|
||||
this.expeditionInfo = new HashMap<>();
|
||||
@ -209,6 +208,7 @@ public class Player {
|
||||
this.signature = "";
|
||||
this.teamManager = new TeamManager(this);
|
||||
this.birthday = new PlayerBirthday();
|
||||
this.codex = new PlayerCodex();
|
||||
this.setProperty(PlayerProperty.PROP_PLAYER_LEVEL, 1);
|
||||
this.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1);
|
||||
this.setProperty(PlayerProperty.PROP_SPRING_AUTO_USE_PERCENT, 50);
|
||||
@ -758,7 +758,6 @@ public class Player {
|
||||
return expeditionInfo.get(avaterGuid);
|
||||
}
|
||||
|
||||
|
||||
public List<ShopLimit> getShopLimit() {
|
||||
return shopLimit;
|
||||
}
|
||||
@ -984,6 +983,8 @@ public class Player {
|
||||
return this.birthday.getDay() > 0;
|
||||
}
|
||||
|
||||
public PlayerCodex getCodex(){ return this.codex; }
|
||||
|
||||
public Set<Integer> getRewardedLevels() {
|
||||
return rewardedLevels;
|
||||
}
|
||||
@ -1159,6 +1160,7 @@ public class Player {
|
||||
|
||||
@PostLoad
|
||||
private void onLoad() {
|
||||
this.getCodex().setPlayer(this);
|
||||
this.getTeamManager().setPlayer(this);
|
||||
this.getTowerManager().setPlayer(this);
|
||||
}
|
||||
@ -1229,7 +1231,6 @@ public class Player {
|
||||
session.send(new PacketFinishedParentQuestNotify(this));
|
||||
session.send(new PacketQuestListNotify(this));
|
||||
session.send(new PacketCodexDataFullNotify(this));
|
||||
session.send(new PacketServerCondMeetQuestListUpdateNotify(this));
|
||||
session.send(new PacketAllWidgetDataNotify(this));
|
||||
session.send(new PacketWidgetGadgetAllDataNotify());
|
||||
session.send(new PacketPlayerHomeCompInfoNotify(this));
|
||||
|
160
src/main/java/emu/grasscutter/game/player/PlayerCodex.java
Normal file
160
src/main/java/emu/grasscutter/game/player/PlayerCodex.java
Normal file
@ -0,0 +1,160 @@
|
||||
package emu.grasscutter.game.player;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.def.CodexAnimalData;
|
||||
import emu.grasscutter.data.def.CodexReliquaryData;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.inventory.MaterialType;
|
||||
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Entity
|
||||
public class PlayerCodex {
|
||||
@Transient private Player player;
|
||||
|
||||
//itemId is not codexId!
|
||||
private Set<Integer> unlockedWeapon;
|
||||
private Map<Integer, Integer> unlockedAnimal;
|
||||
private Set<Integer> unlockedMaterial;
|
||||
private Set<Integer> unlockedBook;
|
||||
private Set<Integer> unlockedTip;
|
||||
private Set<Integer> unlockedView;
|
||||
private Set<Integer> unlockedReliquary;
|
||||
private Set<Integer> unlockedReliquarySuitCodex;
|
||||
|
||||
public PlayerCodex(){
|
||||
this.unlockedWeapon = new HashSet<>();
|
||||
this.unlockedAnimal = new HashMap<>();
|
||||
this.unlockedMaterial = new HashSet<>();
|
||||
this.unlockedBook = new HashSet<>();
|
||||
this.unlockedTip = new HashSet<>();
|
||||
this.unlockedView = new HashSet<>();
|
||||
this.unlockedReliquary = new HashSet<>();
|
||||
this.unlockedReliquarySuitCodex = new HashSet<>();
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void checkAddedItem(GameItem item){
|
||||
ItemType type = item.getItemData().getItemType();
|
||||
if (type == ItemType.ITEM_WEAPON){
|
||||
if(!getUnlockedWeapon().contains(item.getItemId())){
|
||||
getUnlockedWeapon().add(item.getItemId());
|
||||
var codexItem = GameData.getCodexWeaponDataIdMap().get(item.getItemId());
|
||||
if(codexItem != null){
|
||||
player.save();
|
||||
this.player.sendPacket(new PacketCodexDataUpdateNotify(2, codexItem.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == ItemType.ITEM_MATERIAL){
|
||||
if( item.getItemData().getMaterialType() == MaterialType.MATERIAL_FOOD ||
|
||||
item.getItemData().getMaterialType() == MaterialType.MATERIAL_WIDGET||
|
||||
item.getItemData().getMaterialType() == MaterialType.MATERIAL_EXCHANGE||
|
||||
item.getItemData().getMaterialType() == MaterialType.MATERIAL_AVATAR_MATERIAL||
|
||||
item.getItemData().getMaterialType() == MaterialType.MATERIAL_NOTICE_ADD_HP){
|
||||
if (!getUnlockedMaterial().contains(item.getItemId())) {
|
||||
var codexMaterial = GameData.getCodexMaterialDataIdMap().get(item.getItemId());
|
||||
if (codexMaterial != null) {
|
||||
getUnlockedMaterial().add(item.getItemId());
|
||||
player.save();
|
||||
this.player.sendPacket(new PacketCodexDataUpdateNotify(4, codexMaterial.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == ItemType.ITEM_RELIQUARY) {
|
||||
if(!getUnlockedReliquary().contains(item.getItemId())){
|
||||
getUnlockedReliquary().add(item.getItemId());
|
||||
checkUnlockedSuits(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkAnimal(GameEntity target, CodexAnimalData.CodexAnimalUnlockCondition condition){
|
||||
if(target.getEntityType() == 2){
|
||||
var monsterId = target.getSpawnEntry().getMonsterId();
|
||||
var codexAnimal = GameData.getCodexAnimalDataMap().get(monsterId);
|
||||
|
||||
if(!getUnlockedAnimal().containsKey(monsterId)) {
|
||||
if (codexAnimal != null) {
|
||||
if(codexAnimal.getUnlockCondition() == condition){
|
||||
getUnlockedAnimal().put(monsterId, 1);
|
||||
player.save();
|
||||
this.player.sendPacket(new PacketCodexDataUpdateNotify(3, monsterId));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
getUnlockedAnimal().put(monsterId, getUnlockedAnimal().get(monsterId) + 1);
|
||||
player.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkUnlockedSuits(GameItem item){
|
||||
int reliquaryId = item.getItemId();
|
||||
Optional<CodexReliquaryData> excelReliquarySuitList = GameData.getcodexReliquaryArrayList().stream().filter(
|
||||
x -> x.getCupId() == reliquaryId
|
||||
|| x.getLeatherId() == reliquaryId
|
||||
|| x.getCapId() == reliquaryId
|
||||
|| x.getFlowerId() == reliquaryId
|
||||
|| x.getSandId() == reliquaryId
|
||||
).findFirst();
|
||||
if(excelReliquarySuitList.isPresent()) {
|
||||
var excelReliquarySuit = excelReliquarySuitList.get();
|
||||
if(!getUnlockedReliquarySuitCodex().contains(excelReliquarySuit.getId())){
|
||||
if(
|
||||
getUnlockedReliquary().contains(excelReliquarySuit.getCupId()) &&
|
||||
getUnlockedReliquary().contains(excelReliquarySuit.getLeatherId()) &&
|
||||
getUnlockedReliquary().contains(excelReliquarySuit.getCapId()) &&
|
||||
getUnlockedReliquary().contains(excelReliquarySuit.getFlowerId()) &&
|
||||
getUnlockedReliquary().contains(excelReliquarySuit.getSandId())
|
||||
){
|
||||
getUnlockedReliquarySuitCodex().add(excelReliquarySuit.getId());
|
||||
player.save();
|
||||
this.player.sendPacket(new PacketCodexDataUpdateNotify(8, excelReliquarySuit.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedWeapon() {
|
||||
return unlockedWeapon;
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getUnlockedAnimal() {
|
||||
return unlockedAnimal;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedMaterial() {
|
||||
return unlockedMaterial;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedBook() {
|
||||
return unlockedBook;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedTip() {
|
||||
return unlockedTip;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedView() {
|
||||
return unlockedView;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedReliquary() {
|
||||
return unlockedReliquary;
|
||||
}
|
||||
|
||||
public Set<Integer> getUnlockedReliquarySuitCodex() {
|
||||
return unlockedReliquarySuitCodex;
|
||||
}
|
||||
|
||||
}
|
@ -121,7 +121,6 @@ public class QuestManager {
|
||||
mainQuest.save();
|
||||
|
||||
// Send packet
|
||||
getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(quest));
|
||||
getPlayer().sendPacket(new PacketQuestListUpdateNotify(quest));
|
||||
|
||||
return quest;
|
||||
|
@ -2,10 +2,7 @@ package emu.grasscutter.game.world;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
import emu.grasscutter.data.def.DungeonData;
|
||||
import emu.grasscutter.data.def.MonsterData;
|
||||
import emu.grasscutter.data.def.SceneData;
|
||||
import emu.grasscutter.data.def.WorldLevelData;
|
||||
import emu.grasscutter.data.def.*;
|
||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
||||
import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
@ -389,6 +386,9 @@ public class Scene {
|
||||
}
|
||||
|
||||
public void killEntity(GameEntity target, int attackerId) {
|
||||
for (Player player : this.getPlayers()) {
|
||||
player.getCodex().checkAnimal(target, CodexAnimalData.CodexAnimalUnlockCondition.CODEX_COUNT_TYPE_KILL);
|
||||
}
|
||||
// Packet
|
||||
this.broadcastPacket(new PacketLifeStateChangeNotify(attackerId, target, LifeState.LIFE_DEAD));
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.QueryCodexMonsterBeKilledNumReqOuterClass;
|
||||
import emu.grasscutter.net.proto.QueryCodexMonsterBeKilledNumReqOuterClass.QueryCodexMonsterBeKilledNumReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketQueryCodexMonsterBeKilledNumRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.QueryCodexMonsterBeKilledNumReq)
|
||||
public class HandlerQueryCodexMonsterBeKilledNumReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
QueryCodexMonsterBeKilledNumReq req = QueryCodexMonsterBeKilledNumReq.parseFrom(payload);
|
||||
session.send(new PacketQueryCodexMonsterBeKilledNumRsp(session.getPlayer(), req.getCodexIdListList()));
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,13 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CodexDataFullNotifyOuterClass.CodexDataFullNotify;
|
||||
import emu.grasscutter.net.proto.CodexTypeDataOuterClass.CodexTypeData;
|
||||
import emu.grasscutter.net.proto.CodexTypeOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
public class PacketCodexDataFullNotify extends BasePacket {
|
||||
public PacketCodexDataFullNotify(Player player) {
|
||||
@ -21,6 +17,22 @@ public class PacketCodexDataFullNotify extends BasePacket {
|
||||
CodexTypeData.Builder questTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(1);
|
||||
|
||||
//Weapons
|
||||
CodexTypeData.Builder weaponTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(2);
|
||||
|
||||
//Animals
|
||||
CodexTypeData.Builder animalTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(3);
|
||||
|
||||
//Materials
|
||||
CodexTypeData.Builder materialTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(4);
|
||||
|
||||
//Books
|
||||
CodexTypeData.Builder bookTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(5);
|
||||
|
||||
//Tips
|
||||
CodexTypeData.Builder pushTipsTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(6);
|
||||
@ -29,25 +41,53 @@ public class PacketCodexDataFullNotify extends BasePacket {
|
||||
CodexTypeData.Builder viewTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(7);
|
||||
|
||||
//Weapons
|
||||
CodexTypeData.Builder weaponTypeData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(2);
|
||||
|
||||
//Reliquary
|
||||
CodexTypeData.Builder reliquaryData = CodexTypeData.newBuilder()
|
||||
.setTypeValue(8);
|
||||
|
||||
player.getQuestManager().forEachMainQuest(mainQuest -> {
|
||||
if(mainQuest.isFinished()){
|
||||
var codexQuest = GameData.getCodexQuestIdMap().get(mainQuest.getParentQuestId());
|
||||
var codexQuest = GameData.getCodexQuestDataIdMap().get(mainQuest.getParentQuestId());
|
||||
if(codexQuest != null){
|
||||
questTypeData.addCodexIdList(codexQuest.getId()).addAllHaveViewedList(Collections.singleton(true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.getCodex().getUnlockedWeapon().forEach(weapon -> {
|
||||
var codexWeapon = GameData.getCodexWeaponDataIdMap().get(weapon);
|
||||
if(codexWeapon != null){
|
||||
weaponTypeData.addCodexIdList(codexWeapon.getId()).addAllHaveViewedList(Collections.singleton(true));
|
||||
}
|
||||
});
|
||||
|
||||
player.getCodex().getUnlockedAnimal().forEach((animal, amount) -> {
|
||||
var codexAnimal = GameData.getCodexAnimalDataMap().get(animal);
|
||||
if(codexAnimal != null){
|
||||
animalTypeData.addCodexIdList(codexAnimal.getId()).addAllHaveViewedList(Collections.singleton(true));
|
||||
}
|
||||
});
|
||||
|
||||
player.getCodex().getUnlockedMaterial().forEach(material -> {
|
||||
var codexMaterial = GameData.getCodexMaterialDataIdMap().get(material);
|
||||
if(codexMaterial != null){
|
||||
materialTypeData.addCodexIdList(codexMaterial.getId()).addAllHaveViewedList(Collections.singleton(true));
|
||||
}
|
||||
});
|
||||
|
||||
player.getCodex().getUnlockedReliquarySuitCodex().forEach(reliquarySuit -> {
|
||||
reliquaryData.addCodexIdList(reliquarySuit).addAllHaveViewedList(Collections.singleton(true));
|
||||
});
|
||||
|
||||
CodexDataFullNotify.Builder proto = CodexDataFullNotify.newBuilder()
|
||||
.addTypeDataList(questTypeData.build())
|
||||
.addTypeDataList(weaponTypeData)
|
||||
.addTypeDataList(animalTypeData)
|
||||
.addTypeDataList(materialTypeData)
|
||||
.addTypeDataList(bookTypeData)
|
||||
.addTypeDataList(pushTipsTypeData.build())
|
||||
.addTypeDataList(viewTypeData.build())
|
||||
.addTypeDataList(weaponTypeData);
|
||||
.addTypeDataList(reliquaryData);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
@ -1,21 +1,15 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CodexDataUpdateNotifyOuterClass.CodexDataUpdateNotify;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
public class PacketCodexDataUpdateNotify extends BasePacket {
|
||||
public PacketCodexDataUpdateNotify(GameMainQuest quest) {
|
||||
super(PacketOpcodes.CodexDataUpdateNotify, true);
|
||||
var codexQuest = GameData.getCodexQuestIdMap().get(quest.getParentQuestId());
|
||||
var codexQuest = GameData.getCodexQuestDataIdMap().get(quest.getParentQuestId());
|
||||
if(codexQuest != null){
|
||||
CodexDataUpdateNotify proto = CodexDataUpdateNotify.newBuilder()
|
||||
.setTypeValue(1)
|
||||
@ -24,4 +18,13 @@ public class PacketCodexDataUpdateNotify extends BasePacket {
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
public PacketCodexDataUpdateNotify(int typeValue, int codexId){
|
||||
super(PacketOpcodes.CodexDataUpdateNotify, true);
|
||||
CodexDataUpdateNotify proto = CodexDataUpdateNotify.newBuilder()
|
||||
.setTypeValue(typeValue)
|
||||
.setId(codexId)
|
||||
.build();
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QueryCodexMonsterBeKilledNumRspOuterClass.QueryCodexMonsterBeKilledNumRsp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketQueryCodexMonsterBeKilledNumRsp extends BasePacket {
|
||||
|
||||
public PacketQueryCodexMonsterBeKilledNumRsp(Player player, List<Integer> codexList) {
|
||||
super(PacketOpcodes.QueryCodexMonsterBeKilledNumRsp);
|
||||
QueryCodexMonsterBeKilledNumRsp.Builder proto = QueryCodexMonsterBeKilledNumRsp.newBuilder();
|
||||
|
||||
codexList.forEach(animal -> {
|
||||
if(player.getCodex().getUnlockedAnimal().containsKey(animal)){
|
||||
proto.addCodexIdList(animal)
|
||||
.addBeKilledNumList(player.getCodex().getUnlockedAnimal().get(animal))
|
||||
.addBeKilledNumEmptyList(0);
|
||||
}
|
||||
});
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -12,13 +12,15 @@ public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
||||
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||
|
||||
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
|
||||
|
||||
|
||||
/*
|
||||
player.getQuestManager().forEachQuest(quest -> {
|
||||
if (quest.getState().getValue() <= 2) {
|
||||
proto.addAddQuestIdList(quest.getQuestId());
|
||||
}
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
@ -26,9 +28,9 @@ public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
||||
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||
|
||||
ServerCondMeetQuestListUpdateNotify proto = ServerCondMeetQuestListUpdateNotify.newBuilder()
|
||||
.addAddQuestIdList(quest.getQuestId())
|
||||
//.addAddQuestIdList(quest.getQuestId())
|
||||
.build();
|
||||
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@
|
||||
"description": "Gives the player a specified artifact"
|
||||
},
|
||||
"giveChar": {
|
||||
"usage": "Usage: givechar <player> <itemID|itemName> [amount]",
|
||||
"usage": "Usage: givechar <player> <itemID|itemName> [level]",
|
||||
"given": "Given %s with level %s to %s.",
|
||||
"invalid_avatar_id": "Invalid avatar ID.",
|
||||
"invalid_avatar_level": "Invalid avatar level.",
|
||||
|
@ -163,7 +163,7 @@
|
||||
"description": "给予指定圣遗物"
|
||||
},
|
||||
"giveChar": {
|
||||
"usage": "用法:givechar <玩家> <角色ID|角色名> [数量]",
|
||||
"usage": "用法:givechar <玩家> <角色ID|角色名> [等级]",
|
||||
"given": "已将角色 %s [等级 %s] 给与 %s。",
|
||||
"invalid_avatar_id": "无效的角色ID。",
|
||||
"invalid_avatar_level": "无效的角色等级。",
|
||||
|
@ -37,8 +37,9 @@
|
||||
"session_key_error": "對話密鑰不符。",
|
||||
"username_error": "未找到此用戶名。",
|
||||
"username_create_error": "未找到用戶名,建立失敗。",
|
||||
"server_max_player_limit": "服務器在綫人數已滿"
|
||||
}
|
||||
"server_max_player_limit": "服務器在線人數已滿"
|
||||
},
|
||||
"router_error": "[Dispatch] 無法附加到路由上。"
|
||||
},
|
||||
"status": {
|
||||
"free_software": "Grasscutter 是免費開源軟體。如果你已經付錢了,那你可能被騙了。主頁:https://github.com/Grasscutters/Grasscutter",
|
||||
@ -158,7 +159,7 @@
|
||||
"description": "給予指定聖遺物。"
|
||||
},
|
||||
"giveChar": {
|
||||
"usage": "用法:givechar <player> <itemId|itemName> [amount]",
|
||||
"usage": "用法:givechar <player> <itemId|itemName> [level]",
|
||||
"given": "已將 %s 等級 %s 給予 %s。",
|
||||
"invalid_avatar_id": "無效的角色ID。",
|
||||
"invalid_avatar_level": "無效的角色等級。.",
|
||||
@ -396,5 +397,27 @@
|
||||
"available_four_stars": "可獲得的4星物品",
|
||||
"available_three_stars": "可獲得的3星物品"
|
||||
}
|
||||
},
|
||||
"documentation": {
|
||||
"handbook": {
|
||||
"title": "GM手冊",
|
||||
"title_commands": "指令",
|
||||
"title_avatars": "角色",
|
||||
"title_items": "道具",
|
||||
"title_scenes": "場景",
|
||||
"title_monsters": "怪物",
|
||||
"header_id": "ID",
|
||||
"header_command": "指令",
|
||||
"header_description": "描述",
|
||||
"header_avatar": "角色",
|
||||
"header_item": "物品",
|
||||
"header_scene": "場景",
|
||||
"header_monster": "怪物"
|
||||
},
|
||||
"index": {
|
||||
"title": "文件",
|
||||
"handbook": "GM手冊",
|
||||
"gacha_mapping": "祈願物品映射到JSON上"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user