Commit 1de402bd authored by KingRainbow44's avatar KingRainbow44
Browse files

Merge branch 'development' into more-events

parents b9b4b6f4 f25fb629
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.player.Player.SceneLoadState;
import emu.grasscutter.game.quest.QuestGroupSuite;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler;
......@@ -16,7 +18,7 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
session.getPlayer().setSceneLoadState(SceneLoadState.LOADED);
// Done
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
// Spawn player in world
......@@ -35,11 +37,15 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
// notify client to load the npc for quest
var questGroupSuites = session.getPlayer().getQuestManager().getSceneGroupSuite(session.getPlayer().getSceneId());
session.getPlayer().getScene().loadGroupForQuest(questGroupSuites);
Grasscutter.getLogger().debug("Loaded Scene {} Quest(s) Groupsuite(s): {}", session.getPlayer().getSceneId(), questGroupSuites);
session.send(new PacketGroupSuiteNotify(questGroupSuites));
// Reset timer for sending player locations
session.getPlayer().resetSendPlayerLocTime();
//Rsp
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
}
}
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.enums.ParentQuestState;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
......@@ -11,16 +15,28 @@ import emu.grasscutter.server.packet.send.PacketNpcTalkRsp;
@Opcodes(PacketOpcodes.NpcTalkReq)
public class HandlerNpcTalkReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
NpcTalkReq req = NpcTalkReq.parseFrom(payload);
// Why are there 2 quest triggers that do the same thing...
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId());
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId());
//Check if mainQuest exists
int talkId = req.getTalkId();
//remove last 2 digits to get a mainQuestId
int mainQuestId = talkId/100;
MainQuestData mainQuestData = GameData.getMainQuestDataMap().get(mainQuestId);
if(mainQuestData != null) {
MainQuestData.TalkData talk = mainQuestData.getTalks().stream().filter(p -> p.getId() == talkId).toList().get(0);
if(talk != null) {
//talk is finished
session.getPlayer().getQuestManager().getMainQuestById(mainQuestId).getTalks().put(Integer.valueOf(talkId),talk);
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_ANY_TALK,String.valueOf(req.getTalkId()), 0, 0);
// Why are there 2 quest triggers that do the same thing...
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId(),0);
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId(),0);
}
}
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
}
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ public class HandlerPersonalLineAllDataReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
session.send(new PacketPersonalLineAllDataRsp(session.getPlayer().getQuestManager().getQuests().values()));
session.send(new PacketPersonalLineAllDataRsp(session.getPlayer().getQuestManager().getMainQuests().values()));
}
}
......@@ -14,7 +14,7 @@ public class HandlerPostEnterSceneReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
if(session.getPlayer().getScene().getSceneType() == SceneType.SCENE_ROOM){
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_ROOM, session.getPlayer().getSceneId());
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_ROOM, session.getPlayer().getSceneId(),0);
}
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PacketHeadOuterClass;
import emu.grasscutter.net.proto.PlayerSetPauseReqOuterClass;
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass;
import emu.grasscutter.net.proto.QuestVarOpOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketPlayerSetPauseRsp;
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
import java.util.List;
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
public class HandlerQuestUpdateQuestVarReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
//Client sends packets. One with the value, and one with the index and the new value to set/inc/dec
var req = QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq.parseFrom(payload);
GameMainQuest mainQuest = session.getPlayer().getQuestManager().getMainQuestById(req.getQuestId()/100);
List<QuestVarOpOuterClass.QuestVarOp> questVars = req.getQuestVarOpListList();
if (mainQuest.getQuestVarsUpdate().size() == 0) {
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
mainQuest.getQuestVarsUpdate().add(questVar.getValue());
}
} else {
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
if (questVar.getIsAdd()) {
if (questVar.getValue() >= 0) {
mainQuest.incQuestVar(questVar.getIndex(), questVar.getValue());
} else {
mainQuest.decQuestVar(questVar.getIndex(), questVar.getValue());
}
} else {
mainQuest.setQuestVar(questVar.getIndex(), mainQuest.getQuestVarsUpdate().get(0));
}
//remove the first element from the update list
mainQuest.getQuestVarsUpdate().remove(0);
}
}
session.send(new PacketQuestUpdateQuestVarRsp(req.getQuestId()));
}
}
......@@ -2,21 +2,25 @@ package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.enums.ParentQuestState;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.FinishedParentQuestNotifyOuterClass.FinishedParentQuestNotify;
public class PacketFinishedParentQuestNotify extends BasePacket {
public PacketFinishedParentQuestNotify(Player player) {
super(PacketOpcodes.FinishedParentQuestNotify, true);
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
for (GameMainQuest mainQuest : player.getQuestManager().getQuests().values()) {
proto.addParentQuestList(mainQuest.toProto());
for (GameMainQuest mainQuest : player.getQuestManager().getMainQuests().values()) {
//Canceled Quests do not appear in this packet
if(mainQuest.getState() != ParentQuestState.PARENT_QUEST_STATE_CANCELED) {
proto.addParentQuestList(mainQuest.toProto());
}
}
this.setData(proto);
}
}
......@@ -5,15 +5,29 @@ import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
import java.util.List;
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
FinishedParentQuestUpdateNotify proto = FinishedParentQuestUpdateNotify.newBuilder()
.addParentQuestList(quest.toProto())
.build();
this.setData(proto);
}
public PacketFinishedParentQuestUpdateNotify(List<GameMainQuest> quests) {
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
var proto = FinishedParentQuestUpdateNotify.newBuilder();
for(GameMainQuest mainQuest : quests) {
proto.addParentQuestList(mainQuest.toProto());
}
proto.build();
this.setData(proto);
}
}
......@@ -23,7 +23,7 @@ public class PacketPersonalLineAllDataRsp extends BasePacket {
.map(GameMainQuest::getChildQuests)
.map(Map::values)
.flatMap(Collection::stream)
.map(GameQuest::getQuestId)
.map(GameQuest::getSubQuestId)
.collect(Collectors.toSet());
GameData.getPersonalLineDataMap().values().stream()
......
......@@ -3,21 +3,24 @@ package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.QuestManager;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestListNotifyOuterClass.QuestListNotify;
public class PacketQuestListNotify extends BasePacket {
public PacketQuestListNotify(Player player) {
super(PacketOpcodes.QuestListNotify, true);
QuestListNotify.Builder proto = QuestListNotify.newBuilder();
player.getQuestManager().forEachQuest(quest -> {
proto.addQuestList(quest.toProto());
if(quest.getState() != QuestState.QUEST_STATE_UNSTARTED) {
proto.addQuestList(quest.toProto());
}
});
this.setData(proto);
}
}
......@@ -6,15 +6,28 @@ import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestListUpdateNotifyOuterClass.QuestListUpdateNotify;
import java.util.List;
public class PacketQuestListUpdateNotify extends BasePacket {
public PacketQuestListUpdateNotify(GameQuest quest) {
super(PacketOpcodes.QuestListUpdateNotify);
QuestListUpdateNotify proto = QuestListUpdateNotify.newBuilder()
.addQuestList(quest.toProto())
.build();
this.setData(proto);
}
public PacketQuestListUpdateNotify(List<GameQuest> quests) {
super(PacketOpcodes.QuestListUpdateNotify);
var proto = QuestListUpdateNotify.newBuilder();
for(GameQuest quest : quests) {
proto.addQuestList(quest.toProto());
}
proto.build();
this.setData(proto);
}
}
......@@ -7,24 +7,24 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestProgressUpdateNotifyOuterClass.QuestProgressUpdateNotify;
public class PacketQuestProgressUpdateNotify extends BasePacket {
public PacketQuestProgressUpdateNotify(GameQuest quest) {
super(PacketOpcodes.QuestProgressUpdateNotify);
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getQuestId());
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getSubQuestId());
if (quest.getFinishProgressList() != null) {
for (int i : quest.getFinishProgressList()) {
proto.addFinishProgressList(i);
}
}
if (quest.getFailProgressList() != null) {
for (int i : quest.getFailProgressList()) {
proto.addFailProgressList(i);
}
}
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass;
import emu.grasscutter.net.proto.QuestUpdateQuestVarRspOuterClass;
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
public class PacketQuestUpdateQuestVarRsp extends BasePacket {
public PacketQuestUpdateQuestVarRsp(int questId) {
super(PacketOpcodes.QuestUpdateQuestVarRsp);
var rsp = QuestUpdateQuestVarRspOuterClass.QuestUpdateQuestVarRsp.newBuilder()
.setQuestId(questId).build();
this.setData(rsp);
}
}
......@@ -6,8 +6,11 @@ import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ServerCondMeetQuestListUpdateNotifyOuterClass.ServerCondMeetQuestListUpdateNotify;
import java.util.List;
import java.util.Set;
public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
public PacketServerCondMeetQuestListUpdateNotify(Player player) {
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
......@@ -23,13 +26,24 @@ public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
this.setData(proto);
}
public PacketServerCondMeetQuestListUpdateNotify(GameQuest quest) {
public PacketServerCondMeetQuestListUpdateNotify(List<GameQuest> quests) {
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
ServerCondMeetQuestListUpdateNotify proto = ServerCondMeetQuestListUpdateNotify.newBuilder()
//.addAddQuestIdList(quest.getQuestId())
.build();
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
for (GameQuest quest : quests) {
proto.addAddQuestIdList(quest.getSubQuestId());
}
proto.build();
this.setData(proto);
}
public PacketServerCondMeetQuestListUpdateNotify() {
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
proto.build();
this.setData(proto);
}
......
......@@ -256,6 +256,14 @@
"success": "Message sent.",
"description": "Sends a message to a player as the server. If used with no target, sends to all players on the server."
},
"setConst": {
"range_error": "Constellation level must be between 0 and 6.",
"level_error": "Invalid constellation level.",
"fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.",
"description": "Sets constellation level for your current active character"
},
"setFetterLevel": {
"range_error": "Fetter level must be between 0 and 10.",
"success": "Fetter level set to %s.",
......@@ -266,7 +274,11 @@
"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.\n\tValues for <prop>: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "Sets fight property for your current active character\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"
"description": "Sets fight property for your current active character\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",
"locked_to": "%s locked to %s.",
"locked_for_to": "%s for %s locked to %s.",
"unlocked": "%s unlocked.",
"unlocked_for": "%s for %s unlocked."
},
"spawn": {
"success": "Spawned %s of %s.",
......
......@@ -256,6 +256,14 @@
"success": "Mensaje enviado.",
"description": "Envía un mensaje a un jugador como servidor. Si se usa sin un objetivo fijado, lo envía a todos los jugadores del servidor."
},
"setConst": {
"range_error": "El nivel de constelación debe estar entre 0 y 6.",
"level_error": "Nivel de constelación inválido.",
"fail": "Error al establecer la constelación.",
"failed_success": "Las constelaciones de %s han sido establecidas a %s. Por favor reinicia el escenario para ver los cambios.",
"success": "Las constelaciones de %s han sido establecidas a %s.",
"description": "Establece el nivel de constelación para tu personaje actual"
},
"setFetterLevel": {
"range_error": "El nivel de amistad debe estar entre 0 y 10.",
"success": "Nivel de amistad establecido a %s.",
......@@ -266,7 +274,11 @@
"description": "Establece propiedades de la cuenta. Cosas como el modo Dios pueden ser establecidos con este comando, además de cambiar cosas como desbloquear pisos del abusmo o progreso del pase de batalla.\n\tValores para <prop>: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel\n\t(cont.) Observa PlayerProperty enum para ver otros posibles valores, de la forma PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "Establece propiedades de combate para tu personaje actual\n\tValores para <estado>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus de daño elemental: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Resistencia elemental: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys"
"description": "Establece propiedades de combate para tu personaje actual\n\tValores para <estado>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Bonus de daño elemental: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Resistencia elemental: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys",
"locked_to": "%s fijado a %s.",
"locked_for_to": "%s para %s fijado a %s.",
"unlocked": "%s desfijado.",
"unlocked_for": "%s para %s desfijado."
},
"spawn": {
"success": "Generados %s de %s.",
......@@ -326,6 +338,10 @@
"invalid_time": "No se puede establecer la marca de tiempo.",
"description": "Beta a un jugador"
},
"unlockall": {
"success": "Desfijados todos los estados abiertos para %s.",
"description": "Desfija todos los estados abiertos para un jugador."
},
"unban": {
"success": "Exitoso.",
"failure": "Error, jugador no encontrado.",
......
......@@ -28,8 +28,8 @@
"login_token_attempt": "[Dispatch] Le client %s essaye de se connecter via un jeton.",
"login_token_error": "[Dispatch] Le client %s n'a pas réussi à se connecter via un jeton.",
"login_token_success": "[Dispatch] Le client %s est connecté via un jeton en tant que %s.",
"login_password_error": "🇺🇸[Dispatch] Client %s failed to log in via password.",
"login_password_storage_error": "🇺🇸[Dispatch] Client %s failed to log in via password because there is no password in the database.",
"login_password_error": "[Dispatch] Le client %s n'a pas réussi a se connecter avec un mot de passe",
"login_password_storage_error": "[Dispatch] Le client %s n'a pas réussi a se conencter avec un mot de passe car il n'y a pass de mot de passe dans la base de données",
"combo_token_success": "[Dispatch] Le client %s a réussi à échanger le jeton combiné.",
"combo_token_error": "[Dispatch] Le client %s n'a pas réussi à échanger le jeton combiné.",
"account_login_create_success": "[Dispatch] Le client %s n'a pas réussi à se connecter : Le compte %s a été créé.",
......@@ -39,9 +39,9 @@
"session_key_error": "Mauvaise clé de session.",
"username_error": "Nom d'utilisateur introuvable.",
"username_create_error": "Nom d'utilisateur introuvable, création échouée.",
"password_error": "🇺🇸Invalid Password",
"password_length_error": "🇺🇸Password length must be greater then or equal to 8",
"password_storage_error": "🇺🇸You don't have a password for your account. Please contact an administrator.",
"password_error": "Mot de passe invalide",
"password_length_error": "La longueur du mot de passe doit être supérieure a 8",
"password_storage_error": "Vous n'avez pas de mot de passe pour votre compte. Veuillez contacter un administrateur.",
"server_max_player_limit": "Le nombre de joueurs maximum est atteint."
},
"router_error": "[Dispatch] Impossible d'attacher le routeur."
......@@ -60,8 +60,8 @@
"version": "Version de Grasscutter: %s-%s",
"game_version": "Version du jeu: %s",
"resources": {
"loading": "🇺🇸Loading resources...",
"finish": "🇺🇸Finished loading resources."
"loading": "Chargement des ressources...",
"finish": "Chargement des ressources terminé."
}
}
},
......@@ -87,14 +87,14 @@
"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.",
"value_between": "Valeur invalide: %s doit être compris entre %s et %s.",
"playerId": "ID du joueur invalide.",
"uid": "UID invalide.",
"id": "ID invalide."
}
},
"execution": {
"usage_prefix": "🇺🇸Usage: ",
"usage_prefix": "Utilisation: ",
"player_exist_error": "Joueur introuvable.",
"player_offline_error": "Le joueur n'est pas connecté.",
"item_player_exist_error": "UID ou objet invalide.",
......@@ -123,11 +123,11 @@
"description": "Modifie les comptes utilisateurs"
},
"announce": {
"send_success": "🇺🇸Send an announcement successfully, you can revoke it by /a revoke %s.",
"refresh_success": "🇺🇸Refresh announcement config file successfully. [Total %s]",
"revoke_done": "🇺🇸Try to revoke announcement %s.",
"not_found": "🇺🇸Could not found announcement %s.",
"description": "🇺🇸Send announcement to all online players, or manage server's announcement"
"send_success": "L'annonce à bien été envoyée, vous pouvez la révoquer en utilisant /a revoke %s.",
"refresh_success": "Le fichier de configuration des annonces à bien été actualisée. [Total : %s]",
"revoke_done": "Tentative de révoquation de l'annonce %s.",
"not_found": "Impossible de trouver l'annonce %s.",
"description": "Envoie une annonce à tous les joueurs en ligne, ou configure les annonces du serveur"
},
"clear": {
"weapons": "Les armes de %s ont été supprimés.",
......@@ -150,13 +150,13 @@
"description": "Entrer dans un donjon"
},
"give": {
"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.",
"usage_relic": "Utilisation: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
"illegal_relic": "L'ID de cet artéfact appartient a une liste blacklistée, ce n'est peut-être pas celui que vous désirez.",
"given": "L'objet %s à été donné %s fois à %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.",
"giveall_success": "🇺🇸Successfully gave all items.",
"giveall_success": "Tous les objet ont été donnés avec succès.",
"description": "Donne un objet au joueur spécifié"
},
"heal": {
......@@ -166,7 +166,7 @@
"help": {
"aliases": "Alias: ",
"available_commands": "Commandes disponibles: ",
"tip_need_permission": "🇺🇸Permission: ",
"tip_need_permission": "Permissions requises: ",
"tip_need_no_permission": " Aucune",
"tip_permission_targeted": " (La permission %s est également requise pour utiliser sur d'autres joueurs)",
"warn_player_has_no_permission": "Information: Vous n'avez pas la permission d'utiliser cette commande.",
......@@ -256,6 +256,14 @@
"success": "Message envoyé.",
"description": "Envoie un message au joueur spécifié en tant que Serveur"
},
"setConst": {
"range_error": "🇺🇸Constellation level must be between 0 and 6.",
"level_error": "🇺🇸Invalid constellation level.",
"fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character"
},
"setFetterLevel": {
"range_error": "Le niveau d'affinité doit être compris entre 0 et 10.",
"success": "Niveau d'affinité défini à %s.",
......@@ -266,7 +274,11 @@
"description": "Définit des propriétes pour votre compte. Des choses comme le godemode peuvent être activés avec cette commande, et le déblocage de l'abysse ainsi que l'avancement du PB.\n\tValues for <prop>: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "Définit les propriétés de combat de votre personnage actif\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"
"description": "Définit les propriétés de combat de votre personnage actif\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",
"locked_to": "🇺🇸%s locked to %s.",
"locked_for_to": "🇺🇸%s for %s locked to %s.",
"unlocked": "🇺🇸%s unlocked.",
"unlocked_for": "🇺🇸%s for %s unlocked."
},
"spawn": {
"success": " %s %s sont apparu.",
......@@ -326,6 +338,10 @@
"invalid_time": "Impossible d'analyser le timestamp.",
"description": "Bannis un joueur"
},
"unlockall": {
"success": "🇺🇸Unlocked all open states for %s.",
"description": "🇺🇸Unlocks all open states for a player."
},
"unban": {
"success": "Succès.",
"failure": "Échec, joueur introuvable.",
......@@ -340,7 +356,7 @@
"available_three_stars": "Objets 3 étoiles disponibles"
},
"records": {
"title": "🇺🇸Gacha Records",
"title": "Historique de voeux",
"date": "🇺🇸Date",
"item": "Objet"
}
......
......@@ -256,6 +256,14 @@
"success": "Wiadomość wysłana.",
"description": "Wyślij wiadomość do gracza jako serwer. Jeśli nie określono celu, wysyła do wszystkich graczy na serwerze."
},
"setConst": {
"range_error": "🇺🇸Constellation level must be between 0 and 6.",
"level_error": "🇺🇸Invalid constellation level.",
"fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character"
},
"setFetterLevel": {
"range_error": "Poziom przyjaźni musi być pomiędzy 0 a 10.",
"success": "Poziom przyjaźni został pomyślnie ustawiony na %s.",
......@@ -266,7 +274,11 @@
"description": "Ustaw pewne własności konta, takie jak tryb nieśmiertelności (godmode) czy też zmiana postępu Battle Pass.\n\tMożliwe nazwy własności: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel | ...\n\tTa komenda ma więcej nazw własności, które może otrzymać. Możesz je wszystkie zobaczyć w pliku \"game/props/PlayerProperty.java\".\n\tW tym pliku, przyjmują one formę \"PROP_XXX_YYY_ZZZ\", ale powinieneś je zapisywać jako \"xxx_yyy_zzz\" jeśli chcesz je użyć w tej komendzie."
},
"setStats": {
"description": "Ustaw statystykę walki dla obecnie wybranej postaci wybranego gracza.\n\tMożliwe nazwy statystyki: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\tDodatkowe obrażenia od żywiołu: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\tOdporność na żywioł: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys"
"description": "Ustaw statystykę walki dla obecnie wybranej postaci wybranego gracza.\n\tMożliwe nazwy statystyki: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\tDodatkowe obrażenia od żywiołu: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\tOdporność na żywioł: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys",
"locked_to": "🇺🇸%s locked to %s.",
"locked_for_to": "🇺🇸%s for %s locked to %s.",
"unlocked": "🇺🇸%s unlocked.",
"unlocked_for": "🇺🇸%s for %s unlocked."
},
"spawn": {
"success": "Stworzono %s obiektów o ID %s.",
......@@ -326,6 +338,10 @@
"invalid_time": "Nieprawidłowy czas bana.",
"description": "Zbanuj podanego gracza."
},
"unlockall": {
"success": "🇺🇸Unlocked all open states for %s.",
"description": "🇺🇸Unlocks all open states for a player."
},
"unban": {
"success": "Pomyślnie odbanowano podanego gracza.",
"failure": "Gracz o podanym ID nie istnieje.",
......
......@@ -256,6 +256,14 @@
"success": "Mesaj trimis.",
"description": "Trimite un mesaj unui jucător în calitate de server. Dacă este utilizat fără țintă, trimite mesajul către toți jucătorii de pe server."
},
"setConst": {
"range_error": "🇺🇸Constellation level must be between 0 and 6.",
"level_error": "🇺🇸Invalid constellation level.",
"fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character"
},
"setFetterLevel": {
"range_error": "Nivelul Fetter trebuie să fie între 0 și 10.",
"success": "Nivelul Fetter setat ca %s.",
......@@ -266,7 +274,11 @@
"description": "Stabilește proprietățile la nivel de cont. Lucruri precum godmode pot fi activate în acest fel, precum și schimbarea unor lucuri precum etajul abisului deblocat și progresul battle pass.\n\tValori pentru <prop>: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel\n\t(cont.) see PlayerProperty enum for other possible values, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "Stabilește proprietatea de luptă pentru caracterul activ curent.\n\tValori pentru <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"
"description": "Stabilește proprietatea de luptă pentru caracterul activ curent.\n\tValori pentru <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",
"locked_to": "🇺🇸%s locked to %s.",
"locked_for_to": "🇺🇸%s for %s locked to %s.",
"unlocked": "🇺🇸%s unlocked.",
"unlocked_for": "🇺🇸%s for %s unlocked."
},
"spawn": {
"success": "A generat %s de %s.",
......@@ -326,6 +338,10 @@
"invalid_time": "Imposibil de analizat durata.",
"description": "Interziceți un jucător"
},
"unlockall": {
"success": "🇺🇸Unlocked all open states for %s.",
"description": "🇺🇸Unlocks all open states for a player."
},
"unban": {
"success": "Succes.",
"failure": "Eșec, jucătorul nu a fost găsit.",
......
......@@ -256,6 +256,14 @@
"success": "Сообщение было отправлено.",
"description": "Отправляет сообщение выбранному игроку от имени сервера. При отсутствии конкретной цели, отправляет сообщение всем игрокам на сервере."
},
"setConst": {
"range_error": "Уровень созвездия должен быть между 0 и 6.",
"level_error": "Некорректный уровень созвездия.",
"fail": "Не удалось установить уровень созвездия.",
"failed_success": "Созвездия для %s установлены на %s. Перезайдите чтобы изменения вступили в силу.",
"success": "Созвездия для %s были установлены на %s.",
"description": "Задает уровень созвездия для активного персонажа"
},
"setFetterLevel": {
"range_error": "Значение уровня дружбы должно быть между 0 и 10.",
"success": "Уровень дружбы стал равен %s.",
......@@ -266,7 +274,11 @@
"description": "Задаёт свойства аккаунта. С помощью данной команды может быть включен godmode, а также разблокированы этажи Коридора Бездны и изменён прогресс боевого пропуска.\n\tВозможные значения <св-во>: godmode | nostamina | unlimitedenergy | abyss | worldlevel | bplevel\n\t(прод.) см. перечисление (enum) PlayerProperty для остальных возможных значений, of form PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "Задаёт боевые характеристики для активного персонажа\n\tВозможные значения <хар-ка>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(прод.) Бонус элементального урона: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(прод.) Элементальное сопротивление: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys"
"description": "Задаёт боевые характеристики для активного персонажа\n\tВозможные значения <хар-ка>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(прод.) Бонус элементального урона: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(прод.) Элементальное сопротивление: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys",
"locked_to": "🇺🇸%s locked to %s.",
"locked_for_to": "🇺🇸%s for %s locked to %s.",
"unlocked": "🇺🇸%s unlocked.",
"unlocked_for": "🇺🇸%s for %s unlocked."
},
"spawn": {
"success": "Заспавнено %s %s.",
......@@ -326,6 +338,10 @@
"invalid_time": "Не удалось определить промежуток времени.",
"description": "Запрещает игроку присоединяться к серверу (\"банит\")"
},
"unlockall": {
"success": "Разблокированы все состояния для %s.",
"description": "Разблокировка всех состояний для Игрока. (Мультиплеер, Боевой пропуск и тд)"
},
"unban": {
"success": "Успех.",
"failure": "Неудача, игрок не найден.",
......
......@@ -28,8 +28,8 @@
"login_token_attempt": "[Dispatch] 客户端 %s 正在尝试通过 token 登录",
"login_token_error": "[Dispatch] 客户端 %s 通过 token 登录失败",
"login_token_success": "[Dispatch] 客户端 %s 已通过 token 登录,UID 为 %s",
"login_password_error": "🇺🇸[Dispatch] Client %s failed to log in via password.",
"login_password_storage_error": "🇺🇸[Dispatch] Client %s failed to log in via password because there is no password in the database.",
"login_password_error": "[Dispatch] 客户端 %s 无法通过密码登录",
"login_password_storage_error": "[Dispatch] 客户端 %s 无法登录! 因为数据库中没有密码",
"combo_token_success": "[Dispatch] 客户端 %s 成功交换 token",
"combo_token_error": "[Dispatch] 客户端 %s 交换 token 失败",
"account_login_create_success": "[Dispatch] 客户端 %s 登录失败:已注册 UID 为 %s 的账号",
......@@ -38,10 +38,10 @@
"account_cache_error": "游戏账号缓存信息错误",
"session_key_error": "会话密钥错误",
"username_error": "未找到用户名",
"username_create_error": "未找到用户名,建立连接失败",
"password_error": "🇺🇸Invalid Password",
"password_length_error": "🇺🇸Password length must be greater then or equal to 8",
"password_storage_error": "🇺🇸You don't have a password for your account. Please contact an administrator.",
"username_create_error": "用户名不存在,登录失败",
"password_error": "登录失败,请确认帐号/密码是否正确",
"password_length_error": "密码必须大于或等于8位",
"password_storage_error": "你没有密码,请联系管理员",
"server_max_player_limit": "服务器在线人数已满"
},
"router_error": "[Dispatch] 无法连接路由"
......@@ -256,6 +256,14 @@
"success": "消息已发送。",
"description": "向玩家以服务器的身份发送消息。如果没有指定目标,则向服务器的全部玩家发送"
},
"setConst": {
"range_error": "命座等级必须是 0~6级",
"level_error": "无效的命座等级",
"fail": "命座等级设置失败",
"failed_success": "命座 %s 已设置为 %s. 请传送到重载场景或重新登录查看效果",
"success": "命座 %s 已设置为 %s.",
"description": "为当前活跃角色设置命座等级"
},
"setFetterLevel": {
"range_error": "好感度等级必须在 0-10 之间。",
"success": "好感度已设为 %s 级。",
......@@ -266,7 +274,11 @@
"description": "设置账号的状态。比如可以通过此命令启用 godmode,也可以解锁深渊或更改纪行等级\n\t可更改的状态列表:godmode(上帝模式)|nostamina(无限体力)|unlimitedenergy(无限能量)|abyss(深渊)|worldlevel(世界等级)|bplevel(纪行等级)\n查看 PlayerProperty enum 以获得其他数值,格式为 PROP_MAX_SPRING_VOLUME -> max_spring_volume"
},
"setStats": {
"description": "设置当前角色的属性\n\t可更改的属性列表:hp(生命值)|maxhp(最大生命值)|def(防御力)|atk(攻击力)|em(元素精通)|er(元素充能效率)|crate(暴击率)|cdmg(暴击伤害)|cdr(冷却缩减)|heal(治疗加成)|heali(受治疗加成)|shield(护盾强效)|defi(无视防御)\n元素增伤:epyro(火)|ecryo(冰)|ehydro(水)|egeo(岩)|edendro(草)|eelectro(雷)|ephys(物理)\n元素抗性:respyro(火)|rescryo(冰)|reshydro(水)|resgeo(岩)|resdendro(草)|reselectro(雷)|resphys(物理)"
"description": "设置当前角色的属性\n\t可更改的属性列表:hp(生命值)|maxhp(最大生命值)|def(防御力)|atk(攻击力)|em(元素精通)|er(元素充能效率)|crate(暴击率)|cdmg(暴击伤害)|cdr(冷却缩减)|heal(治疗加成)|heali(受治疗加成)|shield(护盾强效)|defi(无视防御)\n元素增伤:epyro(火)|ecryo(冰)|ehydro(水)|egeo(岩)|edendro(草)|eelectro(雷)|ephys(物理)\n元素抗性:respyro(火)|rescryo(冰)|reshydro(水)|resgeo(岩)|resdendro(草)|reselectro(雷)|resphys(物理)",
"locked_to": "🇺🇸%s locked to %s.",
"locked_for_to": "🇺🇸%s for %s locked to %s.",
"unlocked": "🇺🇸%s unlocked.",
"unlocked_for": "🇺🇸%s for %s unlocked."
},
"spawn": {
"success": "已生成 %s 个 %s。",
......@@ -326,6 +338,10 @@
"invalid_time": "无法解析时间戳。",
"description": "封禁玩家"
},
"unlockall": {
"success": "🇺🇸Unlocked all open states for %s.",
"description": "🇺🇸Unlocks all open states for a player."
},
"unban": {
"success": "成功取消玩家的封禁。",
"failure": "取消玩家的封禁失败,因为玩家不存在。",
......@@ -347,7 +363,7 @@
},
"documentation": {
"handbook": {
"title": "🇺🇸GM Handbook",
"title": "GM 手册",
"title_commands": "命令",
"title_avatars": "角色",
"title_items": "物品",
......@@ -363,8 +379,8 @@
},
"index": {
"title": "文档",
"handbook": "🇺🇸GM Handbook",
"handbook": "GM 手册",
"gacha_mapping": "祈愿物品映射JSON"
}
}
}
\ No newline at end of file
}
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