Browse Source

Merge pull request 'release-1.3' (#13) from release-1.3 into master

Reviewed-on: #13
pull/16/head
MagicBot 2 years ago
parent
commit
2436579752
  1. 65
      README.md
  2. 3
      src/discord/MagicBot.java
  3. 6
      src/engine/Enum.java
  4. 1
      src/engine/ai/MobileFSM.java
  5. 2
      src/engine/ai/MobileFSMManager.java
  6. 137
      src/engine/ai/utilities/CombatUtilities.java
  7. 2
      src/engine/db/archive/DataWarehouse.java
  8. 10
      src/engine/gameManager/ConfigManager.java
  9. 2
      src/engine/gameManager/MaintenanceManager.java
  10. 94
      src/engine/gameManager/MovementManager.java
  11. 40
      src/engine/jobs/FlightJob.java
  12. 16
      src/engine/net/client/handlers/AbandonAssetMsgHandler.java
  13. 19
      src/engine/net/client/handlers/DestroyBuildingHandler.java
  14. 93
      src/engine/net/client/handlers/PlaceAssetMsgHandler.java
  15. 12
      src/engine/objects/City.java
  16. 5
      src/engine/objects/Mob.java
  17. 5
      src/engine/objects/PlayerCharacter.java
  18. 107
      src/engine/powers/poweractions/AbstractPowerAction.java
  19. 10
      src/engine/server/MBServerStatics.java
  20. 4
      src/engine/server/login/LoginServer.java
  21. 2
      src/engine/server/login/LoginServerMsgHandler.java
  22. 4
      src/engine/server/world/WorldServer.java
  23. 60
      src/engine/util/MiscUtils.java

65
README.md

@ -20,70 +20,11 @@ The Magicbane Team has wanted to open source Shadowbane for half a decade. We a @@ -20,70 +20,11 @@ The Magicbane Team has wanted to open source Shadowbane for half a decade. We a
## Contributing
- Project is released under an MIT license. Please see the LICENSE file.
- Inbound == Outbound.
- IntelliJ is the supported IDE.
- Write code today see it running on the Magicbane production server tomorrow.
## Project setup
## Support
**Prerequisites**:
- Git
- IntelliJ
- Java 8 JDK
- Account on the Magicbane [Public Repository](http://repo.magicbane.com)
Copy the HTTP link if you haven't yet installed a public key:
![CopyUrl](https://www.magicbane.com/Development/images/repo.png)
- Clone the Magicbane public repo to your local machine using the copied URL.
![CloneURL](https://www.magicbane.com/Development/images/intellij1.png)
- Under Settings->VersionControl->Git make sure to turn off these two settings.
![CommitOff](https://www.magicbane.com/Development/images/commit.png)
- Select the Project Structure settings within the IDE.
![ProjectStructure](https://www.magicbane.com/Development/images/projectstructure.png)
- Select Java 8 as the IDE target as shown.
![Java8](https://www.magicbane.com/Development/images/project.png)
- Delete and recreate content root pointing at the **Server** directory.
- Make sure the Language Level still reflects Java 8.
- The IDE should now autodetect the cloned source.
![hmm](https://www.magicbane.com/Development/images/module.png)
Magicbane currently has the following dependencies.
<br>
- [EnumBitSet](https://github.com/claudemartin/enum-bit-set)
- [HikariCP](https://github.com/brettwooldridge/HikariCP)
- [JDA](https://github.com/DV8FromTheWorld/JDA)
- [JodaTime](https://github.com/JodaOrg/joda-time)
- [TinyLog](https://github.com/tinylog-org/tinylog/tree/v1.3)
- [MySqlConnector](https://dev.mysql.com/downloads/connector/j/)
They are all directly obtainable from a running MagicBox instance.
``` docker cp magicbox:/usr/share/java/EnumBitSet.jar Dependencies/```
Add the jar files as project libraries as shown.
![Libs](https://www.magicbane.com/Development/images/libraries.png)
You should now be able to build the game!
![Build](https://magicbane.com/Development/images/buildproject.png)
### Next Steps
You can now move onto the [Development Workflow](http://repo.magicbane.com/MagicBane/Server/wiki/Development-workflow) or [MagicBox Setup](http://repo.magicbane.com/MagicBane/Server/wiki/MagicBox-:-Magicbane-in-a-Box) pages for further information.
Support is also available through the Magicbane [Discord server](www.magicbane.com). Feel free to stop in and pick Magicbot's brain!
Documentation is available through the Magicbane [Wiki](http://repo.magicbane.com/MagicBane/Server/wiki) and [Discord server](www.magicbane.com).

3
src/discord/MagicBot.java

@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
package discord;
import discord.handlers.*;
import engine.Enum;
import engine.gameManager.ConfigManager;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
@ -29,8 +28,6 @@ import org.pmw.tinylog.writers.RollingFileWriter; @@ -29,8 +28,6 @@ import org.pmw.tinylog.writers.RollingFileWriter;
import javax.security.auth.login.LoginException;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;

6
src/engine/Enum.java

@ -2416,9 +2416,9 @@ public class Enum { @@ -2416,9 +2416,9 @@ public class Enum {
public enum CityBoundsType {
GRID(576),
ZONE(640),
SIEGE(814);
GRID(512),
ZONE(576),
SIEGE(1040);
public final float extents;

1
src/engine/ai/MobileFSM.java

@ -1130,7 +1130,6 @@ public class MobileFSM { @@ -1130,7 +1130,6 @@ public class MobileFSM {
}
HashMap<Integer, Integer> staticPowers = aiAgent.getMobBase().getStaticPowers();
if (staticPowers != null && !staticPowers.isEmpty()) {
int chance = ThreadLocalRandom.current().nextInt(100);

2
src/engine/ai/MobileFSMManager.java

@ -16,8 +16,6 @@ import engine.server.MBServerStatics; @@ -16,8 +16,6 @@ import engine.server.MBServerStatics;
import engine.util.ThreadUtils;
import org.pmw.tinylog.Logger;
import java.util.HashSet;
public class MobileFSMManager {

137
src/engine/ai/utilities/CombatUtilities.java

@ -15,13 +15,19 @@ import engine.Enum.*; @@ -15,13 +15,19 @@ import engine.Enum.*;
import engine.ai.MobileFSM.STATE;
import engine.gameManager.ChatManager;
import engine.gameManager.CombatManager;
import engine.gameManager.PowersManager;
import engine.math.Vector3fImmutable;
import engine.net.DispatchMessage;
import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.TargetedActionMsg;
import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
@ -237,7 +243,6 @@ public class CombatUtilities { @@ -237,7 +243,6 @@ public class CombatUtilities {
speed = agent.getSpeedHandOne();
else
speed = agent.getSpeedHandTwo();
DamageType dt = DamageType.Crush;
if (agent.isSiege())
dt = DamageType.Siege;
@ -271,15 +276,85 @@ public class CombatUtilities { @@ -271,15 +276,85 @@ public class CombatUtilities {
int passiveAnim = CombatManager.getSwingAnimation(wb, null,mainHand);
if(canSwing(agent)) {
if(triggerDefense(agent,target))
swingIsMiss(agent,target, passiveAnim);
else if(triggerDodge(agent,target))
swingIsDodge(agent,target, passiveAnim);
else if(triggerParry(agent,target))
swingIsParry(agent,target, passiveAnim);
else if(triggerBlock(agent,target))
swingIsBlock(agent,target, passiveAnim);
if(triggerDefense(agent,target)) {
swingIsMiss(agent, target, passiveAnim);
return;
}
else if(triggerDodge(agent,target)) {
swingIsDodge(agent, target, passiveAnim);
return;
}
else if (triggerParry(agent, target)){
swingIsParry(agent, target, passiveAnim);
return;
}
else if(triggerBlock(agent,target)) {
swingIsBlock(agent, target, passiveAnim);
return;
}
else
//check for a cast here?
//agent.mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(agent.getMobBaseID());
if(agent.mobPowers.size() > 0 && agent.mobPowers != null)
{
//get cast chance 33% cast 67% mele
int random = ThreadLocalRandom.current().nextInt(agent.mobPowers.size() * 10);
//allow casting of spell
if(random <= agent.mobPowers.size())
{
int powerToken;
int powerRank;
//cast a spell
Map<Integer,Integer> entries = agent.mobPowers;
int count = 0;
for(Map.Entry<Integer,Integer> entry : entries.entrySet())
{
count += 1;
if(count == random)
{
powerToken = entry.getKey();
//powerRank = entry.getValue();
switch(agent.getLevel())
{
default:
powerRank = 1;
break;
case 10:
powerRank = 5;
break;
case 20:
powerRank = 10;
break;
case 30:
powerRank = 15;
break;
case 40:
powerRank = 25;
break;
case 50:
powerRank = 30;
break;
case 60:
powerRank = 35;
break;
case 70:
powerRank = 40;
break;
}
//System.out.println(agent.getMobBase().getFirstName() + " is casting: " + PowersManager.getPowerByToken(powerToken).skillName);
PowersManager.applyPower(agent,target,target.getLoc(),powerToken,powerRank, false);
//PerformActionMsg msg = new PerformActionMsg();
//PowersManager.sendPowerMsg((PlayerCharacter)target,0,msg);
//return;
}
}
return;
}
}
//finished with casting check
swingIsDamage(agent,target, determineDamage(agent,target, mainHand, speed, dt), anim);
if (agent.getWeaponPower() != null)
@ -380,11 +455,46 @@ public class CombatUtilities { @@ -380,11 +455,46 @@ public class CombatUtilities {
public static float determineDamage(Mob agent,AbstractWorldObject target, boolean mainHand, float speed, DamageType dt) {
float min = (mainHand) ? agent.getMinDamageHandOne() : agent.getMinDamageHandTwo();
float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo();;
float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo();
if(agent.isSummonedPet() == true)
{
min = 40 * (1 + (agent.getLevel()/10));
max = 60 * (1 + (agent.getLevel()/8));
//check if we have powers to cast
if(agent.mobPowers.isEmpty() == false) {
//check for power usage
Random random = new Random();
int value = random.nextInt(0 + (agent.mobPowers.size() + (agent.mobPowers.size() * 5))) + 0;
if (value <= agent.mobPowers.size())
{
//do power
int powerId = agent.mobPowers.get(value);
PowersManager.runPowerAction(agent,target,target.getLoc(),new ActionsBase(),40, PowersManager.getPowerByToken(powerId));
}
else
{
//do mele damage
float range = max - min;
float damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return ((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, damage, 0);
if (target.getObjectType() == GameObjectType.Building) {
Building building = (Building) target;
Resists resists = building.getResists();
return damage * (1 - (resists.getResist(dt, 0) / 100));
}
}
}
}
float range = max - min;
float damage = min + ((ThreadLocalRandom.current().nextFloat()*range)+(ThreadLocalRandom.current().nextFloat()*range))/2;
//DAMAGE FORMULA FOR PET
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter)target).isSit())
damage *= 2.5f; //increase damage if sitting
@ -405,9 +515,6 @@ public class CombatUtilities { @@ -405,9 +515,6 @@ public class CombatUtilities {
public static boolean RunAIRandom(){
int random = ThreadLocalRandom.current().nextInt(4);
if (random == 0)
return true;
return false;
return random == 0;
}
}

2
src/engine/db/archive/DataWarehouse.java

@ -39,7 +39,7 @@ public class DataWarehouse implements Runnable { @@ -39,7 +39,7 @@ public class DataWarehouse implements Runnable {
// If WarehousePush is disabled
// then early exit
if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equals("false")) {
if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equalsIgnoreCase("false")) {
Logger.info("Warehouse Remote Connection disabled along with push");
return;
}

10
src/engine/gameManager/ConfigManager.java

@ -20,6 +20,7 @@ import org.pmw.tinylog.Logger; @@ -20,6 +20,7 @@ import org.pmw.tinylog.Logger;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
public enum ConfigManager {
@ -47,6 +48,8 @@ public enum ConfigManager { @@ -47,6 +48,8 @@ public enum ConfigManager {
MB_LOGIN_PORT,
MB_LOGIN_AUTOREG,
MB_LOGIN_FNAME_REGEX,
MB_MAJOR_VER,
MB_MINOR_VER,
@ -87,6 +90,7 @@ public enum ConfigManager { @@ -87,6 +90,7 @@ public enum ConfigManager {
public static NetMsgHandler handler;
public static WorldServer worldServer;
public static LoginServer loginServer;
public static Map<ConfigManager, Pattern> regex = new HashMap<>();
// Called at bootstrap: ensures that all config values are loaded.
@ -99,9 +103,15 @@ public enum ConfigManager { @@ -99,9 +103,15 @@ public enum ConfigManager {
Logger.info(configSetting.name() + ":" + configSetting.getValue());
else {
Logger.error("Missing Config: " + configSetting.name());
Logger.error("This codebase requires >= MagicBox v1.3");
Logger.error("docker pull magicbane/magicbox:latest");
return false;
}
// compile regex here
regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue()));
return true;
}

2
src/engine/gameManager/MaintenanceManager.java

@ -349,7 +349,7 @@ public enum MaintenanceManager { @@ -349,7 +349,7 @@ public enum MaintenanceManager {
// Run maintenance on player buildings
if ((boolean) ConfigManager.MB_WORLD_MAINTENANCE.getValue().equals("true"))
if ((boolean) ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true"))
processBuildingMaintenance();
else
Logger.info("Maintenance Costings: DISABLED");

94
src/engine/gameManager/MovementManager.java

@ -15,16 +15,11 @@ import engine.Enum.SourceType; @@ -15,16 +15,11 @@ import engine.Enum.SourceType;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.exception.MsgSendException;
import engine.job.JobContainer;
import engine.job.JobScheduler;
import engine.jobs.ChangeAltitudeJob;
import engine.jobs.FlightJob;
import engine.math.Bounds;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ChangeAltitudeMsg;
import engine.net.client.msg.MoveToPointMsg;
import engine.net.client.msg.TeleportToPointMsg;
import engine.net.client.msg.UpdateStateMsg;
@ -339,61 +334,7 @@ public enum MovementManager { @@ -339,61 +334,7 @@ public enum MovementManager {
}
//Update for when the character is in flight
public static void updateFlight(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) {
if (pc == null)
return;
// clear flight timer job as we are about to update stuff and submit a new job
pc.clearTimer(flightTimerJobName);
if (!pc.isActive()) {
pc.setAltitude(0);
pc.setDesiredAltitude(0);
pc.setTakeOffTime(0);
return;
}
// Check to see if we are mid height change
JobContainer cjc = pc.getTimers().get(changeAltitudeTimerJobName);
if (cjc != null) {
addFlightTimer(pc, msg, MBServerStatics.FLY_FREQUENCY_MS);
return;
}
// Altitude is zero, do nothing
if (pc.getAltitude() < 1)
return;
//make sure player is still allowed to fly
boolean canFly = false;
PlayerBonuses bonus = pc.getBonuses();
if (bonus != null && !bonus.getBool(ModType.NoMod, SourceType.Fly) && bonus.getBool(ModType.Fly, SourceType.None) && pc.isAlive())
canFly = true;
// if stam less that 2 - time to force a landing
if (pc.getStamina() < 10f || !canFly) {
// dont call stop movement here as we want to
// preserve endloc
//pc.stopMovement();
// sync world location
pc.setLoc(pc.getLoc());
// force a landing
msg.setStartAlt(pc.getAltitude());
msg.setTargetAlt(0);
msg.setAmountToMove(pc.getAltitude());
msg.setUp(false);
DispatchMessage.dispatchMsgToInterestArea(pc, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
MovementManager.addChangeAltitudeTimer(pc, msg.getStartAlt(), msg.getTargetAlt(), (int) (MBServerStatics.HEIGHT_CHANGE_TIMER_MS * pc.getAltitude()));
pc.setAltitude(msg.getStartAlt() - 10);
} else //Add a new flight timer to check stam / force land
if (pc.getAltitude() > 0)
addFlightTimer(pc, msg, MBServerStatics.FLY_FREQUENCY_MS);
}
public static void finishChangeAltitude(AbstractCharacter ac, float targetAlt) {
@ -530,43 +471,17 @@ public enum MovementManager { @@ -530,43 +471,17 @@ public enum MovementManager {
}
}
//Getting rid of flgith timer.
public static void addFlightTimer(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) {
if (pc == null || pc.getTimers() == null)
return;
if (!pc.getTimers().containsKey(flightTimerJobName)) {
FlightJob ftj = new FlightJob(pc, msg, duration);
JobContainer jc = JobScheduler.getInstance().scheduleJob(ftj, duration);
pc.getTimers().put(flightTimerJobName, jc);
}
}
public static void addChangeAltitudeTimer(PlayerCharacter pc, float startAlt, float targetAlt, int duration) {
if (pc == null || pc.getTimers() == null)
return;
ChangeAltitudeJob catj = new ChangeAltitudeJob(pc, startAlt, targetAlt);
JobContainer jc = JobScheduler.getInstance().scheduleJob(catj, duration);
pc.getTimers().put(changeAltitudeTimerJobName, jc);
}
public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc, Regions region) {
if (targetLoc == null)
return;
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(targetLoc);
teleporter.setRegion(region);
//mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)){
teleporter.setInBuildingID(0);
@ -588,18 +503,12 @@ public enum MovementManager { @@ -588,18 +503,12 @@ public enum MovementManager {
public static void translocateToObject(AbstractCharacter teleporter, AbstractWorldObject worldObject) {
Vector3fImmutable targetLoc = teleporter.getLoc();
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(teleporter.getLoc());
//mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)){
teleporter.setInBuildingID(0);
@ -609,6 +518,7 @@ public enum MovementManager { @@ -609,6 +518,7 @@ public enum MovementManager {
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
return;
}
boolean collide = false;
int maxFloor = -1;
int buildingID = 0;
@ -619,6 +529,7 @@ public enum MovementManager { @@ -619,6 +529,7 @@ public enum MovementManager {
if (collide)
break;
}
if (!collide) {
teleporter.setInBuildingID(0);
teleporter.setInBuilding(-1);
@ -633,7 +544,6 @@ public enum MovementManager { @@ -633,7 +544,6 @@ public enum MovementManager {
}
}
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1);
//we shouldnt need to send teleport message to new area, as loadjob should pick it up.
// DispatchMessage.dispatchMsgToInterestArea(teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);

40
src/engine/jobs/FlightJob.java

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.jobs;
import engine.gameManager.MovementManager;
import engine.job.AbstractScheduleJob;
import engine.net.client.msg.ChangeAltitudeMsg;
import engine.objects.PlayerCharacter;
public class FlightJob extends AbstractScheduleJob {
private final PlayerCharacter pc;
private final ChangeAltitudeMsg msg;
private final int duration;
public FlightJob(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) {
super();
this.msg = msg;
this.duration = duration;
this.pc = pc;
}
@Override
protected void doJob() {
if (this.pc != null && this.msg != null)
MovementManager.updateFlight(pc, msg, duration);
}
@Override
protected void _cancelJob() {
}
}

16
src/engine/net/client/handlers/AbandonAssetMsgHandler.java

@ -92,7 +92,23 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler { @@ -92,7 +92,23 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler {
// Trees require special handling beyond an individual building
if ((building.getBlueprint().getBuildingGroup() == BuildingGroup.TOL))
{
// CHECK IF GUILD HAS A BANE DROPPED
City city = ZoneManager.getCityAtLocation(building.getLoc());
if(city.getGuild().getSubGuildList().isEmpty() == false)
{
//nations cant abandon their tree
ErrorPopupMsg.sendErrorMsg(player, "Nations Cannot Abandon Their Capital!");
return true;
}
if(Bane.getBaneByAttackerGuild(city.getGuild()) != null)
{
ErrorPopupMsg.sendErrorMsg(player, "You Cannot Abandon Your Tree With An Active Siege!");
return true;
}
AbandonAllCityObjects(player, building);
}
else
AbandonSingleAsset(player, building);

19
src/engine/net/client/handlers/DestroyBuildingHandler.java

@ -8,10 +8,8 @@ import engine.gameManager.BuildingManager; @@ -8,10 +8,8 @@ import engine.gameManager.BuildingManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.DestroyBuildingMsg;
import engine.objects.Blueprint;
import engine.objects.Building;
import engine.objects.City;
import engine.objects.PlayerCharacter;
import engine.net.client.msg.ErrorPopupMsg;
import engine.objects.*;
/*
* @Author:
@ -43,7 +41,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { @@ -43,7 +41,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
Blueprint blueprint;
blueprint = building.getBlueprint();
City city = building.getCity();
// Can't destroy buildings without a blueprint.
if (blueprint == null)
@ -57,7 +55,11 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { @@ -57,7 +55,11 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (!BuildingManager.PlayerCanControlNotOwner(building, pc))
return true;
Bane bane = city.getBane();
if(bane.getSiegePhase() == Enum.SiegePhase.WAR && bane != null) {
ErrorPopupMsg.sendErrorPopup(pc, 171);
return true;
}
// Can't destroy a tree of life
if (blueprint.getBuildingGroup() == BuildingGroup.TOL)
return true;
@ -71,15 +73,12 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { @@ -71,15 +73,12 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (blueprint.getBuildingGroup() == BuildingGroup.RUNEGATE)
return true;
//stop if active siege
// Turn off spire if destoying
if (blueprint.getBuildingGroup() == BuildingGroup.SPIRE)
building.disableSpire(true);
if (blueprint.getBuildingGroup() == BuildingGroup.WAREHOUSE) {
City city = building.getCity();
if (city != null)
city.setWarehouseBuildingID(0);
}

93
src/engine/net/client/handlers/PlaceAssetMsgHandler.java

@ -130,7 +130,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -130,7 +130,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
boolean close = true;
lock.writeLock().lock();
boolean isSiege = false;
try {
switch (buildingBlueprint.getBuildingGroup()) {
@ -230,7 +230,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -230,7 +230,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
buildingList = msg.getFirstPlacementInfo();
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc());
// Early exit if something went horribly wrong
// with locating the current or zone
@ -1249,6 +1248,85 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1249,6 +1248,85 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
RealmType currentRealm;
if(Blueprint.getBlueprint(placementInfo.getBlueprintUUID()).isSiegeEquip() == false)
{
if (serverZone.isPlayerCity() == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
City city = ZoneManager.getCityAtLocation(placementInfo.getLoc());
if (player.getGuild().equals(city.getGuild()) == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
if (city.isLocationOnCityGrid(placementInfo.getLoc()) == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
}
else
{
City city = ZoneManager.getCityAtLocation(placementInfo.getLoc());
if(city == null)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
Bane bane = city.getBane();
//check if player is owner/IC of tree or bane
if (player.getGuild().equals(city.getGuild()) == true)
{
//is from owners guild
if(GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
}
else
{
//is not from owners guild
if(bane == null)
{
//bane was null
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
if(city == null)
{
//city was null
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
//check if player is from siege guild
if(player.getGuild().equals(bane.getOwner().getGuild()) == false)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
//check if player is GL or IC of the bane guild
if(GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
//cannot place on grid until bane is live
if(bane.getSiegePhase() != SiegePhase.WAR && city.isLocationOnCityGrid(placementInfo.getLoc()) == true)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
if(city.isLocationWithinSiegeBounds(placementInfo.getLoc()) == false && city.isLocationOnCityZone(placementInfo.getLoc()) == false)
{
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName());
return false;
}
}
}
// Retrieve the building details we're placing
if (serverZone.isNPCCity() == true) {
@ -1259,7 +1337,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1259,7 +1337,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Errant guilds cannot place assets
if (player.getGuild().getGuildState() == GuildState.Errant) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Only soverign or sworn guilds may place assets.");
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Only sovereign or sworn guilds may place assets.");
return false;
}
// Player must be GL or IC of a guild to place buildings.
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 10, ""); // You must be a guild leader
return false;
}
@ -1373,8 +1458,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1373,8 +1458,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
PlaceAssetMsg.sendPlaceAssetError(origin, 9, ""); //You must be a guild member to place this asset
return false;
}
return true;
}
}

12
src/engine/objects/City.java

@ -999,11 +999,9 @@ public class City extends AbstractWorldObject { @@ -999,11 +999,9 @@ public class City extends AbstractWorldObject {
HashSet<Integer> currentMemory;
PlayerCharacter player;
// Gather current list of players within a distance defined by the x extent of the
// city zone. As we want to grab all players with even a remote possibility of
// being in the zone, we might have to increase this distance.
// Gather current list of players within a distance defined by the seige bounds
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, this.parentZone.getBounds().getHalfExtents().x * 1.41421356237, MBServerStatics.MASK_PLAYER);
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.SIEGE.extents, MBServerStatics.MASK_PLAYER);
currentMemory = new HashSet<>();
for (AbstractWorldObject playerObject : currentPlayers) {
@ -1019,9 +1017,8 @@ public class City extends AbstractWorldObject { @@ -1019,9 +1017,8 @@ public class City extends AbstractWorldObject {
if (_playerMemory.contains(player.getObjectUUID()))
continue;
if (!this.isLocationOnCityZone(player.getLoc()))
if (!this.isLocationWithinSiegeBounds(player.getLoc()))
continue;
// Apply safehold affect to player if needed
if ((this.isSafeHold == 1))
@ -1065,7 +1062,8 @@ public class City extends AbstractWorldObject { @@ -1065,7 +1062,8 @@ public class City extends AbstractWorldObject {
player = PlayerCharacter.getFromCache(playerUUID);
if (this.isLocationOnCityZone(player.getLoc()))
if (this.isLocationWithinSiegeBounds(player.getLoc()))
continue;
// Remove players safezone status if warranted

5
src/engine/objects/Mob.java

@ -111,7 +111,7 @@ public class Mob extends AbstractIntelligenceAgent { @@ -111,7 +111,7 @@ public class Mob extends AbstractIntelligenceAgent {
public boolean despawned = false;
public Vector3fImmutable destination = Vector3fImmutable.ZERO;
public Vector3fImmutable localLoc = Vector3fImmutable.ZERO;
public HashMap<Integer,Integer> mobPowers;
/**
* No Id Constructor
*/
@ -365,6 +365,7 @@ public class Mob extends AbstractIntelligenceAgent { @@ -365,6 +365,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.setObjectTypeMask(MBServerStatics.MASK_PET | this.getTypeMasks());
if (ConfigManager.serverType.equals(ServerType.LOGINSERVER))
this.setLoc(this.getLoc());
mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(this.getMobBaseID());
}
if (!isPet && this.contract == null) {
this.level = (short) this.mobBase.getLevel();
@ -2201,7 +2202,7 @@ public class Mob extends AbstractIntelligenceAgent { @@ -2201,7 +2202,7 @@ public class Mob extends AbstractIntelligenceAgent {
} catch(Exception e){
Logger.error( e.getMessage());
}
mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(this.getMobBaseID());
if (this.equip == null) {
Logger.error("Null equipset returned for uuid " + currentID);
this.equip = new HashMap<>(0);

5
src/engine/objects/PlayerCharacter.java

@ -4781,9 +4781,12 @@ public void dismissNecroPets() { @@ -4781,9 +4781,12 @@ public void dismissNecroPets() {
}finally{
this.updateLock.writeLock().unlock();
}
}
//temp removal
if(AbstractCharacter.CanFly(this) == false && this.altitude > 0)
GroundPlayer(this);
}
}
@Override
public void updateFlight() {

107
src/engine/powers/poweractions/AbstractPowerAction.java

@ -76,75 +76,108 @@ public abstract class AbstractPowerAction { @@ -76,75 +76,108 @@ public abstract class AbstractPowerAction {
int token = DbManager.hasher.SBStringHash(IDString);
//cache token, used for applying effects.
PowersManager.ActionTokenByIDString.put(IDString, token);
if (type.equals("ApplyEffect"))
apa = null;
switch (type)
{
default:
Logger.error("valid type not found for poweraction of ID" + rs.getInt("ID"));
break;
case "ApplyEffect":
apa = new ApplyEffectPowerAction(rs, effects);
else if (type.equals("ApplyEffects"))
break;
case "ApplyEffects":
apa = new ApplyEffectsPowerAction(rs, effects);
else if (type.equals("DeferredPower"))
break;
case "DeferredPower":
apa = new DeferredPowerPowerAction(rs, effects);
else if (type.equals("DamageOverTime"))
break;
case "DamageOverTime":
apa = new DamageOverTimePowerAction(rs, effects);
else if (type.equals("Peek"))
break;
case "Peek":
apa = new PeekPowerAction(rs);
else if (type.equals("Charm"))
break;
case "Charm":
apa = new CharmPowerAction(rs);
else if (type.equals("Fear"))
break;
case "Fear":
apa = new FearPowerAction(rs);
else if (type.equals("Confusion"))
break;
case "Confusion":
apa = new ConfusionPowerAction(rs);
else if (type.equals("RemoveEffect"))
break;
case "RemoveEffect":
apa = new RemoveEffectPowerAction(rs);
else if (type.equals("Track"))
break;
case "Track":
apa = new TrackPowerAction(rs, effects);
else if (type.equals("DirectDamage"))
break;
case "DirectDamage":
apa = new DirectDamagePowerAction(rs, effects);
else if (type.equals("Transform"))
break;
case "Transform":
apa = new TransformPowerAction(rs, effects);
else if (type.equals("CreateMob"))
break;
case "CreateMob":
apa = new CreateMobPowerAction(rs);
else if (type.equals("Invis"))
break;
case "Invis":
apa = new InvisPowerAction(rs, effects);
else if (type.equals("ClearNearbyAggro"))
break;
case "ClearNearbyAggro":
apa = new ClearNearbyAggroPowerAction(rs);
else if (type.equals("MobRecall"))
break;
case "MobRecall":
apa = new MobRecallPowerAction(rs);
else if (type.equals("SetItemFlag"))
break;
case "SetItemFlag":
apa = new SetItemFlagPowerAction(rs);
else if (type.equals("SimpleDamage"))
break;
case "SimpleDamage":
apa = new SimpleDamagePowerAction(rs);
else if (type.equals("TransferStatOT"))
break;
case "TransferStatOT":
apa = new TransferStatOTPowerAction(rs, effects);
else if (type.equals("TransferStat"))
break;
case "TransferStat":
apa = new TransferStatPowerAction(rs, effects);
else if (type.equals("Teleport"))
break;
case "Teleport":
apa = new TeleportPowerAction(rs);
else if (type.equals("TreeChoke"))
break;
case "TreeChoke":
apa = new TreeChokePowerAction(rs);
else if (type.equals("Block"))
break;
case "Block":
apa = new BlockPowerAction(rs);
else if (type.equals("Resurrect"))
break;
case "Resurrect":
apa = new ResurrectPowerAction(rs);
else if (type.equals("ClearAggro"))
break;
case "ClearAggro":
apa = new ClearAggroPowerAction(rs);
else if (type.equals("ClaimMine"))
break;
case "ClaimMine":
apa = new ClaimMinePowerAction(rs);
else if (type.equals("Recall"))
break;
case "Recall":
apa = new RecallPowerAction(rs);
else if (type.equals("SpireDisable"))
break;
case "SpireDisable":
apa = new SpireDisablePowerAction(rs);
else if (type.equals("Steal"))
break;
case "Steal":
apa = new StealPowerAction(rs);
else if (type.equals("Summon"))
break;
case "Summon":
apa = new SummonPowerAction(rs);
else if (type.equals("RunegateTeleport"))
apa = new RunegateTeleportPowerAction(rs);
else if (type.equals("RunegateTeleport"))
break;
case "RunegateTeleport":
apa = new RunegateTeleportPowerAction(rs);
else if (type.equals("OpenGate"))
break;
case "OpenGate":
apa = new OpenGatePowerAction(rs);
else {
Logger.error("valid type not found for poweraction of ID" + rs.getInt("ID"));
continue;
break;
}
powerActions.put(IDString, apa);
powerActionsByID.put(apa.UUID, apa);

10
src/engine/server/MBServerStatics.java

@ -124,16 +124,6 @@ public class MBServerStatics { @@ -124,16 +124,6 @@ public class MBServerStatics {
public static final int CHM_THREAD_MED = 2;
public static final int CHM_THREAD_LOW = 1;
/*
* LoginServer related
*/
public static final String PCMajorVer = "1.2.25.5";
public static final String PCMinorVer = "5.25.5";
public static final String MACMajorVer = "1.2.24.3";
public static final String MACMinorVer = "5.24.3";
/*
* LoginErrorMsg related
*/

4
src/engine/server/login/LoginServer.java

@ -169,8 +169,8 @@ public class LoginServer { @@ -169,8 +169,8 @@ public class LoginServer {
// Configure the VersionInfoMsgs:
this.versionInfoMessage = new VersionInfoMsg(MBServerStatics.PCMajorVer,
MBServerStatics.PCMinorVer);
this.versionInfoMessage = new VersionInfoMsg(ConfigManager.MB_MAJOR_VER.getValue(),
ConfigManager.MB_MINOR_VER.getValue());
Logger.info("Initializing Database Pool");
initDatabasePool();

2
src/engine/server/login/LoginServerMsgHandler.java

@ -180,7 +180,7 @@ public class LoginServerMsgHandler implements NetMsgHandler { @@ -180,7 +180,7 @@ public class LoginServerMsgHandler implements NetMsgHandler {
if (account == null) {
if (ConfigManager.MB_LOGIN_AUTOREG.getValue().equals("FALSE")) {
if (ConfigManager.MB_LOGIN_AUTOREG.getValue().equalsIgnoreCase("false")) {
this.KickToLogin(MBServerStatics.LOGINERROR_INVALID_USERNAME_PASSWORD, "Could not find account (" + uname + ')', clientConnection);
Logger.info("Could not find account (" + uname + ')');
return;

4
src/engine/server/world/WorldServer.java

@ -53,7 +53,9 @@ import org.pmw.tinylog.labelers.TimestampLabeler; @@ -53,7 +53,9 @@ import org.pmw.tinylog.labelers.TimestampLabeler;
import org.pmw.tinylog.policies.StartupPolicy;
import org.pmw.tinylog.writers.RollingFileWriter;
import java.io.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Paths;

60
src/engine/util/MiscUtils.java

@ -9,27 +9,19 @@ @@ -9,27 +9,19 @@
package engine.util;
import engine.gameManager.ConfigManager;
import engine.server.MBServerStatics;
import java.util.regex.Pattern;
public class MiscUtils {
// no need to recompile these each call, put them in object scope and
// compile just once.
private static final Pattern lastNameRegex = Pattern
.compile("^[A-Za-z][-'A-Za-z\\x20]*$");
private static final Pattern firstNameRegex = Pattern
.compile("^[A-Za-z]+$");
public static boolean checkIfFirstNameInvalid(String firstName) {
if ((firstName == null) || (firstName.length() == 0)
|| (firstName.length() > MBServerStatics.MAX_NAME_LENGTH)
|| (firstName.length() < MBServerStatics.MIN_NAME_LENGTH)) {
return true;
}
return (!firstNameRegex.matcher(firstName).matches());
return (!ConfigManager.regex.get(ConfigManager.MB_LOGIN_FNAME_REGEX).matcher(firstName).matches());
}
public static boolean checkIfLastNameInvalid(String lastName) {
@ -43,52 +35,4 @@ public class MiscUtils { @@ -43,52 +35,4 @@ public class MiscUtils {
// empty last names are fine, return false
return false;
}
public static String getCallingMethodName() {
StackTraceElement e[] = Thread.currentThread().getStackTrace();
int numElements = e.length;
if (numElements < 1) {
return "NoStack";
}
if (numElements == 1) {
return e[0].getMethodName();
} else if (numElements == 2) {
return e[1].getMethodName();
} else if (numElements == 3) {
return e[2].getMethodName();
} else {
return e[3].getMethodName();
}
}
public static String getCallStackAsString() {
String out = "";
StackTraceElement e[] = Thread.currentThread().getStackTrace();
int numElements = e.length;
for (int i = (numElements - 1); i > 1; --i) {
String[] classStack = e[i].getClassName().split("\\.");
String methName = e[i].getMethodName();
String className = classStack[classStack.length - 1];
if (methName.equals("<init>")) {
methName = className;
}
out += className + '.' + methName + "()";
if (i > 2) {
out += " -> ";
}
}
return out;
}
}

Loading…
Cancel
Save