Commit 19d81463 authored by KingRainbow44's avatar KingRainbow44
Browse files

Merge remote-tracking branch 'origin/development' into development

parents 71b118dd e3e917ef
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BuyBattlePassLevelReqOuterClass.BuyBattlePassLevelReq;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketBuyBattlePassLevelRsp;
@Opcodes(PacketOpcodes.BuyBattlePassLevelReq)
public class HandlerBuyBattlePassLevelReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
BuyBattlePassLevelReq req = BuyBattlePassLevelReq.parseFrom(payload);
int buyLevel = session.getPlayer().getBattlePassManager().buyLevels(req.getBuyLevel());
session.send(new PacketBuyBattlePassLevelRsp(buyLevel));
}
}
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler;
......@@ -10,5 +11,18 @@ public class HandlerPlayerForceExitReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// Client should auto disconnect right now
session.send(new BasePacket(PacketOpcodes.PlayerForceExitRsp));
new Thread(){
@Override
public void run() {
try {
Thread.sleep(1000);// disconnect after 1 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
session.close();
super.run();
}
}.start();
}
}
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.SetBattlePassViewedReqOuterClass.SetBattlePassViewedReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSetBattlePassViewedRsp;
@Opcodes(PacketOpcodes.SetBattlePassViewedReq)
public class HandlerSetBattlePassViewedReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = SetBattlePassViewedReq.parseFrom(payload);
session.getPlayer().getBattlePassManager().updateViewed();
session.send(new PacketSetBattlePassViewedRsp(req.getScheduleId()));
}
}
......@@ -10,9 +10,6 @@ import emu.grasscutter.net.proto.SetPlayerPropReqOuterClass.SetPlayerPropReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSetPlayerPropRsp;
import java.util.ArrayList;
import java.util.List;
@Opcodes(PacketOpcodes.SetPlayerPropReq)
public class HandlerSetPlayerPropReq extends PacketHandler {
......@@ -21,11 +18,10 @@ public class HandlerSetPlayerPropReq extends PacketHandler {
// Auto template
SetPlayerPropReq req = SetPlayerPropReq.parseFrom(payload);
Player player = session.getPlayer();
List<PropValue> propList = req.getPropListList();
for (int i = 0; i < propList.size(); i++) {
PlayerProperty prop = PlayerProperty.getPropById(propList.get(i).getType());
for (PropValue p : req.getPropListList()) {
PlayerProperty prop = PlayerProperty.getPropById(p.getType());
if (prop == PlayerProperty.PROP_IS_MP_MODE_AVAILABLE) {
if (!player.setProperty(prop, (int)propList.get(i).getVal())) {
if (!player.setProperty(prop, (int) p.getVal(), false)) {
session.send(new PacketSetPlayerPropRsp(1));
return;
}
......
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.SetUpLunchBoxWidgetReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSetUpLunchBoxWidgetRsp;
@Opcodes(PacketOpcodes.SetUpLunchBoxWidgetReq)
public class HandlerSetUpLunchBoxWidgetReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req
= SetUpLunchBoxWidgetReqOuterClass.SetUpLunchBoxWidgetReq.parseFrom(payload);
session.send(new PacketSetUpLunchBoxWidgetRsp(req.getLunchBoxData()));
}
}
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.net.proto.TakeBattlePassMissionPointReqOuterClass.TakeBattlePassMissionPointReq;
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)
......@@ -15,11 +12,10 @@ public class HandlerTakeBattlePassMissionPointReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req
= TakeBattlePassMissionPointReqOuterClass.TakeBattlePassMissionPointReq.parseFrom(payload);
var req = TakeBattlePassMissionPointReq.parseFrom(payload);
session.getPlayer().getBattlePassManager().takeMissionPoint(req.getMissionIdListList());
session.send(new PacketBattlePassMissionUpdateNotify(req.getMissionIdListList() , session));
session.send(new PacketBattlePassCurScheduleUpdateNotify(session.getPlayer()));
session.send(new PacketTakeBattlePassMissionPointRsp());
}
}
......@@ -3,7 +3,7 @@ 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.net.proto.TakeBattlePassRewardReqOuterClass.TakeBattlePassRewardReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
......@@ -11,14 +11,8 @@ import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
public class HandlerTakeBattlePassRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req
= TakeBattlePassRewardReqOuterClass.TakeBattlePassRewardReq.parseFrom(payload);
var req = 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()));
session.getPlayer().getBattlePassManager().takeReward(req.getTakeOptionListList());
}
}
......@@ -5,6 +5,7 @@ import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.BattlePassAllDataNotifyOuterClass.BattlePassAllDataNotify;
import java.util.ArrayList;
import java.util.List;
......@@ -13,50 +14,25 @@ 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());
var proto = BattlePassAllDataNotify.newBuilder();
proto
.setHaveCurSchedule(true)
.setCurSchedule(player.getBattlePassManager().getScheduleProto());
for (var missionData : GameData.getBattlePassMissionDataMap().values()) {
// Dont send invalid refresh types
if (!missionData.isValidRefreshType()) {
continue;
}
// Check if player has mission in bp manager. If not, then add an empty proto from the mission data
if (player.getBattlePassManager().hasMission(missionData.getId())) {
proto.addMissionList(player.getBattlePassManager().loadMissionById(missionData.getId()).toProto());
} else {
proto.addMissionList(missionData.toProto());
}
}
setData(proto.build());
}
......
......@@ -4,36 +4,22 @@ import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.BattlePassCurScheduleUpdateNotifyOuterClass.BattlePassCurScheduleUpdateNotify;
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;
var proto = BattlePassCurScheduleUpdateNotify.newBuilder();
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();
proto
.setHaveCurSchedule(true)
.setCurSchedule(player.getBattlePassManager().getScheduleProto())
.build();
setData(proto.build());
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.BattlePassMissionExcelConfigData;
import java.util.Collection;
import emu.grasscutter.game.battlepass.BattlePassMission;
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;
import emu.grasscutter.net.proto.BattlePassMissionUpdateNotifyOuterClass.BattlePassMissionUpdateNotify;
public class PacketBattlePassMissionUpdateNotify extends BasePacket {
public PacketBattlePassMissionUpdateNotify(List<Integer> missionIdList , GameSession session) {
public PacketBattlePassMissionUpdateNotify(BattlePassMission mission) {
super(PacketOpcodes.BattlePassMissionUpdateNotify);
var proto
= BattlePassMissionUpdateNotifyOuterClass.BattlePassMissionUpdateNotify.newBuilder();
Map<Integer, BattlePassMissionExcelConfigData> missionMap
= GameData.getBattlePassMissionExcelConfigDataMap();
var proto = BattlePassMissionUpdateNotify.newBuilder()
.addMissionList(mission.toProto())
.build();
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()));
this.setData(proto);
}
public PacketBattlePassMissionUpdateNotify(Collection<BattlePassMission> missions) {
super(PacketOpcodes.BattlePassMissionUpdateNotify);
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);
var proto = BattlePassMissionUpdateNotify.newBuilder();
missions.forEach(mission -> {
proto.addMissionList(mission.toProto());
});
this.setData(proto.build());
}
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BuyBattlePassLevelRspOuterClass.BuyBattlePassLevelRsp;
public class PacketBuyBattlePassLevelRsp extends BasePacket {
public PacketBuyBattlePassLevelRsp(int buyLevel) {
super(PacketOpcodes.BuyBattlePassLevelRsp);
BuyBattlePassLevelRsp proto = BuyBattlePassLevelRsp.newBuilder()
.setBuyLevel(buyLevel)
.build();
this.setData(proto);
}
}
......@@ -30,21 +30,7 @@ public class PacketGetMailItemRsp extends BasePacket {
if (!message.isAttachmentGot) {//No duplicated item
for (Mail.MailItem mailItem : message.itemList) {
EquipParamOuterClass.EquipParam.Builder item = EquipParamOuterClass.EquipParam.newBuilder();
int promoteLevel = 0;
if (mailItem.itemLevel > 80) { // 80/90
promoteLevel = 6;
} else if (mailItem.itemLevel > 70) { // 70/80
promoteLevel = 5;
} else if (mailItem.itemLevel > 60) { // 60/70
promoteLevel = 4;
} else if (mailItem.itemLevel > 50) { // 50/60
promoteLevel = 3;
} else if (mailItem.itemLevel > 40) { // 40/50
promoteLevel = 2;
} else if (mailItem.itemLevel > 20) { // 20/40
promoteLevel = 1;
}
int promoteLevel = GameItem.getMinPromoteLevel(mailItem.itemLevel);
item.setItemId(mailItem.itemId);
item.setItemNum(mailItem.itemCount);
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SetBattlePassViewedRspOuterClass.SetBattlePassViewedRsp;
public class PacketSetBattlePassViewedRsp extends BasePacket {
public PacketSetBattlePassViewedRsp(int scheduleId) {
super(PacketOpcodes.SetBattlePassViewedRsp);
SetBattlePassViewedRsp proto = SetBattlePassViewedRsp.newBuilder()
.setScheduleId(scheduleId)
.build();
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.LunchBoxDataOuterClass;
import emu.grasscutter.net.proto.SetUpLunchBoxWidgetRspOuterClass;
public class PacketSetUpLunchBoxWidgetRsp extends BasePacket {
public PacketSetUpLunchBoxWidgetRsp(LunchBoxDataOuterClass.LunchBoxData lunchBoxData) {
super(PacketOpcodes.SetUpLunchBoxWidgetRsp);
var rsp
= SetUpLunchBoxWidgetRspOuterClass.SetUpLunchBoxWidgetRsp.newBuilder();
rsp.setLunchBoxData(lunchBoxData);
setData(rsp.build());
}
}
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.data.common.ItemParamData;
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.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.net.proto.TakeBattlePassRewardRspOuterClass.TakeBattlePassRewardRsp;
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) {
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOption> takeOptionList, List<ItemParamData> rewardItems) {
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());
var proto = TakeBattlePassRewardRsp.newBuilder()
.addAllTakeOptionList(takeOptionList);
if (rewardItems != null) {
for (ItemParamData param : rewardItems) {
proto.addItemList(ItemParam.newBuilder().setItemId(param.getItemId()).setCount(param.getCount()));
}
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);
}
}
package emu.grasscutter.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public final class SparseSet {
/*
* A convenience class for constructing integer sets out of large ranges
* Designed to be fed literal strings from this project only -
* can and will throw exceptions to tell you to fix your code if you feed it garbage. :)
*/
private static class Range {
private final int min, max;
public Range(int min, int max) {
if (min > max) {
throw new IllegalArgumentException("Range passed minimum higher than maximum - " + Integer.toString(min) + " > " + Integer.toString(max));
}
this.min = min;
this.max = max;
}
public boolean check(int value) {
return value >= this.min && value <= this.max;
}
}
private final List<Range> rangeEntries;
private final Set<Integer> denseEntries;
public SparseSet(String csv) {
this.rangeEntries = new ArrayList<>();
this.denseEntries = new TreeSet<>();
for (String token : csv.replace("\n", "").replace(" ", "").split(",")) {
String[] tokens = token.split("-");
switch (tokens.length) {
case 1:
this.denseEntries.add(Integer.parseInt(tokens[0]));
break;
case 2:
this.rangeEntries.add(new Range(Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1])));
break;
default:
throw new IllegalArgumentException("Invalid token passed to SparseSet initializer - " + token + " (split length " + Integer.toString(tokens.length) + ")");
}
}
}
public boolean contains(int i) {
for (Range range : this.rangeEntries) {
if (range.check(i)) {
return true;
}
}
return this.denseEntries.contains(i);
}
}
\ No newline at end of file
{
"scheduleId" : 45,
"scheduleStartTime" : "2022-05-01T00:00:00+08:00",
"nextScheduleChangeTime" : "2022-05-30T00:00:00+08:00"
}
\ No newline at end of file
"scheduleStartTime" : "2022-06-01T00:00:00+08:00",
"nextScheduleChangeTime" : "2030-06-30T00:00:00+08:00"
}
......@@ -70,6 +70,8 @@
"command_exist_error": "No command found.",
"no_usage_specified": "No usage specified",
"no_description_specified": "No description specified",
"set_to": "%s set to %s.",
"set_for_to": "%s for %s set to %s.",
"invalid": {
"amount": "Invalid amount.",
"artifactId": "Invalid artifact ID.",
......@@ -79,6 +81,8 @@
"itemId": "Invalid item ID.",
"itemLevel": "Invalid itemLevel.",
"itemRefinement": "Invalid itemRefinement.",
"statValue": "Invalid stat value.",
"value_between": "Invalid value: %s must be between %s and %s.",
"playerId": "Invalid player ID.",
"uid": "Invalid UID.",
"id": "Invalid ID."
......@@ -113,18 +117,6 @@
"no_account": "Account not found.",
"description": "Modify user accounts"
},
"broadcast": {
"command_usage": "Usage: broadcast <message>",
"message_sent": "Message sent.",
"description": "Sends a message to all the players"
},
"changescene": {
"usage": "Usage: changescene <sceneID>",
"already_in_scene": "You are already in that scene.",
"success": "Changed to scene %s.",
"exists_error": "The specified scene does not exist.",
"description": "Changes your scene"
},
"clear": {
"command_usage": "Usage: clear <all|wp|art|mat>",
"weapons": "Cleared weapons for %s.",
......@@ -141,11 +133,6 @@
"success": "Summoned %s to %s's world.",
"description": "Forces someone to join the world of others. If no one is targeted, it sends you into co-op mode anyway."
},
"drop": {
"command_usage": "Usage: drop <itemID|itemName> [amount]",
"success": "Dropped %s of %s.",
"description": "Drops an item near you"
},
"enter_dungeon": {
"usage": "Usage: enterdungeon <dungeonID>",
"changed": "Changed to dungeon %s.",
......@@ -153,39 +140,16 @@
"in_dungeon_error": "You are already in that dungeon.",
"description": "Enter a dungeon"
},
"giveAll": {
"usage": "Usage: giveall [player] [amount]",
"started": "Receiving all items...",
"success": "Successfully gave all items to %s.",
"invalid_amount_or_playerId": "Invalid amount or player ID.",
"description": "Gives all items"
},
"giveArtifact": {
"usage": "Usage: giveart|gart [player] <artifactID> <mainPropID> [<appendPropID>[,<times>]]... [level]",
"id_error": "Invalid artifact ID.",
"success": "Given %s to %s.",
"description": "Gives the player a specified artifact"
},
"giveChar": {
"usage": "Usage: givechar <player> <avatarID> [level]",
"given": "Given %s with level %s to %s.",
"invalid_avatar_id": "Invalid avatar ID.",
"invalid_avatar_level": "Invalid avatar level.",
"invalid_avatar_or_player_id": "Invalid avatar or player ID.",
"description": "Gives the player a specified character"
},
"give": {
"usage": "Usage: give <player> <itemID|itemName> [amount] [level] [refinement]",
"refinement_only_applicable_weapons": "Refinement is only applicable to weapons.",
"refinement_must_between_1_and_5": "Refinement must be between 1 and 5.",
"usage": "Usage: give <itemID|avatarID|\"all\"|\"weapons\"|\"mats\"|\"avatars\"> [x<amount>] [lv<level>] [r<refinement>]",
"usage_relic": "Usage: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
"illegal_relic": "This artifactID belongs to a blacklisted range, it may not be the one you wanted.",
"given": "Given %s of %s to %s.",
"given_with_level_and_refinement": "Given %s with level %s, refinement %s %s times to %s.",
"given_level": "Given %s with level %s %s times to %s.",
"description": "Gives an item to you or the specified player"
},
"godmode": {
"success": "Godmode is now %s for %s.",
"description": "Prevents you from taking damage. Defaults to toggle."
"given_avatar": "Given %s with level %s to %s.",
"giveall_success": "Successfully gave all items.",
"description": "Gives an item to you or the specified player. Can also give all weapons, avatars and/or materials, and can construct custom artifacts."
},
"heal": {
"success": "All characters have been healed.",
......@@ -223,10 +187,6 @@
"success": "There are %s player(s) online:",
"description": "List online players"
},
"nostamina": {
"success": "NoStamina is now %s for %s.",
"description": "Keep your endurance to the maximum."
},
"permission": {
"usage": "Usage: permission <add|remove> <username> <permission>",
"add": "Permission added.",
......@@ -263,9 +223,6 @@
"success": "Reset complete.",
"description": "Reset target player's shop refresh time"
},
"restart": {
"description": "Restarts the current session"
},
"sendMail": {
"usage": "Usage: sendmail <userID|all|help> [templateID]",
"user_not_exist": "The user with an ID of '%s' does not exist.",
......@@ -290,9 +247,9 @@
"description": "Sends mail to the specified user. The usage of this command changes based on its composition state"
},
"sendMessage": {
"usage": "Usage: sendmessage <player> <message>",
"usage": "Usage: sendmessage <message>",
"success": "Message sent.",
"description": "Sends a message to a player as the server"
"description": "Sends a message to a player as the server. If used with no target, sends to all players on the server."
},
"setFetterLevel": {
"usage": "Usage: setfetterlevel <level>",
......@@ -301,25 +258,14 @@
"level_error": "Invalid fetter level.",
"description": "Sets your fetter level for your current active character"
},
"setProp": {
"usage": "Usage: setprop|prop <prop> <value>\n\tValues for <prop>: godmode | nostamina | unlimitedenergy | abyssfloor | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume",
"description": "Sets accountwide properties. Things like godmode can be enabled this way, as well as changing things like unlocked abyss floor and battle pass progress."
},
"setStats": {
"usage_console": "Usage: setstats|stats @<UID> <stat> <value>",
"usage_ingame": "Usage: setstats|stats [@UID] <stat> <value>",
"help_message": "\n\tValues for <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Elemental DMG Bonus: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Elemental RES: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"value_error": "Invalid stat value.",
"uid_error": "Invalid UID.",
"player_error": "Player not found or offline.",
"set_self": "%s set to %s.",
"set_for_uid": "%s for %s set to %s.",
"set_max_hp": "MAX HP set to %s.",
"usage": "Usage: setstats|stats <stat> <value>\n\tValues for <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Elemental DMG Bonus: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Elemental RES: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"description": "Sets fight property for your current active character"
},
"setWorldLevel": {
"usage": "Usage: setworldlevel <level>",
"value_error": "World level must be between 0-8.",
"success": "World level set to %s.",
"invalid_world_level": "Invalid world level.",
"description": "Sets your world level (Relog to see proper effects)"
},
"spawn": {
"usage": "Usage: spawn <entityID> [amount] [level(monster only)] [<x> <y> <z>(monster only, optional)]",
"success": "Spawned %s of %s.",
......@@ -375,18 +321,10 @@
"usage": "Usage: tp [@<playerID>] <x> <y> <z> [sceneID]",
"specify_player_id": "You must specify a player ID.",
"invalid_position": "Invalid position.",
"exists_error": "The specified scene does not exist.",
"success": "Teleported %s to %s, %s, %s in scene %s.",
"description": "Change the player's position"
},
"unlimitenergy": {
"success": "UnlimitEnergy is now %s for %s.",
"config_error": "Command is disabled, because energyUsage is false in config.json.",
"description": "Use the element does not waste energy"
},
"unlocktower": {
"success": "Abyss Corridor's Floors are all unlocked now.",
"description": "Unlock all levels of tower"
},
"weather": {
"usage": "Usage: weather [weatherId] [climateType]\nWeather IDs can be found in WeatherExcelConfigData.json.\nClimate types: sunny, cloudy, rain, thunderstorm, snow, mist",
"success": "Set weather ID to %s with climate type %s.",
......@@ -394,18 +332,16 @@
"description": "Changes weather ID and climate type. Weather IDs can be found in WeatherExcelConfigData.json.\nClimate types: sunny, cloudy, rain, thunderstorm, snow, mist"
},
"ban": {
"command_usage": "Usage: ban <playerId> [timestamp] [reason]",
"command_usage": "Usage: ban <@playerId> [timestamp] [reason]",
"success": "Successful.",
"failure": "Failed, player not found.",
"invalid_time": "Unable to parse timestamp.",
"invalid_player_id": "Unable to parse player ID.",
"description": "Ban a player"
},
"unban": {
"command_usage": "Usage: unban <playerId>",
"command_usage": "Usage: unban <@playerId>",
"success": "Successful.",
"failure": "Failed, player not found.",
"invalid_player_id": "Unable to parse player ID.",
"description": "Unban a player"
}
},
......
......@@ -70,6 +70,8 @@
"command_exist_error": "Aucune commande trouvée.",
"no_usage_specified": "Pas de description de l'utilisation spécifiée.",
"no_description_specified": "Pas de description spécifiée",
"set_to": "%s a été défini a %s.",
"set_for_to": "%s de %s a été défini a %s.",
"invalid": {
"amount": "Montant invalide.",
"artifactId": "ID de l'artéfact invalide.",
......@@ -79,6 +81,8 @@
"itemId": "ID de l'objet invalide.",
"itemLevel": "Niveau de l'objet invalide.",
"itemRefinement": "Raffinement de l'objet invalide.",
"statValue": "Valeur de <stat> invalide.",
"value_between": "Invalid value: %s must be between %s and %s.",
"playerId": "ID du joueur invalide.",
"uid": "UID invalide.",
"id": "ID invalide."
......@@ -114,18 +118,6 @@
"command_usage": "Utilisation: account <create|delete> <nom_d'utilisateur> [UID]",
"description": "Modifie les comptes utilisateurs"
},
"broadcast": {
"command_usage": "Usage: broadcast <message>",
"message_sent": "Message envoyé.",
"description": "Envoie un message a tous les joueurs"
},
"changescene": {
"usage": "Usage: changescene <sceneID>",
"already_in_scene": "Vous êtes déjà dans cette scène.",
"success": "Nouvelle scène : %s.",
"exists_error": "La scène spécifié n'existe pas.",
"description": "Change votre scène"
},
"clear": {
"command_usage": "Usage: clear <all|wp|art|mat>",
"weapons": "Les armes de %s ont été supprimés.",
......@@ -142,11 +134,6 @@
"success": "%s est apparu dans de monde de %s.",
"description": "Force quelqu'un a rejoindre le monde d'un autre. Si personne n'est ciblé, vous envoie quand même en mode multijoueur."
},
"drop": {
"command_usage": "Usage: drop <itemID|itemName> [quantité]",
"success": " %s %s ont été jetés.",
"description": "Jette un objet près de vous"
},
"enter_dungeon": {
"usage": "Usage: enterdungeon <dungeonID>",
"changed": "Entré dans le donjon %s.",
......@@ -167,21 +154,14 @@
"success": "%s a été donné à %s.",
"description": "Donne au joueur l'artéfact spécifié."
},
"giveChar": {
"usage": "Usage: givechar <joueur> <avatarID> [niveau]",
"given": "%s avec le niveau %s a été donné à %s.",
"invalid_avatar_id": "ID de l'avatar invalide.",
"invalid_avatar_level": "Niveau de l'avatar invalide.",
"invalid_avatar_or_player_id": "ID de l'avatar ou du joueur invalide.",
"description": "Donne au joueur le personnage spécifié"
},
"give": {
"usage": "Usage: give <joueur> <itemID|itemName> [quantité] [niveau] [raffinement]",
"usage": "Usage: give <joueur> <itemID|avatarID> [quantité] [niveau] [raffinement]",
"refinement_only_applicable_weapons": "Le raffinement est uniquement applicable aux armes.",
"refinement_must_between_1_and_5": "Le raffinement doit être compris entre 1 et 5.",
"given": "Given %s of %s to %s.",
"given_with_level_and_refinement": "%s avec le niveau %s, raffinement %s %s fois à %s.",
"given_level": "%s avec le niveau %s %s fois à %s.",
"given_avatar": "%s avec le niveau %s a été donné à %s.",
"description": "Donne un objet au joueur spécifié"
},
"godmode": {
......@@ -264,9 +244,6 @@
"success": "Réinitialisation terminée.",
"description": "Réinitialise le temps d'actualisation de la boutique du joueur spécifié"
},
"restart": {
"description": "Redémare la session actuelle"
},
"sendMail": {
"usage": "Usage: sendmail <userID|all|help> [templateID]",
"user_not_exist": "L'utilisateur avec l'identifiant '%s' n'existe pas.",
......@@ -302,16 +279,12 @@
"level_error": "Niveau d'affinité invalide.",
"description": "Défini le niveau d'affinité de votre personnage actif"
},
"setProp": {
"usage": "Usage: setprop|prop <prop> <value>\n\tValues for <prop>: godmode | nostamina | unlimitedenergy | abyssfloor | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume",
"description": "Sets accountwide properties. Things like godmode can be enabled this way, as well as changing things like unlocked abyss floor and battle pass progress."
},
"setStats": {
"usage_console": "Usage: setstats|stats @<UID> <stat> <valeur>",
"usage_ingame": "Usage: setstats|stats [@UID] <stat> <valeur>",
"help_message": "\n\tValeurs pour <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus de dégât élémentaire: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Résistance élémentaire: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"value_error": "Valeur de <stat> invalide.",
"uid_error": "UID invalide.",
"player_error": "Joueur introuvable ou hors ligne.",
"set_self": "%s a été défini a %s.",
"set_for_uid": "%s de %s a été défini a %s.",
"set_max_hp": "MAX HP a été défini a %s.",
"usage": "Usage: setstats|stats <stat> <valeur>\n\tValeurs pour <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus de dégât élémentaire: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Résistance élémentaire: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"description": "Définit les propriétés de combat de votre personnage actif"
},
"setWorldLevel": {
......@@ -376,6 +349,7 @@
"usage": "Utilisation: tp [@<playerID>] <x> <y> <z> [sceneID]",
"specify_player_id": "Vous devez spécifier un ID d'utilisateur.",
"invalid_position": "Position invalide.",
"exists_error": "La scène spécifié n'existe pas.",
"success": "%s a été téléporté à %s, %s, %s dans la scène %s.",
"description": "Change la position du joueur"
},
......@@ -399,15 +373,13 @@
"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]"
"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>"
"command_usage": "Usage: unban <@playerId>"
}
},
"gacha": {
......
......@@ -64,6 +64,8 @@
"console_execute_error": "Tą komende można wywołać tylko z konsoli.",
"player_execute_error": "Wywołaj tą komendę w grze.",
"command_exist_error": "Nie znaleziono komendy.",
"set_to": "%s ustawiono na %s.",
"set_for_to": "%s dla %s ustawiono na %s.",
"invalid": {
"amount": "Błędna ilość.",
"artifactId": "Błędne ID artefaktu.",
......@@ -73,6 +75,7 @@
"id przedmiotu": "Błędne id przedmiotu.",
"itemLevel": "Błędny poziom przedmiotu.",
"itemRefinement": "Błędne ulepszenie.",
"value_between": "Invalid value: %s must be between %s and %s.",
"playerId": "Błędne playerId.",
"uid": "Błędne UID.",
"id": "Błędne ID."
......@@ -107,16 +110,6 @@
"no_account": "Nie znaleziono konta.",
"command_usage": "Użycie: account <create|delete> <nazwa> [uid]"
},
"broadcast": {
"command_usage": "Użycie: broadcast <wiadomość>",
"message_sent": "Wiadomość wysłana."
},
"changescene": {
"usage": "Użycie: changescene <id sceny>",
"already_in_scene": "Już jesteś na tej scenie.",
"success": "Zmieniono scene na %s.",
"exists_error": "Ta scena nie istenieje."
},
"clear": {
"command_usage": "Użycie: clear <all|wp|art|mat>",
"weapons": "Wyczyszczono bronie dla %s.",
......@@ -148,20 +141,14 @@
"id_error": "Błędne ID artefaktu.",
"success": "Dano %s dla %s."
},
"giveChar": {
"usage": "Użycie: givechar <gracz> <avatarId> [ilość]",
"given": "Dano %s z poziomem %s dla %s.",
"invalid_avatar_id": "Błędne ID postaci.",
"invalid_avatar_level": "Błędny poziom postaci.",
"invalid_avatar_or_player_id": "Błędne ID postaci lub gracza."
},
"give": {
"usage": "Użycie: give <gracz> <id przedmiotu | nazwa przedmiotu> [ilość] [poziom] [refinement]",
"usage": "Użycie: give <gracz> <id przedmiotu | avatarID> [ilość] [poziom] [refinement]",
"refinement_only_applicable_weapons": "Ulepszenie można zastosować tylko dla broni.",
"refinement_must_between_1_and_5": "Ulepszenie musi być pomiędzy 1, a 5.",
"given": "Dano %s %s dla %s.",
"given_with_level_and_refinement": "Dano %s z poziomem %s, ulepszeniem %s %s razy dla %s",
"given_level": "Dano %s z poziomem %s %s razy dla %s"
"given_level": "Dano %s z poziomem %s %s razy dla %s",
"given_avatar": "Dano %s z poziomem %s dla %s."
},
"godmode": {
"success": "Godmode jest teraz %s dla %s."
......@@ -241,16 +228,13 @@
"success": "Poziom przyjaźni ustawiono na: %s",
"level_error": "Błędny poziom przyjaźni."
},
"setProp": {
"usage": "Usage: setprop|prop <prop> <value>\n\tValues for <prop>: godmode | nostamina | unlimitedenergy | abyssfloor | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume",
"description": "Sets accountwide properties. Things like godmode can be enabled this way, as well as changing things like unlocked abyss floor and battle pass progress."
},
"setStats": {
"usage_console": "Użycie: setstats|stats @<UID> <statystyka> <wartość>",
"usage_ingame": "Użycie: setstats|stats [@UID] <statystyka> <wartość>",
"help_message": "\n\tWartości dla Statystyka: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus DMG żywiołu: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) RES na żywioł: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"value_error": "Błędna wartość statystyki.",
"uid_error": "Błędne UID.",
"player_error": "Gracza nie znaleziono lub jest offline.",
"set_self": "%s ustawiono na %s.",
"set_for_uid": "%s dla %s ustawiono na %s.",
"set_max_hp": "Maksymalne HP ustawione na %s."
"usage": "Użycie: setstats|stats <statystyka> <wartość>\n\tWartości dla Statystyka: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus DMG żywiołu: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) RES na żywioł: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
"description": "Sets fight property for your current active character"
},
"setWorldLevel": {
"usage": "Użycie: setworldlevel <poziom>",
......@@ -290,6 +274,7 @@
"usage": "Użycie: /tp [@<ID gracza>] <x> <y> <z> [ID sceny]",
"specify_player_id": "Musisz określić ID gracza.",
"invalid_position": "Błędna pozycja.",
"exists_error": "Ta scena nie istenieje.",
"success": "Przeteleportowano %s do %s, %s, %s w scenie %s"
},
"weather": {
......@@ -298,10 +283,6 @@
"success": "Set weather ID to %s with climate type %s.",
"status": "Current weather ID is %s with climate type %s."
},
"drop": {
"command_usage": "Użycie: drop <ID przedmiotu|nazwa przedmiotu> [ilość]",
"success": "Wyrzucono %s of %s."
},
"help": {
"usage": "Użycie: ",
"aliases": "Aliasy: ",
......@@ -310,6 +291,19 @@
"unlocktower": {
"success": "odblokować gotowe",
"description": "Odblokuj głęboką spiralę"
},
"ban": {
"command_usage": "Usage: ban <@playerId> [timestamp] [reason]",
"success": "Successful.",
"failure": "Failed, player not found.",
"invalid_time": "Unable to parse timestamp.",
"description": "Ban a player"
},
"unban": {
"command_usage": "Usage: unban <@playerId>",
"success": "Successful.",
"failure": "Failed, player not found.",
"description": "Unban a player"
}
},
"gacha": {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment