Large improvements to server stability

This commit is contained in:
ceikry 2021-07-30 10:49:49 -05:00
parent 88cca3dea8
commit d618239e0a
9 changed files with 67 additions and 86 deletions

View file

@ -1,54 +1,33 @@
package core.game.system.task;
package core.game.system.task
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* A class holding methods to execute tasks.
* @author Emperor
*/
public final class TaskExecutor {
object TaskExecutor {
/**
* The executor to use.
*/
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
/**
* Executes an SQL handling task.
* @param task The task.
*/
@JvmStatic
fun executeSQL(task: () -> Unit) {
GlobalScope.launch {
task.invoke()
}
}
/**
* The SQL task executor.
*/
private static final ScheduledExecutorService SQL_EXECUTOR = Executors.newSingleThreadScheduledExecutor();
/**
* Constructs a new {@code TaskExecutor} {@code Object}.
*/
private TaskExecutor() {
/*
* empty.
*/
}
/**
* Executes an SQL handling task.
* @param task The task.
*/
public static void executeSQL(Runnable task) {
SQL_EXECUTOR.execute(task);
}
/**
* Executes the task.
* @param task The task to execute.
*/
public static void execute(Runnable task) {
EXECUTOR.execute(task);
}
/**
* Gets the executor.
* @return The executor.
*/
public static ScheduledExecutorService getExecutor() {
return EXECUTOR;
}
/**
* Executes the task.
* @param task The task to execute.
*/
@JvmStatic
fun execute(task: () -> Unit) {
GlobalScope.launch {
task.invoke()
}
}
}

View file

@ -10,6 +10,7 @@ import core.gui.ConsoleFrame;
import core.gui.ConsoleTab;
import core.tools.PlayerLoader;
import core.tools.StringUtils;
import kotlin.Unit;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
@ -417,6 +418,7 @@ public final class UtilityTab extends ConsoleTab {
populating = true;
players.clear();
TaskExecutor.execute(() -> {
Thread.currentThread().setName("Utility Tab");
ConsoleFrame.getInstance().getPlayerTab().getPlayerNames().clear();
ConsoleFrame.getInstance().getPlayerTab().populatePlayerSearch();
for (String name : ConsoleFrame.getInstance().getPlayerTab().getPlayerNames()) {
@ -435,6 +437,7 @@ public final class UtilityTab extends ConsoleTab {
populating = false;
System.gc();
lblPlayersLoaded.setText("Players loaded: " + players.size());
return Unit.INSTANCE;
});
}

View file

@ -7,6 +7,7 @@ import core.net.EventProducer;
import core.net.IoSession;
import core.net.NioReactor;
import core.net.producer.MSHSEventProducer;
import kotlin.Unit;
import rs09.game.node.entity.player.info.login.LoginParser;
import rs09.game.system.SystemLogger;
import rs09.game.world.GameWorld;
@ -76,15 +77,13 @@ public final class WorldCommunicator {
return;
}
loginAttempts.put(parser.getDetails().getUsername(), parser);
TaskExecutor.executeSQL(new Runnable() {
@Override
public void run() {
if (!parser.getDetails().parse()) {
parser.getDetails().getSession().write(Response.INVALID_LOGIN_SERVER, true);
return;
}
MSPacketRepository.sendPlayerRegistry(parser);
TaskExecutor.executeSQL(() -> {
if (!parser.getDetails().parse()) {
parser.getDetails().getSession().write(Response.INVALID_LOGIN_SERVER, true);
return Unit.INSTANCE;
}
MSPacketRepository.sendPlayerRegistry(parser);
return Unit.INSTANCE;
});
}

View file

@ -8,6 +8,7 @@ import core.game.system.mysql.SQLManager;
import core.game.system.task.TaskExecutor;
import core.net.Constants;
import core.net.IoSession;
import kotlin.Unit;
import rs09.ServerConstants;
import rs09.game.system.SystemLogger;
import rs09.game.world.GameWorld;
@ -76,19 +77,17 @@ public class AccountRegister extends SQLEntryHandler<RegistryDetails> {
break;
}
System.out.println(username);
TaskExecutor.executeSQL(new Runnable() {
@Override
public void run() {
try {
if (PlayerSQLManager.hasSqlAccount(username, "username")) {
response(session, RegistryResponse.NOT_AVAILBLE_USER);
return;
}
response(session, RegistryResponse.SUCCESS);
} catch (SQLException e) {
e.printStackTrace();
TaskExecutor.executeSQL(() -> {
try {
if (PlayerSQLManager.hasSqlAccount(username, "username")) {
response(session, RegistryResponse.NOT_AVAILBLE_USER);
return Unit.INSTANCE;
}
response(session, RegistryResponse.SUCCESS);
} catch (SQLException e) {
e.printStackTrace();
}
return Unit.INSTANCE;
});
break;
case 36://Register details
@ -129,21 +128,19 @@ public class AccountRegister extends SQLEntryHandler<RegistryDetails> {
buffer.getInt();
@SuppressWarnings("deprecation")
final RegistryDetails details = new RegistryDetails(name, SystemManager.getEncryption().hashPassword(password), new Date(year, month, day), country);
TaskExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (PlayerSQLManager.hasSqlAccount(name, "username")) {
response(session, RegistryResponse.CANNOT_CREATE);
return;
}
SQLEntryHandler.write(new AccountRegister(details));
response(session, RegistryResponse.SUCCESS);
} catch (SQLException e) {
e.printStackTrace();
TaskExecutor.execute(() -> {
try {
if (PlayerSQLManager.hasSqlAccount(name, "username")) {
response(session, RegistryResponse.CANNOT_CREATE);
return Unit.INSTANCE;
}
SQLEntryHandler.write(new AccountRegister(details));
response(session, RegistryResponse.SUCCESS);
} catch (SQLException e) {
e.printStackTrace();
response(session, RegistryResponse.CANNOT_CREATE);
}
return Unit.INSTANCE;
});
break;
default:

View file

@ -340,7 +340,7 @@ class ScriptAPI(private val bot: Player) {
*/
fun walkTo(loc: Location){
if(!bot.walkingQueue.isMoving) {
Executors.newSingleThreadExecutor().execute {
GlobalScope.launch {
walkToIterator(loc)
}
}
@ -645,7 +645,7 @@ class ScriptAPI(private val bot: Player) {
* @return true if item was successfully bought, false if not.
*/
fun buyFromGE(bot: Player, itemID: Int, amount: Int){
Executors.newSingleThreadExecutor().execute{
GlobalScope.launch {
val offer = GrandExchangeOffer()
offer.itemID = itemID
offer.sell = false

View file

@ -100,6 +100,7 @@ class CombatStateIntermediate(val bot: PestControlTestBot2) {
fun randomWalkTo(loc: Location, radius: Int) {
if(!bot.walkingQueue.isMoving) {
Executors.newSingleThreadExecutor().execute {
Thread.currentThread().name = "RandomWalkToIteratorBot"
var newloc = loc.transform(RandomFunction.random(radius, -radius),
RandomFunction.random(radius, -radius), 0)
walkToIterator(newloc)

View file

@ -15,6 +15,7 @@ object ImmerseWorld {
@JvmStatic
fun init() {
Executors.newSingleThreadExecutor().execute {
Thread.currentThread().name = "BotSpawner"
immerseSeersAndCatherby()
immerseLumbridgeDraynor()
immerseVarrock()

View file

@ -2,9 +2,6 @@ package rs09.game.world.repository
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.login.PlayerParser
import core.game.system.mysql.SQLEntryHandler
import core.game.system.mysql.impl.HighscoreSQLHandler
import core.game.system.mysql.impl.PlayerLogSQLHandler
import core.game.system.task.TaskExecutor
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
@ -71,7 +68,10 @@ class DisconnectionQueue {
return true
}
if (!force) {
TaskExecutor.executeSQL { save(player, true) }
TaskExecutor.executeSQL {
Thread.currentThread().name = "PlayerSave SQL"
save(player, true)
}
return true
}
save(player, false)

View file

@ -103,21 +103,22 @@ class LoginReadEvent
session.isaacPair = ISAACPair(inCipher, outCipher)
session.clientInfo = ClientInfo(displayMode, windowMode, screenWidth, screenHeight)
val b = buffer
TaskExecutor.executeSQL(Runnable {
TaskExecutor.executeSQL {
Thread.currentThread().name = "Login Password Response"
try {
val username = StringUtils.longToString(b.long)
val password = ByteBufferUtils.getString(b)
val response = PlayerSQLManager.getCredentialResponse(username, password)
if (response != Response.SUCCESSFUL) {
session.write(response, true)
return@Runnable
return@executeSQL
}
login(PlayerDetails(username, password), session, b, opcode)
} catch (e: Exception) {
e.printStackTrace()
session.write(Response.COULD_NOT_LOGIN)
}
})
}
}
/**
@ -138,7 +139,7 @@ class LoginReadEvent
if (WorldCommunicator.isEnabled()) {
WorldCommunicator.register(parser)
} else {
TaskExecutor.executeSQL(parser)
TaskExecutor.executeSQL {parser.run()}
}
}