Added signLookup API methods

This commit is contained in:
Intelli committed 2026-05-06 13:31:39 -06:00
1 parent 3be769ed96
commit cebcc8655a
5 files changed
+480 -2

No files matched your search

+111
View File
@@ -39,6 +39,14 @@ List<MessageResult> commandLookup(String user, int time)
List<MessageResult> commandLookup(String user, int time, int radius, Location radius_location)
```
- Added `MessageResult` for reading chat and command data without parsing `String[]` lookup rows.
- Added typed sign lookup methods:
```java
List<SignResult> signLookup(Location location, int time)
List<SignResult> signLookup(Location location, int time, int radius)
List<SignResult> signLookup(String user, int time)
List<SignResult> signLookup(String user, int time, int radius, Location radius_location)
```
- Added `SignResult` for reading sign text data without parsing `String[]` lookup rows.
---
@@ -118,6 +126,14 @@ List<MessageResult> commandLookup(String user, int time)
List<MessageResult> commandLookup(String user, int time, int radius, Location radius_location)
List<SignResult> signLookup(Location location, int time)
List<SignResult> signLookup(Location location, int time, int radius)
List<SignResult> signLookup(String user, int time)
List<SignResult> signLookup(String user, int time, int radius, Location radius_location)
List<String[]> sessionLookup(String user, int time)
List<String[]> queueLookup(Block block)
@@ -327,6 +343,66 @@ All chat and command lookup methods return `MessageResult` entries with typed ac
---
#### `signLookup(Location location, int time)`
This will perform a sign text lookup at a single location.
* **location:** The location to perform the lookup on.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
---
#### `signLookup(Location location, int time, int radius)`
This will perform a sign text lookup around a location, similar to running `/co lookup a:sign r:<radius>`.
* **location:** The center location to perform the lookup around.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
* **radius:** Specify the radius to search in the X/Z plane. Set to "0" to perform a single-location lookup.
---
#### `signLookup(String user, int time)`
This will perform a sign text lookup for a user. Use `null` or `#global` to search all users.
* **user:** The username to perform the lookup on.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
---
#### `signLookup(String user, int time, int radius, Location radius_location)`
This will perform a sign text lookup around a location, similar to running `/co lookup a:sign r:<radius>`.
* **user:** The username to perform the lookup on. Use `null` or `#global` to search all users.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
* **radius:** Specify the radius to search in the X/Z plane. Set to "0" to search the exact location.
* **radius_location:** Specify the center location to search around.
All sign lookup methods return `SignResult` entries with typed access to the following:
* **getX():** Get the X coordinate of the sign.
* **getY():** Get the Y coordinate of the sign.
* **getZ():** Get the Z coordinate of the sign.
* **getLine(int line):** Get a sign line by zero-based line number.
* **getLines():** Get a copy of all sign lines.
* **getMessage():** Get the written sign side as a single string.
* **getPlayer():** Get the username as a string.
* **getTimestamp():** Get the time the sign text was logged.
* **getActionId():** Get the action ID. (1=placed/written)
* **getActionString():** Get the action as a string.
* **getColor():** Get the front sign text color.
* **getColorSecondary():** Get the back sign text color.
* **getData():** Get the raw sign data value.
* **isFront():** If the logged text is for the front side.
* **isFrontGlowing():** If the front side is glowing.
* **isBackGlowing():** If the back side is glowing.
* **isWaxed():** If the sign is waxed.
* **worldName():** The name of the world where the sign is located.
---
#### `queueLookup(Block block)`
This will search the consumer queue for changes on a block not yet saved in the database.
@@ -660,6 +736,41 @@ if (CoreProtect != null){ // Ensure we have access to the API
---
- Get the last 60 seconds of sign text at a specific location.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<SignResult> lookup = CoreProtect.signLookup(location, 60);
if (lookup != null){
for (SignResult result : lookup){
String message = result.getMessage();
String[] lines = result.getLines();
// ...
}
}
}
```
---
- Get the last 60 seconds of sign text written by the user "Notch" within 5 blocks of a location.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<SignResult> lookup = CoreProtect.signLookup("Notch", 60, 5, location);
if (lookup != null){
for (SignResult result : lookup){
int x = result.getX();
int y = result.getY();
int z = result.getZ();
// ...
}
}
}
```
---
- Get the last 1 day of session data for the user "Notch".
```java
CoreProtectAPI CoreProtect = getCoreProtect();
@@ -21,8 +21,10 @@ import net.coreprotect.api.BlockAPI;
import net.coreprotect.api.MessageAPI;
import net.coreprotect.api.QueueLookup;
import net.coreprotect.api.SessionLookup;
import net.coreprotect.api.SignAPI;
import net.coreprotect.api.result.ContainerResult;
import net.coreprotect.api.result.MessageResult;
import net.coreprotect.api.result.SignResult;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
@@ -239,6 +241,76 @@ public class CoreProtectAPI extends Queue {
return null;
}
/**
* Performs a sign text lookup at the specified location.
*
* @param location
* The location to look up
* @param time
* Time constraint in seconds
* @return List of results or null if API is disabled
*/
public List<SignResult> signLookup(Location location, int time) {
if (isEnabled()) {
return SignAPI.performLookup(location, time);
}
return null;
}
/**
* Performs a sign text lookup around the specified location.
*
* @param location
* The center location to look up
* @param time
* Time constraint in seconds
* @param radius
* Radius to search in the X/Z plane; 0 searches the exact location
* @return List of results or null if API is disabled
*/
public List<SignResult> signLookup(Location location, int time, int radius) {
if (isEnabled()) {
return SignAPI.performLookup(location, time, radius);
}
return null;
}
/**
* Performs a sign text lookup for the specified user.
*
* @param user
* The user to look up, or #global/null for all users
* @param time
* Time constraint in seconds
* @return List of results or null if API is disabled
*/
public List<SignResult> signLookup(String user, int time) {
if (isEnabled()) {
return SignAPI.performLookup(user, time);
}
return null;
}
/**
* Performs a sign text lookup around the specified location.
*
* @param user
* The user to look up, or #global/null for all users
* @param time
* Time constraint in seconds
* @param radius
* Radius to search in the X/Z plane; 0 searches the exact location
* @param radiusLocation
* Center location for the radius search
* @return List of results or null if API is disabled
*/
public List<SignResult> signLookup(String user, int time, int radius, Location radiusLocation) {
if (isEnabled()) {
return SignAPI.performLookup(user, time, radius, radiusLocation);
}
return null;
}
/**
* Determines if a user has placed a block at the specified location.
*
@@ -132,7 +132,7 @@ public class MessageAPI {
return result;
}
private static Integer getUserId(Connection connection, String user) throws Exception {
static Integer getUserId(Connection connection, String user) throws Exception {
if (user == null || user.isEmpty() || user.equalsIgnoreCase("#global")) {
return null;
}
@@ -172,7 +172,7 @@ public class MessageAPI {
);
}
private static int clampToInt(long value) {
static int clampToInt(long value) {
if (value > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
@@ -0,0 +1,158 @@
package net.coreprotect.api;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import net.coreprotect.api.result.SignResult;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.utility.WorldUtils;
/**
* Provides API methods for sign text lookups.
*/
public class SignAPI {
private SignAPI() {
throw new IllegalStateException("API class");
}
public static List<SignResult> performLookup(Location location, int offset) {
return performLookup(null, offset, 0, location);
}
public static List<SignResult> performLookup(Location location, int offset, int radius) {
return performLookup(null, offset, radius, location);
}
public static List<SignResult> performLookup(String user, int offset) {
return performLookup(user, offset, -1, null);
}
public static List<SignResult> performLookup(String user, int offset, int radius, Location location) {
List<SignResult> result = new ArrayList<>();
if (!Config.getGlobal().API_ENABLED) {
return result;
}
if (location != null && location.getWorld() == null) {
return result;
}
try (Connection connection = Database.getConnection(false, 1000)) {
if (connection == null) {
return result;
}
Integer userId = MessageAPI.getUserId(connection, user);
if (userId != null && userId == -1) {
return result;
}
int checkTime = 0;
if (offset > 0) {
checkTime = (int) (System.currentTimeMillis() / 1000L) - offset;
}
StringBuilder query = new StringBuilder("SELECT time,user,wid,x,y,z,action,color,color_secondary,data,waxed,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8 FROM ");
query.append(ConfigHandler.prefix).append("sign ");
if (location != null) {
query.append(WorldUtils.getWidIndex("sign"));
}
query.append("WHERE time > ? AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0)");
if (userId != null) {
query.append(" AND user = ?");
}
if (location != null) {
query.append(" AND wid = ?");
if (radius > 0) {
query.append(" AND x >= ? AND x <= ? AND z >= ? AND z <= ?");
}
else {
query.append(" AND x = ? AND y = ? AND z = ?");
}
}
query.append(" ORDER BY rowid DESC");
try (PreparedStatement statement = connection.prepareStatement(query.toString())) {
int parameterIndex = 1;
statement.setInt(parameterIndex++, checkTime);
if (userId != null) {
statement.setInt(parameterIndex++, userId);
}
if (location != null) {
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
statement.setInt(parameterIndex++, WorldUtils.getWorldId(location.getWorld().getName()));
if (radius > 0) {
statement.setInt(parameterIndex++, MessageAPI.clampToInt((long) x - radius));
statement.setInt(parameterIndex++, MessageAPI.clampToInt((long) x + radius));
statement.setInt(parameterIndex++, MessageAPI.clampToInt((long) z - radius));
statement.setInt(parameterIndex++, MessageAPI.clampToInt((long) z + radius));
}
else {
statement.setInt(parameterIndex++, x);
statement.setInt(parameterIndex++, y);
statement.setInt(parameterIndex, z);
}
}
try (ResultSet results = statement.executeQuery()) {
while (results.next()) {
result.add(parseSignResult(connection, results));
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static SignResult parseSignResult(Connection connection, ResultSet results) throws Exception {
int userId = results.getInt("user");
String username = ConfigHandler.playerIdCacheReversed.get(userId);
if (username == null) {
username = UserStatement.loadName(connection, userId);
}
String[] lines = new String[] {
valueOrEmpty(results.getString("line_1")),
valueOrEmpty(results.getString("line_2")),
valueOrEmpty(results.getString("line_3")),
valueOrEmpty(results.getString("line_4")),
valueOrEmpty(results.getString("line_5")),
valueOrEmpty(results.getString("line_6")),
valueOrEmpty(results.getString("line_7")),
valueOrEmpty(results.getString("line_8"))
};
return new SignResult(
results.getLong("time"), username, WorldUtils.getWorldName(results.getInt("wid")),
results.getInt("x"), results.getInt("y"), results.getInt("z"),
results.getInt("action"), results.getInt("color"), results.getInt("color_secondary"),
results.getInt("data"), results.getInt("waxed") == 1, results.getInt("face") == 0, lines
);
}
private static String valueOrEmpty(String value) {
return value == null ? "" : value;
}
}
@@ -0,0 +1,137 @@
package net.coreprotect.api.result;
import net.coreprotect.utility.BlockUtils;
/**
* Represents logged sign text.
*/
public class SignResult {
private final long time;
private final String username;
private final String world;
private final int x;
private final int y;
private final int z;
private final int actionId;
private final int color;
private final int colorSecondary;
private final int data;
private final boolean waxed;
private final boolean front;
private final String[] lines;
public SignResult(long time, String username, String world, int x, int y, int z, int actionId, int color, int colorSecondary, int data, boolean waxed, boolean front, String[] lines) {
this.time = time;
this.username = username;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.actionId = actionId;
this.color = color;
this.colorSecondary = colorSecondary;
this.data = data;
this.waxed = waxed;
this.front = front;
this.lines = lines.clone();
}
public int getActionId() {
return actionId;
}
public String getActionString() {
switch (actionId) {
case 0:
return "break";
case 1:
return "place";
case 2:
return "edit";
default:
return "unknown";
}
}
public int getColor() {
return color;
}
public int getColorSecondary() {
return colorSecondary;
}
public int getData() {
return data;
}
public String getLine(int line) {
if (line < 0 || line >= lines.length) {
return "";
}
return lines[line];
}
public String[] getLines() {
return lines.clone();
}
public String getMessage() {
StringBuilder message = new StringBuilder();
int startLine = front ? 0 : 4;
int endLine = front ? 4 : 8;
for (int index = startLine; index < endLine; index++) {
String line = lines[index];
if (line != null && !line.isEmpty()) {
message.append(line);
if (!line.endsWith(" ")) {
message.append(" ");
}
}
}
return message.toString();
}
public String getPlayer() {
return username;
}
public long getTimestamp() {
return time * 1000L;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
public boolean isBackGlowing() {
return BlockUtils.isSideGlowing(false, data);
}
public boolean isFront() {
return front;
}
public boolean isFrontGlowing() {
return BlockUtils.isSideGlowing(true, data);
}
public boolean isWaxed() {
return waxed;
}
public String worldName() {
return world;
}
}