Reworked logging framework
This commit is contained in:
@@ -13,11 +13,11 @@ import core.game.node.entity.player.Player;
|
|||||||
import core.game.node.entity.player.info.login.PlayerParser;
|
import core.game.node.entity.player.info.login.PlayerParser;
|
||||||
import core.game.node.entity.state.EntityState;
|
import core.game.node.entity.state.EntityState;
|
||||||
import core.game.node.item.Item;
|
import core.game.node.item.Item;
|
||||||
import core.game.system.monitor.PlayerMonitor;
|
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
import core.tools.RandomFunction;
|
import core.tools.RandomFunction;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import rs09.game.content.global.action.EquipHandler;
|
import rs09.game.content.global.action.EquipHandler;
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor;
|
||||||
import rs09.game.system.config.ItemConfigParser;
|
import rs09.game.system.config.ItemConfigParser;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
@@ -311,7 +311,7 @@ public final class DuelSession extends ComponentPlugin {
|
|||||||
log = log.substring(0, log.length() - 1);
|
log = log.substring(0, log.length() - 1);
|
||||||
}
|
}
|
||||||
log += "}";
|
log += "}";
|
||||||
player.getMonitor().log(log, PlayerMonitor.DUEL_LOG);
|
PlayerMonitor.logMisc(player, "Duel", log);
|
||||||
} else {
|
} else {
|
||||||
player.removeExtension(DuelSession.class);
|
player.removeExtension(DuelSession.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import core.game.node.entity.skill.summoning.familiar.FamiliarManager;
|
|||||||
import core.game.node.item.GroundItemManager;
|
import core.game.node.item.GroundItemManager;
|
||||||
import core.game.node.item.Item;
|
import core.game.node.item.Item;
|
||||||
import core.game.system.communication.CommunicationInfo;
|
import core.game.system.communication.CommunicationInfo;
|
||||||
import core.game.system.monitor.PlayerMonitor;
|
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.game.world.map.*;
|
import core.game.world.map.*;
|
||||||
import core.game.world.map.build.DynamicRegion;
|
import core.game.world.map.build.DynamicRegion;
|
||||||
@@ -73,6 +72,7 @@ import rs09.game.node.entity.combat.equipment.EquipmentDegrader;
|
|||||||
import rs09.game.node.entity.player.graves.Grave;
|
import rs09.game.node.entity.player.graves.Grave;
|
||||||
import rs09.game.node.entity.player.graves.GraveType;
|
import rs09.game.node.entity.player.graves.GraveType;
|
||||||
import rs09.game.node.entity.player.graves.GraveController;
|
import rs09.game.node.entity.player.graves.GraveController;
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor;
|
||||||
import rs09.game.node.entity.player.info.login.PlayerSaver;
|
import rs09.game.node.entity.player.info.login.PlayerSaver;
|
||||||
import rs09.game.node.entity.skill.runecrafting.PouchManager;
|
import rs09.game.node.entity.skill.runecrafting.PouchManager;
|
||||||
import rs09.game.node.entity.state.newsys.State;
|
import rs09.game.node.entity.state.newsys.State;
|
||||||
@@ -88,6 +88,7 @@ import rs09.tools.TickUtilsKt;
|
|||||||
import rs09.worker.ManagementEvents;
|
import rs09.worker.ManagementEvents;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static api.ContentAPIKt.*;
|
import static api.ContentAPIKt.*;
|
||||||
import static rs09.game.node.entity.player.info.stats.StatAttributeKeysKt.STATS_BASE;
|
import static rs09.game.node.entity.player.info.stats.StatAttributeKeysKt.STATS_BASE;
|
||||||
@@ -255,11 +256,6 @@ public class Player extends Entity {
|
|||||||
* The farming manager.
|
* The farming manager.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* The monitor which monitors player actions.
|
|
||||||
*/
|
|
||||||
private final PlayerMonitor monitor = new PlayerMonitor();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the players warning messages.
|
* Represents the players warning messages.
|
||||||
*/
|
*/
|
||||||
@@ -383,6 +379,7 @@ public class Player extends Entity {
|
|||||||
details.save();
|
details.save();
|
||||||
sendLogoutEvents();
|
sendLogoutEvents();
|
||||||
Repository.getDisconnectionQueue().add(this);
|
Repository.getDisconnectionQueue().add(this);
|
||||||
|
checkForWealthUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendLogoutEvents() {
|
private void sendLogoutEvents() {
|
||||||
@@ -475,6 +472,39 @@ public class Player extends Entity {
|
|||||||
|
|
||||||
//Decrements prayer points
|
//Decrements prayer points
|
||||||
getPrayer().tick();
|
getPrayer().tick();
|
||||||
|
|
||||||
|
//update wealth tracking
|
||||||
|
checkForWealthUpdate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForWealthUpdate(boolean force) {
|
||||||
|
if (isArtificial()) return;
|
||||||
|
long previousWealth = getAttribute("last-wealth", -1L);
|
||||||
|
long lastWealthCheck = getAttribute("last-wealth-check", -1L);
|
||||||
|
|
||||||
|
long nowTime = System.currentTimeMillis();
|
||||||
|
if (force || nowTime - lastWealthCheck >= TimeUnit.MINUTES.toMillis(5)) {
|
||||||
|
long totalWealth = 0L;
|
||||||
|
for (Item i : inventory.toArray()) {
|
||||||
|
if (i == null) continue;
|
||||||
|
totalWealth += (long) i.getDefinition().getValue() * i.getAmount();
|
||||||
|
}
|
||||||
|
for (Item i : bank.toArray()) {
|
||||||
|
if (i == null) break;
|
||||||
|
totalWealth += (long) i.getDefinition().getValue() * i.getAmount();
|
||||||
|
}
|
||||||
|
for (Item i : bankSecondary.toArray()) {
|
||||||
|
if (i == null) break;
|
||||||
|
totalWealth += (long) i.getDefinition().getValue() * i.getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
long diff = previousWealth == -1 ? 0L : totalWealth - previousWealth;
|
||||||
|
setAttribute("/save:last-wealth", totalWealth);
|
||||||
|
setAttribute("/save:last-wealth-check", nowTime);
|
||||||
|
|
||||||
|
if (diff != 0)
|
||||||
|
PlayerMonitor.logWealthChange(this, totalWealth, diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -611,8 +641,11 @@ public class Player extends Entity {
|
|||||||
Grave g = GraveController.produceGrave(GraveController.getGraveType(this));
|
Grave g = GraveController.produceGrave(GraveController.getGraveType(this));
|
||||||
g.initialize(this, location, Arrays.stream(c[1].toArray()).filter(Objects::nonNull).toArray(Item[]::new)); //note: the amount of code required to filter nulls from an array in Java is atrocious.
|
g.initialize(this, location, Arrays.stream(c[1].toArray()).filter(Objects::nonNull).toArray(Item[]::new)); //note: the amount of code required to filter nulls from an array in Java is atrocious.
|
||||||
} else {
|
} else {
|
||||||
|
StringBuilder itemsLost = new StringBuilder();
|
||||||
for (Item item : c[1].toArray()) {
|
for (Item item : c[1].toArray()) {
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
if (killer instanceof Player)
|
||||||
|
itemsLost.append(getItemName(item.getId())).append("(").append(item.getAmount()).append("), ");
|
||||||
if (GraveController.shouldCrumble(item.getId()))
|
if (GraveController.shouldCrumble(item.getId()))
|
||||||
continue;
|
continue;
|
||||||
if (GraveController.shouldRelease(item.getId()))
|
if (GraveController.shouldRelease(item.getId()))
|
||||||
@@ -620,6 +653,8 @@ public class Player extends Entity {
|
|||||||
item = GraveController.checkTransform(item);
|
item = GraveController.checkTransform(item);
|
||||||
GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this);
|
GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this);
|
||||||
}
|
}
|
||||||
|
if (killer instanceof Player)
|
||||||
|
PlayerMonitor.logMisc((Player) killer, "PK", "Killed " + name + ", who dropped: " + itemsLost);
|
||||||
sendMessage(colorize("%RDue to the circumstances of your death, you do not have a grave."));
|
sendMessage(colorize("%RDue to the circumstances of your death, you do not have a grave."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,13 +1208,6 @@ public class Player extends Entity {
|
|||||||
* @return The farmingManager.
|
* @return The farmingManager.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the monitor.
|
|
||||||
* @return The monitor.
|
|
||||||
*/
|
|
||||||
public PlayerMonitor getMonitor() {
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the warningMessages.
|
* Gets the warningMessages.
|
||||||
|
|||||||
+7
-21
@@ -7,10 +7,9 @@ import core.game.node.entity.player.Player
|
|||||||
import core.game.node.entity.player.link.request.RequestModule
|
import core.game.node.entity.player.link.request.RequestModule
|
||||||
import core.game.node.item.GroundItemManager
|
import core.game.node.item.GroundItemManager
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
import core.game.system.monitor.PlayerMonitor
|
|
||||||
import rs09.game.ai.AIRepository
|
import rs09.game.ai.AIRepository
|
||||||
import rs09.game.ai.general.scriptrepository.DoublingMoney
|
import rs09.game.ai.general.scriptrepository.DoublingMoney
|
||||||
import rs09.game.system.SystemLogger
|
import rs09.game.node.entity.player.info.PlayerMonitor
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -352,17 +351,16 @@ class TradeModule
|
|||||||
* @param module the module.
|
* @param module the module.
|
||||||
*/
|
*/
|
||||||
private fun giveContainers(module: TradeModule) {
|
private fun giveContainers(module: TradeModule) {
|
||||||
val pContainer: Container? = module.container
|
val pContainer: Container = module.container ?: return
|
||||||
val oContainer: Container? = getExtension(module.target)!!.container
|
val oContainer: Container = getExtension(module.target)!!.container ?: return
|
||||||
|
|
||||||
SystemLogger.logTrade(module.player!!.username + " -> " + module.target!!.username + " " + Arrays.toString(pContainer!!.toArray()))
|
PlayerMonitor.logTrade(module.player!!, module.target!!, pContainer, oContainer)
|
||||||
SystemLogger.logTrade(module.target!!.username + " -> " + module.player!!.username + " " + Arrays.toString(oContainer!!.toArray()))
|
|
||||||
|
|
||||||
(AIRepository.PulseRepository[module.player!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.target!!, oContainer)
|
(AIRepository.PulseRepository[module.player!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.target!!, oContainer)
|
||||||
(AIRepository.PulseRepository[module.target!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.player!!, pContainer)
|
(AIRepository.PulseRepository[module.target!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.player!!, pContainer)
|
||||||
|
|
||||||
addContainer(module.player, module.target, oContainer)
|
addContainer(module.player, oContainer)
|
||||||
addContainer(module.target, module.player, pContainer)
|
addContainer(module.target, pContainer)
|
||||||
module.target!!.packetDispatch.sendMessage("Accepted trade.")
|
module.target!!.packetDispatch.sendMessage("Accepted trade.")
|
||||||
module.player!!.packetDispatch.sendMessage("Accepted trade.")
|
module.player!!.packetDispatch.sendMessage("Accepted trade.")
|
||||||
}
|
}
|
||||||
@@ -373,10 +371,9 @@ class TradeModule
|
|||||||
* @param target the target who gains the items.
|
* @param target the target who gains the items.
|
||||||
* @param container the container.
|
* @param container the container.
|
||||||
*/
|
*/
|
||||||
private fun addContainer(player: Player?, target: Player?, container: Container?) {
|
private fun addContainer(player: Player?, container: Container?) {
|
||||||
val c = Container(container!!.itemCount(), ContainerType.ALWAYS_STACK)
|
val c = Container(container!!.itemCount(), ContainerType.ALWAYS_STACK)
|
||||||
c.addAll(container)
|
c.addAll(container)
|
||||||
var log = "traded => " + target!!.name + " received => {"
|
|
||||||
for (i in container.toArray()) {
|
for (i in container.toArray()) {
|
||||||
if (i == null) {
|
if (i == null) {
|
||||||
continue
|
continue
|
||||||
@@ -388,17 +385,6 @@ class TradeModule
|
|||||||
GroundItemManager.create(i, player)
|
GroundItemManager.create(i, player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i in c.toArray()) {
|
|
||||||
if (i == null) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log += i.name + " x " + i.amount + ","
|
|
||||||
}
|
|
||||||
if (log[log.length - 1] == ',') {
|
|
||||||
log = log.substring(0, log.length - 1)
|
|
||||||
}
|
|
||||||
log += "}"
|
|
||||||
player!!.monitor.log(log, PlayerMonitor.TRADE_LOG)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ import core.game.world.update.flag.player.AppearanceFlag;
|
|||||||
import core.net.packet.PacketRepository;
|
import core.net.packet.PacketRepository;
|
||||||
import core.net.packet.context.SkillContext;
|
import core.net.packet.context.SkillContext;
|
||||||
import core.net.packet.out.SkillLevel;
|
import core.net.packet.out.SkillLevel;
|
||||||
|
import kotlin.Pair;
|
||||||
import org.json.simple.JSONArray;
|
import org.json.simple.JSONArray;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor;
|
||||||
import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks;
|
import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks;
|
||||||
import rs09.game.world.GameWorld;
|
import rs09.game.world.GameWorld;
|
||||||
import rs09.game.world.repository.Repository;
|
import rs09.game.world.repository.Repository;
|
||||||
@@ -23,6 +25,8 @@ import rs09.plugin.CorePluginTypes.XPGainPlugins;
|
|||||||
import org.rs09.consts.Items;
|
import org.rs09.consts.Items;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static java.lang.Math.floor;
|
import static java.lang.Math.floor;
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
@@ -68,6 +72,10 @@ public final class Skills {
|
|||||||
*/
|
*/
|
||||||
private final double[] experience;
|
private final double[] experience;
|
||||||
|
|
||||||
|
private double[] lastUpdateXp = null;
|
||||||
|
|
||||||
|
private int lastUpdate = GameWorld.getTicks();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array containing all the maximum levels.
|
* An array containing all the maximum levels.
|
||||||
*/
|
*/
|
||||||
@@ -212,6 +220,8 @@ public final class Skills {
|
|||||||
* @param experience The experience.
|
* @param experience The experience.
|
||||||
*/
|
*/
|
||||||
public void addExperience(int slot, double experience, boolean playerMod) {
|
public void addExperience(int slot, double experience, boolean playerMod) {
|
||||||
|
if (lastUpdateXp == null)
|
||||||
|
lastUpdateXp = this.experience.clone();
|
||||||
double mod = getExperienceMod(slot, experience, playerMod, true);
|
double mod = getExperienceMod(slot, experience, playerMod, true);
|
||||||
final Player player = entity instanceof Player ? ((Player) entity) : null;
|
final Player player = entity instanceof Player ? ((Player) entity) : null;
|
||||||
final AssistSession assist = entity.getExtension(AssistSession.class);
|
final AssistSession assist = entity.getExtension(AssistSession.class);
|
||||||
@@ -278,6 +288,18 @@ public final class Skills {
|
|||||||
PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, slot));
|
PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, slot));
|
||||||
entity.dispatch(new XPGainEvent(slot, experienceAdd));
|
entity.dispatch(new XPGainEvent(slot, experienceAdd));
|
||||||
}
|
}
|
||||||
|
if (GameWorld.getTicks() - lastUpdate >= 200) {
|
||||||
|
ArrayList<Pair<Integer,Double>> diffs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < this.experience.length; i++) {
|
||||||
|
double diff = this.experience[i] - lastUpdateXp[i];
|
||||||
|
if (diff != 0.0) {
|
||||||
|
diffs.add(new Pair<>(i, diff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlayerMonitor.logXpGains(player, diffs);
|
||||||
|
lastUpdateXp = this.experience.clone();
|
||||||
|
lastUpdate = GameWorld.getTicks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import rs09.Server;
|
|||||||
import rs09.ServerConstants;
|
import rs09.ServerConstants;
|
||||||
import rs09.ServerStore;
|
import rs09.ServerStore;
|
||||||
import rs09.game.ai.AIRepository;
|
import rs09.game.ai.AIRepository;
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor;
|
||||||
import rs09.game.system.SystemLogger;
|
import rs09.game.system.SystemLogger;
|
||||||
import rs09.game.world.GameWorld;
|
import rs09.game.world.GameWorld;
|
||||||
import rs09.game.world.repository.Repository;
|
import rs09.game.world.repository.Repository;
|
||||||
@@ -55,6 +56,7 @@ public final class SystemTermination {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GameWorld.getShutdownListeners().forEach(ShutdownListener::shutdown);
|
GameWorld.getShutdownListeners().forEach(ShutdownListener::shutdown);
|
||||||
|
PlayerMonitor.flushRemainingEventsImmediately();
|
||||||
ServerStore s = null;
|
ServerStore s = null;
|
||||||
for (PersistWorld wld : GameWorld.getWorldPersists()) {
|
for (PersistWorld wld : GameWorld.getWorldPersists()) {
|
||||||
if (wld instanceof ServerStore)
|
if (wld instanceof ServerStore)
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import core.game.content.activity.ActivityPlugin;
|
|||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.entity.player.info.PlayerDetails;
|
import core.game.node.entity.player.info.PlayerDetails;
|
||||||
import core.game.node.entity.player.info.Rights;
|
import core.game.node.entity.player.info.Rights;
|
||||||
import core.game.system.monitor.PlayerMonitor;
|
|
||||||
import proto.management.ClanJoinNotification;
|
import proto.management.ClanJoinNotification;
|
||||||
import proto.management.ClanLeaveNotification;
|
import proto.management.ClanLeaveNotification;
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor;
|
||||||
import rs09.game.world.GameWorld;
|
import rs09.game.world.GameWorld;
|
||||||
import rs09.game.world.repository.Repository;
|
import rs09.game.world.repository.Repository;
|
||||||
import core.net.amsc.WorldCommunicator;
|
import core.net.amsc.WorldCommunicator;
|
||||||
@@ -198,9 +198,7 @@ public final class ClanRepository {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder(message);
|
PlayerMonitor.logChat(player, "clan", message);
|
||||||
sb.append(" => ").append(name).append(" (owned by ").append(owner).append(")");
|
|
||||||
player.getMonitor().log(sb.toString(), PlayerMonitor.CLAN_CHAT_LOG);
|
|
||||||
for (Iterator<ClanEntry> it = players.iterator(); it.hasNext();) {
|
for (Iterator<ClanEntry> it = players.iterator(); it.hasNext();) {
|
||||||
ClanEntry entry = it.next();
|
ClanEntry entry = it.next();
|
||||||
Player p = entry.getPlayer();
|
Player p = entry.getPlayer();
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import proto.management.PrivateMessage;
|
import proto.management.PrivateMessage;
|
||||||
import rs09.auth.UserAccountInfo;
|
import rs09.auth.UserAccountInfo;
|
||||||
import rs09.game.system.SystemLogger;
|
import rs09.game.system.SystemLogger;
|
||||||
import core.game.system.monitor.PlayerMonitor;
|
|
||||||
import core.game.system.mysql.SQLTable;
|
import core.game.system.mysql.SQLTable;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import rs09.game.world.GameWorld;
|
import rs09.game.world.GameWorld;
|
||||||
|
|||||||
@@ -1,284 +0,0 @@
|
|||||||
package core.game.system.monitor;
|
|
||||||
|
|
||||||
import core.cache.misc.buffer.ByteBufferUtils;
|
|
||||||
import core.game.node.entity.player.Player;
|
|
||||||
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the player monitoring.
|
|
||||||
* @author Emperor
|
|
||||||
*/
|
|
||||||
public final class PlayerMonitor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The public chat log.
|
|
||||||
*/
|
|
||||||
public static final int PUBLIC_CHAT_LOG = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The private chat log.
|
|
||||||
*/
|
|
||||||
public static final int PRIVATE_CHAT_LOG = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The clan chat log.
|
|
||||||
*/
|
|
||||||
public static final int CLAN_CHAT_LOG = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The IP/MAC-address log.
|
|
||||||
*/
|
|
||||||
public static final int ADDRESS_LOG = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command log.
|
|
||||||
*/
|
|
||||||
public static final int COMMAND_LOG = 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The trade log.
|
|
||||||
*/
|
|
||||||
public static final int TRADE_LOG = 5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The GE logs.
|
|
||||||
*/
|
|
||||||
public static final int GRAND_EXCHANGE_LOG = 6;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The duel stake logs.
|
|
||||||
*/
|
|
||||||
public static final int DUEL_LOG = 7;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The macro flag for a click when the client was out of focus.
|
|
||||||
*/
|
|
||||||
public static final int MF_NO_FOCUS_CLICK = 0x1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The networth of the player.
|
|
||||||
*/
|
|
||||||
private long networth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the client is currently focused.
|
|
||||||
*/
|
|
||||||
private boolean clientFocus = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How likely it is this player has used a macro.
|
|
||||||
*/
|
|
||||||
private int macroFlag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The duplication log.
|
|
||||||
*/
|
|
||||||
private DuplicationLog duplicationLog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The message monitors.
|
|
||||||
*/
|
|
||||||
private MessageLog[] logs = new MessageLog[8];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new {@code PlayerMonitor} {@code Object}.
|
|
||||||
*/
|
|
||||||
public PlayerMonitor() {
|
|
||||||
logs[PUBLIC_CHAT_LOG] = new MessageLog(500);
|
|
||||||
logs[PRIVATE_CHAT_LOG] = new MessageLog(500);
|
|
||||||
logs[CLAN_CHAT_LOG] = new MessageLog(500);
|
|
||||||
logs[ADDRESS_LOG] = new MessageLog(200);
|
|
||||||
logs[COMMAND_LOG] = new MessageLog(200);
|
|
||||||
logs[TRADE_LOG] = new MessageLog(200);
|
|
||||||
logs[GRAND_EXCHANGE_LOG] = new MessageLog(500);
|
|
||||||
logs[DUEL_LOG] = new MessageLog(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the logs.
|
|
||||||
*/
|
|
||||||
public void clear() {
|
|
||||||
for (int i = 0; i < logs.length; i++) {
|
|
||||||
if (logs[i] == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
logs[i].getMessages().clear();
|
|
||||||
}
|
|
||||||
duplicationLog.getMessages().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the player's actions should be logged.
|
|
||||||
* @return {@code True} if so.
|
|
||||||
*/
|
|
||||||
public boolean isLogActions() {
|
|
||||||
return duplicationLog != null && duplicationLog.isLoggingFlagged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs the given string.
|
|
||||||
* @param string The string to log.
|
|
||||||
* @param type The log type.
|
|
||||||
*/
|
|
||||||
public void log(String string, int type) {
|
|
||||||
log(string, type, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs the given string.
|
|
||||||
* @param string The string to log.
|
|
||||||
* @param type The log type.
|
|
||||||
* @param timeStamp If we should time stamp the logged string.
|
|
||||||
*/
|
|
||||||
public void log(String string, int type, boolean timeStamp) {
|
|
||||||
if (type < 3) {
|
|
||||||
String check = string.toLowerCase();
|
|
||||||
if (check.contains("dupe") || check.contains("duping") || check.contains("bug") || check.contains("glitch") || check.contains("exploit")) {
|
|
||||||
getDuplicationLog().flag(DuplicationLog.DUPE_TALK);
|
|
||||||
String prefix = null;
|
|
||||||
if (type == PUBLIC_CHAT_LOG) {
|
|
||||||
prefix = "Public";
|
|
||||||
} else if (type == PRIVATE_CHAT_LOG) {
|
|
||||||
prefix = "Private";
|
|
||||||
} else {
|
|
||||||
prefix = "Clan";
|
|
||||||
}
|
|
||||||
getDuplicationLog().log(prefix + " chat message: " + string, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logs[type].log(string, timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the networth difference for a player (called on logout).
|
|
||||||
* @param player The player.
|
|
||||||
* @param currentNet The current networth.
|
|
||||||
*/
|
|
||||||
public void checkNetworth(Player player, long currentNet) {
|
|
||||||
long difference = currentNet - this.networth;
|
|
||||||
if (difference < 1) { // The player lost money.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (difference > 150_000_000l) {
|
|
||||||
getDuplicationLog().flag(DuplicationLog.NW_INCREASE);
|
|
||||||
getDuplicationLog().log("Large networth increase - [incr=" + difference + ", old=" + this.networth + ", cur=" + currentNet + "].", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the player does a mouse click.
|
|
||||||
* @param x The x-coordinate of the cursor.
|
|
||||||
* @param y The y-coordinate of the cursor.
|
|
||||||
* @param delay The time between this click and last.
|
|
||||||
* @param rightClick If the right mouse-button was used to click.
|
|
||||||
*/
|
|
||||||
public void handleMouseClick(int x, int y, int delay, boolean rightClick) {
|
|
||||||
if (!clientFocus) {
|
|
||||||
macroFlag |= MF_NO_FOCUS_CLICK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the address log.
|
|
||||||
* @param original the original log.
|
|
||||||
* @param address the address.
|
|
||||||
* @return the address.
|
|
||||||
*/
|
|
||||||
public static String getAddressLog(String original, String address) {
|
|
||||||
String log = "";
|
|
||||||
if (original != null && original.length() > 0) {
|
|
||||||
log += original;
|
|
||||||
if (log.charAt(log.length() - 1) != '|') {
|
|
||||||
log += "|";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (address != null && address.length() > 0 && (original == null || !original.contains(address))) {
|
|
||||||
log += address + "|";
|
|
||||||
}
|
|
||||||
if (log.length() > 0 && log.charAt(log.length() - 1) == '|') {
|
|
||||||
log = log.substring(0, log.length() - 1);
|
|
||||||
}
|
|
||||||
if (log == null) {
|
|
||||||
log = "";
|
|
||||||
}
|
|
||||||
return log;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a macro flag.
|
|
||||||
* @param flag The flag.
|
|
||||||
*/
|
|
||||||
public void addMacroFlag(int flag) {
|
|
||||||
macroFlag |= flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the macroFlag.
|
|
||||||
* @return The macroFlag.
|
|
||||||
*/
|
|
||||||
public int getMacroFlag() {
|
|
||||||
return macroFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the macroFlag.
|
|
||||||
* @param macroFlag The macroFlag to set.
|
|
||||||
*/
|
|
||||||
public void setMacroFlag(int macroFlag) {
|
|
||||||
this.macroFlag = macroFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the networth.
|
|
||||||
* @return The networth.
|
|
||||||
*/
|
|
||||||
public long getNetworth() {
|
|
||||||
return networth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the networth.
|
|
||||||
* @param networth The networth to set.
|
|
||||||
*/
|
|
||||||
public void setNetworth(long networth) {
|
|
||||||
this.networth = networth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the clientFocus.
|
|
||||||
* @return The clientFocus.
|
|
||||||
*/
|
|
||||||
public boolean isClientFocus() {
|
|
||||||
return clientFocus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the clientFocus.
|
|
||||||
* @param clientFocus The clientFocus to set.
|
|
||||||
*/
|
|
||||||
public void setClientFocus(boolean clientFocus) {
|
|
||||||
this.clientFocus = clientFocus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the logs.
|
|
||||||
* @return The logs.
|
|
||||||
*/
|
|
||||||
public MessageLog[] getLogs() {
|
|
||||||
return logs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the duplicationLog.
|
|
||||||
* @return The duplicationLog.
|
|
||||||
*/
|
|
||||||
public DuplicationLog getDuplicationLog() {
|
|
||||||
if (duplicationLog == null) {
|
|
||||||
duplicationLog = new DuplicationLog();
|
|
||||||
}
|
|
||||||
return duplicationLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package rs09.game.content.global.action
|
package rs09.game.content.global.action
|
||||||
|
|
||||||
import api.events.PickUpEvent
|
import api.events.PickUpEvent
|
||||||
|
import api.getItemName
|
||||||
import core.game.content.dialogue.FacialExpression
|
import core.game.content.dialogue.FacialExpression
|
||||||
import core.game.content.global.GodType
|
import core.game.content.global.GodType
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
@@ -13,6 +14,7 @@ import core.game.node.item.Item
|
|||||||
import core.game.world.map.RegionManager
|
import core.game.world.map.RegionManager
|
||||||
import core.game.world.update.flag.context.Animation
|
import core.game.world.update.flag.context.Animation
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor
|
||||||
import rs09.game.system.SystemLogger
|
import rs09.game.system.SystemLogger
|
||||||
import rs09.game.system.config.GroundSpawnLoader
|
import rs09.game.system.config.GroundSpawnLoader
|
||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
@@ -55,6 +57,9 @@ object PickupHandler {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (item.isActive && player.inventory.add(add)) {
|
if (item.isActive && player.inventory.add(add)) {
|
||||||
|
if (item.dropper is Player && item.dropper.details.uid != player.details.uid){
|
||||||
|
PlayerMonitor.logMisc(item.dropper, "DropTrade", "${getItemName(item.id)} x${item.amount} picked up by ${player.name}.")
|
||||||
|
}
|
||||||
if (!RegionManager.isTeleportPermitted(item.location)) {
|
if (!RegionManager.isTeleportPermitted(item.location)) {
|
||||||
player.animate(Animation.create(535))
|
player.animate(Animation.create(535))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
package rs09.game.node.entity.player.info
|
||||||
|
|
||||||
|
import api.getItemName
|
||||||
|
import core.game.container.Container
|
||||||
|
import core.game.node.entity.player.Player
|
||||||
|
import core.game.node.entity.skill.Skills
|
||||||
|
import discord.Discord
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.sqlite.SQLiteDataSource
|
||||||
|
import rs09.ServerConstants
|
||||||
|
import rs09.game.system.SystemLogger
|
||||||
|
import java.io.File
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
object PlayerMonitor {
|
||||||
|
private val eventQueue = LinkedBlockingQueue<LogEvent>()
|
||||||
|
private var activeTask: Job? = null
|
||||||
|
|
||||||
|
@JvmStatic fun logWealthChange(player: Player, totalWealth: Long, diff: Long) {
|
||||||
|
val event = LogEvent.WealthLog(
|
||||||
|
player.name,
|
||||||
|
player.details.uid,
|
||||||
|
totalWealth,
|
||||||
|
diff,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
dispatch(event)
|
||||||
|
if (abs(diff) >= 500_000L)
|
||||||
|
Discord.postPlayerAlert(player.name, "Dubious change in wealth: $diff, total wealth: $totalWealth")
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun logChat(player: Player, type: String, message: String) {
|
||||||
|
val event = LogEvent.ChatLog(
|
||||||
|
player.name,
|
||||||
|
player.details.uid,
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
checkForFlaggedText(player.name, message)
|
||||||
|
dispatch(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun logTrade(player1: Player, player2: Player, container1: Container, container2: Container) {
|
||||||
|
val container1String = StringBuilder()
|
||||||
|
val container2String = StringBuilder()
|
||||||
|
|
||||||
|
for (item in container1.toArray()) {
|
||||||
|
item ?: continue
|
||||||
|
container1String.append(getItemName(item.id) + "(${item.amount}), ")
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item in container2.toArray()) {
|
||||||
|
item ?: continue
|
||||||
|
container2String.append(getItemName(item.id) + "(${item.amount}), ")
|
||||||
|
}
|
||||||
|
|
||||||
|
val event = LogEvent.TradeLog(
|
||||||
|
player1.name,
|
||||||
|
player1.details.uid,
|
||||||
|
player2.name,
|
||||||
|
player2.details.uid,
|
||||||
|
container1String.toString(),
|
||||||
|
container2String.toString(),
|
||||||
|
System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
dispatch(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun logPrivateChat(sender: Player, receiver: String, message: String) {
|
||||||
|
val event = LogEvent.ChatLog(
|
||||||
|
sender.name,
|
||||||
|
sender.details.uid,
|
||||||
|
"private",
|
||||||
|
"=> $receiver: $message",
|
||||||
|
System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
checkForFlaggedText(sender.name, message)
|
||||||
|
dispatch(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun logMisc(player: Player, type: String, details: String) {
|
||||||
|
val event = LogEvent.MiscLog(
|
||||||
|
player.name,
|
||||||
|
player.details.uid,
|
||||||
|
type,
|
||||||
|
details,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
dispatch(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun logXpGains(player: Player, xpDiff: List<Pair<Int,Double>>) {
|
||||||
|
if (player.isArtificial) return
|
||||||
|
if (xpDiff.isEmpty()) return
|
||||||
|
val query = StringBuilder("INSERT INTO xp_gains(player,uid,")
|
||||||
|
val xpNames = StringBuilder()
|
||||||
|
val xpAmounts = StringBuilder()
|
||||||
|
for ((skillId, amount) in xpDiff) {
|
||||||
|
xpNames.append(Skills.SKILL_NAME[skillId].lowercase() + ",")
|
||||||
|
xpAmounts.append("$amount,")
|
||||||
|
}
|
||||||
|
query.append(xpNames)
|
||||||
|
query.append("timestamp) VALUES(")
|
||||||
|
query.append("'" + player.name + "',")
|
||||||
|
query.append(player.details.uid.toString() + ",")
|
||||||
|
query.append(xpAmounts)
|
||||||
|
query.append(System.currentTimeMillis().toString())
|
||||||
|
query.append(");")
|
||||||
|
dispatch(LogEvent.XpLog(query.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dispatch(event: LogEvent) {
|
||||||
|
eventQueue.put(event)
|
||||||
|
if (eventQueue.size >= 50) {
|
||||||
|
processQueuedEvents()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processQueuedEvents() {
|
||||||
|
val path = ServerConstants.LOGS_PATH + "playerlogs.db"
|
||||||
|
if (activeTask?.isActive == true)
|
||||||
|
return
|
||||||
|
if (!File(path).exists()) {
|
||||||
|
createSqliteDatabase(path)
|
||||||
|
}
|
||||||
|
activeTask = GlobalScope.launch {
|
||||||
|
val conn = connect(path)
|
||||||
|
conn.use {
|
||||||
|
while (eventQueue.isNotEmpty()) {
|
||||||
|
val event = withContext(Dispatchers.IO) { eventQueue.take() }
|
||||||
|
process(event, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun flushRemainingEventsImmediately() {
|
||||||
|
SystemLogger.logInfo(this::class.java, "Flushing player log events...")
|
||||||
|
val path = ServerConstants.LOGS_PATH + "playerlogs.db"
|
||||||
|
if (!File(path).exists()) {
|
||||||
|
createSqliteDatabase(path)
|
||||||
|
}
|
||||||
|
if (activeTask != null)
|
||||||
|
activeTask?.cancel("Interrupted by shutdown. This is probably fine.")
|
||||||
|
val conn = connect(path)
|
||||||
|
conn.use {
|
||||||
|
while (eventQueue.isNotEmpty())
|
||||||
|
process(eventQueue.take(), it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connect(path: String) : Connection {
|
||||||
|
val source = SQLiteDataSource()
|
||||||
|
source.url = "jdbc:sqlite:$path"
|
||||||
|
return source.connection
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSqliteDatabase(path: String) {
|
||||||
|
if (!File(ServerConstants.LOGS_PATH).exists())
|
||||||
|
File(ServerConstants.LOGS_PATH).mkdirs()
|
||||||
|
val connection = connect(path)
|
||||||
|
val stmt = connection.createStatement()
|
||||||
|
stmt.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE "chat_logs" ( "player" TEXT, "uid" INTEGER, "type" TEXT, "message" TEXT, "timestamp" NUMERIC );
|
||||||
|
""")
|
||||||
|
stmt.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE "misc_logs" ( "player" TEXT, "uid" INTEGER, "type" TEXT, "details" TEXT , "timestamp" NUMERIC);
|
||||||
|
""")
|
||||||
|
stmt.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE "trade_logs" ( "player_a" TEXT, "player_b" TEXT, "uid_a" INTEGER, "uid_b" INTEGER, "items_a" TEXT, "items_b" TEXT, "timestamp" NUMERIC );
|
||||||
|
""")
|
||||||
|
stmt.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE "xp_gains" ( "player" TEXT, "uid" INTEGER, "attack" INTEGER, "defence" INTEGER, "strength" INTEGER, "hitpoints" INTEGER, "ranged" INTEGER, "prayer" INTEGER, "magic" INTEGER, "cooking" INTEGER, "woodcutting" INTEGER, "fletching" INTEGER, "fishing" INTEGER, "firemaking" INTEGER, "crafting" INTEGER, "smithing" INTEGER, "mining" INTEGER, "herblore" INTEGER, "agility" INTEGER, "thieving" INTEGER, "slayer" INTEGER, "farming" INTEGER, "runecrafting" INTEGER, "hunter" INTEGER, "construction" INTEGER, "summoning" INTEGER , "timestamp" NUMERIC)
|
||||||
|
""")
|
||||||
|
stmt.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE "wealth_logs" ( "player" TEXT, "uid" INTEGER, "total" NUMERIC, "diff" NUMERIC, "timestamp" NUMERIC )
|
||||||
|
""")
|
||||||
|
stmt.close()
|
||||||
|
connection.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun process(event: LogEvent, conn: Connection) {
|
||||||
|
when (event) {
|
||||||
|
is LogEvent.ChatLog -> {
|
||||||
|
val stmt = conn.prepareStatement(CHAT_LOG_INSERT)
|
||||||
|
stmt.setString(1, event.player)
|
||||||
|
stmt.setInt(2, event.uid)
|
||||||
|
stmt.setString(3, event.type)
|
||||||
|
stmt.setString(4, event.message)
|
||||||
|
stmt.setLong(5, event.timestamp)
|
||||||
|
stmt.execute()
|
||||||
|
}
|
||||||
|
is LogEvent.TradeLog -> {
|
||||||
|
val stmt = conn.prepareStatement(TRADE_LOG_INSERT)
|
||||||
|
stmt.setString(1, event.player1)
|
||||||
|
stmt.setString(2, event.player2)
|
||||||
|
stmt.setInt(3, event.uid1)
|
||||||
|
stmt.setInt(4, event.uid2)
|
||||||
|
stmt.setString(5, event.items1)
|
||||||
|
stmt.setString(6, event.items2)
|
||||||
|
stmt.setLong(7, event.timestamp)
|
||||||
|
stmt.execute()
|
||||||
|
}
|
||||||
|
is LogEvent.MiscLog -> {
|
||||||
|
val stmt = conn.prepareStatement(MISC_LOG_INSERT)
|
||||||
|
stmt.setString(1, event.player)
|
||||||
|
stmt.setInt(2, event.uid)
|
||||||
|
stmt.setString(3, event.type)
|
||||||
|
stmt.setString(4, event.details)
|
||||||
|
stmt.setLong(5, event.timestamp)
|
||||||
|
stmt.execute()
|
||||||
|
}
|
||||||
|
is LogEvent.XpLog -> {
|
||||||
|
val stmt = conn.createStatement()
|
||||||
|
stmt.execute(event.query)
|
||||||
|
}
|
||||||
|
is LogEvent.WealthLog -> {
|
||||||
|
val stmt = conn.prepareStatement(WEALTH_LOG_INSERT)
|
||||||
|
stmt.setString(1, event.player)
|
||||||
|
stmt.setInt(2, event.uid)
|
||||||
|
stmt.setLong(3, event.total)
|
||||||
|
stmt.setLong(4, event.diff)
|
||||||
|
stmt.setLong(5, event.timeStamp)
|
||||||
|
stmt.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkForFlaggedText(username: String, message: String) {
|
||||||
|
if (message.contains("dupe") || message.contains("bug") || message.contains("exploit") || message.contains("glitch")) {
|
||||||
|
Discord.postPlayerAlert(username, "Flagged Chat - $message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class LogEvent {
|
||||||
|
data class ChatLog(val player: String, val uid: Int, val type: String, val message: String, val timestamp: Long) : LogEvent()
|
||||||
|
data class TradeLog(val player1: String, val uid1: Int, val player2 : String, val uid2: Int, val items1: String, val items2: String, val timestamp: Long) : LogEvent()
|
||||||
|
data class MiscLog(val player: String, val uid: Int, val type: String, val details: String, val timestamp: Long) : LogEvent()
|
||||||
|
data class XpLog(val query: String) : LogEvent()
|
||||||
|
data class WealthLog(val player: String, val uid: Int, val total: Long, val diff: Long, val timeStamp: Long) : LogEvent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val CHAT_LOG_INSERT = "INSERT INTO chat_logs(player,uid,type,message,timestamp) VALUES (?,?,?,?,?);"
|
||||||
|
private const val TRADE_LOG_INSERT = "INSERT INTO trade_logs(player_a,player_b,uid_a,uid_b,items_a,items_b,timestamp) VALUES (?,?,?,?,?,?,?);"
|
||||||
|
private const val MISC_LOG_INSERT = "INSERT INTO misc_logs(player,uid,type,details,timestamp) VALUES (?,?,?,?,?);"
|
||||||
|
private const val WEALTH_LOG_INSERT = "INSERT INTO wealth_logs(player,uid,total,diff,timestamp) VALUES (?,?,?,?,?);"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import core.game.node.entity.player.info.login.LoginConfiguration
|
|||||||
import core.game.node.entity.player.info.login.PlayerParser
|
import core.game.node.entity.player.info.login.PlayerParser
|
||||||
import core.game.node.entity.player.info.login.Response
|
import core.game.node.entity.player.info.login.Response
|
||||||
import core.game.system.SystemManager
|
import core.game.system.SystemManager
|
||||||
import core.game.system.monitor.PlayerMonitor
|
|
||||||
import core.game.system.task.Pulse
|
import core.game.system.task.Pulse
|
||||||
import rs09.auth.AuthResponse
|
import rs09.auth.AuthResponse
|
||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
@@ -53,9 +52,6 @@ class LoginParser(val details: PlayerDetails) {
|
|||||||
flag(AuthResponse.Success)
|
flag(AuthResponse.Success)
|
||||||
player.init()
|
player.init()
|
||||||
}
|
}
|
||||||
player.monitor.log(player.details.ipAddress, PlayerMonitor.ADDRESS_LOG)
|
|
||||||
player.monitor.log(player.details.serial, PlayerMonitor.ADDRESS_LOG)
|
|
||||||
player.monitor.log(player.details.macAddress, PlayerMonitor.ADDRESS_LOG)
|
|
||||||
} else {
|
} else {
|
||||||
Repository.playerNames.remove(player.name)
|
Repository.playerNames.remove(player.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,19 +208,6 @@ class PlayerSaveParser(val player: Player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun parseMonitor() {
|
fun parseMonitor() {
|
||||||
val monitorData = saveFile!!["playerMonitor"] as JSONObject
|
|
||||||
if (monitorData.containsKey("duplicationFlag")) {
|
|
||||||
val duplicationFlag: Int = (monitorData.get("duplicationFlag") as String).toInt()
|
|
||||||
player.monitor.duplicationLog.flag(duplicationFlag)
|
|
||||||
}
|
|
||||||
if (monitorData.containsKey("macroFlag")) {
|
|
||||||
val macroFlag: Int = (monitorData.get("macroFlag") as String).toInt()
|
|
||||||
player.monitor.macroFlag = macroFlag
|
|
||||||
}
|
|
||||||
if (monitorData.containsKey("lastIncreaseFlag")) {
|
|
||||||
val lastIncreaseFlag: Long = (monitorData.get("lastIncreaseFlag") as String).toLong()
|
|
||||||
player.monitor.duplicationLog.lastIncreaseFlag = lastIncreaseFlag
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseConfigs() {
|
fun parseConfigs() {
|
||||||
|
|||||||
@@ -304,17 +304,7 @@ class PlayerSaver (val player: Player){
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun savePlayerMonitor(root: JSONObject){
|
fun savePlayerMonitor(root: JSONObject){
|
||||||
val playerMonitor = JSONObject()
|
|
||||||
if(player.monitor.duplicationLog != null && player.monitor.duplicationLog.flag != 0){
|
|
||||||
playerMonitor.put("duplicationFlag",player.monitor.duplicationLog.flag.toString())
|
|
||||||
}
|
|
||||||
if(player.monitor.macroFlag != 0){
|
|
||||||
playerMonitor.put("macroFlag",player.monitor.macroFlag.toString())
|
|
||||||
}
|
|
||||||
if(player.monitor.duplicationLog != null && player.monitor.duplicationLog.isLoggingFlagged){
|
|
||||||
playerMonitor.put("lastIncreaseFlag",player.monitor.duplicationLog.lastIncreaseFlag.toString())
|
|
||||||
}
|
|
||||||
root.put("playerMonitor",playerMonitor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveConfigs(root: JSONObject){
|
fun saveConfigs(root: JSONObject){
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import core.game.node.item.Item
|
|||||||
import core.game.node.scenery.Scenery
|
import core.game.node.scenery.Scenery
|
||||||
import core.game.system.communication.ClanRank
|
import core.game.system.communication.ClanRank
|
||||||
import core.game.system.communication.CommunicationInfo
|
import core.game.system.communication.CommunicationInfo
|
||||||
import core.game.system.monitor.PlayerMonitor
|
|
||||||
import core.game.system.task.Pulse
|
import core.game.system.task.Pulse
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import core.game.world.map.RegionManager
|
import core.game.world.map.RegionManager
|
||||||
@@ -54,6 +53,7 @@ import rs09.game.interaction.InteractionListeners
|
|||||||
import rs09.game.interaction.InterfaceListeners
|
import rs09.game.interaction.InterfaceListeners
|
||||||
import rs09.game.interaction.QCRepository
|
import rs09.game.interaction.QCRepository
|
||||||
import rs09.game.interaction.inter.ge.StockMarket
|
import rs09.game.interaction.inter.ge.StockMarket
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor
|
||||||
import rs09.game.node.entity.skill.magic.SpellListener
|
import rs09.game.node.entity.skill.magic.SpellListener
|
||||||
import rs09.game.node.entity.skill.magic.SpellListeners
|
import rs09.game.node.entity.skill.magic.SpellListeners
|
||||||
import rs09.game.node.entity.skill.magic.SpellUtils
|
import rs09.game.node.entity.skill.magic.SpellUtils
|
||||||
@@ -199,8 +199,8 @@ object PacketProcessor {
|
|||||||
pkt.player.interfaceManager.closeChatbox()
|
pkt.player.interfaceManager.closeChatbox()
|
||||||
}
|
}
|
||||||
is Packet.Command -> {
|
is Packet.Command -> {
|
||||||
if (CommandSystem.commandSystem.parse(pkt.player, pkt.commandLine))
|
PlayerMonitor.logMisc(pkt.player, "CommandUse", pkt.commandLine)
|
||||||
pkt.player.monitor.log(pkt.commandLine, PlayerMonitor.COMMAND_LOG)
|
CommandSystem.commandSystem.parse(pkt.player, pkt.commandLine)
|
||||||
}
|
}
|
||||||
is Packet.ChatMessage -> {
|
is Packet.ChatMessage -> {
|
||||||
if (pkt.player.details.isMuted)
|
if (pkt.player.details.isMuted)
|
||||||
@@ -215,7 +215,7 @@ object PacketProcessor {
|
|||||||
ManagementEvents.publish(builder.build())
|
ManagementEvents.publish(builder.build())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pkt.player.monitor.log(pkt.message, PlayerMonitor.PUBLIC_CHAT_LOG)
|
PlayerMonitor.logChat(pkt.player, "public", pkt.message)
|
||||||
val ctx = ChatMessage(pkt.player, pkt.message, pkt.effects, pkt.message.length)
|
val ctx = ChatMessage(pkt.player, pkt.message, pkt.effects, pkt.message.length)
|
||||||
pkt.player.updateMasks.register(ChatFlag(ctx))
|
pkt.player.updateMasks.register(ChatFlag(ctx))
|
||||||
}
|
}
|
||||||
@@ -229,6 +229,7 @@ object PacketProcessor {
|
|||||||
pkt.player.sendMessage("You have been muted due to breaking a rule.")
|
pkt.player.sendMessage("You have been muted due to breaking a rule.")
|
||||||
else
|
else
|
||||||
CommunicationInfo.sendMessage(pkt.player, pkt.username, pkt.message)
|
CommunicationInfo.sendMessage(pkt.player, pkt.username, pkt.message)
|
||||||
|
PlayerMonitor.logPrivateChat(pkt.player, pkt.username, pkt.message)
|
||||||
}
|
}
|
||||||
is Packet.PacketCountUpdate -> {
|
is Packet.PacketCountUpdate -> {
|
||||||
val final = pkt.count - pkt.player.interfaceManager.getPacketCount(0)
|
val final = pkt.count - pkt.player.interfaceManager.getPacketCount(0)
|
||||||
@@ -282,7 +283,7 @@ object PacketProcessor {
|
|||||||
|
|
||||||
private fun processTrackingPacket(pkt: Packet) {
|
private fun processTrackingPacket(pkt: Packet) {
|
||||||
when(pkt) {
|
when(pkt) {
|
||||||
is Packet.TrackingFocus -> pkt.player.monitor.isClientFocus = pkt.isFocused
|
is Packet.TrackingFocus -> {}
|
||||||
is Packet.TrackingDisplayUpdate -> {
|
is Packet.TrackingDisplayUpdate -> {
|
||||||
pkt.player.session.clientInfo.screenWidth = pkt.screenWidth
|
pkt.player.session.clientInfo.screenWidth = pkt.screenWidth
|
||||||
pkt.player.session.clientInfo.screenHeight = pkt.screenHeight
|
pkt.player.session.clientInfo.screenHeight = pkt.screenHeight
|
||||||
@@ -298,9 +299,7 @@ object PacketProcessor {
|
|||||||
}
|
}
|
||||||
is Packet.TrackingMouseClick -> {
|
is Packet.TrackingMouseClick -> {
|
||||||
//TODO see above todo
|
//TODO see above todo
|
||||||
if (!pkt.player.monitor.isClientFocus) {
|
|
||||||
Discord.postPlayerAlert(pkt.player.username, "Mouseclick without window focus!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import rs09.ServerStore
|
|||||||
import rs09.ServerStore.Companion.addToList
|
import rs09.ServerStore.Companion.addToList
|
||||||
import rs09.ServerStore.Companion.getList
|
import rs09.ServerStore.Companion.getList
|
||||||
import rs09.auth.AuthResponse
|
import rs09.auth.AuthResponse
|
||||||
|
import rs09.game.node.entity.player.info.PlayerMonitor
|
||||||
import rs09.game.node.entity.player.info.login.LoginParser
|
import rs09.game.node.entity.player.info.login.LoginParser
|
||||||
import rs09.game.system.SystemLogger
|
import rs09.game.system.SystemLogger
|
||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
@@ -131,6 +132,7 @@ object Login {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val player = Player(details)
|
val player = Player(details)
|
||||||
|
PlayerMonitor.logMisc(player, "login_ip", details.ipAddress)
|
||||||
if (canBypassAccountLimitCheck(player)) {
|
if (canBypassAccountLimitCheck(player)) {
|
||||||
proceedWithAcceptableLogin(session, player, opcode)
|
proceedWithAcceptableLogin(session, player, opcode)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user