diff --git a/CommonCore/SQL/src/de/steamwar/sql/AuditLog.java b/CommonCore/SQL/src/de/steamwar/sql/AuditLog.java
new file mode 100644
index 00000000..82d07c1b
--- /dev/null
+++ b/CommonCore/SQL/src/de/steamwar/sql/AuditLog.java
@@ -0,0 +1,132 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 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 .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+
+import java.sql.Timestamp;
+import java.time.Instant;
+
+@AllArgsConstructor
+public class AuditLog {
+
+ static {
+ SqlTypeMapper.nameEnumMapper(AuditLog.Type.class);
+ }
+
+ public static final String SERVER_NAME_VELOCITY = "Velocity";
+
+ private static final Table table = new Table<>(AuditLog.class);
+
+ private static final SelectStatement byId = table.select(Table.PRIMARY);
+
+ private static final Statement create = table.insertFields(true, "time", "serverName", "serverOwner", "actor", "actionType", "actionText");
+
+ @Getter
+ @Field(keys = {Table.PRIMARY}, autoincrement = true)
+ private final int auditLogId;
+
+ @Getter
+ @Field
+ private final Timestamp time;
+
+ @Getter
+ @Field
+ private final String serverName;
+
+ @Field(nullable = true)
+ private final int serverOwner;
+
+ @Field
+ private final int actor;
+
+ @Getter
+ @Field
+ private final Type actionType;
+
+ @Getter
+ @Field
+ private final String actionText;
+
+ public enum Type {
+ JOIN,
+ LEAVE,
+ COMMAND,
+ SENSITIVE_COMMAND,
+
+ CHAT,
+ GUI_OPEN,
+ GUI_CLOSE,
+ GUI_CLICK,
+ }
+
+ public static AuditLog get(int auditLogId) {
+ return byId.select(auditLogId);
+ }
+
+ private static AuditLog create(String serverName, SteamwarUser serverOwner, SteamwarUser actor, Type actionType, String text) {
+ return get(create.insertGetKey(Timestamp.from(Instant.now()), serverName, serverOwner, actor, actionType, text));
+ }
+
+ public static AuditLog createJoin(@NonNull String jointServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
+ return create(jointServerName, serverOwner, joinedPlayer, Type.JOIN, "");
+ }
+
+ public static AuditLog createLeave(@NonNull String leftServerName, SteamwarUser serverOwner, @NonNull SteamwarUser joinedPlayer) {
+ return create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE, "");
+ }
+
+ public static AuditLog createCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
+ if (player == null) return null;
+ return create(serverName, serverOwner, player, Type.COMMAND, command);
+ }
+
+ public static AuditLog createSensitiveCommand(@NonNull String serverName, SteamwarUser serverOwner, SteamwarUser player, @NonNull String command) {
+ if (player == null) return null;
+ return create(serverName, serverOwner, player, Type.SENSITIVE_COMMAND, command);
+ }
+
+ public static AuditLog createChat(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser chatter, @NonNull String chat) {
+ return create(serverName, serverOwner, chatter, Type.CHAT, chat);
+ }
+
+ public static AuditLog createGuiOpen(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
+ return create(serverName, serverOwner, player, Type.GUI_OPEN, guiName);
+ }
+
+ public static AuditLog createGuiClick(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName, @NonNull String clickType, int slot, @NonNull String itemName) {
+ return create(serverName, serverOwner, player, Type.GUI_CLICK, "Gui: " + guiName + "\nSlot: " + slot + "\nClickType: " + clickType + "\nItemName: " + itemName);
+ }
+
+ public static AuditLog createGuiClose(@NonNull String serverName, SteamwarUser serverOwner, @NonNull SteamwarUser player, @NonNull String guiName) {
+ return create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName);
+ }
+
+ public SteamwarUser getServerOwner() {
+ return SteamwarUser.get(serverOwner);
+ }
+
+ public SteamwarUser getActor() {
+ return SteamwarUser.get(actor);
+ }
+}
diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
index 9ebc4f0c..67a6116e 100644
--- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
+++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
@@ -68,6 +68,11 @@ public class FightSystem extends JavaPlugin {
Core.setInstance(this);
TinyProtocol.init();
}
+ if (Config.SpectatePort != 0) {
+ Core.setServerName("Spectate");
+ } else if (Config.ReplayID != 0) {
+ Core.setServerName("Replay");
+ }
message = new Message("de.steamwar.fightsystem.FightSystem", FightSystem.class.getClassLoader());
diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java b/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java
index 56af8fd7..6712e45a 100644
--- a/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java
+++ b/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java
@@ -53,6 +53,7 @@ public class BauSystem extends JavaPlugin implements Listener {
@Override
public void onEnable() {
+ Core.setServerName("Dev");
plugin = this;
Mapper.init();
diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java
index 4d198d4b..900d0941 100644
--- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java
+++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java
@@ -19,6 +19,7 @@
package de.steamwar.lobby;
+import de.steamwar.core.Core;
import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.command.FlyCommand;
import de.steamwar.lobby.command.HologramCommand;
@@ -52,6 +53,7 @@ public class LobbySystem extends JavaPlugin {
message = new Message("de.steamwar.lobby.LobbySystem", getClassLoader());
entityServer = new REntityServer();
debugEntityServer = new REntityServer();
+ Core.setServerName("Lobby");
CustomMap.init();
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/command/CaseInsensitiveCommandsListener.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/command/CaseInsensitiveCommandsListener.java
index a829308a..05eafdbb 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/command/CaseInsensitiveCommandsListener.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/command/CaseInsensitiveCommandsListener.java
@@ -19,6 +19,10 @@
package de.steamwar.command;
+import de.steamwar.core.Core;
+import de.steamwar.providers.BauServerInfo;
+import de.steamwar.sql.AuditLog;
+import de.steamwar.sql.SteamwarUser;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -31,5 +35,6 @@ public class CaseInsensitiveCommandsListener implements Listener {
String[] strings = event.getMessage().split(" ");
strings[0] = strings[0].toLowerCase();
event.setMessage(String.join(" ", strings));
+ AuditLog.createCommand(Core.getServerName(), BauServerInfo.getOwnerUser(), SteamwarUser.get(event.getPlayer().getUniqueId()), event.getMessage());
}
}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java
index c2086b0b..91c05851 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java
@@ -33,6 +33,8 @@ import de.steamwar.network.handlers.ServerDataHandler;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.internal.Statement;
+import lombok.Getter;
+import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Listener;
@@ -52,12 +54,17 @@ public class Core extends JavaPlugin {
return Reflection.MAJOR_VERSION;
}
+ @Getter
+ @Setter
private static JavaPlugin instance;
- public static JavaPlugin getInstance() {
- return instance;
- }
- public static void setInstance(JavaPlugin instance) {
- Core.instance = instance;
+
+ @Getter
+ private static String serverName = "";
+
+ public static void setServerName(String serverName) {
+ if (serverName.isEmpty()) {
+ Core.serverName = serverName;
+ }
}
private ErrorHandler errorHandler;
@@ -66,6 +73,7 @@ public class Core extends JavaPlugin {
@Override
public void onLoad() {
setInstance(this);
+ serverName = System.getProperty("serverName", "");
}
@Override
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PlayerJoinedEvent.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PlayerJoinedEvent.java
index 29b0ffd8..d3fd33a0 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PlayerJoinedEvent.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PlayerJoinedEvent.java
@@ -19,6 +19,9 @@
package de.steamwar.core.events;
+import de.steamwar.core.Core;
+import de.steamwar.providers.BauServerInfo;
+import de.steamwar.sql.AuditLog;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import de.steamwar.sql.internal.Statement;
@@ -44,12 +47,14 @@ public class PlayerJoinedEvent implements Listener{
player.setDisplayName(prefix.getColorCode() + player.getName() + "§r");
event.setJoinMessage("§a§l» §r" + player.getDisplayName());
+ AuditLog.createJoin(Core.getServerName(), BauServerInfo.getOwnerUser(), user);
}
- @EventHandler
+ @EventHandler(priority = EventPriority.LOWEST)
private void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
event.setQuitMessage("§c§l« §r" + player.getDisplayName());
+ AuditLog.createLeave(Core.getServerName(), BauServerInfo.getOwnerUser(), SteamwarUser.get(player.getUniqueId()));
}
}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWInventory.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWInventory.java
index 001fae9f..1b4529d3 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWInventory.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWInventory.java
@@ -20,7 +20,9 @@
package de.steamwar.inventory;
import de.steamwar.core.Core;
-import de.steamwar.core.TrickyTrialsWrapper;
+import de.steamwar.providers.BauServerInfo;
+import de.steamwar.sql.AuditLog;
+import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -145,6 +147,7 @@ public class SWInventory implements Listener {
Bukkit.getPluginManager().registerEvents(this, Core.getInstance());
open = true;
}
+ AuditLog.createGuiOpen(Core.getServerName(), BauServerInfo.getOwnerUser(), SteamwarUser.get(player.getUniqueId()), title);
}
@EventHandler
@@ -156,6 +159,7 @@ public class SWInventory implements Listener {
e.setCancelled(true);
Core.getInstance().getLogger().info("[SWINV] " + e.getWhoClicked().getName() + " " + e.getClick().name() + " clicked " + e.getRawSlot() + " on " + (e.getCurrentItem() != null ? e.getCurrentItem().getItemMeta().getDisplayName() : "[EMPTY]") + " in " + e.getView().getTitle());
callbacks.get(e.getRawSlot()).accept(e);
+ AuditLog.createGuiClick(Core.getServerName(), BauServerInfo.getOwnerUser(), SteamwarUser.get(player.getUniqueId()), e.getView().getTitle(), e.getClick().name(), e.getRawSlot(), (e.getCurrentItem() != null ? e.getCurrentItem().getItemMeta().getDisplayName() : "[EMPTY]"));
}
}
@@ -167,8 +171,10 @@ public class SWInventory implements Listener {
InventoryClickEvent.getHandlerList().unregister(this);
InventoryCloseEvent.getHandlerList().unregister(this);
Core.getInstance().getLogger().info("[SWINV] " + player.getName() + " closed " + title);
- if(callbacks.containsKey(-1))
+ if(callbacks.containsKey(-1)) {
callbacks.get(-1).accept(null);
+ }
open = false;
+ AuditLog.createGuiClose(Core.getServerName(), BauServerInfo.getOwnerUser(), SteamwarUser.get(player.getUniqueId()), title);
}
}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/providers/BauServerInfo.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/providers/BauServerInfo.java
index ddc7839e..309db835 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/providers/BauServerInfo.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/providers/BauServerInfo.java
@@ -19,6 +19,7 @@
package de.steamwar.providers;
+import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
public class BauServerInfo {
@@ -37,4 +38,9 @@ public class BauServerInfo {
public static boolean isBauServer() {
return bauOwner != null;
}
+
+ public static SteamwarUser getOwnerUser() {
+ if (bauOwner == null) return null;
+ return SteamwarUser.get(bauOwner);
+ }
}
diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
index d295d62b..058771e7 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
@@ -276,6 +276,7 @@ public class ServerStarter {
int port = portrange.freePort();
String serverName = serverNameProvider.apply(port);
+ arguments.put("serverName", serverName);
if(node == null) {
node = Node.getNode();
diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java
index 17137bf5..dfdf5c7f 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java
@@ -27,6 +27,8 @@ import com.velocitypowered.api.event.player.PlayerChatEvent;
import com.velocitypowered.api.event.player.TabCompleteEvent;
import com.velocitypowered.api.proxy.ConsoleCommandSource;
import com.velocitypowered.api.proxy.Player;
+import com.velocitypowered.api.proxy.ServerConnection;
+import com.velocitypowered.api.proxy.server.ServerInfo;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatterGroup;
import de.steamwar.messages.Message;
@@ -80,17 +82,32 @@ public class ChatListener extends BasicListener {
if(VelocityCore.getProxy().getCommandManager().hasCommand(cmd)) {
CommandSource source = e.getCommandSource();
String name;
- if(source instanceof Player player)
+ SteamwarUser user = null;
+ if (source instanceof Player player) {
+ user = SteamwarUser.get(player.getUniqueId());
name = player.getUsername();
- else if(source instanceof ConsoleCommandSource)
+ } else if (source instanceof ConsoleCommandSource) {
+ user = SteamwarUser.get(-1);
name = "«CONSOLE»";
- else
+ } else {
name = source.toString();
+ }
if (noLogCommands.contains(cmd)) {
return;
}
+ switch (cmd) {
+ case "msg":
+ case "r":
+ case "tc":
+ AuditLog.createSensitiveCommand(AuditLog.SERVER_NAME_VELOCITY, null, user, "/" + command);
+ break;
+ default:
+ AuditLog.createCommand(AuditLog.SERVER_NAME_VELOCITY, null, user, "/" + command);
+ break;
+ }
+
cmdLogger.log(Level.INFO, "%s -> executed command /%s".formatted(name, command));
} else if (e.getCommandSource() instanceof Player player) {
// System.out.println("spoofChatInput " + e);
@@ -106,8 +123,8 @@ public class ChatListener extends BasicListener {
e.setResult(PlayerChatEvent.ChatResult.denied());
+ SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if (message.contains("jndi:ldap")) {
- SteamwarUser user = SteamwarUser.get(player.getUniqueId());
PunishmentCommand.ban(user, Punishment.PERMA_TIME, "Versuchte Exploit-Ausnutzung", SteamwarUser.get(-1), true);
VelocityCore.getLogger().log(Level.SEVERE, "%s %s wurde automatisch wegen jndi:ldap gebannt.".formatted(user.getUserName(), user.getId()));
return;
@@ -117,13 +134,20 @@ public class ChatListener extends BasicListener {
return;
Subserver subserver = Subserver.getSubserver(player);
+ String serverName = AuditLog.SERVER_NAME_VELOCITY;
if(Subserver.isArena(subserver) && subserver.getServer() == player.getCurrentServer().orElseThrow().getServerInfo()) {
+ serverName = subserver.getServer().getName();
localChat(Chatter.of(player), message);
} else if (message.startsWith("+")) {
+ serverName = player.getCurrentServer()
+ .map(ServerConnection::getServerInfo)
+ .map(ServerInfo::getName)
+ .orElse(serverName);
localChat(Chatter.of(player), message.substring(1));
} else {
sendChat(Chatter.of(player), Chatter.globalChat(), "CHAT_GLOBAL", null, message);
}
+ AuditLog.createChat(serverName, null, user, message);
}
private static boolean isMistypedCommand(Player player, String message) {
diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/SessionManager.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/SessionManager.java
index 7caeac14..248fd606 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/listeners/SessionManager.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/SessionManager.java
@@ -22,6 +22,7 @@ package de.steamwar.velocitycore.listeners;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.PostLoginEvent;
+import de.steamwar.sql.AuditLog;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.sql.Session;
import de.steamwar.sql.SteamwarUser;
@@ -36,10 +37,12 @@ public class SessionManager extends BasicListener {
@Subscribe
public void onPostLogin(PostLoginEvent event){
sessions.put(event.getPlayer(), Timestamp.from(Instant.now()));
+ AuditLog.createJoin(AuditLog.SERVER_NAME_VELOCITY, null, SteamwarUser.get(event.getPlayer().getUniqueId()));
}
@Subscribe
public void onDisconnect(DisconnectEvent e){
+ AuditLog.createLeave(AuditLog.SERVER_NAME_VELOCITY, null, SteamwarUser.get(e.getPlayer().getUniqueId()));
Timestamp timestamp = sessions.remove(e.getPlayer());
if(timestamp != null) {
VelocityCore.schedule(() -> Session.insertSession(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), timestamp)).schedule();