-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First attempt at allowing dynamic portals #118
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ | |
import vg.civcraft.mc.bettershards.misc.LocationWrapper; | ||
import vg.civcraft.mc.bettershards.misc.TeleportInfo; | ||
import vg.civcraft.mc.bettershards.portal.Portal; | ||
import vg.civcraft.mc.bettershards.portal.PortalFactory; | ||
import vg.civcraft.mc.bettershards.portal.portals.CircularPortal; | ||
import vg.civcraft.mc.bettershards.portal.portals.CuboidPortal; | ||
import vg.civcraft.mc.bettershards.portal.portals.WorldBorderPortal; | ||
|
@@ -101,6 +102,11 @@ public class DatabaseManager { | |
private static final String getAllBedLocation = "select * from player_beds;"; | ||
private static final String removeBedLocation = "delete from player_beds where uuid = ?;"; | ||
|
||
private static final String addPortalType = "insert ignore into portalVersion (" | ||
+ "plugin_name, portal_plugin_id) values (?, ?);"; | ||
private static final String getPortalType = "select portal_id from portalVersion " | ||
+ "where plugin_name = ? and portal_plugin_id = ?;"; | ||
|
||
private String cleanupLocks; | ||
|
||
private BukkitTask lockCleanup; | ||
|
@@ -221,6 +227,11 @@ public Boolean call() { | |
+ "inv_id INT NOT NULL," | ||
+ "last_upd TIMESTAMP NOT NULL DEFAULT NOW()," | ||
+ "PRIMARY KEY (uuid, inv_id));"); | ||
this.db.registerMigration(3, false, "CREATE TABLE IF NOT EXISTS portalVersion(" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is redundant with the portal_type column in the table "createPortalDataTable". It also doesnt convert over any preexisting portals There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It isn't. portal_type doesn't offer any unique way for other plugins to know what ids are taken by who. |
||
+ "portal_id INT NOT NULL AUTO_INCREMENT," | ||
+ "plugin_name VARCHAR(36) NOT NULL," | ||
+ "portal_plugin_id INT NOT NULL," | ||
+ "PRIMARY KEY (plugin_name, portal_plugin_id));"); | ||
} | ||
|
||
@CivConfigs({ | ||
|
@@ -419,7 +430,7 @@ public void addPortalData(Portal portal, Portal connection){ | |
PreparedStatement addPortalData = connect.prepareStatement(DatabaseManager.addPortalData);) { | ||
addPortalData.setString(1, portal.getName()); | ||
addPortalData.setString(2, serverName); | ||
addPortalData.setInt(3, portal.specialId); | ||
addPortalData.setInt(3, portal.getPortalID()); | ||
String name = null; | ||
if (connection != null) | ||
name = connection.getName(); | ||
|
@@ -785,22 +796,20 @@ private Portal getPortalData(String name, LocationWrapper first, LocationWrapper | |
String serverName = set.getString("server_name"); | ||
String partner = set.getString("partner_id"); | ||
boolean currentServer = serverName.equals(MercuryAPI.serverName()); | ||
switch (specialId) { | ||
case 0: | ||
CuboidPortal p = new CuboidPortal(name, first.getFakeLocation(), second.getFakeLocation(), partner, currentServer); | ||
p.setServerName(serverName); | ||
return p; | ||
case 1: | ||
WorldBorderPortal wb = new WorldBorderPortal(name, partner, currentServer, first, second); | ||
wb.setServerName(serverName); | ||
return wb; | ||
case 2: | ||
CircularPortal cp = new CircularPortal(name, partner, currentServer, first.getFakeLocation(), second.getFakeLocation()); | ||
cp.setServerName(serverName); | ||
return cp; | ||
default: | ||
return null; | ||
} | ||
|
||
PortalFactory factory = BetterShardsPlugin.getPortalManager().getPortalFactory(); | ||
Class<? extends Portal> clazz = factory.getPortal(specialId); | ||
|
||
Portal p = factory.buildPortal(clazz); | ||
p.setName(name); | ||
p.setIsOnCurrentServer(true); | ||
p.setServerName(MercuryAPI.serverName()); | ||
p.setFirstLocation(first); | ||
p.setSecondLocation(second); | ||
p.setPartnerPortal(partner); | ||
p.valuesPopulated(); | ||
|
||
return p; | ||
} catch (SQLException e) { | ||
logger.log(Level.SEVERE, "Failed to getPortalData for {0}", name); | ||
logger.log(Level.SEVERE, "Failed to getPortalData, exception:", e); | ||
|
@@ -1019,6 +1028,64 @@ public void removeBed(UUID uuid) { | |
logger.log(Level.SEVERE, "Failed to removeBed, exception:", e); | ||
} | ||
} | ||
|
||
/** | ||
* This method is used to register with BetterShards what portal_id should | ||
* be associated with each portal so when saving occurs each portal specific id | ||
* is respected. | ||
* This method should be called for each portal type that exists. | ||
* So what should happen is in each plugin you give your custom portal it's own | ||
* specific id that is internally recognized and tracked. From there you will pass | ||
* that id and your plugin name to this method and it will create an id that can be | ||
* used to pass in your constructor for your portal objects. | ||
* After calling this method refer to the | ||
* {@link #getPortalID(String, int)} method for getting what id to pass to | ||
* your custom portal constructors. | ||
* This method can be called at every start and if an id is already present it will | ||
* fail silently. | ||
* @param id The id that will be used internally in your plugin to reference each | ||
* portal type. | ||
* @param plugin Your plugin's name. | ||
*/ | ||
public void addPortalType(int id, String plugin) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those ids should be managed in BetterShards, what you are doing here will require all possible users of this API to coordinate with each other to avoid overlap, which is exactly the opposite of what you want in an API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No they won't because when they get the portal id it will be specific in that specific server set up. |
||
try (Connection connection = db.getConnection(); | ||
PreparedStatement addPortalLoc = connection.prepareStatement(DatabaseManager.addPortalType)){ | ||
addPortalLoc.setString(1, plugin); | ||
addPortalLoc.setInt(2, id); | ||
addPortalLoc.execute(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's worth noting that inserts / updates / deletes can silently fail. Always use executeUpdate() and check the value returned. If != to the number of rows you thought you'd be modifying, you've got a failure-state. |
||
} | ||
catch (SQLException e) { | ||
logger.log(Level.SEVERE, "Add PortalType DB failure: ", e); | ||
} | ||
} | ||
|
||
/** | ||
* This method is used to get an id that will be used in each portal's constructor. | ||
* This id is important because it is used to map what kind of portal is being saved | ||
* in the database. | ||
* To use this method you must first call {@link #addPortalType(int, String)} in | ||
* order to generate an id that can be used. | ||
* @param plugin The plugin that is generating an id. | ||
* @param id The plugin specific id that is used to reference what id | ||
* should be returned based on what kind of portal it is. | ||
* @return Should return an id that should be passed in your portal subclass constructor. | ||
*/ | ||
public int getPortalID(String plugin, int id) { | ||
int type_id = -1; | ||
try (Connection connection = db.getConnection(); | ||
PreparedStatement addPortalLoc = connection.prepareStatement(DatabaseManager.getPortalType)){ | ||
addPortalLoc.setString(1, plugin); | ||
addPortalLoc.setInt(2, id); | ||
ResultSet set = addPortalLoc.executeQuery(); | ||
if (!set.next()) | ||
return -1; | ||
type_id = set.getInt(1); | ||
} | ||
catch (SQLException e) { | ||
logger.log(Level.SEVERE, "Get PortalType DB failure: ", e); | ||
} | ||
return type_id; | ||
} | ||
|
||
private void shortTrace() { | ||
StackTraceElement[] ste = Thread.currentThread().getStackTrace(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is called from startup and repeatedly elsewhere, shouldn't you be checking if this type exists before adding it? Even though your uniqueness pkey guarantee will probably prevent a new row from being generated, relying on an error is risky... better to explicitly check imho.