diff --git a/scripts/commands/generic/admin_setGodMode.js b/scripts/commands/generic/admin_setGodMode.js new file mode 100644 index 000000000..605d8f1c8 --- /dev/null +++ b/scripts/commands/generic/admin_setGodMode.js @@ -0,0 +1,20 @@ +var execute = function(galManager, player, target, args) { + //TODO: Move to java callback + if(player.getAccessLevel() == (Java.type('resources.player.AccessLevel')).PLAYER){ + intentFactory.sendSystemMessage(player, "Players cannot use this command :("); + return; + } + + var creatureObject = player.getCreatureObject(); + if(target){ + creatureObject = target.getCreatureObject(); + } + + if(creatureObject.hasAbility("admin")){ + creatureObject.removeAbility("admin"); + intentFactory.sendSystemMessage(player, "God Mode Disabled");//TODO: See if there's an STF to send + }else{ + creatureObject.addAbility("admin"); + intentFactory.sendSystemMessage(player, "God Mode Enabled");//TODO: See if there's an STF to send + } +} \ No newline at end of file diff --git a/src/resources/client_info/visitors/DatatableData.java b/src/resources/client_info/visitors/DatatableData.java index 859163c83..96028112a 100644 --- a/src/resources/client_info/visitors/DatatableData.java +++ b/src/resources/client_info/visitors/DatatableData.java @@ -31,6 +31,8 @@ import resources.client_info.ClientData; import resources.client_info.IffNode; import resources.client_info.SWGFile; +import java.util.Arrays; + public class DatatableData extends ClientData { private String[] columnNames; @@ -263,6 +265,10 @@ public class DatatableData extends ClientData { return columnTypes[column]; } + public int getColumnFromName(String name){ + return Arrays.asList(columnNames).indexOf(name); + } + public void handleRows(DatatableRowHandler handler) { for (int r = 0; r < getRowCount(); r++) { handler.handleRow(r); diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 233323596..38a46a679 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -634,6 +634,12 @@ public class CreatureObject extends TangibleObject { public int getBaseAction() { return attributes.get(2); } + + public void addAbility(String abilityName){ abilities.put(abilityName, 1); }//TODO: Figure out what the integer value should be for each ability + + public void removeAbility(String abilityName) { abilities.remove(abilityName); } + + public boolean hasAbility(String abilityName) { return abilities.get(abilityName) != null; } public void setHealth(int health) { synchronized(attributes) { diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index e3fd1b828..f0d289c4a 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -250,10 +250,11 @@ public class PlayerObject extends IntangibleObject { public void setAdminTag(AccessLevel access) { switch(access) { - case PLAYER: break; - case ADMIN: adminTag = 1; break; - case DEV: adminTag = 2; break; - case QA: adminTag = 4; break; + case PLAYER: break; + case CSR: adminTag = 1; break; + case DEV: adminTag = 2; break; + case WARDEN: adminTag = 3; break; + case QA: adminTag = 4; break; } sendDelta(6, 2, adminTag); } diff --git a/src/resources/player/AccessLevel.java b/src/resources/player/AccessLevel.java index dc1c293e1..8254aa5c0 100644 --- a/src/resources/player/AccessLevel.java +++ b/src/resources/player/AccessLevel.java @@ -27,9 +27,52 @@ ***********************************************************************************/ package resources.player; +/** + * I believe that the godLevel value in the iffs corresponds to the access level of the command. + * This might not be correct, since there are at least 69 commands with godLevel 0 that require the "admin" ability, + * however, the godLevels seem to follow this hierarchy relatively decently. + * + * The way the admin system is currently set up is that each level has access to all levels beneath it. + * + * For example: WARDENSs have access to all PLAYER commands, CSRs have access to all WARDEN commands and PLAYER commands, + * QAs have access to all CSR commands ... etc. + * + * With that in mind, if we restrict the ability to have the "admin" ability to those with WARDEN+ then the godLevel 0 + * commands with the "admin" ability would effectively just become WARDEN commands. + * + * We can change the names/swap the values of these as needed. This is just a rough estimate on my part. + */ public enum AccessLevel { - PLAYER, - QA, - ADMIN, - DEV + PLAYER(0), + WARDEN(5), + CSR(10), + QA(15), + DEV(50); + + private final int value; + + private AccessLevel(int value){ + this.value = value; + } + + public int getValue(){ + return value; + } + + public static AccessLevel getFromValue(int value){ + switch(value){ + case 0: + return PLAYER; + case 5: + return WARDEN; + case 10: + return CSR; + case 15: + return QA; + case 50: + return DEV; + default: + return PLAYER; + } + } } diff --git a/src/services/commands/CommandService.java b/src/services/commands/CommandService.java index 6b6b0cc01..197f7ce7e 100644 --- a/src/services/commands/CommandService.java +++ b/src/services/commands/CommandService.java @@ -112,15 +112,21 @@ public class CommandService extends Service { Log.e("CommandService", "No creature object associated with the player '%s'!", player.getUsername()); return; } - - if (command.getGodLevel() > 0 || command.getCharacterAbility().toLowerCase().equals("admin")) {//HACK @Glen characterAbility check should be handled in the "has ability" TODO below. Not sure if abilities are implemented yet. - if (player.getAccessLevel() == AccessLevel.PLAYER) { - System.out.printf("[%s] failed to use admin command \"%s\" with access level %s with parameters \"%s\"\n", player.getCharacterName(), command.getName(), player.getAccessLevel().toString(), args); - return; - } - System.out.printf("[%s] successfully used admin command \"%s\" with access level %s with parameters \"%s\"\n", player.getCharacterName(), command.getName(), player.getAccessLevel().toString(), args); + + if(player.getAccessLevel().getValue() < command.getGodLevel()) { + String commandAccessLevel = AccessLevel.getFromValue(command.getGodLevel()).toString(); + String playerAccessLevel = player.getAccessLevel().toString(); + Log.i("CommandService", "[%s] attempted to use the command \"%s\", but did not have the minimum access level. Access Level Required: %s, Player Access Level: %s", + player.getCharacterName(), command.getName(), commandAccessLevel, playerAccessLevel); + return; } - + + if(!command.getCharacterAbility().isEmpty() && !player.getCreatureObject().hasAbility(command.getCharacterAbility())){ + Log.i("CommandService", "[%s] attempted to use the command \"%s\", but did not have the required ability. Ability Required: %s", + player.getCharacterName(), command.getName(), command.getCharacterAbility()); + return; + } + // TODO: Check if the player has the ability // TODO: Cool-down checks // TODO: Handle for different target @@ -148,7 +154,8 @@ public class CommandService extends Service { private void loadBaseCommands(String table) { DatatableData baseCommands = (DatatableData) ClientFactory.getInfoFromFile("datatables/command/"+table+".iff"); - + + int godLevel = baseCommands.getColumnFromName("godLevel"); for (int row = 0; row < baseCommands.getRowCount(); row++) { Object [] cmdRow = baseCommands.getRow(row); @@ -158,7 +165,11 @@ public class CommandService extends Service { command.setCppHook((String)cmdRow[4]); command.setDefaultTime((float) cmdRow[6]); command.setCharacterAbility((String) cmdRow[7]); - + + if(godLevel >= 0){ + command.setGodLevel((int) cmdRow[godLevel]); + } + addCommand(command); } } diff --git a/src/services/player/LoginService.java b/src/services/player/LoginService.java index a3cbf9f3c..6fc59d2ad 100644 --- a/src/services/player/LoginService.java +++ b/src/services/player/LoginService.java @@ -200,9 +200,10 @@ public class LoginService extends Service { player.setPlayerState(PlayerState.LOGGING_IN); switch(user.getString("access_level")) { case "player": player.setAccessLevel(AccessLevel.PLAYER); break; - case "admin": player.setAccessLevel(AccessLevel.ADMIN); break; - case "dev": player.setAccessLevel(AccessLevel.DEV); break; + case "warden": player.setAccessLevel(AccessLevel.WARDEN); break; + case "csr": player.setAccessLevel(AccessLevel.CSR); break; case "qa": player.setAccessLevel(AccessLevel.QA); break; + case "dev": player.setAccessLevel(AccessLevel.DEV); break; default: player.setAccessLevel(AccessLevel.PLAYER); break; } sendLoginSuccessPacket(player); @@ -338,7 +339,7 @@ public class LoginService extends Service { g.setRecommended(true); g.setPopulationStatus(populationStatus(consumed)); // If locked, restricted, or full - if (p.getAccessLevel() == AccessLevel.ADMIN && g.getStatus() != GalaxyStatus.UP) + if (p.getAccessLevel() == AccessLevel.QA && g.getStatus() != GalaxyStatus.UP) g.setStatus(GalaxyStatus.UP); galaxies.add(g); }