Compare commits
51 Commits
0f629a6387
...
1.21
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a46f10f8b | |||
| 0b14a216d9 | |||
| b2853b9dec | |||
| df5c363fb7 | |||
| c9e4b57f12 | |||
| fdcd248ba6 | |||
| f573771355 | |||
| 80078cd8e2 | |||
| 76fc468d89 | |||
| 1304048509 | |||
|
|
cf4ac95c2f | ||
|
|
f2d8c9c02b | ||
|
|
2405c5e620 | ||
| d9493c7474 | |||
| 2ccb240ef5 | |||
| d1d1679c0a | |||
| 62002e44d7 | |||
|
|
9c3f7526ff | ||
| eefe17e5f7 | |||
|
|
812e78d277 | ||
| fd220d7fd4 | |||
| 446cd5deae | |||
| a6c46d0270 | |||
| 2686ab285b | |||
| 57ea1470e2 | |||
| bfdc9c118a | |||
| dafe838a8a | |||
| 13bd154383 | |||
| 9248c9fa51 | |||
|
|
764dec99f4 | ||
| c9a1528dfe | |||
| 8c37466312 | |||
| 3b7e38aceb | |||
| e7c4c998a0 | |||
| 5907648462 | |||
| b32d6e9c69 | |||
| f533e85007 | |||
| 81c310c946 | |||
| 47c8cb1701 | |||
| f62af55d39 | |||
| 1dcd2f102c | |||
| 87f0765506 | |||
| b37ded3a8d | |||
|
|
c4e9f80315 | ||
| 19e14f787a | |||
|
|
9467291020 | ||
|
|
e14c7321c2 | ||
|
|
c94d67660a | ||
|
|
394591f302 | ||
|
|
3b41cc4ac5 | ||
|
|
29cb1cc5da |
@@ -113,8 +113,8 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
||||
if (Core.getVersion() < 19) return;
|
||||
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
||||
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
|
||||
if (e.isCancelled()) return;
|
||||
e.setCancelled(true);
|
||||
e.getBlock().setType(Material.BARRIER, false);
|
||||
e.getBlock().setType(Material.AIR, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.script.lua.libs;
|
||||
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
@Linked
|
||||
public class TracerLib implements LuaLib {
|
||||
@Override
|
||||
public String name() {
|
||||
return "tracer";
|
||||
}
|
||||
|
||||
private static LuaTable convertTrace(Trace trace) {
|
||||
LuaTable luaTrace = new LuaTable();
|
||||
|
||||
luaTrace.set("getRecords", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.listOf(
|
||||
trace.getHistories()
|
||||
.stream()
|
||||
.map((history) -> LuaValue.listOf(history
|
||||
.stream()
|
||||
.map(TracerLib::convertTntPoint)
|
||||
.toArray(LuaValue[]::new)))
|
||||
.toArray(LuaValue[]::new));
|
||||
}
|
||||
});
|
||||
|
||||
luaTrace.set("getId", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.valueOf(trace.getUuid().toString());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return luaTrace;
|
||||
}
|
||||
|
||||
private static LuaTable convertTntPoint(TNTPoint tntPoint) {
|
||||
Location pointPos = tntPoint.getLocation();
|
||||
LuaTable luaPos = LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("x"), LuaValue.valueOf(pointPos.getX()),
|
||||
LuaValue.valueOf("y"), LuaValue.valueOf(pointPos.getY()),
|
||||
LuaValue.valueOf("z"), LuaValue.valueOf(pointPos.getZ()),
|
||||
});
|
||||
|
||||
Vector pointVel = tntPoint.getVelocity();
|
||||
LuaTable luaVel = LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("x"), LuaValue.valueOf(pointVel.getX()),
|
||||
LuaValue.valueOf("y"), LuaValue.valueOf(pointVel.getY()),
|
||||
LuaValue.valueOf("z"), LuaValue.valueOf(pointVel.getZ()),
|
||||
});
|
||||
|
||||
return LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("pos"), luaPos,
|
||||
LuaValue.valueOf("vel"), luaVel,
|
||||
LuaValue.valueOf("ticksSinceStart"), LuaValue.valueOf(tntPoint.getTicksSinceStart()),
|
||||
LuaValue.valueOf("fuse"), LuaValue.valueOf(tntPoint.getFuse()),
|
||||
LuaValue.valueOf("isExplosion"), LuaValue.valueOf(tntPoint.isExplosion()),
|
||||
LuaValue.valueOf("isInWater"), LuaValue.valueOf(tntPoint.isInWater()),
|
||||
LuaValue.valueOf("hasDestroyedBuild"), LuaValue.valueOf(tntPoint.isDestroyedBuildArea()),
|
||||
LuaValue.valueOf("hasDestroyedTestblock"), LuaValue.valueOf(tntPoint.isDestroyedTestBlock())
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuaTable get(Player player) {
|
||||
LuaTable rootTable = LuaValue.tableOf();
|
||||
|
||||
rootTable.set("getTraces", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.listOf(TraceManager.instance.getAll()
|
||||
.stream()
|
||||
.map(TracerLib::convertTrace)
|
||||
.toArray(LuaValue[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return rootTable;
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public class SmartPlaceListener implements Listener {
|
||||
Block block = event.getBlock().getRelative(BlockFace.DOWN);
|
||||
BlockState old = block.getState();
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
block.setType(Material.GLASS);
|
||||
block.setType(Material.GLASS, false);
|
||||
old.update(true, false);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,15 @@ public class SkullCommand extends SWCommand {
|
||||
super("skull", "head");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void giveCommand(@Validator Player p) {
|
||||
if (p.getName().startsWith(".")) {
|
||||
BauSystem.MESSAGE.send("SKULL_INVALID", p);
|
||||
return;
|
||||
}
|
||||
giveCommand(p, p.getName());
|
||||
}
|
||||
|
||||
@Register(description = "SKULL_HELP")
|
||||
public void giveCommand(@Validator Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) {
|
||||
ItemStack is = SWItem.getPlayerSkull(skull).getItemStack();
|
||||
@@ -63,7 +72,7 @@ public class SkullCommand extends SWCommand {
|
||||
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.endsWith("⍇")).collect(Collectors.toList());
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.startsWith(".")).collect(Collectors.toList());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -200,21 +200,6 @@ function tnt.onlyTb() return nil end
|
||||
---@return boolean
|
||||
function tnt.onlyBuild() return nil end
|
||||
|
||||
---@class trace
|
||||
local trace = {}
|
||||
|
||||
---@return boolean
|
||||
function trace.active() return nil end
|
||||
|
||||
---@return boolean
|
||||
function trace.auto() return nil end
|
||||
|
||||
---@return string
|
||||
function trace.status() return nil end
|
||||
|
||||
---@return number
|
||||
function trace.time() return nil end
|
||||
|
||||
---@param name string
|
||||
---@return iregion
|
||||
function region.get(name) return nil end
|
||||
@@ -222,6 +207,25 @@ function region.get(name) return nil end
|
||||
---@return iregion[]
|
||||
function region.list() return nil end
|
||||
|
||||
---@class tracerLib
|
||||
tracer = {}
|
||||
|
||||
---@class TraceRecord
|
||||
---@field pos Position
|
||||
---@field vel Position
|
||||
---@field ticksSinceStart number
|
||||
---@field fuse number
|
||||
---@field isExplosion boolean
|
||||
---@field isInWater boolean
|
||||
---@field hasDestroyedBuild boolean
|
||||
---@field hasDestroyedTestblock boolean
|
||||
|
||||
---@class Tracer
|
||||
---@field getId fun(): string
|
||||
---@field getRecords fun(): {[number]: {[number]: TraceRecord}}
|
||||
|
||||
function tracer.getTraces() return nil end
|
||||
|
||||
---@class Position
|
||||
---@field x number
|
||||
---@field y number
|
||||
|
||||
@@ -31,10 +31,13 @@ public class SchematicNode {
|
||||
|
||||
static {
|
||||
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> {
|
||||
throw new SecurityException("SchematicNode cannot be used as type (recursive select)");
|
||||
}, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
}
|
||||
|
||||
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
|
||||
|
||||
public static void clear() {
|
||||
TAB_CACHE.clear();
|
||||
}
|
||||
@@ -42,39 +45,60 @@ public class SchematicNode {
|
||||
private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode ";
|
||||
|
||||
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem",
|
||||
"NodeType");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem",
|
||||
"NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
|
||||
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
|
||||
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector
|
||||
+ "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId");
|
||||
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table,
|
||||
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
|
||||
+ Statement.NULL_SAFE_EQUALS
|
||||
+ "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table,
|
||||
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
|
||||
+ Statement.NULL_SAFE_EQUALS
|
||||
+ "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
|
||||
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId"
|
||||
+ Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
|
||||
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table,
|
||||
"SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||
|
||||
static {
|
||||
NodeMember.init();
|
||||
}
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
@Field(keys = { Table.PRIMARY }, autoincrement = true)
|
||||
private final int nodeId;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
@Field(keys = { "OwnerNameParent" })
|
||||
private final int nodeOwner;
|
||||
@Field(def = "0")
|
||||
@Getter
|
||||
private final int effectiveOwner;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
@Field(keys = { "OwnerNameParent" })
|
||||
private String nodeName;
|
||||
@Field(keys = {"OwnerNameParent"}, nullable = true)
|
||||
@Field(keys = { "OwnerNameParent" }, nullable = true)
|
||||
private Integer parentNode;
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
private Timestamp lastUpdate;
|
||||
@@ -102,8 +126,7 @@ public class SchematicNode {
|
||||
SchematicType nodeType,
|
||||
int nodeRank,
|
||||
boolean replaceColor,
|
||||
boolean allowReplay
|
||||
) {
|
||||
boolean allowReplay) {
|
||||
this.nodeId = nodeId;
|
||||
this.nodeOwner = nodeOwner;
|
||||
this.effectiveOwner = effectiveOwner;
|
||||
@@ -118,7 +141,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAll(SteamwarUser user) {
|
||||
return all.listSelect(user);
|
||||
return all.listSelect(user, user, user);
|
||||
}
|
||||
|
||||
public static Map<Integer, List<SchematicNode>> getAllMap(SteamwarUser user) {
|
||||
@@ -130,7 +153,8 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) {
|
||||
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, name);
|
||||
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId,
|
||||
name);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
||||
@@ -142,10 +166,11 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
|
||||
return schematicAccessibleForUser.select(user, schematicId) != null;
|
||||
return schematicAccessibleForUser.select(user, user, user, schematicId) != null;
|
||||
}
|
||||
|
||||
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
||||
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type,
|
||||
Integer parentId) {
|
||||
return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId);
|
||||
}
|
||||
|
||||
@@ -160,7 +185,8 @@ public class SchematicNode {
|
||||
private static Map<Integer, List<SchematicNode>> map(List<SchematicNode> in) {
|
||||
Map<Integer, List<SchematicNode>> map = new HashMap<>();
|
||||
for (SchematicNode effectiveSchematicNode : in) {
|
||||
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
|
||||
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>())
|
||||
.add(effectiveSchematicNode);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@@ -218,7 +244,8 @@ public class SchematicNode {
|
||||
return byId.select(id);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType,
|
||||
Integer parent) {
|
||||
return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent);
|
||||
}
|
||||
|
||||
@@ -283,10 +310,12 @@ public class SchematicNode {
|
||||
}
|
||||
if (s.contains("/")) {
|
||||
String[] layers = s.split("/");
|
||||
Optional<SchematicNode> currentNode = Optional.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
|
||||
Optional<SchematicNode> currentNode = Optional
|
||||
.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
|
||||
for (int i = 1; i < layers.length; i++) {
|
||||
int finalI = i;
|
||||
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode
|
||||
.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||
if (!node.isPresent()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -365,7 +394,7 @@ public class SchematicNode {
|
||||
|
||||
@Deprecated
|
||||
public void setType(String type) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeType = SchematicType.fromDB(type);
|
||||
updateDB();
|
||||
@@ -376,13 +405,13 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public String getFileEnding() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return NodeData.get(this).getNodeFormat().getFileEnding();
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return nodeRank;
|
||||
}
|
||||
@@ -393,19 +422,19 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeRank = rank;
|
||||
}
|
||||
|
||||
public SchematicType getSchemtype() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setSchemtype(SchematicType type) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.nodeType = type;
|
||||
updateDB();
|
||||
@@ -416,7 +445,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setReplaceColor(boolean replaceColor) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.replaceColor = replaceColor;
|
||||
updateDB();
|
||||
@@ -427,14 +456,15 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setAllowReplay(boolean allowReplay) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.allowReplay = allowReplay;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public SchematicNode getParentNode() {
|
||||
if(parentNode == null) return null;
|
||||
if (parentNode == null)
|
||||
return null;
|
||||
return SchematicNode.getSchematicNode(parentNode);
|
||||
}
|
||||
|
||||
@@ -486,7 +516,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs() {
|
||||
if(brCache == null) {
|
||||
if (brCache == null) {
|
||||
brCache = generateBreadcrumbs("/");
|
||||
}
|
||||
return brCache;
|
||||
@@ -495,11 +525,15 @@ public class SchematicNode {
|
||||
public String generateBreadcrumbs(String split) {
|
||||
StringBuilder builder = new StringBuilder(getName());
|
||||
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
if (currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
builder.append(split);
|
||||
}
|
||||
while (currentNode.isPresent()) {
|
||||
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
|
||||
currentNode = currentNode
|
||||
.flatMap(schematicNode -> Optional
|
||||
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
|
||||
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
|
||||
.map(SchematicNode::getSchematicNode);
|
||||
currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.getName()));
|
||||
}
|
||||
return builder.toString();
|
||||
@@ -508,17 +542,22 @@ public class SchematicNode {
|
||||
public List<Map.Entry<String, Integer>> generateBreadcrumbsMap(SteamwarUser user) {
|
||||
List<Map.Entry<String, Integer>> map = new ArrayList<>();
|
||||
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
if (currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
map.add(new AbstractMap.SimpleEntry<>(getName(), getId()));
|
||||
}
|
||||
while (currentNode.isPresent()) {
|
||||
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
|
||||
currentNode = currentNode
|
||||
.flatMap(schematicNode -> Optional
|
||||
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
|
||||
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
|
||||
.map(SchematicNode::getSchematicNode);
|
||||
currentNode.ifPresent(node -> map.add(0, new AbstractMap.SimpleEntry<>(node.getName(), node.getId())));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||
|
||||
public static boolean invalidSchemName(String[] layers) {
|
||||
for (String layer : layers) {
|
||||
if (layer.isEmpty()) {
|
||||
@@ -535,7 +574,7 @@ public class SchematicNode {
|
||||
layer.contains(" ")) {
|
||||
return true;
|
||||
}
|
||||
if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
if (FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -549,14 +588,15 @@ public class SchematicNode {
|
||||
}
|
||||
int index = s.lastIndexOf("/");
|
||||
String cacheKey = index == -1 ? "" : s.substring(0, index);
|
||||
if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
if (TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (s.contains("/")) {
|
||||
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
|
||||
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
|
||||
if (pa == null) return new ArrayList<>();
|
||||
if (pa == null)
|
||||
return new ArrayList<>();
|
||||
List<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
|
||||
String br = pa.generateBreadcrumbs();
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : "")));
|
||||
|
||||
@@ -75,15 +75,7 @@ public class UserElo {
|
||||
|
||||
public static void setElo(int userId, String gameMode, int elo) {
|
||||
emblemCache.remove(userId);
|
||||
|
||||
int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode);
|
||||
int newPlacement = getPlacement(elo, gameMode);
|
||||
|
||||
gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId);
|
||||
if (oldPlacement <= 3 || newPlacement <= 3) {
|
||||
emblemCache.clear();
|
||||
}
|
||||
|
||||
setElo.update(Season.getSeason(), gameMode, userId, elo);
|
||||
}
|
||||
|
||||
@@ -112,27 +104,17 @@ public class UserElo {
|
||||
public static String getEmblemProgression(String gameMode, int userId) {
|
||||
switch (getProgression(userId, gameMode)) {
|
||||
case -1:
|
||||
return "§f/ §8∨ ∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§8❱❱❱❱ ❂";
|
||||
case 0:
|
||||
return "§8/ §6∨ §8∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱§8❱❱❱ ❂";
|
||||
case 1:
|
||||
return "§8/ ∨ §6∧ §8∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱❱§8❱❱ ❂";
|
||||
case 2:
|
||||
return "§8/ ∨ ∧ §7∨ §8∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱❱❱§8❱ ❂";
|
||||
case 3:
|
||||
return "§8/ ∨ ∧ ∨ §7∧ §8∨ ∧ ❂ III II I";
|
||||
return "§e❱❱❱❱§8 ❂";
|
||||
case 4:
|
||||
return "§8/ ∨ ∧ ∨ ∧ §e∨ §8∧ ❂ III II I";
|
||||
case 5:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ §e∧ §8❂ III II I";
|
||||
case 6:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ §5❂ §8III II I";
|
||||
case 7:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ §5III §8II I";
|
||||
case 8:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III §5II §8I";
|
||||
case 9:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III II §5I";
|
||||
return "§8❱❱❱❱ §5❂";
|
||||
default:
|
||||
throw new SecurityException("Progression is not in range");
|
||||
}
|
||||
@@ -142,19 +124,11 @@ public class UserElo {
|
||||
int elo = getElo(userId, gameMode).orElse(-1);
|
||||
if (elo < 0) return -1;
|
||||
|
||||
if (elo <= 100) return 0;
|
||||
if (elo <= 200) return 1;
|
||||
if (elo <= 400) return 2;
|
||||
if (elo <= 600) return 3;
|
||||
if (elo <= 900) return 4;
|
||||
if (elo <= 1200) return 5;
|
||||
|
||||
int placement = getPlacement(elo, gameMode);
|
||||
if (placement == 1) return 9;
|
||||
if (placement == 2) return 8;
|
||||
if (placement == 3) return 7;
|
||||
|
||||
return 6;
|
||||
if (elo < 150) return 0;
|
||||
if (elo < 350) return 1;
|
||||
if (elo < 600) return 2;
|
||||
if (elo < 900) return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static String toEmblem(int progression) {
|
||||
@@ -162,25 +136,15 @@ public class UserElo {
|
||||
case -1:
|
||||
return "";
|
||||
case 0:
|
||||
return "§6∨ ";
|
||||
return "§e❱ ";
|
||||
case 1:
|
||||
return "§6∧ ";
|
||||
return "§e❱❱ ";
|
||||
case 2:
|
||||
return "§7∨ ";
|
||||
return "§e❱❱❱ ";
|
||||
case 3:
|
||||
return "§7∧ ";
|
||||
return "§e❱❱❱❱ ";
|
||||
case 4:
|
||||
return "§e∨ ";
|
||||
case 5:
|
||||
return "§e∧ ";
|
||||
case 6:
|
||||
return "§5❂ ";
|
||||
case 7:
|
||||
return "§5III ";
|
||||
case 8:
|
||||
return "§5II ";
|
||||
case 9:
|
||||
return "§5I ";
|
||||
default:
|
||||
throw new SecurityException("Progression out of range");
|
||||
}
|
||||
|
||||
@@ -29,4 +29,5 @@ dependencies {
|
||||
compileOnly(libs.worldedit15)
|
||||
compileOnly(libs.fastutil)
|
||||
compileOnly(libs.authlib)
|
||||
compileOnly(libs.netty)
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ public class FightSystem extends JavaPlugin {
|
||||
new PrepareSchem();
|
||||
new TestJoin();
|
||||
new NormalJoin();
|
||||
new Spectator();
|
||||
new RunningWorldInteraction();
|
||||
new PersonalKitCreator();
|
||||
new ArrowStopper();
|
||||
@@ -156,6 +157,7 @@ public class FightSystem extends JavaPlugin {
|
||||
new LockschemCommand();
|
||||
new StateCommand();
|
||||
new SkipCommand();
|
||||
new TechhiderbugCommand();
|
||||
new TPSWarpCommand();
|
||||
new UnrankCommand();
|
||||
new WinCommand();
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.commands;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentCommand;
|
||||
import de.steamwar.sql.SWException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TechhiderbugCommand implements CommandExecutor {
|
||||
|
||||
public TechhiderbugCommand() {
|
||||
new StateDependentCommand(ArenaMode.All, FightState.All, "techhiderbug", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) {
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
writer.append("ArenaMode: ").append(Config.mode.name()).append('\n');
|
||||
writer.append("FightState: ").append(FightState.getFightState().name()).append('\n');
|
||||
writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n');
|
||||
|
||||
writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n');
|
||||
writer.append("Team regions: ");
|
||||
Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append("HullHider regions: ");
|
||||
FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append("Hidden regions: ");
|
||||
FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append('\n').append("Netty pipelines:\n");
|
||||
Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n'));
|
||||
|
||||
SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -104,40 +104,6 @@ public class Fight {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setPlayerGamemode(Player player, GameMode gameMode) {
|
||||
player.setGameMode(gameMode);
|
||||
|
||||
if(gameMode == GameMode.SPECTATOR) {
|
||||
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
currentPlayer.hidePlayer(player);
|
||||
player.hidePlayer(currentPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
if(Config.test() || Config.isReferee(player))
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
pseudoSpectator(player, true);
|
||||
}, 1);
|
||||
}else if(gameMode == GameMode.SURVIVAL) {
|
||||
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
currentPlayer.showPlayer(player);
|
||||
player.showPlayer(currentPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void pseudoSpectator(Player player, boolean enable) {
|
||||
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
|
||||
}
|
||||
|
||||
public static boolean publicOnly() {
|
||||
if (Config.OnlyPublicSchematics) {
|
||||
return true;
|
||||
|
||||
@@ -73,7 +73,6 @@ public class FightTeam {
|
||||
|
||||
if(ArenaMode.VariableTeams.contains(Config.mode)){
|
||||
notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests);
|
||||
notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers);
|
||||
if(!AIManager.availableAIs().isEmpty())
|
||||
notReadyKit.setItem(6, "ADD_AI", new ItemBuilder(Material.REDSTONE).build(), GUI::addAI);
|
||||
}
|
||||
@@ -81,6 +80,7 @@ public class FightTeam {
|
||||
if(Config.test())
|
||||
notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).enchant().build(), GUI::preSchemDialog);
|
||||
|
||||
notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers);
|
||||
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).enchant().build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
|
||||
}
|
||||
private static final HotbarKit chooseSchemKit = new HotbarKit(notReadyKit);
|
||||
@@ -282,9 +282,9 @@ public class FightTeam {
|
||||
FightSystem.getHullHider().updatePlayer(player);
|
||||
|
||||
if(FightState.Spectate.contains(FightState.getFightState())) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
} else {
|
||||
Fight.setPlayerGamemode(player, GameMode.SURVIVAL);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
(FightState.ingame() ? fightPlayer.getKit() : memberKit).loadToPlayer(player);
|
||||
}
|
||||
});
|
||||
@@ -317,7 +317,7 @@ public class FightTeam {
|
||||
entity.teleport(Config.SpecSpawn);
|
||||
|
||||
fightPlayer.ifPlayer(player -> {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.getInventory().clear();
|
||||
|
||||
if(player.isOnline()){
|
||||
@@ -517,14 +517,14 @@ public class FightTeam {
|
||||
@Override
|
||||
public void enable() {
|
||||
players.values().forEach(fightPlayer -> {
|
||||
fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SPECTATOR));
|
||||
fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SPECTATOR));
|
||||
fightPlayer.getEntity().teleport(FightTeam.this.spawn);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SURVIVAL)));
|
||||
players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SURVIVAL)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,6 @@ public class LeaveableArena implements Listener {
|
||||
|
||||
private void markInArena(Player player) {
|
||||
spectatorsInArena.put(player, player.getGameMode());
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class Permanent implements Listener {
|
||||
public void handlePlayerRespawn(PlayerRespawnEvent event){
|
||||
Player player = event.getPlayer();
|
||||
if(Fight.fighting(player)) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
|
||||
FightTeam team = Fight.getPlayerTeam(player);
|
||||
event.setRespawnLocation(team == null ? Config.SpecSpawn : team.getSpawn());
|
||||
@@ -98,11 +98,11 @@ public class Permanent implements Listener {
|
||||
FightPlayer fp = Fight.getFightPlayer(player);
|
||||
|
||||
if (!Config.ArenaLeaveable && fp == null) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
spectatorTeam.addEntry(player.getName());
|
||||
player.teleport(Config.SpecSpawn);
|
||||
} else if(fp != null && !fp.isLiving()) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.teleport(fp.getTeam().getSpawn());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import de.steamwar.core.ProtocolWrapper;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
|
||||
|
||||
public class Spectator implements Listener {
|
||||
|
||||
private final Set<Player> pseudoSpectator = new HashSet<>();
|
||||
|
||||
public Spectator() {
|
||||
new StateDependentListener(ArenaMode.AntiTest, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.AntiTest, FightState.All, this::pseudoSpectatorCheck, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void handlePlayerJoin(PlayerJoinEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
|
||||
if(player.getGameMode() == GameMode.SPECTATOR)
|
||||
gameModeChange(player, GameMode.SPECTATOR);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGameModeChange(PlayerGameModeChangeEvent e) {
|
||||
gameModeChange(e.getPlayer(), e.getNewGameMode());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void gameModeChange(Player player, GameMode gameMode) {
|
||||
if (gameMode == GameMode.SPECTATOR) {
|
||||
for(Player p : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(p.getUniqueId() != player.getUniqueId())
|
||||
p.hidePlayer(player);
|
||||
}
|
||||
} else {
|
||||
for(Player p : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(p.getUniqueId() != player.getUniqueId())
|
||||
p.showPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerQuit(PlayerQuitEvent e) {
|
||||
pseudoSpectator.remove(e.getPlayer());
|
||||
}
|
||||
|
||||
private void pseudoSpectatorCheck() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player.getGameMode() != GameMode.SPECTATOR) {
|
||||
pseudoSpectator.remove(player);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Config.isReferee(player))
|
||||
continue;
|
||||
|
||||
FightPlayer fightPlayer = Fight.getFightPlayer(player);
|
||||
if (fightPlayer == null || !fightPlayer.getTeam().getExtendRegion().playerInRegion(player.getLocation())) {
|
||||
if (pseudoSpectator.add(player))
|
||||
pseudoSpectator(player, true);
|
||||
} else {
|
||||
if (pseudoSpectator.remove(player))
|
||||
pseudoSpectator(player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void pseudoSpectator(Player player, boolean enable) {
|
||||
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,14 @@
|
||||
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.events.BoardingEvent;
|
||||
import de.steamwar.fightsystem.events.TeamDeathEvent;
|
||||
import de.steamwar.fightsystem.events.TeamLeaveEvent;
|
||||
@@ -32,23 +37,12 @@ import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TeamArea implements Listener {
|
||||
|
||||
private final FightTeam team;
|
||||
private final Border spectatorBorder;
|
||||
private final Border bordingBorder;
|
||||
private final Set<Player> realSpectator = new HashSet<>();
|
||||
|
||||
public TeamArea(FightTeam team) {
|
||||
this.team = team;
|
||||
@@ -56,7 +50,6 @@ public class TeamArea implements Listener {
|
||||
this.bordingBorder = new Border(team.getExtendRegion().to2d(), true, 1, "NO_ENTERN", team.getName() + ".boardingBorder");
|
||||
|
||||
new StateDependentListener(ArenaMode.AntiTest, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.AntiTest, FightState.TeamFix, this::realSpectatorCheck, 1, 1);
|
||||
new OneShotStateDependent(ArenaMode.AntiTest, FightState.Spectate, () -> Fight.teams().forEach(t -> t.getPlayers().forEach(this::teamSpectator)));
|
||||
}
|
||||
|
||||
@@ -114,30 +107,5 @@ public class TeamArea implements Listener {
|
||||
Player player = e.getPlayer();
|
||||
spectatorBorder.removePlayer(player);
|
||||
bordingBorder.removePlayer(player);
|
||||
realSpectator.remove(player);
|
||||
}
|
||||
|
||||
private void realSpectatorCheck() {
|
||||
for(FightPlayer fightPlayer : team.getPlayers()) {
|
||||
if(fightPlayer.isLiving())
|
||||
continue;
|
||||
|
||||
fightPlayer.ifPlayer(player -> {
|
||||
boolean inRegion = team.getExtendRegion().playerInRegion(player.getLocation());
|
||||
if(inRegion && !realSpectator.contains(player)) {
|
||||
realSpectator.add(player);
|
||||
|
||||
//Later to prevent race condition with Fight.setSpecatator() during respawn
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
Fight.pseudoSpectator(player, false);
|
||||
}, 2);
|
||||
}else if(!inRegion && realSpectator.contains(player)) {
|
||||
Fight.pseudoSpectator(player, true);
|
||||
realSpectator.remove(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public enum FightState {
|
||||
public static final Set<FightState> AntiIngame = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PRE_RUNNING, RUNNING)));
|
||||
public static final Set<FightState> AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE)));
|
||||
|
||||
@Getter
|
||||
private static final Map<IStateDependent, Boolean> stateDependentFeatures = new HashMap<>();
|
||||
@Getter
|
||||
private static FightState fightState = PRE_LEADER_SETUP;
|
||||
|
||||
@@ -45,6 +45,7 @@ public class Hull {
|
||||
return material.isOccluding() || Config.HiddenBlocks.contains(material);
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final Region region;
|
||||
private final boolean groundVisible;
|
||||
private final IntVector[] directions;
|
||||
|
||||
@@ -33,6 +33,7 @@ import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import de.steamwar.techhider.TechHider;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -56,6 +57,7 @@ import java.util.function.Function;
|
||||
|
||||
public class HullHider implements Listener {
|
||||
|
||||
@Getter
|
||||
private final Map<FightTeam, Hull> hullMap = new HashMap<>();
|
||||
private final Hull[] hulls;
|
||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> packetHiders = new HashMap<>();
|
||||
|
||||
@@ -159,4 +159,9 @@ public class Region {
|
||||
public interface TriConsumer<T, V, U>{
|
||||
void accept(T x, V y, U z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.techhider.TechHider;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -51,6 +52,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati
|
||||
|
||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||
|
||||
@Getter
|
||||
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Player, Long> patterns = new ConcurrentHashMap<>();
|
||||
private final TechHider techHider;
|
||||
|
||||
@@ -27,4 +27,5 @@ commands:
|
||||
resettb:
|
||||
tpslimit:
|
||||
tpswarp:
|
||||
techhiderbug:
|
||||
unrank:
|
||||
@@ -35,10 +35,10 @@ public class DownloadCommand extends SWCommand {
|
||||
@Register(help = true)
|
||||
public void genericCommand(Player player, String... args) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", 0);
|
||||
SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", (Integer) null);
|
||||
boolean newSchem = false;
|
||||
if(copyNode == null) {
|
||||
copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", 0, SchematicType.Normal.toDB(), "");
|
||||
if (copyNode == null) {
|
||||
copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", null, SchematicType.Normal.toDB(), "");
|
||||
newSchem = true;
|
||||
}
|
||||
|
||||
@@ -46,13 +46,13 @@ public class DownloadCommand extends SWCommand {
|
||||
new SchematicData(copyNode).saveFromPlayer(player);
|
||||
} catch (IOException e) {
|
||||
SchematicSystem.MESSAGE.send("DOWNLOAD_ERROR", player);
|
||||
if(newSchem) {
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
throw new SecurityException(e);
|
||||
} catch (NoClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_CLIPBOARD_EMPTY", player);
|
||||
if(newSchem) {
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -66,8 +66,8 @@ public class BlockIds14 implements BlockIds {
|
||||
return getBlock.invoke(null, material);
|
||||
}
|
||||
|
||||
private static final Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData);
|
||||
private int getCombinedId(Object blockData) {
|
||||
@Override
|
||||
public int getCombinedId(Object blockData) {
|
||||
return (int) getCombinedId.invoke(null, blockData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BountifulWrapper21 extends BountifulWrapper9 {
|
||||
return (packet, x, y, z, pitch, yaw) -> {
|
||||
PositionMoveRotation pos = field.get(packet);
|
||||
|
||||
field.set(packet, new PositionMoveRotation(new Vec3D(x, y, z), pos.b(), yaw, pitch));
|
||||
field.set(packet, new PositionMoveRotation(new Vec3D(x, y, z), pos == null ? new Vec3D(0, 0, 0) : pos.b(), yaw, pitch));
|
||||
};
|
||||
} catch (IllegalArgumentException e) {
|
||||
return super.getPositionSetter(packetClass, fieldOffset);
|
||||
|
||||
@@ -25,6 +25,12 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds8 implements BlockIds {
|
||||
@Override
|
||||
public int getCombinedId(Object iBlockData) {
|
||||
int id = (int) getCombinedId.invoke(null, iBlockData); // blockState << 12 | blockId
|
||||
return (id & 4095) | (id >> 12);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int materialToId(Material material) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.steamwar.Reflection;
|
||||
import de.steamwar.Reflection.Field;
|
||||
import de.steamwar.core.Core;
|
||||
import io.netty.channel.*;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -67,6 +68,7 @@ public class TinyProtocol implements Listener {
|
||||
private boolean closed;
|
||||
|
||||
private final Map<Class<?>, List<BiFunction<Player, Object, Object>>> packetFilters = new HashMap<>();
|
||||
@Getter
|
||||
private final Map<Player, PacketInterceptor> playerInterceptors = new HashMap<>();
|
||||
|
||||
private TinyProtocol(final Plugin plugin) {
|
||||
@@ -136,8 +138,9 @@ public class TinyProtocol implements Listener {
|
||||
private static final Field<Channel> getChannel = Reflection.getField(networkManager, Channel.class, 0);
|
||||
private static final Field<UUID> getUUID = Reflection.getField(networkManager, UUID.class, 0);
|
||||
|
||||
private final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
public final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
private final Player player;
|
||||
@Getter
|
||||
private final Channel channel;
|
||||
|
||||
private PacketInterceptor(Player player) {
|
||||
|
||||
@@ -177,9 +177,30 @@ public final class Reflection {
|
||||
}
|
||||
|
||||
public void set(Object target, Object value) {
|
||||
// This now works for Fields in records!
|
||||
try {
|
||||
f.set(target, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
long offset = Unsafe.getUnsafe().objectFieldOffset(f);
|
||||
Class<?> type = f.getType();
|
||||
if (type == int.class) {
|
||||
Unsafe.getUnsafe().putInt(target, offset, (Integer) value);
|
||||
} else if (type == float.class) {
|
||||
Unsafe.getUnsafe().putFloat(target, offset, (Float) value);
|
||||
} else if (type == double.class) {
|
||||
Unsafe.getUnsafe().putDouble(target, offset, (Double) value);
|
||||
} else if (type == boolean.class) {
|
||||
Unsafe.getUnsafe().putBoolean(target, offset, (Boolean) value);
|
||||
} else if (type == byte.class) {
|
||||
Unsafe.getUnsafe().putByte(target, offset, (Byte) value);
|
||||
} else if (type == char.class) {
|
||||
Unsafe.getUnsafe().putChar(target, offset, (Character) value);
|
||||
} else if (type == short.class) {
|
||||
Unsafe.getUnsafe().putShort(target, offset, (Short) value);
|
||||
} else if (type == long.class) {
|
||||
Unsafe.getUnsafe().putLong(target, offset, (Long) value);
|
||||
} else {
|
||||
Unsafe.getUnsafe().putReference(target, offset, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Cannot write field", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,10 +396,26 @@ public class REntity {
|
||||
public static final Class<?> teleportPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket");
|
||||
public static final Reflection.Field<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0);
|
||||
public static final BountifulWrapper.PositionSetter teleportPosition = BountifulWrapper.impl.getPositionSetter(teleportPacket, Core.getVersion() == 8 ? 1 : 0);
|
||||
public static final Class<?> relative;
|
||||
public static final Reflection.Field<Set> relatives;
|
||||
static {
|
||||
if (Core.getVersion() >= 21) {
|
||||
relative = Reflection.getClass("net.minecraft.world.entity.Relative");
|
||||
relatives = Reflection.getField(teleportPacket, Set.class, 0);
|
||||
} else {
|
||||
relative = null;
|
||||
relatives = null;
|
||||
}
|
||||
}
|
||||
private Object getTeleportPacket(){
|
||||
Object packet = Reflection.newInstance(teleportPacket);
|
||||
teleportEntity.set(packet, entityId);
|
||||
teleportPosition.set(packet, x, y, z, pitch, yaw);
|
||||
if (Core.getVersion() >= 21) {
|
||||
// https://mappings.dev/1.21.3/net/minecraft/world/entity/Relative.html
|
||||
Object[] constants = relative.getEnumConstants();
|
||||
relatives.set(packet, new HashSet<>(Arrays.asList(constants[0], constants[1], constants[2], constants[3], constants[4], constants[5])));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import org.bukkit.Material;
|
||||
@@ -28,6 +29,9 @@ import java.util.Set;
|
||||
public interface BlockIds {
|
||||
BlockIds impl = VersionDependent.getVersionImpl(Core.getInstance());
|
||||
|
||||
Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData);
|
||||
|
||||
int getCombinedId(Object iBlockData);
|
||||
int materialToId(Material material);
|
||||
Set<Integer> materialToAllIds(Material material);
|
||||
}
|
||||
|
||||
@@ -49,10 +49,8 @@ public class TechHider {
|
||||
public static final Class<?> craftMagicNumbers = Reflection.getClass("org.bukkit.craftbukkit.util.CraftMagicNumbers");
|
||||
private static final Reflection.Method getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class);
|
||||
|
||||
private static final Reflection.Method getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
|
||||
private static final Reflection.Method getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block);
|
||||
public boolean iBlockDataHidden(Object iBlockData) {
|
||||
return obfuscate.contains((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData)));
|
||||
return obfuscateIds.contains(BlockIds.impl.getCombinedId(iBlockData));
|
||||
}
|
||||
|
||||
public static final Object AIR = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.AIR));
|
||||
@@ -66,15 +64,12 @@ public class TechHider {
|
||||
@Getter
|
||||
private final int obfuscationTargetId;
|
||||
@Getter
|
||||
private final Set<Material> obfuscate;
|
||||
@Getter
|
||||
private final Set<Integer> obfuscateIds;
|
||||
@Getter
|
||||
private final Set<String> hiddenBlockEntities;
|
||||
|
||||
public TechHider(LocationEvaluator locationEvaluator, Material obfuscationTarget, Set<Material> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
this.locationEvaluator = locationEvaluator;
|
||||
this.obfuscate = obfuscate;
|
||||
this.obfuscateIds = obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
|
||||
this.hiddenBlockEntities = hiddenBlockEntities;
|
||||
this.obfuscationTarget = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, obfuscationTarget));
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MsgCommand extends SWCommand {
|
||||
}
|
||||
|
||||
public static void msg(PlayerChatter sender, Player target, String[] args) {
|
||||
if(target == null) {
|
||||
if(target == null || target.getCurrentServer().isEmpty()) {
|
||||
sender.system("MSG_OFFLINE");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.velocitycore.commands.CheckCommand;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,7 +42,8 @@ public class ChecklistChannel extends DiscordChannel {
|
||||
schems.removeIf(schem -> lastSchematics.contains(schem.getId()));
|
||||
|
||||
for(SchematicNode schem : schems) {
|
||||
system("CHECK_LIST_TO_CHECK", CheckCommand.getWaitTime(schem), schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName());
|
||||
String waitTime = "<t:" + (schem.getLastUpdate().getTime() / 1000) + ":R>";
|
||||
system("CHECK_LIST_TO_CHECK", waitTime, schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName());
|
||||
lastSchematics.add(schem.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,13 @@ import de.steamwar.velocitycore.discord.DiscordBot;
|
||||
import de.steamwar.velocitycore.discord.listeners.ChannelListener;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.entities.Icon;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.utils.ImageProxy;
|
||||
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
@@ -61,12 +64,54 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
|
||||
}
|
||||
|
||||
public void send(String message) {
|
||||
message = message
|
||||
.replace("&", "")
|
||||
.replace("@everyone", "`@everyone`")
|
||||
.replace("@here", "`@here`")
|
||||
.replaceAll("<[@#]!?\\d+>", "`$0`");
|
||||
|
||||
if (getChannel() instanceof TextChannel && message.contains("»")) {
|
||||
String[] strings = message.split("»", 2);
|
||||
String userName = strings[0];
|
||||
String sendMessage = strings[1];
|
||||
strings = userName.split(" ");
|
||||
|
||||
String ingameName = strings[strings.length - 1];
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(ingameName);
|
||||
if (user == null) {
|
||||
send(new MessageCreateBuilder()
|
||||
.setContent(message));
|
||||
return;
|
||||
}
|
||||
|
||||
ImageProxy avatarUrl;
|
||||
if (user.getDiscordId() != null) {
|
||||
avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatar();
|
||||
} else {
|
||||
avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatar();
|
||||
}
|
||||
|
||||
TextChannel textChannel = (TextChannel) getChannel();
|
||||
try {
|
||||
textChannel.createWebhook(userName)
|
||||
.setAvatar(Icon.from(avatarUrl.download(128).get()))
|
||||
.onSuccess(webhook -> {
|
||||
webhook.sendMessage(sendMessage)
|
||||
.onSuccess(__ -> {
|
||||
webhook.delete().queue();
|
||||
})
|
||||
.queue();
|
||||
})
|
||||
.queue();
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// Ignore and send message as normal!
|
||||
}
|
||||
}
|
||||
|
||||
send(new MessageCreateBuilder()
|
||||
.setContent(message
|
||||
.replace("&", "")
|
||||
.replace("@everyone", "`@everyone`")
|
||||
.replace("@here", "`@here`")
|
||||
.replaceAll("<[@#]!?\\d+>", "`$0`")));
|
||||
.setContent(message));
|
||||
}
|
||||
|
||||
public void send(MessageCreateBuilder builder) {
|
||||
|
||||
@@ -185,7 +185,6 @@ public class Tablist extends ChannelInboundHandlerAdapter {
|
||||
if(msg instanceof UpsertPlayerInfoPacket packet) {
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.INITIALIZE_CHAT);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LATENCY);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LISTED);
|
||||
if(packet.getActions().isEmpty()) {
|
||||
ReferenceCountUtil.release(msg);
|
||||
|
||||
@@ -46,7 +46,7 @@ dependencyResolutionManagement {
|
||||
if (isInCi) {
|
||||
url = URI("file:///var/www/maven/")
|
||||
} else {
|
||||
url = URI("https://steamwar.de/maven/")
|
||||
url = URI("https://maven.steamwar.de/")
|
||||
credentials {
|
||||
val swProps = Properties()
|
||||
swProps.load(rootDir.resolve("steamwar.properties").inputStream())
|
||||
|
||||
Reference in New Issue
Block a user