Merge remote-tracking branch 'upstream/master'

This commit is contained in:
skelsoft
2021-07-31 12:31:53 +10:00
24 changed files with 303 additions and 147 deletions
@@ -204,6 +204,7 @@ public final class DialogueInterpreter {
public boolean close() {
if (dialogue != null || dialogueStage != null) {
actions.clear();
if (player.getInterfaceManager().getChatbox() != null && player.getInterfaceManager().getChatbox().getCloseEvent() != null) {
return true;
}
@@ -211,8 +212,10 @@ public final class DialogueInterpreter {
dialogueStage = null;
player.getInterfaceManager().closeChatbox();
}
if (dialogue != null && dialogue.close()) {
if (dialogue != null) {
DialoguePlugin d = dialogue;
dialogue = null;
d.close();
}
}
return dialogue == null && dialogueStage == null;
@@ -122,6 +122,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
public boolean close() {
player.getInterfaceManager().closeChatbox();
player.getInterfaceManager().openChatbox(137);
if(file != null) file.end();
finished = true;
return true;
}
@@ -1,54 +0,0 @@
package core.game.system.task;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
/**
* A class holding methods to execute tasks.
* @author Emperor
*/
public final class TaskExecutor {
/**
* The executor to use.
*/
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
/**
* 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;
}
}
@@ -0,0 +1,33 @@
package core.game.system.task
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* A class holding methods to execute tasks.
* @author Emperor
*/
object TaskExecutor {
/**
* Executes an SQL handling task.
* @param task The task.
*/
@JvmStatic
fun executeSQL(task: () -> Unit) {
GlobalScope.launch {
task.invoke()
}
}
/**
* Executes the task.
* @param task The task to execute.
*/
@JvmStatic
fun execute(task: () -> Unit) {
GlobalScope.launch {
task.invoke()
}
}
}
@@ -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;
});
}
@@ -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() {
TaskExecutor.executeSQL(() -> {
if (!parser.getDetails().parse()) {
parser.getDetails().getSession().write(Response.INVALID_LOGIN_SERVER, true);
return;
return Unit.INSTANCE;
}
MSPacketRepository.sendPlayerRegistry(parser);
}
return Unit.INSTANCE;
});
}
@@ -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() {
TaskExecutor.executeSQL(() -> {
try {
if (PlayerSQLManager.hasSqlAccount(username, "username")) {
response(session, RegistryResponse.NOT_AVAILBLE_USER);
return;
return Unit.INSTANCE;
}
response(session, RegistryResponse.SUCCESS);
} catch (SQLException e) {
e.printStackTrace();
}
}
return Unit.INSTANCE;
});
break;
case 36://Register details
@@ -129,13 +128,11 @@ 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() {
TaskExecutor.execute(() -> {
try {
if (PlayerSQLManager.hasSqlAccount(name, "username")) {
response(session, RegistryResponse.CANNOT_CREATE);
return;
return Unit.INSTANCE;
}
SQLEntryHandler.write(new AccountRegister(details));
response(session, RegistryResponse.SUCCESS);
@@ -143,7 +140,7 @@ public class AccountRegister extends SQLEntryHandler<RegistryDetails> {
e.printStackTrace();
response(session, RegistryResponse.CANNOT_CREATE);
}
}
return Unit.INSTANCE;
});
break;
default:
+23 -2
View File
@@ -167,6 +167,26 @@ object ContentAPI {
if(!player.inventory.add(item)) GroundItemManager.create(item,player)
}
/**
* Clears an NPC with the "poof" smoke graphics commonly seen with random event NPCs.
* @param npc the NPC object to initialize
*/
@JvmStatic
fun poofClear(npc: NPC){
submitWorldPulse(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
2 -> {
npc.isInvisible = true; Graphics.send(Graphics(86), npc.location)
}
3 -> npc.clear().also { return true }
}
return false
}
})
}
/**
* Check if an item exists in a player's bank
* @param player the player whose bank to check
@@ -545,9 +565,10 @@ object ContentAPI {
*/
@JvmStatic
fun openDialogue(player: Player, dialogue: Any, vararg args: Any) {
player.dialogueInterpreter.close()
when (dialogue) {
is Int -> player.dialogueInterpreter.open(dialogue, args)
is DialogueFile -> player.dialogueInterpreter.open(dialogue, args)
is Int -> player.dialogueInterpreter.open(dialogue, *args)
is DialogueFile -> player.dialogueInterpreter.open(dialogue, *args)
else -> SystemLogger.logErr("Invalid object type passed to openDialogue() -> ${dialogue.javaClass.simpleName}")
}
}
@@ -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
@@ -7,6 +7,8 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import rs09.game.content.activity.pestcontrol.PestControlHelper.GATE_ENTRIES
import rs09.game.content.activity.pestcontrol.PestControlHelper.getMyPestControlSession1
import rs09.game.world.GameWorld
@@ -100,7 +102,7 @@ class CombatState(val bot: PestControlTestBot) {
fun randomWalkTo(loc: Location, radius: Int) {
if(!bot.walkingQueue.isMoving) {
Executors.newSingleThreadExecutor().execute {
GlobalScope.launch {
var newloc = loc.transform(RandomFunction.random(radius, -radius),
RandomFunction.random(radius, -radius), 0)
walkToIterator(newloc)
@@ -7,6 +7,8 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import rs09.game.content.activity.pestcontrol.PestControlHelper.GATE_ENTRIES
import rs09.game.content.activity.pestcontrol.PestControlHelper.getMyPestControlSession2
import rs09.game.world.GameWorld
@@ -99,7 +101,8 @@ class CombatStateIntermediate(val bot: PestControlTestBot2) {
fun randomWalkTo(loc: Location, radius: Int) {
if(!bot.walkingQueue.isMoving) {
Executors.newSingleThreadExecutor().execute {
GlobalScope.launch {
Thread.currentThread().name = "RandomWalkToIteratorBot"
var newloc = loc.transform(RandomFunction.random(radius, -radius),
RandomFunction.random(radius, -radius), 0)
walkToIterator(newloc)
@@ -1,5 +1,6 @@
package rs09.game.content.ame
import api.ContentAPI
import core.game.interaction.MovementPulse
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
@@ -36,18 +37,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
open fun terminate(){
player.antiMacroHandler.event = null
if(initialized){
Pulser.submit(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
when(counter++){
2 -> {
isInvisible = true; Graphics.send(SMOKE_GRAPHICS, location)
}
3 -> clear().also { return true }
}
return false
}
})
ContentAPI.poofClear(this)
}
}
@@ -73,9 +63,9 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
}
override fun init() {
initialized = true
spawnLocation ?: terminate()
location = spawnLocation
initialized = true
super.init()
}
@@ -1,6 +1,8 @@
package rs09.game.content.ame.events.certer
import api.ContentAPI
import core.game.component.Component
import core.game.node.item.GroundItemManager
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
@@ -21,7 +23,7 @@ class CerterDialogue(val initial: Boolean) : DialogueFile() {
0 -> if(!isCorrect) npc("Sorry, I don't think so.").also { stage = END_DIALOGUE; player!!.antiMacroHandler.event?.terminate() } else npc("Oh yes! That's right.").also { stage++ }
1 -> {
npc("Please, take this as a thanks.")
player!!.antiMacroHandler.event?.loot!!.roll(player!!).forEach { player!!.inventory.add(it) }
player!!.antiMacroHandler.event?.loot!!.roll().forEach { ContentAPI.addItemOrDrop(player!!, it.id, it.amount) }
player!!.antiMacroHandler.event?.terminate()
stage = END_DIALOGUE
}
@@ -75,7 +75,7 @@ abstract class DialogueFile {
return player(expr, *splitLines(msg!!))
}
fun end(){
open fun end(){
if(interpreter != null) interpreter!!.close()
}
@@ -0,0 +1,98 @@
package rs09.game.content.zone
import api.ContentAPI
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.system.task.Pulse
import core.game.world.map.zone.MapZone
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneBuilder
import core.plugin.Initializable
import core.plugin.Plugin
import org.rs09.consts.NPCs
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.secondsToTicks
import java.util.concurrent.TimeUnit
@Initializable
class FarmingPatchZone : MapZone("farming patch", true), Plugin<Any> {
val playersInZone = hashMapOf<Player,Int>()
override fun configure() {
registerRegion(12083)
registerRegion(10548)
register(ZoneBorders(3594,3521,3608,3532))
ContentAPI.submitWorldPulse(zonePulse)
}
override fun newInstance(arg: Any?): Plugin<Any> {
ZoneBuilder.configure(this)
return this
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
override fun enter(e: Entity?): Boolean {
if(e is Player && playersInZone[e] == null && ContentAPI.getStatLevel(e, Skills.FARMING) <= 15) {
playersInZone[e] = 0
}
return super.enter(e)
}
override fun leave(e: Entity?, logout: Boolean): Boolean {
if(e is Player){
playersInZone.remove(e)
}
return super.enter(e)
}
val zonePulse = object : Pulse(){
override fun pulse(): Boolean {
playersInZone.toList().forEach { (player, ticks) ->
if(ticks == secondsToTicks(TimeUnit.MINUTES.toSeconds(5).toInt())){
val npc = NPC(NPCs.GITHAN_7122)
npc.location = player.location
npc.init()
npc.moveStep()
npc.face(player)
ContentAPI.openDialogue(player, SpiritDialogue(true), npc)
} else if (ticks == secondsToTicks(TimeUnit.MINUTES.toSeconds(10).toInt())){
val npc = NPC(NPCs.GITHAN_7122)
npc.location = player.location
npc.init()
npc.moveStep()
npc.face(player)
ContentAPI.openDialogue(player, SpiritDialogue(false), npc)
playersInZone.remove(player)
}
playersInZone[player] = ticks + 1
}
return false
}
}
internal class SpiritDialogue(val is5: Boolean) : DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> {
if(is5) npcl(FacialExpression.NEUTRAL, "In case you didn't know, you don't have to stand by your Farming patch. Your crops will grow even if you're not around.").also { stage++ }
else npcl(FacialExpression.NEUTRAL, " Did you know that if your Farming patch has fully grown, it will never catch disease or die? It will be perfectly safe until you choose to harvest it.").also { stage++ }
}
1 -> end()
}
}
override fun end(){
super.end()
ContentAPI.poofClear(npc ?: return)
}
}
}
@@ -1,5 +1,6 @@
package rs09.game.node.entity.skill.farming
import api.ContentAPI
import core.cache.def.impl.SceneryDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
@@ -66,12 +67,8 @@ class CropHarvester : OptionHandler() {
delay = 2
player.inventory.add(Item(plantable.harvestItem,1))
player.skills.addExperience(Skills.FARMING,plantable.harvestXP)
patch.harvestAmt--
if(patch.harvestAmt <= 0){
patch.clear()
}
return patch.harvestAmt <= 0
patch.rollLivesDecrement(ContentAPI.getDynLevel(player, Skills.FARMING), requiredItem == Items.MAGIC_SECATEURS_7409)
return patch.cropLives <= 0
}
})
@@ -4,6 +4,8 @@ import core.game.node.entity.player.Player
import core.tools.RandomFunction
import rs09.game.system.SystemLogger
import java.util.concurrent.TimeUnit
import kotlin.math.ceil
import kotlin.math.min
class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantable?, var currentGrowthStage: Int, var isDiseased: Boolean, var isDead: Boolean, var isWatered: Boolean, var nextGrowth: Long, var harvestAmt: Int, var isCheckHealth: Boolean) {
constructor(player: Player, patch: FarmingPatch) : this(player,patch,null,0,false,false,false,0L,0,false)
@@ -11,22 +13,58 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
var diseaseMod = 0
var compost = CompostType.NONE
var protectionPaid = false
var cropLives = 3
fun setNewHarvestAmount() {
if(patch.type == PatchType.ALLOTMENT){
harvestAmt = RandomFunction.random(4,17)
} else if(patch.type == PatchType.FLOWER || patch.type == PatchType.EVIL_TURNIP) {
harvestAmt = when (plantable) {
Plantable.LIMPWURT_SEED, Plantable.WOAD_SEED -> 3
else -> 1
cropLives = 3
}
fun rollLivesDecrement(farmingLevel: Int, magicSecateurs: Boolean){
if(patch.type == PatchType.HERB){
//authentic formula thanks to released data.
var herbSaveLow = when(plantable){
Plantable.GUAM_SEED -> min(24 + farmingLevel, 80)
Plantable.MARRENTILL_SEED -> min(28 + farmingLevel, 80)
Plantable.TARROMIN_SEED -> min(31 + farmingLevel, 80)
Plantable.HARRALANDER_SEED -> min(36 + farmingLevel, 80)
Plantable.GOUT_TUBER -> min(39 + farmingLevel, 80)
Plantable.RANARR_SEED -> min(39 + farmingLevel, 80)
Plantable.SPIRIT_WEED_SEED -> min(43 + farmingLevel, 80)
Plantable.TOADFLAX_SEED -> min(43 + farmingLevel, 80)
Plantable.IRIT_SEED -> min(46 + farmingLevel, 80)
Plantable.AVANTOE_SEED -> min(50 + farmingLevel, 80)
Plantable.KWUARM_SEED -> min(54 + farmingLevel, 80)
Plantable.SNAPDRAGON_SEED -> min(57 + farmingLevel, 80)
Plantable.CADANTINE_SEED -> min(60 + farmingLevel, 80)
Plantable.LANTADYME_SEED -> min(64 + farmingLevel, 80)
Plantable.DWARF_WEED_SEED -> min(67 + farmingLevel, 80)
Plantable.TORSTOL_SEED -> min(71 + farmingLevel, 80)
else -> -1
}
if(magicSecateurs) herbSaveLow = ceil(1.10 * herbSaveLow).toInt()
val rand = RandomFunction.random(256)
if(rand > herbSaveLow){
cropLives -= 1
}
} else if(patch.type == PatchType.HOPS){
harvestAmt = RandomFunction.random(3,35)
} else {
harvestAmt = RandomFunction.random(3,5)
//inauthentic formulae based on reported averages due to lack of formula
var chance = when(patch.type){
PatchType.ALLOTMENT -> 8 //average of 8 per life times 3 lives = average 24
PatchType.HOPS -> 6 //average of 6 per life times 3 lives = 18
PatchType.BELLADONNA -> 2 //average of 2 per life times 3 lives = 6
PatchType.CACTUS -> 3 //average of 3 per life times 3 lives = 9
else -> return
}
if(compost == CompostType.NORMAL) harvestAmt += 1
if(compost == CompostType.SUPER) harvestAmt += 2
if(magicSecateurs) chance += ceil(1.10 * chance).toInt() //will increase average yield by roughly 3.
if(RandomFunction.roll(chance)) cropLives -= 1
}
if(cropLives <= 0) clear()
}
fun isWeedy(): Boolean {
@@ -82,6 +120,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
if(isDead) player.varpManager.get(patch.varpIndex).setVarbit(patch.varpOffset, getCactusDeathValue())
else if(isDiseased && !isDead) player.varpManager.get(patch.varpIndex).setVarbit(patch.varpOffset, getCactusDiseaseValue())
}
PatchType.HERB -> {
if(isDead) player.varpManager.get(patch.varpIndex).setVarbit(patch.varpOffset, getHerbDeathValue())
else if(isDiseased && !isDead) player.varpManager.get(patch.varpIndex).setVarbit(patch.varpOffset, getHerbDiseaseValue())
else player.varpManager.get(patch.varpIndex).setVarbit(patch.varpOffset, (plantable?.value ?: 0) + currentGrowthStage)
}
else -> {}
}
}
@@ -144,6 +187,22 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
return (plantable?.value ?: 0) + currentGrowthStage + 16
}
private fun getHerbDiseaseValue(): Int {
return if (plantable?.value ?: -1 <= 103) {
128 + (((plantable?.ordinal ?: 0) - Plantable.GUAM_SEED.ordinal) * 3) + currentGrowthStage - 1
} else if (plantable == Plantable.SPIRIT_WEED_SEED) {
211 + currentGrowthStage - 1
} else {
198 + currentGrowthStage -1
}
}
private fun getHerbDeathValue(): Int {
return if(plantable == Plantable.GOUT_TUBER){
201 + currentGrowthStage - 1
} else 170 + currentGrowthStage - 1
}
private fun grow(){
if(isWeedy() && getCurrentState() > 0) {
nextGrowth = System.currentTimeMillis() + 60000
@@ -164,8 +223,8 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
}
if(RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP){
//bush, tree, fruit tree and cactus can not disease on stage 1(0) of growth.
if(!((patch.type == PatchType.BUSH || patch.type == PatchType.TREE || patch.type == PatchType.FRUIT_TREE || patch.type == PatchType.CACTUS) && currentGrowthStage == 0)) {
//bush, tree, fruit tree, herb and cactus can not disease on stage 1(0) of growth.
if(!((patch.type == PatchType.BUSH || patch.type == PatchType.TREE || patch.type == PatchType.FRUIT_TREE || patch.type == PatchType.CACTUS || patch.type == PatchType.HERB) && currentGrowthStage == 0)) {
isDiseased = true
return
}
@@ -63,17 +63,18 @@ enum class Plantable(val itemID: Int, val value: Int, val stages: Int, val plant
MARRENTILL_SEED(5292,11,4,13.5,15.0,0.0,14,PatchType.HERB,Items.GRIMY_MARRENTILL_201),
TARROMIN_SEED(5293,18,4,16.0,18.0,0.0,19,PatchType.HERB,Items.GRIMY_TARROMIN_203),
HARRALANDER_SEED(5294,25,4,21.5,24.0,0.0,26,PatchType.HERB,Items.GRIMY_HARRALANDER_205),
GOUT_TUBER(6311,32,4,105.0,45.0,0.0,29,PatchType.HERB,Items.GOUTWEED_3261),
RANARR_SEED(5295,39,4,27.0,30.5,0.0,32,PatchType.HERB,Items.GRIMY_RANARR_207),
TOADFLAX_SEED(5296,47,4,34.0,38.5,0.0,38,PatchType.HERB,Items.GRIMY_TOADFLAX_3049),
IRIT_SEED(5297,54,4,43.0,48.5,0.0,44,PatchType.HERB,Items.GRIMY_IRIT_209),
AVANTOE_SEED(5298,204,4,54.5,61.5,0.0,50,PatchType.HERB,Items.GRIMY_AVANTOE_211),
RANARR_SEED(5295,32,4,27.0,30.5,0.0,32,PatchType.HERB,Items.GRIMY_RANARR_207),
AVANTOE_SEED(5298,39,4,54.5,61.5,0.0,50,PatchType.HERB,Items.GRIMY_AVANTOE_211),
TOADFLAX_SEED(5296,46,4,34.0,38.5,0.0,38,PatchType.HERB,Items.GRIMY_TOADFLAX_3049),
IRIT_SEED(5297,53,4,43.0,48.5,0.0,44,PatchType.HERB,Items.GRIMY_IRIT_209),
KWUARM_SEED(5299,68,4,69.0,78.0,0.0,56,PatchType.HERB,Items.GRIMY_KWUARM_213),
SNAPDRAGON_SEED(5300,75,4,87.5,98.5,0.0,62,PatchType.HERB,Items.GRIMY_SNAPDRAGON_3051),
CADANTINE_SEED(5301,82,4,106.5,120.0,0.0,67,PatchType.HERB,Items.GRIMY_CADANTINE_215),
LANTADYME_SEED(5302,89,4,134.5,151.5,0.0,73,PatchType.HERB,Items.GRIMY_LANTADYME_2485),
DWARF_WEED_SEED(5303,96,4,170.5,192.0,0.0,79,PatchType.HERB,Items.GRIMY_DWARF_WEED_217),
TORSTOL_SEED(5304,103,4,199.5,224.5,0.0,85,PatchType.HERB,Items.GRIMY_TORSTOL_219),
GOUT_TUBER(6311,192,4,105.0,45.0,0.0,29,PatchType.HERB,Items.GOUTWEED_3261),
SPIRIT_WEED_SEED(12176, 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB, Items.GRIMY_SPIRIT_WEED_12174),
//Other
BELLADONNA_SEED(5281, 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA, Items.CAVE_NIGHTSHADE_2398),
@@ -128,6 +128,7 @@ object UseWithPatchHandler{
if(p.plantable != null){
p.harvestAmt += if(p.compost == CompostType.NORMAL) 1 else if(p.compost == CompostType.SUPER) 2 else 0
}
p.cropLives += if(p.compost == CompostType.SUPER) 2 else 1
player.inventory.add(Item(Items.BUCKET_1925))
}
return true
@@ -50,6 +50,7 @@ class FarmingState(player: Player? = null) : State(player) {
p.put("patch-checkHealth",patch.isCheckHealth)
p.put("patch-compost",patch.compost.ordinal)
p.put("patch-paidprot",patch.protectionPaid)
p.put("patch-croplives", patch.cropLives)
patches.add(p)
}
val bins = JSONArray()
@@ -91,10 +92,12 @@ class FarmingState(player: Player? = null) : State(player) {
val savedState = p["patch-state"].toString().toInt()
val compostOrdinal = p["patch-compost"].toString().toInt()
val protectionPaid = p["patch-paidprot"] as Boolean
val cropLives = if(p["patch-croplives"] != null) p["patch-croplives"].toString().toInt() else 3
val fPatch = FarmingPatch.values()[patchOrdinal]
val plantable = if(patchPlantableOrdinal != -1) Plantable.values()[patchPlantableOrdinal] else null
val patch = Patch(player,fPatch,plantable,patchStage,patchDiseased,patchDead,patchWatered,nextGrowth,harvestAmt,checkHealth)
patch.cropLives = cropLives
patch.compost = CompostType.values()[compostOrdinal]
patch.protectionPaid = protectionPaid
patch.setCurrentState(savedState)
@@ -15,6 +15,7 @@ object ImmerseWorld {
@JvmStatic
fun init() {
Executors.newSingleThreadExecutor().execute {
Thread.currentThread().name = "BotSpawner"
immerseSeersAndCatherby()
immerseLumbridgeDraynor()
immerseVarrock()
@@ -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)
@@ -8,6 +8,8 @@ import core.game.world.repository.InitializingNodeList
import core.net.packet.PacketRepository
import core.net.packet.context.PlayerContext
import core.net.packet.out.ClearMinimapFlag
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import rs09.game.world.repository.Repository
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
@@ -58,7 +60,7 @@ class UpdateSequence
fun run() {
val latch = CountDownLatch(renderablePlayers.size)
playersList!!.forEach(Consumer { player: Player ->
EXECUTOR.execute {
GlobalScope.launch {
try {
player.update()
} catch (t: Throwable) {
@@ -89,7 +91,6 @@ class UpdateSequence
* Terminates the update sequence.
*/
fun terminate() {
EXECUTOR.shutdown()
}
companion object {
@@ -103,11 +104,5 @@ class UpdateSequence
@JvmStatic
val renderablePlayers = InitializingNodeList<Player>()
/**
* The executor used.
*/
@JvmStatic
private val EXECUTOR = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
}
}
@@ -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()}
}
}