Compare commits

...
Author SHA1 Message Date
MagicBotandClaude Opus 5.5 015d536337 Remove CREATE_BUILDING
Every caller now goes through Building.createBuilding and persistBuilding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:02:17 -04:00
MagicBotandClaude Opus 5.5 d586536c74 Create player buildings in memory with a single DB write
Building gets a no-arg constructor, a createBuilding factory (in the style
of Mob.createMob) and persistBuilding, which inserts the row through
building_CREATE, sets the returned UID, caches the object and runs
runAfterLoad. The GET_BUILDINGBYUUID re-select after the insert is gone.

PlaceAssetMsgHandler (createStructure, createBarracks, createWarehouse),
Bane and AddBuildingCmd move onto it.

Value changes:
- floor/level start at -1 and the other unset fields at the obj_building
  column defaults, same as the reloaded row.
- upgradeDateTime keeps milliseconds instead of the DATETIME-rounded value
  (sub-second difference in the upgrade job time).
- Warehouse placement no longer runs runAfterLoad twice, which submitted
  the warehouse upgrade job twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:02:10 -04:00
5 changed files with 102 additions and 48 deletions

No files matched your search

+23 -30
View File
@@ -37,52 +37,45 @@ public class dbBuildingHandler extends dbHandlerBase {
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID,
Vector3fImmutable location, float meshScale, int currentHP,
ProtectionState protectionState, int currentGold, int rank,
DateTime upgradeDate, int blueprintUUID, float w, float rotY) {
public int PERSIST(Building building) {
Building building = null;
int objectUUID = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);")) {
preparedStatement.setInt(1, parentZoneID);
preparedStatement.setInt(2, OwnerUUID);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, meshUUID);
preparedStatement.setFloat(5, location.x);
preparedStatement.setFloat(6, location.y);
preparedStatement.setFloat(7, location.z);
preparedStatement.setFloat(8, meshScale);
preparedStatement.setInt(9, currentHP);
preparedStatement.setString(10, protectionState.name());
preparedStatement.setInt(11, currentGold);
preparedStatement.setInt(12, rank);
preparedStatement.setInt(1, building.parentZoneUUID);
preparedStatement.setInt(2, building.getOwnerUUID());
preparedStatement.setString(3, building.getName());
preparedStatement.setInt(4, building.meshUUID);
preparedStatement.setFloat(5, building.statLat);
preparedStatement.setFloat(6, building.statAlt);
preparedStatement.setFloat(7, building.statLon);
preparedStatement.setFloat(8, building.getMeshScale().x);
preparedStatement.setInt(9, (int) building.getHealth());
preparedStatement.setString(10, building.getProtectionState().name());
preparedStatement.setInt(11, building.getStrongboxValue());
preparedStatement.setInt(12, building.getRank());
if (upgradeDate != null)
preparedStatement.setTimestamp(13, new java.sql.Timestamp(upgradeDate.getMillis()));
if (building.upgradeDateTime != null)
preparedStatement.setTimestamp(13, java.sql.Timestamp.valueOf(building.upgradeDateTime));
else
preparedStatement.setNull(13, java.sql.Types.DATE);
preparedStatement.setInt(14, blueprintUUID);
preparedStatement.setFloat(15, w);
preparedStatement.setFloat(16, rotY);
preparedStatement.setInt(14, building.getBlueprintUUID());
preparedStatement.setFloat(15, building.getw());
preparedStatement.setFloat(16, building.getRot().y);
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
int objectUUID = (int) rs.getLong("UID");
if (objectUUID > 0)
building = GET_BUILDINGBYUUID(objectUUID);
}
if (rs.next())
objectUUID = (int) rs.getLong("UID");
} catch (SQLException e) {
throw new RuntimeException(e);
Logger.error(e);
}
return building;
return objectUUID;
}
public boolean DELETE_FROM_DATABASE(final Building b) {
+4 -5
View File
@@ -90,11 +90,10 @@ public class AddBuildingCmd extends AbstractDevCmd {
blueprintUUID = blueprint.getBlueprintUUID();
}
Building building = DbManager.BuildingQueries.
CREATE_BUILDING(
zone.getObjectUUID(), 0, buildingName, ID,
localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank,
null, blueprintUUID, w, rot.y);
Building building = Building.persistBuilding(Building.createBuilding(
zone, 0, buildingName, ID,
localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank,
null, blueprintUUID, w, rot.y));
if (building == null) {
@@ -1180,10 +1180,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// if W return is negative, this is a -90 rotation not a 90?
newMesh = DbManager.BuildingQueries.CREATE_BUILDING(
currentZone.getObjectUUID(), playerCharacter.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
newMesh = Building.persistBuilding(Building.createBuilding(
currentZone, playerCharacter.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0,
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
// Make sure we have a valid mesh
@@ -1303,10 +1303,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
DateTime completionDate = DateTime.now().plusHours(blueprint.getRankTime(1));
newMesh = DbManager.BuildingQueries.CREATE_BUILDING(
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
newMesh = Building.persistBuilding(Building.createBuilding(
currentZone, player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0,
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
// Make sure we have a valid mesh
if (newMesh == null) {
@@ -1342,10 +1342,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City city = City.getCity(currentZone.playerCityUUID);
warehouseBuilding = DbManager.BuildingQueries.CREATE_BUILDING(
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
warehouseBuilding = Building.persistBuilding(Building.createBuilding(
currentZone, player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0,
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation));
if (warehouseBuilding == null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
@@ -1363,7 +1363,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
MaintenanceManager.setMaintDateTime(warehouseBuilding, LocalDateTime.now().plusDays(7));
warehouseBuilding.setLoc(warehouseBuilding.getLoc());
InterestManager.setObjectDirty(warehouseBuilding);
warehouseBuilding.runAfterLoad();
if (city == null)
return true;
+3 -3
View File
@@ -210,10 +210,10 @@ public final class Bane {
return false;
}
Building stone = DbManager.BuildingQueries.CREATE_BUILDING(
cityZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(),
Building stone = Building.persistBuilding(Building.createBuilding(
cityZone, player.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(),
localLocation, 1.0f, blueprint.getMaxHealth(rank), ProtectionState.PROTECTED, 0, rank,
null, blueprint.getBlueprintUUID(), 1, 0.0f);
null, blueprint.getBlueprintUUID(), 1, 0.0f));
if (stone == null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
+63
View File
@@ -32,10 +32,12 @@ import engine.net.ByteBufferWriter;
import engine.net.client.msg.ApplyBuildingEffectMsg;
import engine.net.client.msg.UpdateObjectMsg;
import engine.server.MBServerStatics;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
@@ -99,6 +101,14 @@ public class Building extends AbstractWorldObject {
private ConcurrentHashMap<Integer, Condemned> condemned;
private ArrayList<Building> children = null;
/**
* No Id Constructor
*/
public Building() {
super();
}
/**
* ResultSet Constructor
*/
@@ -173,6 +183,59 @@ public class Building extends AbstractWorldObject {
}
}
// Defaults mirror the obj_building column defaults so a new building matches a reloaded one.
public static Building createBuilding(Zone parentZone, int ownerUUID, String name, int meshUUID,
Vector3fImmutable localLoc, float scale, int currentHP,
ProtectionState protectionState, int currentGold, int rank,
DateTime upgradeDate, int blueprintUUID, float w, float rotY) {
Building building = new Building();
building.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
building.gridObjectType = GridObjectType.STATIC;
building.parentZoneUUID = parentZone.getObjectUUID();
building.ownerUUID = ownerUUID;
building.name = name;
building.meshUUID = meshUUID;
building.blueprintUUID = blueprintUUID;
building.statLat = localLoc.x;
building.statAlt = localLoc.y;
building.statLon = localLoc.z;
building.meshScale = new Vector3f(scale, scale, scale);
building.setHealth(currentHP);
building.protectionState = protectionState;
building._strongboxValue = currentGold;
building.maxGold = 15000000;
building.rank = rank;
building.w = w;
building.setRot(new Vector3f(0f, rotY, 0f));
building.parentBuildingID = 0;
building.floor = -1;
building.level = -1;
if (upgradeDate != null)
building.upgradeDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(upgradeDate.getMillis()), ZoneId.systemDefault());
return building;
}
// Writes a new player building once and loads it into the simulation; returns null if the insert failed.
public static Building persistBuilding(Building building) {
int objectUUID;
objectUUID = DbManager.BuildingQueries.PERSIST(building);
if (objectUUID <= 0)
return null;
building.setObjectUUID(objectUUID);
DbManager.addToCache(building);
building.runAfterLoad();
return building;
}
/*
* Getters
*/