Skip to content

Commit

Permalink
Listen for world load changes, and update available portals from that
Browse files Browse the repository at this point in the history
  • Loading branch information
Thorinwasher committed Sep 22, 2024
1 parent 8db75a9 commit f23874d
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 74 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/sgrewritten/stargate/Stargate.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ private void registerListeners() {
pluginManager.registerEvents(new MoveEventListener(getRegistry()), this);
pluginManager.registerEvents(new PlayerEventListener(this.getLanguageManager(), getRegistry(), this.getBungeeManager(), this.getBlockLoggerManager(), this.getStorageAPI()), this);
pluginManager.registerEvents(new PluginEventListener(getEconomyManager(), getBlockLoggerManager()), this);
pluginManager.registerEvents(new WorldEventListener(this), this);
if (NonLegacyClass.PLAYER_ADVANCEMENT_CRITERION_EVENT.isImplemented()) {
pluginManager.registerEvents(new PlayerAdvancementListener(getRegistry()), this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.sgrewritten.stargate.api.database;

import org.bukkit.World;
import org.jetbrains.annotations.ApiStatus;
import org.sgrewritten.stargate.api.StargateAPI;
import org.sgrewritten.stargate.api.network.Network;
Expand Down Expand Up @@ -173,18 +174,20 @@ void removePortalPosition(RealPortal portal, StorageType portalType,

/**
* Update the network name in the database
* @param newName <p>The new name of the network</p>
*
* @param newName <p>The new name of the network</p>
* @param networkName <p>The previous name of the network</p>
* @param portalType <p>The storage type of the network</p>
* @param portalType <p>The storage type of the network</p>
* @throws StorageWriteException <p>If unable to modify the database</p>
*/
@ApiStatus.Internal
void updateNetworkName(String newName, String networkName, StorageType portalType) throws StorageWriteException;

/**
* Update the name of a portal
* @param newName <p>The name of the portal</p>
* @param portalId <p>A portal id representing this portal</p>
*
* @param newName <p>The name of the portal</p>
* @param portalId <p>A portal id representing this portal</p>
* @param portalType <p>How the portal is stored</p>
* @throws StorageWriteException <p>If unable to modify the database</p>
*/
Expand All @@ -193,7 +196,8 @@ void removePortalPosition(RealPortal portal, StorageType portalType,

/**
* Check if the networks exists in the database
* @param netName <p>Network name</p>
*
* @param netName <p>Network name</p>
* @param portalType <p>The storage type of the network</p>
* @return <p>True if exists</p>
* @throws StorageReadException <p>If unable to read the database</p>
Expand All @@ -204,4 +208,11 @@ void removePortalPosition(RealPortal portal, StorageType portalType,
* @return <p>The gate formats of the portals scheduled to be cleared</p>
*/
Set<String> getScheduledGatesClearing();

/**
* Load all portals in specified world
*
* @param world <p>A world</p>
*/
void loadPortalsInWorld(World world, StorageType storageType, StargateAPI stargateAPI) throws StorageReadException, StorageWriteException;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sgrewritten.stargate.api.network;

import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.sgrewritten.stargate.api.StargateAPI;
import org.sgrewritten.stargate.api.network.portal.Portal;
Expand Down Expand Up @@ -113,4 +114,10 @@ public interface NetworkManager {
* @param portal <p>Destroy portal</p>
*/
void destroyPortal(RealPortal portal);

/**
* Load all portals in world
* @param world <p>The world to load all portals from</p>
*/
void loadWorld(World world, StargateAPI stargateAPI);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;


/**
Expand Down Expand Up @@ -261,4 +262,6 @@ public interface RegistryAPI {
* @return <p>The portals in the chunk</p>
*/
@NotNull Set<RealPortal> getPortalsInChunk(StargateChunk chunk);

Stream<Portal> getAllPortals();
}
86 changes: 56 additions & 30 deletions src/main/java/org/sgrewritten/stargate/database/SQLDatabase.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sgrewritten.stargate.database;

import org.bukkit.Bukkit;
import org.bukkit.World;
import org.sgrewritten.stargate.Stargate;
import org.sgrewritten.stargate.api.StargateAPI;
import org.sgrewritten.stargate.api.config.ConfigurationOption;
Expand Down Expand Up @@ -43,10 +44,7 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.logging.Level;

import static javax.management.timer.Timer.ONE_WEEK;
Expand Down Expand Up @@ -203,52 +201,45 @@ public void removePortalFromStorage(Portal portal) throws StorageWriteException
* @throws SQLException <p>If an SQL error occurs</p>
*/
private void loadAllPortals(SQLDatabaseAPI database, StorageType portalType, StargateAPI stargateAPI) throws SQLException {
List<PortalData> portalDataList;
Set<String> worldsToRemove = new HashSet<>();
Set<String> gateFormatsToRemove = new HashSet<>();
PortalLoadData portalLoadData;
try (Connection connection = database.getConnection()) {
PreparedStatement statement = sqlQueryGenerator.generateGetAllPortalsStatement(connection, portalType);

ResultSet resultSet = statement.executeQuery();
portalDataList = new ArrayList<>();

while (resultSet.next()) {
try {
PortalData portalData = PortalStorageHelper.loadPortalData(resultSet, portalType);
portalDataList.add(portalData);
} catch (PortalLoadException e) {
switch (e.getFailureType()) {
case WORLD -> worldsToRemove.add(resultSet.getString("world"));
case GATE_FORMAT -> gateFormatsToRemove.add(resultSet.getString("gateFileName"));
}
}
}
portalLoadData = loadPortalsInQuery(resultSet, portalType);
statement.close();
}
removeWorlds(worldsToRemove, portalType);
String scheduledGateFormatClearing = propertiesDatabase.getProperty(StoredProperty.SCHEDULED_GATE_CLEARING);
if (scheduledGateFormatClearing != null && Long.parseLong(scheduledGateFormatClearing) > System.currentTimeMillis()) {
removeGateFormats(gateFormatsToRemove, portalType);
removeGateFormats(portalLoadData.invalidGates, portalType);
} else {
invalidGateFormats.addAll(gateFormatsToRemove);
invalidGateFormats.addAll(portalLoadData.invalidGates);
}

for (PortalData portalData : portalDataList) {
for (PortalData portalData : portalLoadData.loadedPortals) {
loadPortal(portalData, stargateAPI);
}
}

private void removeWorlds(Set<String> worldsToRemove, StorageType storageType) throws SQLException {
for (String world : worldsToRemove) {
try (Connection connection = database.getConnection()) {
try (PreparedStatement preparedStatement = sqlQueryGenerator.generateDeleteWorldStatement(connection, world, storageType)) {
preparedStatement.execute();
private PortalLoadData loadPortalsInQuery(ResultSet resultSet, StorageType portalType) throws SQLException {
List<PortalData> portalDataList = new ArrayList<>();
Set<String> worldsToRemove = new HashSet<>();
Set<String> gateFormatsToRemove = new HashSet<>();
while (resultSet.next()) {
try {
PortalData portalData = PortalStorageHelper.loadPortalData(resultSet, portalType);
portalDataList.add(portalData);
} catch (PortalLoadException e) {
switch (e.getFailureType()) {
case WORLD -> worldsToRemove.add(resultSet.getString("world"));
case GATE_FORMAT -> gateFormatsToRemove.add(resultSet.getString("gateFileName"));
}
}
}
return new PortalLoadData(portalDataList, worldsToRemove, gateFormatsToRemove);
}

private void removeGateFormats(Set<String> gateFormatsToRemove, StorageType storageType) throws SQLException {
private void removeGateFormats(Collection<String> gateFormatsToRemove, StorageType storageType) throws SQLException {
try (Connection connection = database.getConnection()) {
for (String gateFormat : gateFormatsToRemove) {
try (PreparedStatement preparedStatement = sqlQueryGenerator.generateRemoveGateStatement(connection, gateFormat, storageType)) {
Expand Down Expand Up @@ -656,4 +647,39 @@ public boolean netWorkExists(String netName, StorageType portalType) throws Stor
public Set<String> getScheduledGatesClearing() {
return this.invalidGateFormats;
}

@Override
public void loadPortalsInWorld(World world, StorageType storageType, StargateAPI stargateAPI) throws StorageReadException, StorageWriteException {
PortalLoadData portalLoadData;
try (Connection connection = database.getConnection()) {
ResultSet resultSet = sqlQueryGenerator.generateLoadPortalsInWorldStatement(connection, world, storageType).executeQuery();
portalLoadData = loadPortalsInQuery(resultSet, storageType);
} catch (SQLException e) {
throw new StorageReadException(e);
}

String scheduledGateFormatClearing = propertiesDatabase.getProperty(StoredProperty.SCHEDULED_GATE_CLEARING);
if (scheduledGateFormatClearing != null && Long.parseLong(scheduledGateFormatClearing) > System.currentTimeMillis()) {
try {
removeGateFormats(portalLoadData.invalidGates, storageType);
} catch (SQLException e) {
throw new StorageWriteException(e);
}
} else {
invalidGateFormats.addAll(portalLoadData.invalidGates);
}

for (PortalData portalData : portalLoadData.loadedPortals) {
try {
loadPortal(portalData, stargateAPI);
} catch (SQLException e) {
throw new StorageReadException(e);
}
}
}

private record PortalLoadData(Collection<PortalData> loadedPortals, Collection<String> invalidWorlds,
Collection<String> invalidGates) {

}
}
5 changes: 5 additions & 0 deletions src/main/java/org/sgrewritten/stargate/database/SQLQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ public enum SQLQuery {
*/
DELETE_GATE_FORMAT,

/**
* Get all portals in world
*/
GET_ALL_PORTALS_IN_WORLD,
GET_ALL_INTER_PORTALS_IN_WORLD,
/**
* Delete all inter server portals with the specified gate format and server
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,10 @@ public PreparedStatement generateSetPortalPositionMeta(Connection connection, Re
}

/**
* @param connection <p>A sql connection to the database</p>
* @param portal <p>The portal owning the portal position</p>
* @param connection <p>A sql connection to the database</p>
* @param portal <p>The portal owning the portal position</p>
* @param portalPosition <p>The portal position to get data on</p>
* @param portalType <p>How the portal is stored</p>
* @param portalType <p>How the portal is stored</p>
* @return <p>A prepared statement able to modify fetch data on the portal position</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
*/
Expand All @@ -621,11 +621,10 @@ public PreparedStatement generateGetPortalPositionStatement(Connection connectio
}

/**
*
* @param connection <p>A sql database connection</p>
* @param newName <p>The new name of the network</p>
* @param connection <p>A sql database connection</p>
* @param newName <p>The new name of the network</p>
* @param networkName <p>The previous name of the network</p>
* @param portalType <p>How the portals in the network are being stored</p>
* @param portalType <p>How the portals in the network are being stored</p>
* @return <p>A prepared statement able to modify the network name of all portals with the specified network</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
*/
Expand All @@ -643,12 +642,11 @@ public PreparedStatement generateUpdateNetworkNameStatement(Connection connectio
}

/**
*
* @param connection <p>A sql database connection</p>
* @param newName <p>The new name of the portal to modify</p>
* @param portalName <p>The previous portal name</p>
* @param connection <p>A sql database connection</p>
* @param newName <p>The new name of the portal to modify</p>
* @param portalName <p>The previous portal name</p>
* @param networkName <p>The network name of the portal</p>
* @param portalType <p>How the portal is being stored</p>
* @param portalType <p>How the portal is being stored</p>
* @return <p>A prepared statement able to change the name of a portal</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
*/
Expand All @@ -667,9 +665,8 @@ public PreparedStatement generateUpdatePortalNameStatement(Connection connection
}

/**
*
* @param connection <p>A sql connection to the database</p>
* @param netName <p>The name of the network to get all portals from</p>
* @param netName <p>The name of the network to get all portals from</p>
* @param portalType <p>how the portals in the network is being stored</p>
* @return <p>A prepared statement able to fetch all portals in specified network</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
Expand All @@ -687,9 +684,8 @@ public PreparedStatement generateGetAllPortalsOfNetwork(Connection connection, S
}

/**
*
* @param connection <p>A sql connection to the database</p>
* @param world <p>The world uuid to remove all portals from</p>
* @param connection <p>A sql connection to the database</p>
* @param world <p>The world uuid to remove all portals from</p>
* @param storageType <p>How the portals in the world is being stored</p>
* @return <p>A prepared statement able to delete all data on portals in specified world</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
Expand All @@ -708,8 +704,8 @@ public PreparedStatement generateDeleteWorldStatement(Connection connection, Str
}

/**
* @param connection <p>A sql connection to the database</p>
* @param gateFormat <p>The file name of the gate format to remove all portals of</p>
* @param connection <p>A sql connection to the database</p>
* @param gateFormat <p>The file name of the gate format to remove all portals of</p>
* @param storageType <p>How the portals are being stored</p>
* @return <p>A prepared statement able to remove all portals of specified gate format</p>
* @throws SQLException <p>If the syntax is incorrect or any other sql faults</p>
Expand All @@ -726,4 +722,16 @@ public PreparedStatement generateRemoveGateStatement(Connection connection, Stri
}
return statement;
}

public PreparedStatement generateLoadPortalsInWorldStatement(Connection connection, World world, StorageType storageType) throws SQLException {
PreparedStatement statement;
if(storageType == StorageType.LOCAL){
statement = prepareQuery(connection, getQuery(SQLQuery.GET_ALL_PORTALS_IN_WORLD));
} else {
statement = prepareQuery(connection, getQuery(SQLQuery.GET_ALL_INTER_PORTALS_IN_WORLD));
statement.setString(2, Stargate.getServerUUID());
}
statement.setString(1, world.getUID().toString());
return statement;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.sgrewritten.stargate.listener;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.sgrewritten.stargate.api.StargateAPI;
import org.sgrewritten.stargate.api.network.portal.RealPortal;

public class WorldEventListener implements Listener {

private final StargateAPI stargateAPI;

public WorldEventListener(StargateAPI stargateAPI) {
this.stargateAPI = stargateAPI;
}

@EventHandler
void onWordUnload(WorldUnloadEvent event) {
stargateAPI.getRegistry().getAllPortals().filter(portal -> portal instanceof RealPortal)
.map(portal -> (RealPortal) portal)
.filter(realPortal -> realPortal.getExit().getWorld().equals(event.getWorld()))
.forEach(stargateAPI.getRegistry()::unregisterPortal);
}

@EventHandler
void onWorldLoad(WorldLoadEvent event) {
stargateAPI.getNetworkManager().loadWorld(event.getWorld(), stargateAPI);
}
}
Loading

0 comments on commit f23874d

Please sign in to comment.