Compare commits

..

4 Commits

Author SHA1 Message Date
Melledy
23d7ef8378 Migrate battlepass to its own db collection 2022-06-21 07:59:10 -07:00
诗音澄鸢 镜苑芳依
d8f2421832
implement BattlePass (Except missions) (#1316)
* BattlePass

* BattlePass
2022-06-21 07:18:13 -07:00
loulou310
5c80146aaa
French translation for ban and unban and typos fix (#1337)
* Fixed french readme's typos, and the Discord server link

* Translated ban and unban commands for French
2022-06-21 07:14:47 -07:00
Tesutarin
51533ad4e7 Update 2.7 second half banners 2022-06-21 02:43:21 -07:00
42 changed files with 755 additions and 44 deletions

View File

@ -7,7 +7,7 @@
**Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
## Fonctionalités actuelles : ## Fonctionnalités actuelles :
* Connection * Connection
* Combat * Combat
@ -20,7 +20,7 @@
## Guide de démarrage rapide ## Guide de démarrage rapide
**Note:** Pour obtenir un support, rejoignez notre serveur Discord [Discord](https://discord.gg/T5vZU6UyeG) (en anglais). **Note:** Pour obtenir un support, rejoignez notre serveur [Discord](https://discord.gg/T5vZU6UyeG) (en anglais).
### Logiciels requis ### Logiciels requis
@ -61,7 +61,7 @@
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
``` ```
- Fiddler Classic: Exécutez Fiddler Classic, Activez `Decrypt https traffic` dans les paramàtres et changez le port par défaut ici (Tools -> Options -> Connections) à autre chose que `8888`, et chargez [ce script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Exécutez Fiddler Classic, Activez `Decrypt https traffic` dans les paramètres et changez le port par défaut ici (Tools -> Options -> Connections) à autre chose que `8888`, et chargez [ce script](https://github.lunatic.moe/fiddlerscript).
- [Fichier hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Fichier hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map)

View File

@ -0,0 +1,15 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassMission.proto";
import "BattlePassSchedule.proto";
// CmdId: 2618
// EnetChannelId: 0
// EnetIsReliable: true
message BattlePassAllDataNotify {
bool have_cur_schedule = 11;
BattlePassSchedule cur_schedule = 10;
repeated BattlePassMission mission_list = 1;
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "ItemParam.proto";
// CmdId: 2614
// EnetChannelId: 0
// EnetIsReliable: true
message BattlePassBuySuccNotify {
uint32 schedule_id = 7;
uint32 product_play_type = 9;
repeated ItemParam item_list = 6;
uint32 add_point = 2;
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassSchedule.proto";
// CmdId: 2604
// EnetChannelId: 0
// EnetIsReliable: true
message BattlePassCurScheduleUpdateNotify {
bool have_cur_schedule = 9;
BattlePassSchedule cur_schedule = 15;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message BattlePassCycle {
uint32 cycle_idx = 1;
uint32 begin_time = 2;
uint32 end_time = 3;
}

View File

@ -0,0 +1,19 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message BattlePassMission {
uint32 mission_id = 1;
uint32 cur_progress = 2;
uint32 total_progress = 3;
uint32 reward_battle_pass_point = 4;
uint32 mission_type = 5;
MissionStatus mission_status = 6;
enum MissionStatus {
MISSION_STATUS_INVALID = 0;
MISSION_STATUS_UNFINISHED = 1;
MISSION_STATUS_FINISHED = 2;
MISSION_STATUS_POINT_TAKEN = 3;
}
}

View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2643
// EnetChannelId: 0
// EnetIsReliable: true
message BattlePassMissionDelNotify {
repeated uint32 del_mission_id_list = 4;
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassMission.proto";
// CmdId: 2609
// EnetChannelId: 0
// EnetIsReliable: true
message BattlePassMissionUpdateNotify {
repeated BattlePassMission mission_list = 6;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message BattlePassProduct {
string normal_product_id = 1;
string extra_product_id = 2;
string upgrade_product_id = 3;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassUnlockStatus.proto";
message BattlePassRewardTag {
BattlePassUnlockStatus unlock_status = 1;
uint32 level = 2;
uint32 reward_id = 3;
}

View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassRewardTag.proto";
message BattlePassRewardTakeOption {
BattlePassRewardTag tag = 1;
uint32 option_idx = 2;
}

View File

@ -0,0 +1,24 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassCycle.proto";
import "BattlePassProduct.proto";
import "BattlePassRewardTag.proto";
import "BattlePassUnlockStatus.proto";
message BattlePassSchedule {
uint32 schedule_id = 1;
uint32 level = 2;
uint32 point = 3;
BattlePassUnlockStatus unlock_status = 4;
repeated BattlePassRewardTag reward_taken_list = 5;
uint32 begin_time = 6;
uint32 end_time = 7;
BattlePassCycle cur_cycle = 8;
bool is_extra_paid_reward_taken = 9;
BattlePassProduct product_info = 10;
bool is_viewed = 11;
uint32 cur_cycle_points = 12;
uint32 JPFMGBEBBBJ = 13;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
enum BattlePassUnlockStatus {
BATTLE_PASS_UNLOCK_STATUS_INVALID = 0;
BATTLE_PASS_UNLOCK_STATUS_FREE = 1;
BATTLE_PASS_UNLOCK_STATUS_PAID = 2;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2612
// EnetChannelId: 0
// EnetIsReliable: true
// IsAllowClient: true
message BuyBattlePassLevelReq {
uint32 buy_level = 10;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2646
// EnetChannelId: 0
// EnetIsReliable: true
message BuyBattlePassLevelRsp {
int32 retcode = 9;
uint32 buy_level = 6;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2616
// EnetChannelId: 0
// EnetIsReliable: true
// IsAllowClient: true
message GetBattlePassProductReq {
uint32 battle_pass_product_play_type = 2;
}

View File

@ -0,0 +1,14 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2601
// EnetChannelId: 0
// EnetIsReliable: true
message GetBattlePassProductRsp {
int32 retcode = 13;
uint32 battle_pass_product_play_type = 9;
uint32 cur_schedule_id = 12;
string product_id = 7;
string price_tier = 5;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2637
// EnetChannelId: 0
// EnetIsReliable: true
// IsAllowClient: true
message SetBattlePassViewedReq {
uint32 schedule_id = 6;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2632
// EnetChannelId: 0
// EnetIsReliable: true
message SetBattlePassViewedRsp {
int32 retcode = 15;
uint32 schedule_id = 10;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2626
// EnetChannelId: 0
// EnetIsReliable: true
// IsAllowClient: true
message TakeBattlePassMissionPointReq {
repeated uint32 mission_id_list = 7;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
// CmdId: 2647
// EnetChannelId: 0
// EnetIsReliable: true
message TakeBattlePassMissionPointRsp {
int32 retcode = 12;
repeated uint32 mission_id_list = 2;
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassRewardTakeOption.proto";
// CmdId: 2628
// EnetChannelId: 0
// EnetIsReliable: true
// IsAllowClient: true
message TakeBattlePassRewardReq {
repeated BattlePassRewardTakeOption take_option_list = 4;
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "BattlePassRewardTakeOption.proto";
import "ItemParam.proto";
// CmdId: 2603
// EnetChannelId: 0
// EnetIsReliable: true
message TakeBattlePassRewardRsp {
int32 retcode = 2;
repeated BattlePassRewardTakeOption take_option_list = 1;
repeated ItemParam item_list = 5;
}

View File

@ -0,0 +1,23 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player;
import java.util.List;
@Command(label = "setbp", usage = "", aliases = "bp",permission = "player.setbp", description = "")
public final class SetBPLevelCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
CommandHandler.sendMessage(sender , "Need a arg");
return;
}
int level = Integer.parseInt(args.get(0));
sender.getBattlePassManager().addPoint(level);
sender.getBattlePassManager().updateAwardTakenLevel(0);
}
}

View File

@ -94,6 +94,8 @@ public class GameData {
private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<BattlePassMissionExcelConfigData> battlePassMissionExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<BattlePassRewardExcelConfigData> battlePassRewardExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
@ -416,4 +418,11 @@ public class GameData {
return cityDataMap; return cityDataMap;
} }
public static Int2ObjectMap<BattlePassMissionExcelConfigData> getBattlePassMissionExcelConfigDataMap() {
return battlePassMissionExcelConfigDataMap;
}
public static Int2ObjectMap<BattlePassRewardExcelConfigData> getBattlePassRewardExcelConfigDataMap() {
return battlePassRewardExcelConfigDataMap;
}
} }

View File

@ -0,0 +1,29 @@
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
@FieldDefaults(level = AccessLevel.PRIVATE)
@Getter
@Setter
public class BattlePassMissionExcelConfigData extends GameResource {
private int addPoint;
private int id;
private int progress;
private String refreshType;
@Override
public void onLoad() {
}
@Override
public int getId() {
return this.id;
}
}

View File

@ -0,0 +1,27 @@
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@ResourceType(name = "BattlePassRewardExcelConfigData.json")
@Getter
@Setter
public class BattlePassRewardExcelConfigData extends GameResource {
private int indexId;
private int level;
private List<Integer> freeRewardIdList;
private List<Integer> paidRewardIdList;
@Override
public int getId() {
return this.level;
}
@Override
public void onLoad() {
}
}

View File

@ -11,6 +11,7 @@ import emu.grasscutter.GameConstants;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.battlepass.BattlePassManager;
import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.gacha.GachaRecord; import emu.grasscutter.game.gacha.GachaRecord;
import emu.grasscutter.game.home.GameHome; import emu.grasscutter.game.home.GameHome;
@ -296,10 +297,27 @@ public final class DatabaseHelper {
public static boolean deleteQuest(GameMainQuest quest) { public static boolean deleteQuest(GameMainQuest quest) {
return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged(); return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged();
} }
public static GameHome getHomeByUid(int id) { public static GameHome getHomeByUid(int id) {
return DatabaseManager.getGameDatastore().find(GameHome.class).filter(Filters.eq("ownerUid", id)).first(); return DatabaseManager.getGameDatastore().find(GameHome.class).filter(Filters.eq("ownerUid", id)).first();
} }
public static void saveHome(GameHome gameHome) { public static void saveHome(GameHome gameHome) {
DatabaseManager.getGameDatastore().save(gameHome); DatabaseManager.getGameDatastore().save(gameHome);
} }
public static BattlePassManager loadBattlePass(Player player) {
BattlePassManager manager = DatabaseManager.getGameDatastore().find(BattlePassManager.class).filter(Filters.eq("ownerUid", player.getUid())).first();
if (manager == null) {
manager = new BattlePassManager(player);
manager.save();
} else {
manager.setPlayer(player);
}
return manager;
}
public static void saveBattlePass(BattlePassManager manager) {
DatabaseManager.getGameDatastore().save(manager);
}
} }

View File

@ -14,6 +14,7 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.battlepass.BattlePassManager;
import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.gacha.GachaRecord; import emu.grasscutter.game.gacha.GachaRecord;
import emu.grasscutter.game.home.GameHome; import emu.grasscutter.game.home.GameHome;
@ -31,7 +32,7 @@ public final class DatabaseManager {
private static final Class<?>[] mappedClasses = new Class<?>[] { private static final Class<?>[] mappedClasses = new Class<?>[] {
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class
}; };
public static Datastore getGameDatastore() { public static Datastore getGameDatastore() {

View File

@ -208,7 +208,7 @@ public class Account {
public boolean removePermission(String permission) { public boolean removePermission(String permission) {
return this.permissions.remove(permission); return this.permissions.remove(permission);
} }
// TODO make unique // TODO make unique
public String generateLoginToken() { public String generateLoginToken() {
this.token = Utils.bytesToHex(Crypto.createSessionKey(32)); this.token = Utils.bytesToHex(Crypto.createSessionKey(32));

View File

@ -0,0 +1,65 @@
package emu.grasscutter.game.battlepass;
import org.bson.types.ObjectId;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
import dev.morphia.annotations.Transient;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify;
@Entity(value = "battlepass", useDiscriminator = false)
public class BattlePassManager {
@Id private ObjectId id;
@Transient private Player player;
@Indexed private int ownerUid;
private int point;
private int awardTakenLevel;
@Deprecated // Morphia only
public BattlePassManager() {}
public BattlePassManager(Player player) {
this.setPlayer(player);
}
public ObjectId getId() {
return id;
}
public Player getPlayer() {
return this.player;
}
public void setPlayer(Player player) {
this.player = player;
this.ownerUid = player.getUid();
}
public int getPoint() {
return point;
}
public int getAwardTakenLevel() {
return awardTakenLevel;
}
public void addPoint(int point){
this.point += point;
player.getSession().send(new PacketBattlePassCurScheduleUpdateNotify(player.getSession().getPlayer()));
this.save();
}
public void updateAwardTakenLevel(int level){
this.awardTakenLevel = level;
player.getSession().send(new PacketBattlePassCurScheduleUpdateNotify(player.getSession().getPlayer()));
this.save();
}
public void save() {
DatabaseHelper.saveBattlePass(this);
}
}

View File

@ -12,6 +12,7 @@ import emu.grasscutter.game.ability.AbilityManager;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.avatar.AvatarProfileData; import emu.grasscutter.game.avatar.AvatarProfileData;
import emu.grasscutter.game.avatar.AvatarStorage; import emu.grasscutter.game.avatar.AvatarStorage;
import emu.grasscutter.game.battlepass.BattlePassManager;
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.home.GameHome; import emu.grasscutter.game.home.GameHome;
@ -169,6 +170,7 @@ public class Player {
@Transient private DeforestationManager deforestationManager; @Transient private DeforestationManager deforestationManager;
@Transient private GameHome home; @Transient private GameHome home;
@Transient private FurnitureManager furnitureManager; @Transient private FurnitureManager furnitureManager;
@Transient private BattlePassManager battlePassManager;
private long springLastUsed; private long springLastUsed;
private HashMap<String, MapMark> mapMarks; private HashMap<String, MapMark> mapMarks;
@ -1206,6 +1208,15 @@ public class Player {
return furnitureManager; return furnitureManager;
} }
public BattlePassManager getBattlePassManager(){
return battlePassManager;
}
public void loadBattlePassManager() {
if (this.battlePassManager != null) return;
this.battlePassManager = DatabaseHelper.loadBattlePass(this);
}
public AbilityManager getAbilityManager() { public AbilityManager getAbilityManager() {
return abilityManager; return abilityManager;
} }
@ -1308,15 +1319,17 @@ public class Player {
} }
//Make sure towerManager's player is online player //Make sure towerManager's player is online player
this.getTowerManager().setPlayer(this); this.getTowerManager().setPlayer(this);
// Load from db // Load from db
this.getAvatars().loadFromDatabase(); this.getAvatars().loadFromDatabase();
this.getInventory().loadFromDatabase(); this.getInventory().loadFromDatabase();
this.getAvatars().postLoad(); this.getAvatars().postLoad(); // Needs to be called after inventory is handled
this.getFriendsList().loadFromDatabase(); this.getFriendsList().loadFromDatabase();
this.getMailHandler().loadFromDatabase(); this.getMailHandler().loadFromDatabase();
this.getQuestManager().loadFromDatabase(); this.getQuestManager().loadFromDatabase();
this.loadBattlePassManager();
} }
public void onLogin() { public void onLogin() {
@ -1348,6 +1361,7 @@ public class Player {
session.send(new PacketPlayerStoreNotify(this)); session.send(new PacketPlayerStoreNotify(this));
session.send(new PacketAvatarDataNotify(this)); session.send(new PacketAvatarDataNotify(this));
session.send(new PacketFinishedParentQuestNotify(this)); session.send(new PacketFinishedParentQuestNotify(this));
session.send(new PacketBattlePassAllDataNotify(this));
session.send(new PacketQuestListNotify(this)); session.send(new PacketQuestListNotify(this));
session.send(new PacketCodexDataFullNotify(this)); session.send(new PacketCodexDataFullNotify(this));
session.send(new PacketAllWidgetDataNotify(this)); session.send(new PacketAllWidgetDataNotify(this));

View File

@ -0,0 +1,25 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakeBattlePassMissionPointReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify;
import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify;
import emu.grasscutter.server.packet.send.PacketTakeBattlePassMissionPointRsp;
@Opcodes(PacketOpcodes.TakeBattlePassMissionPointReq)
public class HandlerTakeBattlePassMissionPointReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req
= TakeBattlePassMissionPointReqOuterClass.TakeBattlePassMissionPointReq.parseFrom(payload);
session.send(new PacketBattlePassMissionUpdateNotify(req.getMissionIdListList() , session));
session.send(new PacketBattlePassCurScheduleUpdateNotify(session.getPlayer()));
session.send(new PacketTakeBattlePassMissionPointRsp());
}
}

View File

@ -0,0 +1,24 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakeBattlePassRewardReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
@Opcodes(PacketOpcodes.TakeBattlePassRewardReq)
public class HandlerTakeBattlePassRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req
= TakeBattlePassRewardReqOuterClass.TakeBattlePassRewardReq.parseFrom(payload);
//due to the list only have one element, so we can use get(0)
session.send(new PacketTakeBattlePassRewardRsp(req.getTakeOptionListList() , session));
//update the awardTakenLevel
req.getTakeOptionListList().forEach(battlePassRewardTakeOption ->
session.getPlayer().getBattlePassManager().updateAwardTakenLevel(battlePassRewardTakeOption.getTag().getLevel()));
}
}

View File

@ -0,0 +1,63 @@
package emu.grasscutter.server.packet.send;
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.*;
import java.util.ArrayList;
import java.util.List;
public class PacketBattlePassAllDataNotify extends BasePacket {
public PacketBattlePassAllDataNotify(Player player) {
super(PacketOpcodes.BattlePassAllDataNotify);
var value = player.getBattlePassManager().getPoint();
int level = (int) Math.floor(value / 1000d);
var point = value - level * 1000;
List<BattlePassRewardTagOuterClass.BattlePassRewardTag> rewardTags = new ArrayList<>();
for (int id = 1; id <= player.getBattlePassManager().getAwardTakenLevel(); id++)
rewardTags.add(BattlePassRewardTagOuterClass.BattlePassRewardTag.newBuilder()
.setLevel(id)
.setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE)
.setRewardId(1001000 + id)
.build());
var proto
= BattlePassAllDataNotifyOuterClass.BattlePassAllDataNotify.newBuilder();
var missions
= GameData.getBattlePassMissionExcelConfigDataMap();
var curSchedule
= BattlePassScheduleOuterClass.BattlePassSchedule.newBuilder()
.setScheduleId(2700).setLevel(level).setPoint(point).setBeginTime(1653940800).setEndTime(2059483200).addAllRewardTakenList(rewardTags)
.setIsViewed(true).setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE).setCurCyclePoints(0)
.setCurCycle(BattlePassCycleOuterClass.BattlePassCycle.newBuilder().setBeginTime(1653940800).setEndTime(2059483200).setCycleIdx(3).build());
proto.setHaveCurSchedule(true).setCurSchedule(curSchedule);
//TODO: UNFINISHED YET / Need to add mission data --> Hard work
for (var mission : missions.values())
proto.addMissionList(BattlePassMissionOuterClass.BattlePassMission.newBuilder()
.setMissionId(mission.getId())
.setMissionStatus(BattlePassMissionOuterClass.BattlePassMission.MissionStatus.MISSION_STATUS_UNFINISHED)
.setTotalProgress(mission.getProgress())
.setMissionType(
mission.getRefreshType() == null ? 0 :
mission.getRefreshType().equals("BATTLE_PASS_MISSION_REFRESH_SCHEDULE") ? 2 : mission.getRefreshType().contains("CYCLE") ? 1 : 0)
.setRewardBattlePassPoint(mission.getAddPoint())
.build());
setData(proto.build());
}
}

View File

@ -0,0 +1,41 @@
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.*;
import java.util.ArrayList;
import java.util.List;
public class PacketBattlePassCurScheduleUpdateNotify extends BasePacket {
public PacketBattlePassCurScheduleUpdateNotify(Player player) {
super(PacketOpcodes.BattlePassCurScheduleUpdateNotify);
var value = player.getBattlePassManager().getPoint();
int level = (int) Math.floor(value / 1000d);
var point = value - level * 1000;
List<BattlePassRewardTagOuterClass.BattlePassRewardTag> rewardTags = new ArrayList<>();
for (int id = 1; id <= player.getBattlePassManager().getAwardTakenLevel(); id++)
rewardTags.add(BattlePassRewardTagOuterClass.BattlePassRewardTag.newBuilder()
.setLevel(id)
.setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE)
.setRewardId(1001000 + id)
.build());
var curSchedule
= BattlePassScheduleOuterClass.BattlePassSchedule.newBuilder()
.setScheduleId(2700).setLevel(level).setPoint(point).setBeginTime(1653940800).setEndTime(2059483200).addAllRewardTakenList(rewardTags)
.setIsViewed(true).setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE).setCurCyclePoints(0)
.setCurCycle(BattlePassCycleOuterClass.BattlePassCycle.newBuilder().setBeginTime(1653940800).setEndTime(2059483200).setCycleIdx(3).build());
var proto = BattlePassCurScheduleUpdateNotifyOuterClass.BattlePassCurScheduleUpdateNotify.newBuilder();
proto.setHaveCurSchedule(true).setCurSchedule(curSchedule).build();
setData(proto.build());
}
}

View File

@ -0,0 +1,40 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.BattlePassMissionExcelConfigData;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BattlePassMissionOuterClass;
import emu.grasscutter.net.proto.BattlePassMissionUpdateNotifyOuterClass;
import emu.grasscutter.server.game.GameSession;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.List;
import java.util.Map;
public class PacketBattlePassMissionUpdateNotify extends BasePacket {
public PacketBattlePassMissionUpdateNotify(List<Integer> missionIdList , GameSession session) {
super(PacketOpcodes.BattlePassMissionUpdateNotify);
var proto
= BattlePassMissionUpdateNotifyOuterClass.BattlePassMissionUpdateNotify.newBuilder();
Map<Integer, BattlePassMissionExcelConfigData> missionMap
= GameData.getBattlePassMissionExcelConfigDataMap();
missionIdList.forEach(missionId -> proto.addMissionList
(BattlePassMissionOuterClass.BattlePassMission.newBuilder().setMissionId(missionId).setMissionStatus
(BattlePassMissionOuterClass.BattlePassMission.MissionStatus.MISSION_STATUS_POINT_TAKEN)
.setTotalProgress(missionMap.get(missionId).getProgress()).setRewardBattlePassPoint(missionMap.get(missionId).getAddPoint()).build()));
var point = session.getPlayer().getBattlePassManager().getPoint();
missionIdList.forEach(missionId
-> session.getPlayer().getBattlePassManager().addPoint(missionMap.get(missionId).getAddPoint()));
Grasscutter.getLogger().info("[PacketBattlePassMissionUpdateNotify] addPoint: {}", session.getPlayer().getBattlePassManager().getPoint() - point);
this.setData(proto.build());
}
}

View File

@ -28,7 +28,7 @@ public class PacketGetDailyDungeonEntryInfoRsp extends BasePacket {
var dungeonEntryId = data.getDungeonEntryId(); var dungeonEntryId = data.getDungeonEntryId();
var id = data.getId(); var id = data.getId();
//TODO: 来个爹把这块整活了吧 咚咚咚 // TODO
DungeonEntryInfoOuterClass.DungeonEntryInfo dungeonEntryInfo DungeonEntryInfoOuterClass.DungeonEntryInfo dungeonEntryInfo
= DungeonEntryInfoOuterClass.DungeonEntryInfo.newBuilder().setDungeonId(130).build(); = DungeonEntryInfoOuterClass.DungeonEntryInfo.newBuilder().setDungeonId(130).build();

View File

@ -0,0 +1,13 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakeBattlePassMissionPointRspOuterClass;
import java.util.List;
public class PacketTakeBattlePassMissionPointRsp extends BasePacket {
public PacketTakeBattlePassMissionPointRsp() {
super(PacketOpcodes.TakeBattlePassMissionPointRsp);
}
}

View File

@ -0,0 +1,49 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.BattlePassRewardExcelConfigData;
import emu.grasscutter.data.excels.RewardData;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass;
import emu.grasscutter.net.proto.ItemParamOuterClass;
import emu.grasscutter.net.proto.TakeBattlePassRewardRspOuterClass;
import emu.grasscutter.server.game.GameSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class PacketTakeBattlePassRewardRsp extends BasePacket {
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption> takeOptionList , GameSession session) {
super(PacketOpcodes.TakeBattlePassRewardRsp);
var proto
= TakeBattlePassRewardRspOuterClass.TakeBattlePassRewardRsp.newBuilder();
Map<Integer , BattlePassRewardExcelConfigData> excelConfigDataMap = GameData.getBattlePassRewardExcelConfigDataMap();
Map<Integer , RewardData> rewardDataMap = GameData.getRewardDataMap();
List<Integer> rewardItemList = new ArrayList<>();
for (var takeOption : takeOptionList) {
for (int level = session.getPlayer().getBattlePassManager().getAwardTakenLevel() + 1 ; level <= takeOption.getTag().getLevel() ; level++){
rewardItemList.addAll(excelConfigDataMap.get(level).getFreeRewardIdList());
rewardItemList.addAll(excelConfigDataMap.get(level).getPaidRewardIdList());
}
for (var rewardItemId : rewardItemList) {
var rewardData = rewardDataMap.get(rewardItemId);
if (rewardData == null) continue;
rewardData.getRewardItemList().forEach(i ->
proto.addItemList(ItemParamOuterClass.ItemParam.newBuilder().setItemId(i.getId()).setCount(i.getCount()).build()));
}
}
proto.addAllTakeOptionList(takeOptionList).build();
setData(proto);
}
}

View File

@ -7,44 +7,25 @@
"previewPrefabPath": "UI_Tab_GachaShowPanel_A022", "previewPrefabPath": "UI_Tab_GachaShowPanel_A022",
"titlePath": "UI_GACHA_SHOW_PANEL_A022_TITLE", "titlePath": "UI_GACHA_SHOW_PANEL_A022_TITLE",
"costItemId": 224, "costItemId": 224,
"costItemAmount": 1,
"costItemAmount10": 10,
"beginTime": 0, "beginTime": 0,
"endTime": 1924992000, "endTime": 1924992000,
"sortId": 1000, "sortId": 1000,
"fallbackItems4Pool1": [1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064], "fallbackItems4Pool1": [1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064],
"weights4": [[1,510], [8,510], [10,10000]],
"weights5": [[1,75], [73,150], [90,10000]] "weights5": [[1,75], [73,150], [90,10000]]
}, },
{ {
"gachaType": 301, "gachaType": 301,
"scheduleId": 903, "scheduleId": 903,
"bannerType": "EVENT", "bannerType": "EVENT",
"prefabPath": "GachaShowPanel_A081", "prefabPath": "GachaShowPanel_A084",
"previewPrefabPath": "UI_Tab_GachaShowPanel_A081", "previewPrefabPath": "UI_Tab_GachaShowPanel_A084",
"titlePath": "UI_GACHA_SHOW_PANEL_A081_TITLE", "titlePath": "UI_GACHA_SHOW_PANEL_A061_TITLE",
"costItemId": 223, "costItemId": 223,
"beginTime": 0, "beginTime": 0,
"endTime": 1924992000, "endTime": 1924992000,
"sortId": 9998, "sortId": 9999,
"rateUpItems4": [1034, 1014, 1048], "rateUpItems4": [1065, 1036, 1055],
"rateUpItems5": [1060], "rateUpItems5": [1057],
"fallbackItems5Pool2": [],
"weights5": [[1,80], [73,80], [90,10000]]
},
{
"gachaType": 400,
"scheduleId": 923,
"bannerType": "EVENT",
"prefabPath": "GachaShowPanel_A082",
"previewPrefabPath": "UI_Tab_GachaShowPanel_A082",
"titlePath": "UI_GACHA_SHOW_PANEL_A031_TITLE",
"costItemId": 223,
"beginTime": 0,
"endTime": 1924992000,
"sortId": 9998,
"rateUpItems4": [1034, 1014, 1048],
"rateUpItems5": [1026],
"fallbackItems5Pool2": [], "fallbackItems5Pool2": [],
"weights5": [[1,80], [73,80], [90,10000]] "weights5": [[1,80], [73,80], [90,10000]]
}, },
@ -52,20 +33,19 @@
"gachaType": 302, "gachaType": 302,
"scheduleId": 913, "scheduleId": 913,
"bannerType": "WEAPON", "bannerType": "WEAPON",
"prefabPath": "GachaShowPanel_A083", "prefabPath": "GachaShowPanel_A085",
"previewPrefabPath": "UI_Tab_GachaShowPanel_A083", "previewPrefabPath": "UI_Tab_GachaShowPanel_A085",
"titlePath": "UI_GACHA_SHOW_PANEL_A021_TITLE", "titlePath": "UI_GACHA_SHOW_PANEL_A013_TITLE",
"costItemId": 223, "costItemId": 223,
"beginTime": 0, "beginTime": 0,
"endTime": 1924992000, "endTime": 1924992000,
"sortId": 9997, "sortId": 9998,
"eventChance": 75, "rateUpItems4": [12410, 11405, 13401, 14403, 15402],
"softPity": 80, "rateUpItems5": [12510, 14504],
"hardPity": 80,
"rateUpItems4": [11403, 12401, 13406, 14409, 15403],
"rateUpItems5": [15508, 13505],
"fallbackItems5Pool1": [], "fallbackItems5Pool1": [],
"weights4": [[1,600], [7,600], [8, 6600], [10,12600]], "weights4": [[1,600], [7,600], [8,6600], [10,12600]],
"weights5": [[1,100], [62,100], [73, 7800], [80,10000]] "weights5": [[1,100], [62,100], [73,7800], [80,10000]],
"eventChance4": 75,
"eventChance5": 75
} }
] ]

View File

@ -391,6 +391,21 @@
"success": "Le type de climat a été changé à %s avec le type de météo %s.", "success": "Le type de climat a été changé à %s avec le type de météo %s.",
"invalid_id": "ID invalide.", "invalid_id": "ID invalide.",
"description": "Change la météo" "description": "Change la météo"
},
"ban": {
"description": "Bannis un joueur",
"success": "Succès.",
"failure": "Échec, joueur introuvable.",
"invalid_time": "Impossible d'analyser le timestamp.",
"invalid_player_id": "Impossible d'analyser le player ID.",
"command_usage": "Usage: ban <playerId> [timestamp] [raison]"
},
"unban": {
"description": "Retire le bannissement d'un joueur",
"success": "Succès.",
"failure": "Échec, joueur introuvable.",
"invalid_player_id": "Imossible d'analyser player ID.",
"command_usage": "Usage: unban <playerId>"
} }
}, },
"gacha": { "gacha": {