mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-14 21:34:52 +01:00
Add !character command
This commit is contained in:
@@ -3,6 +3,7 @@ package emu.nebula.command;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import emu.nebula.Nebula;
|
import emu.nebula.Nebula;
|
||||||
|
import emu.nebula.game.character.GameCharacter;
|
||||||
import emu.nebula.game.player.Player;
|
import emu.nebula.game.player.Player;
|
||||||
import emu.nebula.util.Utils;
|
import emu.nebula.util.Utils;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
@@ -21,9 +22,9 @@ public class CommandArgs {
|
|||||||
private int targetUid;
|
private int targetUid;
|
||||||
private int amount;
|
private int amount;
|
||||||
private int level = -1;
|
private int level = -1;
|
||||||
private int rank = -1;
|
private int advance = -1;
|
||||||
private int promotion = -1;
|
private int talent = -1;
|
||||||
private int stage = -1;
|
private int skill = -1;
|
||||||
|
|
||||||
private Int2IntMap map;
|
private Int2IntMap map;
|
||||||
private ObjectSet<String> flags;
|
private ObjectSet<String> flags;
|
||||||
@@ -50,17 +51,14 @@ public class CommandArgs {
|
|||||||
} else if (arg.startsWith("lv")) { // Level
|
} else if (arg.startsWith("lv")) { // Level
|
||||||
this.level = Utils.parseSafeInt(arg.substring(2));
|
this.level = Utils.parseSafeInt(arg.substring(2));
|
||||||
it.remove();
|
it.remove();
|
||||||
} else if (arg.startsWith("r")) { // Rank
|
} else if (arg.startsWith("a")) { // Advance
|
||||||
this.rank = Utils.parseSafeInt(arg.substring(1));
|
this.advance = Utils.parseSafeInt(arg.substring(1));
|
||||||
it.remove();
|
it.remove();
|
||||||
} else if (arg.startsWith("e")) { // Eidolons
|
} else if (arg.startsWith("t")) { // Talents
|
||||||
this.rank = Utils.parseSafeInt(arg.substring(1));
|
this.talent = Utils.parseSafeInt(arg.substring(1));
|
||||||
it.remove();
|
it.remove();
|
||||||
} else if (arg.startsWith("p")) { // Promotion
|
} else if (arg.startsWith("s")) { // Skill
|
||||||
this.promotion = Utils.parseSafeInt(arg.substring(1));
|
this.skill = Utils.parseSafeInt(arg.substring(1));
|
||||||
it.remove();
|
|
||||||
} else if (arg.startsWith("s")) { // Stage or Superimposition
|
|
||||||
this.stage = Utils.parseSafeInt(arg.substring(1));
|
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
} else if (arg.startsWith("-")) { // Flag
|
} else if (arg.startsWith("-")) { // Flag
|
||||||
@@ -127,4 +125,67 @@ public class CommandArgs {
|
|||||||
return this.flags.contains(flag);
|
return this.flags.contains(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility commands
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the properties of an character based on the arguments provided
|
||||||
|
* @param character The targeted character to change
|
||||||
|
* @return A boolean of whether or not any changes were made to the character
|
||||||
|
*/
|
||||||
|
public boolean setProperties(GameCharacter character) {
|
||||||
|
boolean hasChanged = false;
|
||||||
|
|
||||||
|
// Try to set level
|
||||||
|
if (this.getLevel() > 0 && character.getLevel() != this.getLevel()) {
|
||||||
|
character.setLevel(Math.min(this.getLevel(), 90));
|
||||||
|
character.setAdvance(Utils.getMinAdvanceForLevel(character.getLevel()));
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to set advance (ascension level)
|
||||||
|
if (this.getAdvance() >= 0 && character.getAdvance() != this.getAdvance()) {
|
||||||
|
character.setAdvance(Math.min(this.getAdvance(), 8));
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to set skill trees
|
||||||
|
if (this.getSkill() > 0) {
|
||||||
|
int skill = Math.min(this.getSkill(), 10);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int s = character.getSkills()[i];
|
||||||
|
|
||||||
|
if (s != skill) {
|
||||||
|
character.getSkills()[i] = skill;
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to set talents
|
||||||
|
if (this.getTalent() >= 0) {
|
||||||
|
// Clear talents first
|
||||||
|
character.getTalents().clear();
|
||||||
|
|
||||||
|
// Calculate how many talent stars we want to set
|
||||||
|
int talent = Math.min(this.getTalent(), 5);
|
||||||
|
|
||||||
|
for (int i = 0; i < talent; i++) {
|
||||||
|
// Get bitset offset
|
||||||
|
int offset = i * 16;
|
||||||
|
|
||||||
|
// First 10 sub nodes of a talent star
|
||||||
|
for (int x = 1; x <= 10; x++) {
|
||||||
|
character.getTalents().setBit(offset + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final sub node of a talent star
|
||||||
|
character.getTalents().setBit(offset + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package emu.nebula.command.commands;
|
||||||
|
|
||||||
|
import emu.nebula.util.Utils;
|
||||||
|
import emu.nebula.game.character.GameCharacter;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.PubilcGm.Chars;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import emu.nebula.command.Command;
|
||||||
|
import emu.nebula.command.CommandArgs;
|
||||||
|
import emu.nebula.command.CommandHandler;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "character",
|
||||||
|
aliases = {"c", "char"},
|
||||||
|
permission = "player.character",
|
||||||
|
requireTarget = true,
|
||||||
|
desc = "!c [all | {characterId}] lv(level) a(ascension) s(skill level) t(talent level)"
|
||||||
|
)
|
||||||
|
public class CharacterCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandArgs args) {
|
||||||
|
// Init
|
||||||
|
var player = args.getTarget();
|
||||||
|
var characters = new HashSet<GameCharacter>();
|
||||||
|
|
||||||
|
// Parse args
|
||||||
|
for (String arg : args.getList()) {
|
||||||
|
// Lowercase
|
||||||
|
arg = arg.toLowerCase();
|
||||||
|
|
||||||
|
// Handle all characters
|
||||||
|
if (arg.equals("all")) {
|
||||||
|
characters.addAll(player.getCharacters().getCharacterCollection());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse char id
|
||||||
|
int charId = Utils.parseSafeInt(arg);
|
||||||
|
|
||||||
|
var character = player.getCharacters().getCharacterById(charId);
|
||||||
|
if (character == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
characters.add(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (characters.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of modified characters that we send to the client for updates
|
||||||
|
var modified = new ArrayList<GameCharacter>();
|
||||||
|
|
||||||
|
// Modify characters
|
||||||
|
for (var character : characters) {
|
||||||
|
// Apply changes
|
||||||
|
boolean changed = args.setProperties(character);
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
// Save to database
|
||||||
|
character.save();
|
||||||
|
|
||||||
|
// Add to modified list
|
||||||
|
modified.add(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
var proto = Chars.newInstance();
|
||||||
|
|
||||||
|
for (var character : modified) {
|
||||||
|
proto.addList(character.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
player.addNextPackage(NetMsgId.chars_final_notify, proto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ import us.hebi.quickbuf.RepeatedInt;
|
|||||||
@Getter
|
@Getter
|
||||||
@Entity(useDiscriminator = false)
|
@Entity(useDiscriminator = false)
|
||||||
public class CharacterContact {
|
public class CharacterContact {
|
||||||
private transient Character character;
|
private transient GameCharacter character;
|
||||||
|
|
||||||
private boolean top;
|
private boolean top;
|
||||||
private long triggerTime;
|
private long triggerTime;
|
||||||
@@ -27,7 +27,7 @@ public class CharacterContact {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharacterContact(Character character) {
|
public CharacterContact(GameCharacter character) {
|
||||||
this.character = character;
|
this.character = character;
|
||||||
this.chats = new HashMap<>();
|
this.chats = new HashMap<>();
|
||||||
this.triggerTime = character.getCreateTime();
|
this.triggerTime = character.getCreateTime();
|
||||||
@@ -45,7 +45,7 @@ public class CharacterContact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCharacter(Character character) {
|
public void setCharacter(GameCharacter character) {
|
||||||
this.character = character;
|
this.character = character;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class CharacterGemPreset {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharacterGemPreset(Character character) {
|
public CharacterGemPreset(GameCharacter character) {
|
||||||
this.gems = new int[] {-1, -1, -1};
|
this.gems = new int[] {-1, -1, -1};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import lombok.Getter;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class CharacterStorage extends PlayerManager {
|
public class CharacterStorage extends PlayerManager {
|
||||||
private final Int2ObjectMap<Character> characters;
|
private final Int2ObjectMap<GameCharacter> characters;
|
||||||
private final Int2ObjectMap<GameDisc> discs;
|
private final Int2ObjectMap<GameDisc> discs;
|
||||||
|
|
||||||
public CharacterStorage(Player player) {
|
public CharacterStorage(Player player) {
|
||||||
@@ -28,7 +28,7 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
|
|
||||||
// Characters
|
// Characters
|
||||||
|
|
||||||
public Character getCharacterById(int id) {
|
public GameCharacter getCharacterById(int id) {
|
||||||
if (id <= 0) {
|
if (id <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
return this.characters.containsKey(id);
|
return this.characters.containsKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Character addCharacter(int charId) {
|
public GameCharacter addCharacter(int charId) {
|
||||||
// Sanity check to make sure we dont have this character already
|
// Sanity check to make sure we dont have this character already
|
||||||
if (this.hasCharacter(charId)) {
|
if (this.hasCharacter(charId)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -49,14 +49,14 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
return this.addCharacter(GameData.getCharacterDataTable().get(charId));
|
return this.addCharacter(GameData.getCharacterDataTable().get(charId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Character addCharacter(CharacterDef data) {
|
private GameCharacter addCharacter(CharacterDef data) {
|
||||||
// Sanity check to make sure we dont have this character already
|
// Sanity check to make sure we dont have this character already
|
||||||
if (this.hasCharacter(data.getId())) {
|
if (this.hasCharacter(data.getId())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create character
|
// Create character
|
||||||
var character = new Character(this.getPlayer(), data);
|
var character = new GameCharacter(this.getPlayer(), data);
|
||||||
|
|
||||||
// Save to database
|
// Save to database
|
||||||
character.save();
|
character.save();
|
||||||
@@ -66,7 +66,7 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Character> getCharacterCollection() {
|
public Collection<GameCharacter> getCharacterCollection() {
|
||||||
return this.getCharacters().values();
|
return this.getCharacters().values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
public void loadFromDatabase() {
|
public void loadFromDatabase() {
|
||||||
var db = Nebula.getGameDatabase();
|
var db = Nebula.getGameDatabase();
|
||||||
|
|
||||||
db.getObjects(Character.class, "playerUid", getPlayerUid()).forEach(character -> {
|
db.getObjects(GameCharacter.class, "playerUid", getPlayerUid()).forEach(character -> {
|
||||||
// Get data
|
// Get data
|
||||||
var data = GameData.getCharacterDataTable().get(character.getCharId());
|
var data = GameData.getCharacterDataTable().get(character.getCharId());
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import us.hebi.quickbuf.RepeatedInt;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Entity(value = "characters", useDiscriminator = false)
|
@Entity(value = "characters", useDiscriminator = false)
|
||||||
public class Character implements GameDatabaseObject {
|
public class GameCharacter implements GameDatabaseObject {
|
||||||
@Id
|
@Id
|
||||||
private ObjectId uid;
|
private ObjectId uid;
|
||||||
@Indexed
|
@Indexed
|
||||||
@@ -65,15 +65,15 @@ public class Character implements GameDatabaseObject {
|
|||||||
private CharacterContact contact;
|
private CharacterContact contact;
|
||||||
|
|
||||||
@Deprecated // Morphia only!
|
@Deprecated // Morphia only!
|
||||||
public Character() {
|
public GameCharacter() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Character(Player player, int charId) {
|
public GameCharacter(Player player, int charId) {
|
||||||
this(player, GameData.getCharacterDataTable().get(charId));
|
this(player, GameData.getCharacterDataTable().get(charId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Character(Player player, CharacterDef data) {
|
public GameCharacter(Player player, CharacterDef data) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.playerUid = player.getUid();
|
this.playerUid = player.getUid();
|
||||||
this.charId = data.getId();
|
this.charId = data.getId();
|
||||||
@@ -110,6 +110,14 @@ public class Character implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdvance(int advance) {
|
||||||
|
this.advance = advance;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMaxGainableExp() {
|
public int getMaxGainableExp() {
|
||||||
if (this.getLevel() >= this.getMaxLevel()) {
|
if (this.getLevel() >= this.getMaxLevel()) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -12,7 +12,7 @@ import emu.nebula.game.GameContextModule;
|
|||||||
import emu.nebula.game.account.Account;
|
import emu.nebula.game.account.Account;
|
||||||
import emu.nebula.game.agent.AgentManager;
|
import emu.nebula.game.agent.AgentManager;
|
||||||
import emu.nebula.game.battlepass.BattlePass;
|
import emu.nebula.game.battlepass.BattlePass;
|
||||||
import emu.nebula.game.character.Character;
|
import emu.nebula.game.character.GameCharacter;
|
||||||
import emu.nebula.game.character.GameDisc;
|
import emu.nebula.game.character.GameDisc;
|
||||||
import emu.nebula.game.formation.FormationManager;
|
import emu.nebula.game.formation.FormationManager;
|
||||||
import emu.nebula.game.friends.Friendship;
|
import emu.nebula.game.friends.Friendship;
|
||||||
@@ -167,7 +167,7 @@ public class PlayerModule extends GameContextModule {
|
|||||||
var datastore = Nebula.getGameDatabase().getDatastore();
|
var datastore = Nebula.getGameDatabase().getDatastore();
|
||||||
|
|
||||||
// Delete data from collections
|
// Delete data from collections
|
||||||
datastore.getCollection(Character.class).deleteMany(multiFilter);
|
datastore.getCollection(GameCharacter.class).deleteMany(multiFilter);
|
||||||
datastore.getCollection(GameDisc.class).deleteMany(multiFilter);
|
datastore.getCollection(GameDisc.class).deleteMany(multiFilter);
|
||||||
datastore.getCollection(GameItem.class).deleteMany(multiFilter);
|
datastore.getCollection(GameItem.class).deleteMany(multiFilter);
|
||||||
datastore.getCollection(GameResource.class).deleteMany(multiFilter);
|
datastore.getCollection(GameResource.class).deleteMany(multiFilter);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import dev.morphia.annotations.Id;
|
|||||||
import emu.nebula.database.GameDatabaseObject;
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
import emu.nebula.game.player.Player;
|
import emu.nebula.game.player.Player;
|
||||||
import emu.nebula.game.tower.StarTowerBuild;
|
import emu.nebula.game.tower.StarTowerBuild;
|
||||||
import emu.nebula.game.character.Character;
|
import emu.nebula.game.character.GameCharacter;
|
||||||
import emu.nebula.proto.Public.HonorInfo;
|
import emu.nebula.proto.Public.HonorInfo;
|
||||||
import emu.nebula.proto.ScoreBossRank.ScoreBossRankChar;
|
import emu.nebula.proto.ScoreBossRank.ScoreBossRankChar;
|
||||||
import emu.nebula.proto.ScoreBossRank.ScoreBossRankData;
|
import emu.nebula.proto.ScoreBossRank.ScoreBossRankData;
|
||||||
@@ -155,7 +155,7 @@ public class ScoreBossRankEntry implements GameDatabaseObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScoreBossCharEntry(Character character) {
|
public ScoreBossCharEntry(GameCharacter character) {
|
||||||
this.id = character.getCharId();
|
this.id = character.getCharId();
|
||||||
this.level = character.getLevel();
|
this.level = character.getLevel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package emu.nebula.server.handlers;
|
|||||||
import emu.nebula.net.NetHandler;
|
import emu.nebula.net.NetHandler;
|
||||||
import emu.nebula.net.NetMsgId;
|
import emu.nebula.net.NetMsgId;
|
||||||
import emu.nebula.proto.PlayerSignatureEdit.PlayerSignatureEditReq;
|
import emu.nebula.proto.PlayerSignatureEdit.PlayerSignatureEditReq;
|
||||||
|
import emu.nebula.proto.Public.Error;
|
||||||
import emu.nebula.net.HandlerId;
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.Nebula;
|
||||||
import emu.nebula.net.GameSession;
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
@HandlerId(NetMsgId.player_signature_edit_req)
|
@HandlerId(NetMsgId.player_signature_edit_req)
|
||||||
@@ -13,7 +15,22 @@ public class HandlerPlayerSignatureEdit extends NetHandler {
|
|||||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
// Parse request
|
// Parse request
|
||||||
var req = PlayerSignatureEditReq.parseFrom(message);
|
var req = PlayerSignatureEditReq.parseFrom(message);
|
||||||
|
var signature = req.getSignature();
|
||||||
|
|
||||||
|
if (signature == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.player_signature_edit_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we need to handle a command
|
||||||
|
if (signature.charAt(0) == '!' || signature.charAt(0) == '/') {
|
||||||
|
Nebula.getCommandManager().invoke(session.getPlayer(), signature);
|
||||||
|
return session.encodeMsg(
|
||||||
|
NetMsgId.player_signature_edit_failed_ack,
|
||||||
|
Error.newInstance().setCode(119902).addArguments("\nCommand Success")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit signature
|
||||||
session.getPlayer().editSignature(req.getSignature());
|
session.getPlayer().editSignature(req.getSignature());
|
||||||
|
|
||||||
// Send response
|
// Send response
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ public class Utils {
|
|||||||
return Math.floorDiv(System.currentTimeMillis(), 1000);
|
return Math.floorDiv(System.currentTimeMillis(), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMinPromotionForLevel(int level) {
|
public static int getMinAdvanceForLevel(int level) {
|
||||||
return Math.max(Math.min((int) ((level - 11) / 10D), 6), 0);
|
return Math.max(Math.min((int) ((level - 1) / 10D), 8), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user