Merge branch '178-pathfinder-crashing' into 'dev'

Resolve "Pathfinder crashing."

See merge request morningstar/Arcturus-Community!44
This commit is contained in:
Harmonic 2019-06-08 19:28:36 -04:00
commit 2c22b0c8e3
6 changed files with 103 additions and 106 deletions

View File

@ -11,10 +11,10 @@ TheGeneral's own words were "dont like it then dont use it". We did not like wha
Arcturus Morningstar is released under the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.txt). Arcturus Morningstar is released under the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.txt).
## Versions ## ## Versions ##
![image](https://img.shields.io/badge/VERSION-2.1.0-orange.svg?style=for-the-badge&logo=appveyor) ![image](https://img.shields.io/badge/VERSION-2.0.0-success.svg?style=for-the-badge&logo=appveyor)
![image](https://img.shields.io/badge/STATUS-unstable-critical.svg?style=for-the-badge&logo=appveyor) ![image](https://img.shields.io/badge/STATUS-STABLE-blue.svg?style=for-the-badge&logo=appveyor)
Compiled Download: Has not yet reached a Release Candidate. Compiled Download: https://git.krews.org/morningstar/Arcturus-Community/releases
Client build: **PRODUCTION-201611291003-338511768** Client build: **PRODUCTION-201611291003-338511768**

View File

@ -97,12 +97,6 @@ public final class Emulator {
Emulator.runtime = Runtime.getRuntime(); Emulator.runtime = Runtime.getRuntime();
Emulator.config = new ConfigurationManager("config.ini"); Emulator.config = new ConfigurationManager("config.ini");
if (Emulator.getConfig().getValue("username").isEmpty()) {
Emulator.getLogging().logErrorLine("Please make sure you enter your forum login details!");
Thread.sleep(2000);
}
Emulator.database = new Database(Emulator.getConfig()); Emulator.database = new Database(Emulator.getConfig());
Emulator.config.loaded = true; Emulator.config.loaded = true;
Emulator.config.loadFromDatabase(); Emulator.config.loadFromDatabase();
@ -123,12 +117,6 @@ public final class Emulator {
Emulator.rconServer.initializePipeline(); Emulator.rconServer.initializePipeline();
Emulator.rconServer.connect(); Emulator.rconServer.connect();
Emulator.badgeImager = new BadgeImager(); Emulator.badgeImager = new BadgeImager();
// Removed Wesleys Camera Server lol.
/* if (Emulator.getConfig().getBoolean("camera.enabled"))
{
Emulator.getThreading().run(new CameraClientAutoReconnect());
}
*/
Emulator.getLogging().logStart("Habbo Hotel Emulator has succesfully loaded."); Emulator.getLogging().logStart("Habbo Hotel Emulator has succesfully loaded.");
Emulator.getLogging().logStart("You're running: " + Emulator.version); Emulator.getLogging().logStart("You're running: " + Emulator.version);
Emulator.getLogging().logStart("System launched in: " + (System.nanoTime() - startTime) / 1e6 + "ms. Using: " + (Runtime.getRuntime().availableProcessors() * 2) + " threads!"); Emulator.getLogging().logStart("System launched in: " + (System.nanoTime() - startTime) / 1e6 + "ms. Using: " + (Runtime.getRuntime().availableProcessors() * 2) + " threads!");

View File

@ -253,42 +253,29 @@ public class RoomLayout {
return this.roomTiles[x][y].state == RoomTileState.INVALID; return this.roomTiles[x][y].state == RoomTileState.INVALID;
} }
public RoomTileState getStateAt(short x, short y) {
return this.roomTiles[x][y].state;
}
public String getRelativeMap() { public String getRelativeMap() {
return this.heightmap.replace("\r\n", "\r"); return this.heightmap.replace("\r\n", "\r");
} }//re
/// Pathfinder Reworked By Quadral, thanks buddy!! You Saved Morningstar <3
public final Deque<RoomTile> findPath(RoomTile oldTile, RoomTile newTile, RoomTile goalLocation, RoomUnit roomUnit) { public final Deque<RoomTile> findPath(RoomTile oldTile, RoomTile newTile, RoomTile goalLocation, RoomUnit roomUnit) {
LinkedList<RoomTile> openList = new LinkedList<>();
try {
if (this.room == null || !this.room.isLoaded() || oldTile == null || newTile == null || oldTile.equals(newTile) || newTile.state == RoomTileState.INVALID) if (this.room == null || !this.room.isLoaded() || oldTile == null || newTile == null || oldTile.equals(newTile) || newTile.state == RoomTileState.INVALID)
return openList;
List<RoomTile> closedList = new LinkedList<>();
openList.add(oldTile.copy());
long startMillis = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis() - startMillis > 50) {
return new LinkedList<>(); return new LinkedList<>();
} LinkedList<RoomTile> openList = new LinkedList<>();
List<RoomTile> closedList = new LinkedList<>();
RoomTile current = this.lowestFInOpen(openList); RoomTile current;
openList.remove(current); openList.add(oldTile.copy());
while (!openList.isEmpty()) {
current = this.lowestFInOpen(openList);
if ((current.x == newTile.x) && (current.y == newTile.y)) { if ((current.x == newTile.x) && (current.y == newTile.y)) {
return this.calcPath(this.findTile(openList, oldTile.x, oldTile.y), current); return this.calcPath(this.findTile(openList, oldTile.x, oldTile.y), current);
} }
closedList.add(current);
openList.remove(current);
List<RoomTile> adjacentNodes = this.getAdjacent(openList, current, newTile); List<RoomTile> adjacentNodes = this.getAdjacent(openList, current, newTile);
for (RoomTile currentAdj : adjacentNodes) { for (RoomTile currentAdj : adjacentNodes) {
if (closedList.contains(currentAdj)) continue; if (closedList.contains(currentAdj)) continue;
if (roomUnit.canOverrideTile(currentAdj) || (currentAdj.state != RoomTileState.BLOCKED && currentAdj.x == doorX && currentAdj.y == doorY)) { if (roomUnit.canOverrideTile(currentAdj) || (currentAdj.state != RoomTileState.BLOCKED && currentAdj.x == doorX && currentAdj.y == doorY)) {
currentAdj.setPrevious(current); currentAdj.setPrevious(current);
currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y)); currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y));
@ -296,33 +283,19 @@ public class RoomLayout {
openList.add(currentAdj); openList.add(currentAdj);
continue; continue;
} }
if ((currentAdj.state == RoomTileState.BLOCKED) || ((currentAdj.state == RoomTileState.SIT || currentAdj.state == RoomTileState.LAY) && !currentAdj.equals(goalLocation))) {
//If the tile is sitable or layable and its not our goal tile, we cannot walk over it.
if (!currentAdj.equals(goalLocation) && (currentAdj.state == RoomTileState.BLOCKED || currentAdj.state == RoomTileState.SIT || currentAdj.state == RoomTileState.LAY)) {
closedList.add(currentAdj); closedList.add(currentAdj);
openList.remove(currentAdj); openList.remove(currentAdj);
continue; continue;
} }
////if (!room.getLayout().tileWalkable((short) currentAdj.x, (short) currentAdj.y)) continue;
//Height difference.
double height = currentAdj.getStackHeight() - current.getStackHeight(); double height = currentAdj.getStackHeight() - current.getStackHeight();
//If we are not allowed to fall and the height difference is bigger than the maximum stepheight, continue.
if (!ALLOW_FALLING && height < -MAXIMUM_STEP_HEIGHT) continue; if (!ALLOW_FALLING && height < -MAXIMUM_STEP_HEIGHT) continue;
//If the step difference is bigger than the maximum step height, continue.
if (currentAdj.state == RoomTileState.OPEN && height > MAXIMUM_STEP_HEIGHT) continue; if (currentAdj.state == RoomTileState.OPEN && height > MAXIMUM_STEP_HEIGHT) continue;
//Check if the tile has habbos.
if (currentAdj.hasUnits() && (!this.room.isAllowWalkthrough() || currentAdj.equals(goalLocation))) { if (currentAdj.hasUnits() && (!this.room.isAllowWalkthrough() || currentAdj.equals(goalLocation))) {
closedList.add(currentAdj); closedList.add(currentAdj);
openList.remove(currentAdj); openList.remove(currentAdj);
continue; continue;
} }
//if (room.hasPetsAt(currentAdj.x, currentAdj.y)) continue;
if (!openList.contains(currentAdj)) { if (!openList.contains(currentAdj)) {
currentAdj.setPrevious(current); currentAdj.setPrevious(current);
currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y)); currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y));
@ -333,13 +306,8 @@ public class RoomLayout {
currentAdj.setgCosts(current); currentAdj.setgCosts(current);
} }
} }
if (openList.isEmpty()) {
return new LinkedList<>();
}
}
} catch (Exception e) {
Emulator.getLogging().logErrorLine(e);
} }
// System.out.println("Invalid Path.");
return new LinkedList<>(); return new LinkedList<>();
} }
@ -605,8 +573,6 @@ public class RoomLayout {
} }
public boolean fitsOnMap(RoomTile tile, int width, int length, int rotation) { public boolean fitsOnMap(RoomTile tile, int width, int length, int rotation) {
THashSet<RoomTile> pointList = new THashSet<>(width * length, 0.1f);
if (tile != null) { if (tile != null) {
if (rotation == 0 || rotation == 4) { if (rotation == 0 || rotation == 4) {
for (short i = tile.x; i <= (tile.x + (width - 1)); i++) { for (short i = tile.x; i <= (tile.x + (width - 1)); i++) {

View File

@ -47,6 +47,20 @@ public class RoomTile {
this.units = tile.units; this.units = tile.units;
} }
public RoomTile()
{
x = 0;
y = 0;
z = 0;
this.stackHeight = 0;
this.state = RoomTileState.INVALID;
this.allowStack = false;
this.diagonally = false;
this.gCosts = 0;
this.hCosts = 0;
this.units = null;
}
public double getStackHeight() { public double getStackHeight() {
return this.stackHeight; return this.stackHeight;
} }

View File

@ -227,17 +227,15 @@ public class RoomUnit {
//if(!(this.path.size() == 0 && canSitNextTile)) //if(!(this.path.size() == 0 && canSitNextTile))
{ {
if (!room.tileWalkable(next.x, next.y) && !overrideChecks) { if (!room.tileWalkable(next)) {
this.room = room; this.room = room;
this.findPath(); this.findPath();
if (!this.path.isEmpty()) { if (this.path.isEmpty()) {
next = this.path.pop();
item = room.getTopItemAt(next.x, next.y);
} else {
this.status.remove(RoomUnitStatus.MOVE); this.status.remove(RoomUnitStatus.MOVE);
return false; return false;
} }
next = (RoomTile)this.path.pop();
} }
} }
@ -465,14 +463,15 @@ public class RoomUnit {
public void setGoalLocation(RoomTile goalLocation) { public void setGoalLocation(RoomTile goalLocation) {
if (goalLocation != null) { if (goalLocation != null) {
if (goalLocation.state != RoomTileState.INVALID) { // if (goalLocation.state != RoomTileState.INVALID) {
this.setGoalLocation(goalLocation, false); this.setGoalLocation(goalLocation, false);
} }
} //}
} }
public void setGoalLocation(RoomTile goalLocation, boolean noReset) { public void setGoalLocation(RoomTile goalLocation, boolean noReset) {
if (Emulator.getPluginManager().isRegistered(RoomUnitSetGoalEvent.class, false)) { if (Emulator.getPluginManager().isRegistered(RoomUnitSetGoalEvent.class, false))
{
Event event = new RoomUnitSetGoalEvent(this.room, this, goalLocation); Event event = new RoomUnitSetGoalEvent(this.room, this, goalLocation);
Emulator.getPluginManager().fireEvent(event); Emulator.getPluginManager().fireEvent(event);
@ -480,16 +479,18 @@ public class RoomUnit {
return; return;
} }
/// Set start location
this.startLocation = this.currentLocation; this.startLocation = this.currentLocation;
if (goalLocation != null && !noReset) { if (goalLocation != null && !noReset) {
this.goalLocation = goalLocation; this.goalLocation = goalLocation;
this.findPath(); this.findPath(); ///< Quadral: this is where we start formulating a path
if (!this.path.isEmpty()) { if (!this.path.isEmpty()) {
this.tilesWalked = 0; this.tilesWalked = 0;
this.cmdSit = false; this.cmdSit = false;
} else { } else {
this.goalLocation = this.currentLocation; this.goalLocation = this.currentLocation;
} }
} }
} }
@ -524,8 +525,11 @@ public class RoomUnit {
this.room = room; this.room = room;
} }
public void findPath() { public void findPath()
if (this.room != null && this.room.getLayout() != null && this.goalLocation != null && (this.goalLocation.isWalkable() || this.room.canSitOrLayAt(this.goalLocation.x, this.goalLocation.y) || this.canOverrideTile(this.goalLocation))) { {
if (this.room != null && this.room.getLayout() != null && this.goalLocation != null && (this.goalLocation.isWalkable() || this.room.canSitOrLayAt(this.goalLocation.x, this.goalLocation.y) || this.canOverrideTile(this.goalLocation)))
{
this.path = this.room.getLayout().findPath(this.currentLocation, this.goalLocation, this.goalLocation, this); this.path = this.room.getLayout().findPath(this.currentLocation, this.goalLocation, this.goalLocation, this);
} }
} }

View File

@ -15,20 +15,28 @@ import gnu.trove.set.hash.THashSet;
public class RoomUserWalkEvent extends MessageHandler { public class RoomUserWalkEvent extends MessageHandler {
@Override @Override
public void handle() throws Exception { public void handle() throws Exception
if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { {
int x = this.packet.readInt(); if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null)
int y = this.packet.readInt(); {
int x = this.packet.readInt(); ///< Position X
int y = this.packet.readInt(); ///<Position Y
/// Get Habbo object
Habbo habbo = this.client.getHabbo(); Habbo habbo = this.client.getHabbo();
/// Get Room Habbo object (Unique GUID?)
RoomUnit roomUnit = this.client.getHabbo().getRoomUnit(); RoomUnit roomUnit = this.client.getHabbo().getRoomUnit();
/// If habbo is teleporting, dont calculate a new path
if (roomUnit.isTeleporting) if (roomUnit.isTeleporting)
return; return;
/// If habbo is being kicked dont calculate a new path
if (roomUnit.isKicked) if (roomUnit.isKicked)
return; return;
/// If habbo has control (im assuming admin, do something else, but we dont care about this part here)
if (roomUnit.getCacheable().get("control") != null) { if (roomUnit.getCacheable().get("control") != null) {
habbo = (Habbo) roomUnit.getCacheable().get("control"); habbo = (Habbo) roomUnit.getCacheable().get("control");
@ -39,22 +47,34 @@ public class RoomUserWalkEvent extends MessageHandler {
} }
} }
/// Get room unit?
roomUnit = habbo.getRoomUnit(); roomUnit = habbo.getRoomUnit();
/// Get the room the habbo is in
Room room = habbo.getHabboInfo().getCurrentRoom(); Room room = habbo.getHabboInfo().getCurrentRoom();
try { try
if (roomUnit != null && roomUnit.isInRoom() && roomUnit.canWalk()) { {
if (!roomUnit.cmdTeleport) { /// If our room unit is not nullptr and we are in a room and we can walk, then calculate a new path
if (roomUnit != null && roomUnit.isInRoom() && roomUnit.canWalk())
{
/// If we are not teleporting calcualte a new path
if (!roomUnit.cmdTeleport)
{
/// Don't calculate a new path if we are on a horse
if (habbo.getHabboInfo().getRiding() != null && habbo.getHabboInfo().getRiding().getTask() != null && habbo.getHabboInfo().getRiding().getTask().equals(PetTasks.JUMP)) if (habbo.getHabboInfo().getRiding() != null && habbo.getHabboInfo().getRiding().getTask() != null && habbo.getHabboInfo().getRiding().getTask().equals(PetTasks.JUMP))
return; return;
/// Don't calulcate a new path if are already at the end position
if (x == roomUnit.getX() && y == roomUnit.getY()) if (x == roomUnit.getX() && y == roomUnit.getY())
return; return;
if (room == null || room.getLayout() == null) if (room == null || room.getLayout() == null)
return; return;
if (roomUnit.isIdle()) { /// Reset idle status
if (roomUnit.isIdle())
{
UserIdleEvent event = new UserIdleEvent(habbo, UserIdleEvent.IdleReason.WALKED, false); UserIdleEvent event = new UserIdleEvent(habbo, UserIdleEvent.IdleReason.WALKED, false);
Emulator.getPluginManager().fireEvent(event); Emulator.getPluginManager().fireEvent(event);
@ -66,12 +86,15 @@ public class RoomUserWalkEvent extends MessageHandler {
} }
} }
/// Get room height map
RoomTile tile = room.getLayout().getTile((short) x, (short) y); RoomTile tile = room.getLayout().getTile((short) x, (short) y);
/// this should never happen, if it does it would be a design flaw
if (tile == null) { if (tile == null) {
return; return;
} }
/// Don't care
if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.LAY)) { if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.LAY)) {
if (room.getLayout().getTilesInFront(habbo.getRoomUnit().getCurrentLocation(), habbo.getRoomUnit().getBodyRotation().getValue(), 2).contains(tile)) if (room.getLayout().getTilesInFront(habbo.getRoomUnit().getCurrentLocation(), habbo.getRoomUnit().getBodyRotation().getValue(), 2).contains(tile))
return; return;
@ -98,6 +121,8 @@ public class RoomUserWalkEvent extends MessageHandler {
} }
} }
} }
/// This is where we set the end location and begin finding a path
if (tile.isWalkable() || room.canSitOrLayAt(tile.x, tile.y)) { if (tile.isWalkable() || room.canSitOrLayAt(tile.x, tile.y)) {
roomUnit.setGoalLocation(tile); roomUnit.setGoalLocation(tile);
} }