diff --git a/accesslevels/dev.txt b/accesslevels/dev.txt new file mode 100644 index 00000000..048df7ed --- /dev/null +++ b/accesslevels/dev.txt @@ -0,0 +1,5 @@ +findplayer +killplayer +setgodmode +invulnerable +server \ No newline at end of file diff --git a/nge.backup b/nge.backup index 1a761380..3091c7ff 100644 Binary files a/nge.backup and b/nge.backup differ diff --git a/scripts/commands/giveitem.py b/scripts/commands/giveitem.py index 65791788..0b9d2642 100644 --- a/scripts/commands/giveitem.py +++ b/scripts/commands/giveitem.py @@ -9,10 +9,7 @@ def run(core, actor, target, commandString): arg1 = commandArgs[0] if len(commandArgs) > 1: arg2 = commandArgs[1] - - if actor.getClient() and actor.getClient().isGM() == False: - return - + if not commandString.startswith('object/tangible') and not commandString.startswith('object/weapon'): return diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py index 49f3cf40..dd42674f 100644 --- a/scripts/commands/setgodmode.py +++ b/scripts/commands/setgodmode.py @@ -36,16 +36,6 @@ def run(core, actor, target, commandString): if len(commandArgs) > 5: arg5 = commandArgs[5] - if not command: - return - - if actor.getClient().isGM() is False: - return - - if playerObject.getGodLevel() == 0: - actor.addAbility("admin") - playerObject.setGodLevel(50) - if command == 'giveExperience' and arg1: core.playerService.giveExperience(actor, int(arg1)) diff --git a/scripts/radial/terminal/city_maintenance_terminal.py b/scripts/radial/terminal/city_maintenance_terminal.py index 50259cfa..b16bb4be 100644 --- a/scripts/radial/terminal/city_maintenance_terminal.py +++ b/scripts/radial/terminal/city_maintenance_terminal.py @@ -34,7 +34,7 @@ def createRadial(core, owner, target, radials): if owner.getPlayerObject().getCitizenship() != 3 and core.playerCityService.getPlayerCity(owner) == city: radials.add(RadialOptions(2, 230, 0, '@city/city:revoke_citizenship')) - if owner.getClient().isGM(): + if core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()) is not None: radials.add(RadialOptions(2, 231, 0, 'Add 10 citizens')) radials.add(RadialOptions(2, 232, 0, 'Deduct 10 citizens')) diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 990371b9..1bde5b9e 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -65,6 +65,7 @@ import services.ConversationService; import services.EntertainmentService; import services.GroupService; import services.housing.HousingService; +import services.AdminService; import services.BrowserService; import services.InstanceService; import services.LoginService; @@ -216,6 +217,7 @@ public class NGECore { public BrowserService browserService; //public BattlefieldService battlefieldService; public InvasionService invasionService; + public AdminService adminService; // Login Server public NetworkDispatch loginDispatch; @@ -503,10 +505,7 @@ public class NGECore { terrainService.addPlanet(43, "space_tatooine", "terrain/space_tatooine.trn", true); terrainService.addPlanet(44, "space_tatooine_2", "terrain/space_tatooine_2.trn", true); terrainService.addPlanet(45, "space_yavin4", "terrain/space_yavin4.trn", true);*/ - //PSWG New Content Terrains (WARNING Keep commented out unless you have the current build of kaas!) - - //terrainService.addPlanet(46, "kaas", "terrain/kaas.trn", true); - + //end terrainList if (options.getInt("LOAD.RESOURCE.SYSTEM") > 0) { @@ -567,6 +566,7 @@ public class NGECore { browserService = new BrowserService(this); //battlefieldService = new BattlefieldService(this); + adminService = new AdminService(this); DevLogQueuer devLogQueuer = new DevLogQueuer(); diff --git a/src/protocol/swg/LoginClusterStatus.java b/src/protocol/swg/LoginClusterStatus.java index 725a8c8b..4b6bf5ec 100644 --- a/src/protocol/swg/LoginClusterStatus.java +++ b/src/protocol/swg/LoginClusterStatus.java @@ -22,8 +22,13 @@ package protocol.swg; import java.nio.ByteOrder; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.TimeZone; +import main.NGECore; + import org.apache.mina.core.buffer.IoBuffer; import engine.clients.Client; @@ -50,8 +55,8 @@ public class LoginClusterStatus extends SWGMessage { } public void addServer(int galaxyID, String serverIP, int serverPort, int pingPort, int maxCharacters, int status, int recommended, int population, Client client) { IoBuffer result = IoBuffer.allocate(39 + serverIP.length()).order(ByteOrder.LITTLE_ENDIAN); - int populationStatus = 0; + result.putInt(galaxyID); result.put(getAsciiString(serverIP)); result.putShort((short)serverPort); @@ -66,11 +71,10 @@ public class LoginClusterStatus extends SWGMessage { populationStatus = 6; status = 3; } - if(status == 3 && client.isGM()) + if(status == 3 && !NGECore.getInstance().adminService.getAccessLevelFromDB(client.getAccountId()).equals(null)) // Ziggy - admins can enter Locked galaxies status = 2; result.putInt(populationStatus); // 0 = very light, 1 = light, 2 = medium , 3 = heavy, 4 = very heavy, 5 = extremely heavy, 6 = full result.putInt(maxCharacters); - //result.putInt(0xFFFF8F80); // Distance? result.putInt(timeZone.getRawOffset() / 3600000); result.putInt(status); result.put((byte)recommended); diff --git a/src/resources/common/Forager.java b/src/resources/common/Forager.java index 48a26ca5..f2cb383d 100644 --- a/src/resources/common/Forager.java +++ b/src/resources/common/Forager.java @@ -180,7 +180,7 @@ public class Forager { } // chosenObject = 5; // To test TMs - if(forager.getClient().isGM()) // Always yield a TM for testing + if(!NGECore.getInstance().adminService.getAccessLevelFromDB(forager.getClient().getAccountId()).equals(null)) // Always yield a TM for testing chosenObject = 5; //forager.sendSystemMessage("chosenObject " + chosenObject,(byte) 0); diff --git a/src/resources/objects/building/BuildingObject.java b/src/resources/objects/building/BuildingObject.java index fa44577f..cb7cd87a 100644 --- a/src/resources/objects/building/BuildingObject.java +++ b/src/resources/objects/building/BuildingObject.java @@ -403,7 +403,7 @@ public class BuildingObject extends TangibleObject implements IPersistent, Seria } public boolean canEnter(SWGObject object) { - return (getPrivacy() == PRIVATE && (entryList.contains(object.getObjectID()) || adminList.contains(object.getObjectID()))) || !banList.contains(object.getObjectID()) || object.getClient().isGM(); + return (getPrivacy() == PRIVATE && (entryList.contains(object.getObjectID()) || adminList.contains(object.getObjectID()))) || !banList.contains(object.getObjectID()) || !NGECore.getInstance().adminService.getAccessLevelFromDB(object.getClient().getAccountId()).equals(null); } public void updateCellPermissions(SWGObject obj) { diff --git a/src/services/AdminService.java b/src/services/AdminService.java new file mode 100644 index 00000000..3763a874 --- /dev/null +++ b/src/services/AdminService.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.sql.PreparedStatement; + +import main.NGECore; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class AdminService implements INetworkDispatch { + + private NGECore core; + + public AdminService(NGECore core) { + this.core = core; + + } + + public String getAccessLevelFromDB(long id) { + String accessLevel = null; + PreparedStatement preparedStatement; + + try { + preparedStatement = NGECore.getInstance().getDatabase1().preparedStatement("SELECT * FROM accounts WHERE id=" + id + ""); + ResultSet resultSet = preparedStatement.executeQuery(); + if(resultSet.next()) + accessLevel = resultSet.getString("accessLevel"); + } catch (SQLException e) { + e.printStackTrace(); + } + + return accessLevel; + } + + @Override + public void insertOpcodes(Map arg0, Map arg1) { + + } + + @Override + public void shutdown() { + + } + +} diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 7488e77c..a1fff102 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -366,7 +366,7 @@ public class CharacterService implements INetworkDispatch { System.out.println("Saving character with name: " + object.getCustomName()); core.getSWGObjectODB().put(object.getObjectID(), object); - PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO characters (id, \"firstName\", \"lastName\", \"accountId\", \"galaxyId\", \"statusId\", appearance, gmflag) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO characters (id, \"firstName\", \"lastName\", \"accountId\", \"galaxyId\", \"statusId\", appearance) VALUES (?, ?, ?, ?, ?, ?, ?)"); ps.setLong(1, object.getObjectID()); ps.setString(2, clientCreateCharacter.getFirstName()); ps.setString(3, clientCreateCharacter.getLastName()); @@ -374,7 +374,6 @@ public class CharacterService implements INetworkDispatch { ps.setInt(5, galaxyId); ps.setInt(6, 1); ps.setInt(7, CRC.StringtoCRC(raceTemplate)); - ps.setBoolean(8, false); ps.executeUpdate(); ps.close(); CreateCharacterSuccess success = new CreateCharacterSuccess(object.getObjectID()); diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index 4e8ce362..246501fd 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -137,7 +137,6 @@ public class ConnectionService implements INetworkDispatch { if (resultSet.next()) { client.setAccountId(resultSet.getLong("accountId")); client.setSessionKey(clientIdMsg.getSessionKey()); - client.setGM(core.loginService.checkForGmPermission((int) resultSet.getLong("accountId"))); AccountFeatureBits accountFeatureBits = new AccountFeatureBits(); ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(maxNumberOfCharacters - core.characterService.getNumberOfCharacters((int) resultSet.getLong("accountId"))); session.write(new HeartBeatMessage().serialize()); @@ -340,7 +339,6 @@ public class ConnectionService implements INetworkDispatch { } ghost.toggleFlag(PlayerFlags.LD); - object.setPerformanceListenee(null); object.setPerformanceWatchee(null); object.setAttachment("disconnectTask", null); diff --git a/src/services/LoginService.java b/src/services/LoginService.java index cdd65984..437970d5 100644 --- a/src/services/LoginService.java +++ b/src/services/LoginService.java @@ -140,9 +140,7 @@ public class LoginService implements INetworkDispatch{ client.setPassword(pass); client.setSessionKey(generateSessionKey()); client.setAccountId(id); - //client.setAccountEmail(email); client.setSession(session); - client.setGM(checkForGmPermission(id)); core.addClient(session, client); @@ -156,9 +154,6 @@ public class LoginService implements INetworkDispatch{ System.out.println(client.getAccountName() + " was not added to active connections map."); return; } - /*if(!checkIfAccountExistInGameDB(id)) { - createAccountForGameDB(id, user, email, encryptPass); - }*/ persistSession(client); @@ -269,29 +264,6 @@ public class LoginService implements INetworkDispatch{ } - public boolean checkForGmPermission(int id) { - try { - if (core.getConfig().getInt("ADMIN") > 0) { - return true; - } - } catch (Exception e) { - - } - - PreparedStatement preparedStatement; - - try { - preparedStatement = databaseConnection1.preparedStatement("SELECT * FROM accounts WHERE id=" + id + ""); - ResultSet resultSet = preparedStatement.executeQuery(); - if(resultSet.next()) - return resultSet.getBoolean("gmflag"); - } catch (SQLException e) { - e.printStackTrace(); - } - - return false; - } - /** * Saves session data to DB so Zone Server can link sessions to accounts. * @param client Client that needs a session save. diff --git a/src/services/command/BaseSWGCommand.java b/src/services/command/BaseSWGCommand.java index 5025939d..87dff513 100644 --- a/src/services/command/BaseSWGCommand.java +++ b/src/services/command/BaseSWGCommand.java @@ -76,7 +76,10 @@ public class BaseSWGCommand implements Cloneable { if (((String) visitor2.getObject(i, 0)).equalsIgnoreCase(commandName)) { int sub = 0; // Subtract due to command table structures being different - characterAbility = (String) visitor2.getObject(i, 7); + if(((String) visitor2.getObject(i, 7)).equals("admin")) + characterAbility = ""; + else + characterAbility = (String) visitor2.getObject(i, 7); for (int l = (8 - sub); l <= (29 - sub); l++) { if (!((Boolean) visitor2.getObject(i, l))) { diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index 7ae337d2..63bcabd7 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -21,9 +21,14 @@ ******************************************************************************/ package services.command; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteOrder; import java.util.Map; +import java.util.Scanner; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; @@ -31,6 +36,7 @@ import java.util.concurrent.ScheduledExecutorService; import main.NGECore; +import org.apache.commons.io.FileUtils; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; @@ -71,29 +77,23 @@ public class CommandService implements INetworkDispatch { public boolean callCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { - if (actor == null) { + if (actor == null) return false; - } - if (command == null) { + if (actor.getClient().equals(null)) return false; - } - if (command.getCharacterAbility().length() > 0 && !actor.hasAbility(command.getCharacterAbility()) && actor.getClient() != null) { + if (command == null) return false; - } - if (command.isDisabled()) { + if (command.getCharacterAbility().length() > 0 && !actor.hasAbility(command.getCharacterAbility()) && !command.getCharacterAbility().equals("admin")) return false; - } - if (actor.getClient() != null && command.getGodLevel() > actor.getPlayerObject().getGodLevel()) { + if (command.isDisabled()) return false; - } - if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) { + if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) return false; - } // Causes this service method to return with false after equipping a rifle, not allowing to unequip it anymore // because the client seems to consider rifles invalidweapons for an unkown reason @@ -687,19 +687,50 @@ public class CommandService implements INetworkDispatch { } public void processCommand(CreatureObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { + System.out.println("characterAbility: " + command.getCharacterAbility()); + if (command.getGodLevel() > 0 || command.getCommandName().equals("setgodmode")) { // TODO: When loading commands, simply don't put the "admin" characterAbility into the commands + String accessLevel = core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()); + + if(accessLevel != null) { + Scanner scanner; + try { + scanner = new Scanner(new File("accesslevels/" + accessLevel + ".txt")); + boolean levelHasCommand = false; + + while(scanner.hasNextLine()) { + String commandName = scanner.nextLine(); + if(command.getCommandName().equals(commandName)) { + levelHasCommand = true; + break; + } + } + + if (!levelHasCommand) { + actor.sendSystemMessage(" \\#FE2EF7 [GM] \\#FFFFFF " + command.getCommandName() + ": You do not have permission to use this command.", (byte) 0); + return; + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + if (command.getCooldown() > 0f) { actor.addCooldown(command.getCooldownGroup(), command.getCooldown()); } if (command instanceof CombatCommand) { processCombatCommand(actor, target, (CombatCommand) command, actionCounter, commandArgs); - } else { + } else if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) { core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs); } else if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName().toLowerCase() + ".py")) { core.scriptService.callScript("scripts/commands/combat/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs); } - } + + } public void processCommandForInstallation(InstallationObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) { diff --git a/src/services/housing/HousingService.java b/src/services/housing/HousingService.java index 3d897d43..b70036c8 100644 --- a/src/services/housing/HousingService.java +++ b/src/services/housing/HousingService.java @@ -92,7 +92,7 @@ public class HousingService implements INetworkDispatch { public void enterStructureMode(CreatureObject actor, TangibleObject deed) { PlayerCity city = core.playerCityService.getCityObjectIsIn(actor); - if (!actor.getClient().isGM() && !core.terrainService.canBuildAtPosition(actor, actor.getWorldPosition().x, actor.getWorldPosition().z)) { + if (core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()).equals(null) && !core.terrainService.canBuildAtPosition(actor, actor.getWorldPosition().x, actor.getWorldPosition().z)) { actor.sendSystemMessage("You may not place a structure here.", (byte) 0); // should probably load this from an stf return; } diff --git a/src/services/resources/HarvesterService.java b/src/services/resources/HarvesterService.java index 63622849..5c473b15 100644 --- a/src/services/resources/HarvesterService.java +++ b/src/services/resources/HarvesterService.java @@ -1111,7 +1111,7 @@ public class HarvesterService implements INetworkDispatch { public void enterStructurePlacementMode(CreatureObject actor, SWGObject object){ - if (!actor.getClient().isGM() && !core.terrainService.canBuildAtPosition(actor,actor.getPosition().x,actor.getPosition().z)){ + if (core.adminService.getAccessLevelFromDB(actor.getClient().getAccountId()).equals(null) && !core.terrainService.canBuildAtPosition(actor,actor.getPosition().x,actor.getPosition().z)){ actor.sendSystemMessage("@player_structure:not_permitted", (byte) 0); return; }