diff --git a/Server/db_exports/global.sql b/Server/db_exports/global.sql
index 3a706c489..0b5e21b74 100644
--- a/Server/db_exports/global.sql
+++ b/Server/db_exports/global.sql
@@ -17,70 +17,6 @@ SET time_zone = "+00:00";
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
---
--- Database: `global`
---
-
--- --------------------------------------------------------
-
---
--- Table structure for table `dev_log`
---
-
-CREATE TABLE `dev_log` (
- `id` int(11) UNSIGNED NOT NULL,
- `username` varchar(15) DEFAULT NULL,
- `content` longtext NOT NULL,
- `date` timestamp NULL DEFAULT '0000-00-00 00:00:00'
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `highscores`
---
-
-CREATE TABLE `highscores` (
- `id` int(11) UNSIGNED NOT NULL,
- `username` varchar(20) DEFAULT NULL,
- `overall_xp` int(11) NOT NULL DEFAULT 0,
- `total_level` int(11) NOT NULL DEFAULT 0,
- `ironManMode` varchar(15) NOT NULL DEFAULT 'NONE',
- `xp_0` int(11) NOT NULL DEFAULT 0,
- `xp_1` int(11) NOT NULL DEFAULT 0,
- `xp_2` int(11) NOT NULL DEFAULT 0,
- `xp_3` int(11) NOT NULL DEFAULT 0,
- `xp_4` int(11) NOT NULL DEFAULT 0,
- `xp_5` int(11) NOT NULL DEFAULT 0,
- `xp_6` int(11) NOT NULL DEFAULT 0,
- `xp_7` int(11) NOT NULL DEFAULT 0,
- `xp_8` int(11) NOT NULL DEFAULT 0,
- `xp_9` int(11) NOT NULL DEFAULT 0,
- `xp_10` int(11) NOT NULL DEFAULT 0,
- `xp_11` int(11) NOT NULL DEFAULT 0,
- `xp_12` int(11) NOT NULL DEFAULT 0,
- `xp_13` int(11) NOT NULL DEFAULT 0,
- `xp_14` int(11) NOT NULL DEFAULT 0,
- `xp_15` int(11) NOT NULL DEFAULT 0,
- `xp_16` int(11) NOT NULL DEFAULT 0,
- `xp_17` int(11) NOT NULL DEFAULT 0,
- `xp_18` int(11) NOT NULL DEFAULT 0,
- `xp_19` int(11) NOT NULL DEFAULT 0,
- `xp_20` int(11) NOT NULL DEFAULT 0,
- `xp_21` int(11) NOT NULL DEFAULT 0,
- `xp_22` int(11) NOT NULL DEFAULT 0,
- `xp_23` int(11) NOT NULL DEFAULT 0
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
---
--- Dumping data for table `highscores`
---
-
-INSERT INTO `highscores` (`id`, `username`, `overall_xp`, `total_level`, `ironManMode`, `xp_0`, `xp_1`, `xp_2`, `xp_3`, `xp_4`, `xp_5`, `xp_6`, `xp_7`, `xp_8`, `xp_9`, `xp_10`, `xp_11`, `xp_12`, `xp_13`, `xp_14`, `xp_15`, `xp_16`, `xp_17`, `xp_18`, `xp_19`, `xp_20`, `xp_21`, `xp_22`, `xp_23`) VALUES
-(9, 'woah', 1154, 33, 'NONE', 0, 0, 0, 1154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
-(10, 'test', 1154, 33, 'NONE', 0, 0, 0, 1154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
-(11, 'woahscam', 1154, 33, 'NONE', 0, 0, 0, 1154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
-- --------------------------------------------------------
--
@@ -135,194 +71,6 @@ CREATE TABLE `members` (
`posts` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
---
--- Dumping data for table `members`
---
-
-INSERT INTO `members` (`UID`, `email`, `username`, `password`, `salt`, `rights`, `email_activated`, `lastActive`, `donatorType`, `donationTotal`, `credits`, `icon`, `perks`, `ip`, `mac`, `serial`, `computerName`, `monthlyVotes`, `netWorth`, `forumUID`, `ironManMode`, `bank`, `inventory`, `equipment`, `ge`, `muteTime`, `banTime`, `profileImage`, `contacts`, `blocked`, `clanName`, `currentClan`, `clanReqs`, `disconnectTime`, `lastWorld`, `chatSettings`, `timePlayed`, `lastLogin`, `lastGameIp`, `countryCode`, `birthday`, `online`, `signature`, `joined_date`, `posts`) VALUES
-(0, '', '2009Scape', '$2a$12$P0OU2A5S.lEYdkTq5kq3/u1UlfVkMYIS7WWbxsjjeyfxqTDbygpEe', '$2a$12$P0OU2A5S.lEYdkTq5kq3/u', 2, 0, '2019-11-06 00:29:03', 0, 0.00, 0, 0, '', '127.0.0.1', NULL, NULL, 'SERVER', 0, 0, -1, 'STANDARD', NULL, NULL, NULL, NULL, -1, -1, '', '', '', '2009Scape', '2009Scape', '0,0,8,9', 1572999889084, 1, '0,0,0', NULL, 1572999890885, '127.0.0.1', 0, NULL, 0, NULL, NULL, 0);
-
--- --------------------------------------------------------
-
---
--- Table structure for table `messages`
---
-
-CREATE TABLE `messages` (
- `id` int(11) UNSIGNED NOT NULL,
- `sender` varchar(15) NOT NULL DEFAULT '',
- `recipient` varchar(15) NOT NULL DEFAULT '',
- `subject` varchar(40) NOT NULL DEFAULT '',
- `content` longtext NOT NULL,
- `date` timestamp NOT NULL DEFAULT current_timestamp(),
- `is_read` tinyint(1) NOT NULL,
- `s_delete` tinyint(11) NOT NULL,
- `r_delete` tinyint(1) NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `perks`
---
-
-CREATE TABLE `perks` (
- `product_id` int(10) UNSIGNED NOT NULL,
- `name` varchar(100) NOT NULL DEFAULT 'No Name',
- `description` varchar(500) DEFAULT NULL,
- `price` int(10) NOT NULL DEFAULT 0
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
---
--- Dumping data for table `perks`
---
-
-INSERT INTO `perks` (`product_id`, `name`, `description`, `price`) VALUES
-(2, 'Stamina Boost', 'Increase your stamina and run regeneration by a total of 40%.', 60),
-(4, 'Green Thumb', 'With a 35% lifetime increase in your crops growing up healthy, they will be saved and you will also receive a better crop yield!', 100),
-(5, 'Bird Man', 'Increase your rate of receiving a bird nest drop by 35%!', 50),
-(6, 'Stoner', 'Increase your rate of receiving a gem stone drop by 35%!', 50),
-(11, 'Unbreakable Forge', 'Ring of forging never breaks.', 30),
-(12, 'Out of Grave Danger', 'Your gravestone will last up to twice as long with this perk.', 50),
-(13, 'Sleight of Hand', 'With sleight of hand you will increase your success rates in all aspects of thieving. This includes pickpocketing and cracking wall safes for gems.', 50),
-(14, 'Master Chef', 'As a soon to be Master Chef, you will receive a 20% increase in successfully cooking your food!', 50),
-(16, 'Divine Intervention', 'The gods above intervene with your burying of bones. You have a 10% chance while burying a bone to keep it instead.', 70),
-(17, 'Familiar Whisperer', 'Get to know your familiar better by increasing their lifespan by 50%.', 70),
-(18, 'Barrows Befriender', 'Befriend the barrows brothers & never experience the wretched degrading of their armour again', 300),
-(19, 'Abyss Befriender', 'Use the power of the abyss to make your Runecrafting pouches undegradable.', 150),
-(21, 'Charge Befriender', 'The God\'s of the Hero\'s guild have blessed you with the power to use your jewerly free of charge.', 250),
-(22, 'Golden Needle', 'Gain an extra 10% experience whilst spinning something on a spinning wheel, including flax. Creating an item made out of dragonhide rewards an extra 5% experience. Your crafting needle also never breaks and thread is consumed less often.\n', 50),
-(24, 'Slayer Betrayer', 'Obtain the ability through the Slayer Masters to change your slayer task at will. Type ::cleartask to use.', 100),
-(26, 'Thirst Quencher', 'The gods have blessed you with the knowledge of the deserts to gain the skills required to tap into an unlimited water supply.', 30),
-(27, 'Double Trouble', 'Experience a chance of receiving double the resources through skills such as, mining, woodcutting, fishing, and many more.', 250),
-(29, 'Godwars Befriender', 'Now blessed by the gods you have the ability to enter the chambers with a killcount of 30. You will also be granted half the time it takes to recharge at an altar.', 100),
-(30, 'Prayer Betrayer', 'Experience half the prayer drain rate when this perk is enabled.', 150),
-(31, 'Spell Swap', 'The ability to swap spell books without any charge of runes. Cannot be used in combat or in the wilderness.', 80),
-(32, 'Dwarf Befriender', 'Befriended by the dwarfs you now have the ability to use double the cannon balls and experience no decay on your cannon.', 150),
-(33, 'Powerpoint', 'This perk grants you double the points in all minigames.', 300),
-(35, 'Charm Collector', 'Through the power of summoning you will automatically pick up any charms dropped in battle.', 100),
-(36, 'Detective', 'You now have a solid 10% chance of a clue scroll drop from any monster that drops clues as well as a 50% better chance of super rare rewards such as 3rd age. You\'ll also experience a 50% increased chance to obtain more loot.', 250),
-(40, 'Overcharge', 'The power from the overcharge lords is given to you. Your Dragonfire Shield will recharge fully every 10 minutes. The time between casts is also reduced by 50%.', 170),
-(41, 'Unbreakable Crystal', 'This perk allows for your crystal bow to never degrade.', 350),
-(42, 'Crusader', 'With this perk you will have a 25% chance to double loot the barrows chest.', 100),
-(43, 'Pet Befriender', 'This perk gives you the ability to double your chances on getting boss/skilling pets!', 100),
-(60, 'Bone Crusher', 'Automatically crushes your bones as they\'re dropped for prayer experience. Toggle this perk using ::bonecrusher', 100),
-(70, 'Runestone Knowledge', 'You are given extended knowledge of the runecrafting skill and can now craft double death, law, cosmic, blood and nature runes.', 200),
-(71, 'Coin machine', 'Automatically bank all coins dropped from NPC\'s and gives you 25% extra gold. Toggle this perk using ::coinmachine', 150),
-(72, 'Fight Cave Fanatic', 'Eliminates the first 25 waves from the tzhaar fight caves.', 50),
-(73, 'Decanter', 'Zahur will decant your noted potions if you have this perk.', 50);
-
--- --------------------------------------------------------
-
---
--- Table structure for table `player_logs`
---
-
-CREATE TABLE `player_logs` (
- `username` varchar(22) NOT NULL DEFAULT '',
- `public_chat` longtext DEFAULT NULL,
- `private_chat` longtext DEFAULT NULL,
- `clan_chat` longtext DEFAULT NULL,
- `address_log` longtext DEFAULT NULL,
- `command_log` longtext DEFAULT NULL,
- `trade_log` longtext DEFAULT NULL,
- `ge_log` longtext DEFAULT NULL,
- `duplication_log` longtext DEFAULT NULL,
- `duel_log` longtext DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
---
--- Dumping data for table `player_logs`
---
-
-INSERT INTO `player_logs` (`username`, `public_chat`, `private_chat`, `clan_chat`, `address_log`, `command_log`, `trade_log`, `ge_log`, `duplication_log`, `duel_log`) VALUES
-('test', '', '', '', '10/09/2020 14:44:20: 127.0.0.1\n10/09/2020 14:44:20: I116264190\n10/09/2020 14:44:20: 30-9C-23-87-89-8E\n10/09/2020 14:47:49: 127.0.0.1\n10/09/2020 14:47:49: I116264190\n10/09/2020 14:47:49: 30-9C-23-87-89-8E\n10/09/2020 16:26:44: 127.0.0.1\n10/09/2020 16:26:44: I116264190\n10/09/2020 16:26:44: 30-9C-23-87-89-8E\n', '', '', '', '', ''),
-('woah', '10/09/2020 14:35:41: a\\\n10/09/2020 14:47:59: a\n10/09/2020 16:26:56: ok\n', '', '', '10/09/2020 14:34:50: 127.0.0.1\n10/09/2020 14:34:50: I116264190\n10/09/2020 14:34:50: 30-9C-23-87-89-8E\n10/09/2020 14:37:33: 127.0.0.1\n10/09/2020 14:37:33: I116264190\n10/09/2020 14:37:33: 30-9C-23-87-89-8E\n10/09/2020 14:39:09: 127.0.0.1\n10/09/2020 14:39:09: I116264190\n10/09/2020 14:39:09: 30-9C-23-87-89-8E\n10/09/2020 14:41:11: 127.0.0.1\n10/09/2020 14:41:11: I116264190\n10/09/2020 14:41:11: 30-9C-23-87-89-8E\n10/09/2020 14:47:23: 127.0.0.1\n10/09/2020 14:47:23: I116264190\n10/09/2020 14:47:23: 30-9C-23-87-89-8E\n10/09/2020 16:26:23: 127.0.0.1\n10/09/2020 16:26:23: I116264190\n10/09/2020 16:26:23: 30-9C-23-87-89-8E\n10/09/2020 16:35:53: 127.0.0.1\n10/09/2020 16:35:53: I116264190\n10/09/2020 16:35:53: 30-9C-23-87-89-8E\n10/09/2020 17:43:03: 127.0.0.1\n10/09/2020 17:43:03: I116264190\n10/09/2020 17:43:03: 30-9C-23-87-89-8E\n10/09/2020 18:16:22: 127.0.0.1\n10/09/2020 18:16:22: I116264190\n10/09/2020 18:16:22: 30-9C-23-87-89-8E\n10/09/2020 18:24:25: 127.0.0.1\n10/09/2020 18:24:25: I116264190\n10/09/2020 18:24:25: 30-9C-23-87-89-8E\n10/09/2020 18:25:02: 127.0.0.1\n10/09/2020 18:25:02: I116264190\n10/09/2020 18:25:02: 30-9C-23-87-89-8E\n10/09/2020 18:27:39: 127.0.0.1\n10/09/2020 18:27:39: I116264190\n10/09/2020 18:27:39: 30-9C-23-87-89-8E\n10/09/2020 18:28:28: 127.0.0.1\n10/09/2020 18:28:28: I116264190\n10/09/2020 18:28:28: 30-9C-23-87-89-8E\n10/09/2020 18:31:56: 127.0.0.1\n10/09/2020 18:31:56: I116264190\n10/09/2020 18:31:56: 30-9C-23-87-89-8E\n10/09/2020 18:34:27: 127.0.0.1\n10/09/2020 18:34:27: I116264190\n10/09/2020 18:34:27: 30-9C-23-87-89-8E\n10/09/2020 18:36:06: 127.0.0.1\n10/09/2020 18:36:06: I116264190\n10/09/2020 18:36:06: 30-9C-23-87-89-8E\n10/09/2020 18:37:02: 127.0.0.1\n10/09/2020 18:37:02: I116264190\n10/09/2020 18:37:02: 30-9C-23-87-89-8E\n10/09/2020 18:40:32: 127.0.0.1\n10/09/2020 18:40:32: I116264190\n10/09/2020 18:40:32: 30-9C-23-87-89-8E\n10/09/2020 18:41:16: 127.0.0.1\n10/09/2020 18:41:16: I116264190\n10/09/2020 18:41:16: 30-9C-23-87-89-8E\n10/09/2020 18:43:15: 127.0.0.1\n10/09/2020 18:43:15: I116264190\n10/09/2020 18:43:15: 30-9C-23-87-89-8E\n10/09/2020 18:43:58: 127.0.0.1\n10/09/2020 18:43:58: I116264190\n10/09/2020 18:43:58: 30-9C-23-87-89-8E\n10/09/2020 18:47:42: 127.0.0.1\n10/09/2020 18:47:42: I116264190\n10/09/2020 18:47:42: 30-9C-23-87-89-8E\n10/09/2020 18:49:57: 127.0.0.1\n10/09/2020 18:49:57: I116264190\n10/09/2020 18:49:57: 30-9C-23-87-89-8E\n10/09/2020 18:52:37: 127.0.0.1\n10/09/2020 18:52:37: I116264190\n10/09/2020 18:52:37: 30-9C-23-87-89-8E\n10/09/2020 23:12:58: 127.0.0.1\n10/09/2020 23:12:58: I116264190\n10/09/2020 23:12:58: 30-9C-23-87-89-8E\n10/09/2020 23:34:19: 127.0.0.1\n10/09/2020 23:34:19: I116264190\n10/09/2020 23:34:19: 30-9C-23-87-89-8E\n11/09/2020 00:07:46: 127.0.0.1\n11/09/2020 00:07:46: I116264190\n11/09/2020 00:07:46: 30-9C-23-87-89-8E\n11/09/2020 00:19:46: 127.0.0.1\n11/09/2020 00:19:46: I116264190\n11/09/2020 00:19:46: 30-9C-23-87-89-8E\n11/09/2020 01:25:54: 127.0.0.1\n11/09/2020 01:25:54: I116264190\n11/09/2020 01:25:54: 30-9C-23-87-89-8E\n11/09/2020 01:27:54: 127.0.0.1\n11/09/2020 01:27:54: I116264190\n11/09/2020 01:27:54: 30-9C-23-87-89-8E\n11/09/2020 02:59:49: 127.0.0.1\n11/09/2020 02:59:49: I116264190\n11/09/2020 02:59:49: 30-9C-23-87-89-8E\n11/09/2020 03:02:43: 127.0.0.1\n11/09/2020 03:02:43: I116264190\n11/09/2020 03:02:43: 30-9C-23-87-89-8E\n11/09/2020 03:04:45: 127.0.0.1\n11/09/2020 03:04:45: I116264190\n11/09/2020 03:04:45: 30-9C-23-87-89-8E\n12/09/2020 14:53:16: 127.0.0.1\n12/09/2020 14:53:16: I116264190\n12/09/2020 14:53:16: 30-9C-23-87-89-8E\n13/09/2020 14:36:17: 127.0.0.1\n13/09/2020 14:36:17: I116264190\n13/09/2020 14:36:17: 30-9C-23-87-89-8E\n13/09/2020 14:40:43: 127.0.0.1\n13/09/2020 14:40:43: I116264190\n13/09/2020 14:40:43: 30-9C-23-87-89-8E\n13/09/2020 15:09:39: 127.0.0.1\n13/09/2020 15:09:39: I116264190\n13/09/2020 15:09:39: 30-9C-23-87-89-8E\n13/09/2020 15:12:22: 127.0.0.1\n13/09/2020 15:12:22: I116264190\n13/09/2020 15:12:22: 30-9C-23-87-89-8E\n13/09/2020 15:19:02: 127.0.0.1\n13/09/2020 15:19:02: I116264190\n13/09/2020 15:19:02: 30-9C-23-87-89-8E\n13/09/2020 15:22:49: 127.0.0.1\n13/09/2020 15:22:49: I116264190\n13/09/2020 15:22:49: 30-9C-23-87-89-8E\n13/09/2020 15:24:30: 127.0.0.1\n13/09/2020 15:24:30: I116264190\n13/09/2020 15:24:30: 30-9C-23-87-89-8E\n13/09/2020 15:26:58: 127.0.0.1\n13/09/2020 15:26:58: I116264190\n13/09/2020 15:26:58: 30-9C-23-87-89-8E\n13/09/2020 15:30:47: 127.0.0.1\n13/09/2020 15:30:47: I116264190\n13/09/2020 15:30:47: 30-9C-23-87-89-8E\n13/09/2020 15:32:57: 127.0.0.1\n13/09/2020 15:32:57: I116264190\n13/09/2020 15:32:57: 30-9C-23-87-89-8E\n13/09/2020 15:56:59: 127.0.0.1\n13/09/2020 15:56:59: I116264190\n13/09/2020 15:56:59: 30-9C-23-87-89-8E\n13/09/2020 15:58:11: 127.0.0.1\n13/09/2020 15:58:11: I116264190\n13/09/2020 15:58:11: 30-9C-23-87-89-8E\n13/09/2020 15:58:49: 127.0.0.1\n13/09/2020 15:58:49: I116264190\n13/09/2020 15:58:49: 30-9C-23-87-89-8E\n13/09/2020 15:59:48: 127.0.0.1\n13/09/2020 15:59:48: I116264190\n13/09/2020 15:59:48: 30-9C-23-87-89-8E\n13/09/2020 16:00:36: 127.0.0.1\n13/09/2020 16:00:36: I116264190\n13/09/2020 16:00:36: 30-9C-23-87-89-8E\n13/09/2020 16:01:43: 127.0.0.1\n13/09/2020 16:01:43: I116264190\n13/09/2020 16:01:43: 30-9C-23-87-89-8E\n13/09/2020 16:03:42: 127.0.0.1\n13/09/2020 16:03:42: I116264190\n13/09/2020 16:03:42: 30-9C-23-87-89-8E\n13/09/2020 16:04:10: 127.0.0.1\n13/09/2020 16:04:10: I116264190\n13/09/2020 16:04:10: 30-9C-23-87-89-8E\n13/09/2020 16:05:40: 127.0.0.1\n13/09/2020 16:05:40: I116264190\n13/09/2020 16:05:40: 30-9C-23-87-89-8E\n13/09/2020 16:08:10: 127.0.0.1\n13/09/2020 16:08:10: I116264190\n13/09/2020 16:08:10: 30-9C-23-87-89-8E\n13/09/2020 16:09:45: 127.0.0.1\n13/09/2020 16:09:45: I116264190\n13/09/2020 16:09:45: 30-9C-23-87-89-8E\n13/09/2020 16:13:04: 127.0.0.1\n13/09/2020 16:13:04: I116264190\n13/09/2020 16:13:04: 30-9C-23-87-89-8E\n13/09/2020 16:13:59: 127.0.0.1\n13/09/2020 16:13:59: I116264190\n13/09/2020 16:13:59: 30-9C-23-87-89-8E\n13/09/2020 16:15:20: 127.0.0.1\n13/09/2020 16:15:20: I116264190\n13/09/2020 16:15:20: 30-9C-23-87-89-8E\n13/09/2020 16:16:08: 127.0.0.1\n13/09/2020 16:16:08: I116264190\n13/09/2020 16:16:08: 30-9C-23-87-89-8E\n13/09/2020 16:25:07: 127.0.0.1\n13/09/2020 16:25:07: I116264190\n13/09/2020 16:25:07: 30-9C-23-87-89-8E\n13/09/2020 16:28:18: 127.0.0.1\n13/09/2020 16:28:18: I116264190\n13/09/2020 16:28:18: 30-9C-23-87-89-8E\n13/09/2020 16:28:50: 127.0.0.1\n13/09/2020 16:28:50: I116264190\n13/09/2020 16:28:50: 30-9C-23-87-89-8E\n13/09/2020 16:29:28: 127.0.0.1\n13/09/2020 16:29:28: I116264190\n13/09/2020 16:29:28: 30-9C-23-87-89-8E\n13/09/2020 16:30:13: 127.0.0.1\n13/09/2020 16:30:13: I116264190\n13/09/2020 16:30:13: 30-9C-23-87-89-8E\n13/09/2020 16:31:05: 127.0.0.1\n13/09/2020 16:31:05: I116264190\n13/09/2020 16:31:05: 30-9C-23-87-89-8E\n13/09/2020 16:31:32: 127.0.0.1\n13/09/2020 16:31:32: I116264190\n13/09/2020 16:31:32: 30-9C-23-87-89-8E\n13/09/2020 16:32:06: 127.0.0.1\n13/09/2020 16:32:06: I116264190\n13/09/2020 16:32:06: 30-9C-23-87-89-8E\n13/09/2020 16:32:43: 127.0.0.1\n13/09/2020 16:32:43: I116264190\n13/09/2020 16:32:43: 30-9C-23-87-89-8E\n13/09/2020 16:33:31: 127.0.0.1\n13/09/2020 16:33:31: I116264190\n13/09/2020 16:33:31: 30-9C-23-87-89-8E\n13/09/2020 16:37:08: 127.0.0.1\n13/09/2020 16:37:08: I116264190\n13/09/2020 16:37:08: 30-9C-23-87-89-8E\n13/09/2020 16:38:23: 127.0.0.1\n13/09/2020 16:38:23: I116264190\n13/09/2020 16:38:23: 30-9C-23-87-89-8E\n13/09/2020 16:44:09: 127.0.0.1\n13/09/2020 16:44:09: I116264190\n13/09/2020 16:44:09: 30-9C-23-87-89-8E\n13/09/2020 17:01:49: 127.0.0.1\n13/09/2020 17:01:49: I116264190\n13/09/2020 17:01:49: 30-9C-23-87-89-8E\n13/09/2020 17:05:31: 127.0.0.1\n13/09/2020 17:05:31: I116264190\n13/09/2020 17:05:31: 30-9C-23-87-89-8E\n13/09/2020 17:10:08: 127.0.0.1\n13/09/2020 17:10:08: I116264190\n13/09/2020 17:10:08: 30-9C-23-87-89-8E\n13/09/2020 17:30:56: 127.0.0.1\n13/09/2020 17:30:56: I116264190\n13/09/2020 17:30:56: 30-9C-23-87-89-8E\n13/09/2020 17:35:02: 127.0.0.1\n13/09/2020 17:35:02: I116264190\n13/09/2020 17:35:02: 30-9C-23-87-89-8E\n13/09/2020 17:42:08: 127.0.0.1\n13/09/2020 17:42:08: I116264190\n13/09/2020 17:42:08: 30-9C-23-87-89-8E\n13/09/2020 17:42:27: 127.0.0.1\n13/09/2020 17:42:27: I116264190\n13/09/2020 17:42:27: 30-9C-23-87-89-8E\n13/09/2020 17:45:59: 127.0.0.1\n13/09/2020 17:45:59: I116264190\n13/09/2020 17:45:59: 30-9C-23-87-89-8E\n13/09/2020 17:46:47: 127.0.0.1\n13/09/2020 17:46:47: I116264190\n13/09/2020 17:46:47: 30-9C-23-87-89-8E\n13/09/2020 17:47:45: 127.0.0.1\n13/09/2020 17:47:45: I116264190\n13/09/2020 17:47:45: 30-9C-23-87-89-8E\n13/09/2020 17:49:22: 127.0.0.1\n13/09/2020 17:49:22: I116264190\n13/09/2020 17:49:22: 30-9C-23-87-89-8E\n13/09/2020 17:50:34: 127.0.0.1\n13/09/2020 17:50:34: I116264190\n13/09/2020 17:50:34: 30-9C-23-87-89-8E\n13/09/2020 17:52:50: 127.0.0.1\n13/09/2020 17:52:50: I116264190\n13/09/2020 17:52:50: 30-9C-23-87-89-8E\n13/09/2020 17:53:55: 127.0.0.1\n13/09/2020 17:53:55: I116264190\n13/09/2020 17:53:55: 30-9C-23-87-89-8E\n13/09/2020 18:06:04: 127.0.0.1\n13/09/2020 18:06:04: I116264190\n13/09/2020 18:06:04: 30-9C-23-87-89-8E\n13/09/2020 18:20:49: 127.0.0.1\n13/09/2020 18:20:49: I116264190\n13/09/2020 18:20:49: 30-9C-23-87-89-8E\n13/09/2020 18:22:42: 127.0.0.1\n13/09/2020 18:22:42: I116264190\n13/09/2020 18:22:42: 30-9C-23-87-89-8E\n13/09/2020 18:23:26: 127.0.0.1\n13/09/2020 18:23:26: I116264190\n13/09/2020 18:23:26: 30-9C-23-87-89-8E\n13/09/2020 18:29:24: 127.0.0.1\n13/09/2020 18:29:24: I116264190\n13/09/2020 18:29:24: 30-9C-23-87-89-8E\n13/09/2020 18:31:57: 127.0.0.1\n13/09/2020 18:31:57: I116264190\n13/09/2020 18:31:57: 30-9C-23-87-89-8E\n13/09/2020 18:32:52: 127.0.0.1\n13/09/2020 18:32:52: I116264190\n13/09/2020 18:32:52: 30-9C-23-87-89-8E\n13/09/2020 18:34:00: 127.0.0.1\n13/09/2020 18:34:00: I116264190\n13/09/2020 18:34:00: 30-9C-23-87-89-8E\n13/09/2020 18:34:58: 127.0.0.1\n13/09/2020 18:34:58: I116264190\n13/09/2020 18:34:58: 30-9C-23-87-89-8E\n13/09/2020 18:36:05: 127.0.0.1\n13/09/2020 18:36:05: I116264190\n13/09/2020 18:36:05: 30-9C-23-87-89-8E\n13/09/2020 19:17:14: 127.0.0.1\n13/09/2020 19:17:14: I116264190\n13/09/2020 19:17:14: 30-9C-23-87-89-8E\n13/09/2020 19:20:53: 127.0.0.1\n13/09/2020 19:20:53: I116264190\n13/09/2020 19:20:53: 30-9C-23-87-89-8E\n13/09/2020 19:22:35: 127.0.0.1\n13/09/2020 19:22:35: I116264190\n13/09/2020 19:22:35: 30-9C-23-87-89-8E\n13/09/2020 19:29:15: 127.0.0.1\n13/09/2020 19:29:15: I116264190\n13/09/2020 19:29:15: 30-9C-23-87-89-8E\n14/09/2020 14:20:25: 127.0.0.1\n14/09/2020 14:20:25: I116264190\n14/09/2020 14:20:25: 30-9C-23-87-89-8E\n14/09/2020 18:02:16: 127.0.0.1\n14/09/2020 18:02:16: I116264190\n14/09/2020 18:02:16: 30-9C-23-87-89-8E\n14/09/2020 18:03:29: 127.0.0.1\n14/09/2020 18:03:29: I116264190\n14/09/2020 18:03:29: 30-9C-23-87-89-8E\n14/09/2020 19:42:55: 127.0.0.1\n14/09/2020 19:42:55: I116264190\n14/09/2020 19:42:55: 30-9C-23-87-89-8E\n14/09/2020 19:57:58: 127.0.0.1\n14/09/2020 19:57:58: I116264190\n14/09/2020 19:57:58: 30-9C-23-87-89-8E\n14/09/2020 20:06:45: 127.0.0.1\n14/09/2020 20:06:45: I116264190\n14/09/2020 20:06:45: 30-9C-23-87-89-8E\n14/09/2020 20:30:56: 127.0.0.1\n14/09/2020 20:30:56: I116264190\n14/09/2020 20:30:56: 30-9C-23-87-89-8E\n14/09/2020 22:35:50: 127.0.0.1\n14/09/2020 22:35:50: I116264190\n14/09/2020 22:35:50: 30-9C-23-87-89-8E\n14/09/2020 23:07:10: 127.0.0.1\n14/09/2020 23:07:10: I116264190\n14/09/2020 23:07:10: 30-9C-23-87-89-8E\n14/09/2020 23:08:26: 127.0.0.1\n14/09/2020 23:08:26: I116264190\n14/09/2020 23:08:26: 30-9C-23-87-89-8E\n14/09/2020 23:50:43: 127.0.0.1\n14/09/2020 23:50:43: I116264190\n14/09/2020 23:50:43: 30-9C-23-87-89-8E\n15/09/2020 00:46:43: 127.0.0.1\n15/09/2020 00:46:43: I116264190\n15/09/2020 00:46:43: 30-9C-23-87-89-8E\n15/09/2020 11:52:20: 127.0.0.1\n15/09/2020 11:52:20: I116264190\n15/09/2020 11:52:20: 30-9C-23-87-89-8E\n15/09/2020 11:52:50: 127.0.0.1\n15/09/2020 11:52:50: I116264190\n15/09/2020 11:52:50: 30-9C-23-87-89-8E\n15/09/2020 11:55:21: 127.0.0.1\n15/09/2020 11:55:21: I116264190\n15/09/2020 11:55:21: 30-9C-23-87-89-8E\n15/09/2020 11:57:58: 127.0.0.1\n15/09/2020 11:57:58: I116264190\n15/09/2020 11:57:58: 30-9C-23-87-89-8E\n15/09/2020 12:03:43: 127.0.0.1\n15/09/2020 12:03:43: I116264190\n15/09/2020 12:03:43: 30-9C-23-87-89-8E\n15/09/2020 12:39:29: 127.0.0.1\n15/09/2020 12:39:29: I116264190\n15/09/2020 12:39:29: 30-9C-23-87-89-8E\n15/09/2020 12:56:16: 127.0.0.1\n15/09/2020 12:56:16: I116264190\n15/09/2020 12:56:16: 30-9C-23-87-89-8E\n15/09/2020 12:57:18: 127.0.0.1\n15/09/2020 12:57:18: I116264190\n15/09/2020 12:57:18: 30-9C-23-87-89-8E\n15/09/2020 13:31:06: 127.0.0.1\n15/09/2020 13:31:06: I116264190\n15/09/2020 13:31:06: 30-9C-23-87-89-8E\n15/09/2020 13:47:47: 127.0.0.1\n15/09/2020 13:47:47: I116264190\n15/09/2020 13:47:47: 30-9C-23-87-89-8E\n17/09/2020 11:29:59: 127.0.0.1\n17/09/2020 11:29:59: I116264190\n17/09/2020 11:29:59: 30-9C-23-87-89-8E\n17/09/2020 11:36:42: 127.0.0.1\n17/09/2020 11:36:42: I116264190\n17/09/2020 11:36:42: 30-9C-23-87-89-8E\n17/09/2020 11:39:14: 127.0.0.1\n17/09/2020 11:39:14: I116264190\n17/09/2020 11:39:14: 30-9C-23-87-89-8E\n17/09/2020 13:13:51: 127.0.0.1\n17/09/2020 13:13:51: I116264190\n17/09/2020 13:13:51: 30-9C-23-87-89-8E\n17/09/2020 13:55:19: 127.0.0.1\n17/09/2020 13:55:19: I116264190\n17/09/2020 13:55:19: 30-9C-23-87-89-8E\n17/09/2020 14:02:32: 127.0.0.1\n17/09/2020 14:02:32: I116264190\n17/09/2020 14:02:32: 30-9C-23-87-89-8E\n17/09/2020 14:46:02: 127.0.0.1\n17/09/2020 14:46:02: I116264190\n17/09/2020 14:46:02: 30-9C-23-87-89-8E\n17/09/2020 14:47:08: 127.0.0.1\n17/09/2020 14:47:08: I116264190\n17/09/2020 14:47:08: 30-9C-23-87-89-8E\n17/09/2020 14:50:18: 127.0.0.1\n17/09/2020 14:50:18: I116264190\n17/09/2020 14:50:18: 30-9C-23-87-89-8E\n17/09/2020 14:51:26: 127.0.0.1\n17/09/2020 14:51:26: I116264190\n17/09/2020 14:51:26: 30-9C-23-87-89-8E\n17/09/2020 14:51:59: 127.0.0.1\n17/09/2020 14:51:59: I116264190\n17/09/2020 14:51:59: 30-9C-23-87-89-8E\n17/09/2020 14:52:35: 127.0.0.1\n17/09/2020 14:52:35: I116264190\n17/09/2020 14:52:35: 30-9C-23-87-89-8E\n17/09/2020 14:53:13: 127.0.0.1\n17/09/2020 14:53:13: I116264190\n17/09/2020 14:53:13: 30-9C-23-87-89-8E\n17/09/2020 14:53:53: 127.0.0.1\n17/09/2020 14:53:53: I116264190\n17/09/2020 14:53:53: 30-9C-23-87-89-8E\n17/09/2020 14:55:00: 127.0.0.1\n17/09/2020 14:55:00: I116264190\n17/09/2020 14:55:00: 30-9C-23-87-89-8E\n17/09/2020 14:56:22: 127.0.0.1\n17/09/2020 14:56:22: I116264190\n17/09/2020 14:56:22: 30-9C-23-87-89-8E\n17/09/2020 14:56:50: 127.0.0.1\n17/09/2020 14:56:50: I116264190\n17/09/2020 14:56:50: 30-9C-23-87-89-8E\n17/09/2020 14:57:24: 127.0.0.1\n17/09/2020 14:57:24: I116264190\n17/09/2020 14:57:24: 30-9C-23-87-89-8E\n17/09/2020 14:58:46: 127.0.0.1\n17/09/2020 14:58:46: I116264190\n17/09/2020 14:58:46: 30-9C-23-87-89-8E\n17/09/2020 14:59:22: 127.0.0.1\n17/09/2020 14:59:22: I116264190\n17/09/2020 14:59:22: 30-9C-23-87-89-8E\n17/09/2020 15:17:34: 127.0.0.1\n17/09/2020 15:17:34: I116264190\n17/09/2020 15:17:34: 30-9C-23-87-89-8E\n17/09/2020 15:19:06: 127.0.0.1\n17/09/2020 15:19:06: I116264190\n17/09/2020 15:19:06: 30-9C-23-87-89-8E\n17/09/2020 15:22:03: 127.0.0.1\n17/09/2020 15:22:03: I116264190\n17/09/2020 15:22:03: 30-9C-23-87-89-8E\n17/09/2020 15:31:31: 127.0.0.1\n17/09/2020 15:31:31: I116264190\n17/09/2020 15:31:31: 30-9C-23-87-89-8E\n17/09/2020 15:32:17: 127.0.0.1\n17/09/2020 15:32:17: I116264190\n17/09/2020 15:32:17: 30-9C-23-87-89-8E\n17/09/2020 15:45:41: 127.0.0.1\n17/09/2020 15:45:41: I116264190\n17/09/2020 15:45:41: 30-9C-23-87-89-8E\n17/09/2020 15:48:10: 127.0.0.1\n17/09/2020 15:48:10: I116264190\n17/09/2020 15:48:10: 30-9C-23-87-89-8E\n17/09/2020 16:22:03: 127.0.0.1\n17/09/2020 16:22:03: I116264190\n17/09/2020 16:22:03: 30-9C-23-87-89-8E\n17/09/2020 16:32:12: 127.0.0.1\n17/09/2020 16:32:12: I116264190\n17/09/2020 16:32:12: 30-9C-23-87-89-8E\n17/09/2020 16:33:35: 127.0.0.1\n17/09/2020 16:33:35: I116264190\n17/09/2020 16:33:35: 30-9C-23-87-89-8E\n17/09/2020 16:45:15: 127.0.0.1\n17/09/2020 16:45:15: I116264190\n17/09/2020 16:45:15: 30-9C-23-87-89-8E\n17/09/2020 16:46:07: 127.0.0.1\n17/09/2020 16:46:07: I116264190\n17/09/2020 16:46:07: 30-9C-23-87-89-8E\n17/09/2020 16:54:58: 127.0.0.1\n17/09/2020 16:54:58: I116264190\n17/09/2020 16:54:58: 30-9C-23-87-89-8E\n17/09/2020 16:55:28: 127.0.0.1\n17/09/2020 16:55:28: I116264190\n17/09/2020 16:55:28: 30-9C-23-87-89-8E\n17/09/2020 16:55:57: 127.0.0.1\n17/09/2020 16:55:57: I116264190\n17/09/2020 16:55:57: 30-9C-23-87-89-8E\n17/09/2020 16:56:53: 127.0.0.1\n17/09/2020 16:56:53: I116264190\n17/09/2020 16:56:53: 30-9C-23-87-89-8E\n17/09/2020 16:58:16: 127.0.0.1\n17/09/2020 16:58:16: I116264190\n17/09/2020 16:58:16: 30-9C-23-87-89-8E\n17/09/2020 16:58:49: 127.0.0.1\n17/09/2020 16:58:49: I116264190\n17/09/2020 16:58:49: 30-9C-23-87-89-8E\n17/09/2020 16:59:37: 127.0.0.1\n17/09/2020 16:59:37: I116264190\n17/09/2020 16:59:37: 30-9C-23-87-89-8E\n17/09/2020 17:01:57: 127.0.0.1\n17/09/2020 17:01:57: I116264190\n17/09/2020 17:01:57: 30-9C-23-87-89-8E\n17/09/2020 17:02:46: 127.0.0.1\n17/09/2020 17:02:46: I116264190\n17/09/2020 17:02:46: 30-9C-23-87-89-8E\n17/09/2020 18:26:49: 127.0.0.1\n17/09/2020 18:26:49: I116264190\n17/09/2020 18:26:49: 30-9C-23-87-89-8E\n17/09/2020 18:53:22: 127.0.0.1\n17/09/2020 18:53:22: I116264190\n17/09/2020 18:53:22: 30-9C-23-87-89-8E\n17/09/2020 19:24:35: 127.0.0.1\n17/09/2020 19:24:35: I116264190\n17/09/2020 19:24:35: 30-9C-23-87-89-8E\n17/09/2020 19:33:51: 127.0.0.1\n17/09/2020 19:33:51: I116264190\n17/09/2020 19:33:51: 30-9C-23-87-89-8E\n17/09/2020 20:37:55: 127.0.0.1\n17/09/2020 20:37:55: I116264190\n17/09/2020 20:37:55: 30-9C-23-87-89-8E\n17/09/2020 21:03:04: 127.0.0.1\n17/09/2020 21:03:04: I116264190\n17/09/2020 21:03:04: 30-9C-23-87-89-8E\n17/09/2020 21:03:38: 127.0.0.1\n17/09/2020 21:03:38: I116264190\n17/09/2020 21:03:38: 30-9C-23-87-89-8E\n22/09/2020 12:34:31: 127.0.0.1\n22/09/2020 12:34:31: I116264190\n22/09/2020 12:34:31: 30-9C-23-87-89-8E\n22/09/2020 12:35:29: 127.0.0.1\n22/09/2020 12:35:29: I116264190\n22/09/2020 12:35:29: 30-9C-23-87-89-8E\n22/09/2020 12:37:35: 127.0.0.1\n22/09/2020 12:37:35: I116264190\n22/09/2020 12:37:35: 30-9C-23-87-89-8E\n23/09/2020 14:25:26: 127.0.0.1\n23/09/2020 14:25:26: I116264190\n23/09/2020 14:25:26: 30-9C-23-87-89-8E\n23/09/2020 14:31:33: 127.0.0.1\n23/09/2020 14:31:33: I116264190\n23/09/2020 14:31:33: 30-9C-23-87-89-8E\n23/09/2020 14:40:21: 127.0.0.1\n23/09/2020 14:40:21: I116264190\n23/09/2020 14:40:21: 30-9C-23-87-89-8E\n', '10/09/2020 14:47:28: tele 0,50,50,31,30\n10/09/2020 14:47:55: teleto test1\n10/09/2020 14:48:02: teleto test\n10/09/2020 14:48:05: tele 0,39,78,29,10\n10/09/2020 14:48:07: coords\n10/09/2020 14:48:47: coords\n10/09/2020 14:50:14: fpson\n10/09/2020 14:50:18: fpsoff\n10/09/2020 14:50:20: fpson\n10/09/2020 14:50:24: fpsoff\n10/09/2020 14:51:36: tele 0,49,61,57,27\n10/09/2020 14:51:41: tele 0,49,61,45,24\n10/09/2020 14:51:43: tele 0,49,61,44,40\n10/09/2020 14:51:45: tele 0,49,61,36,54\n10/09/2020 14:51:47: tele 0,49,61,20,57\n10/09/2020 14:51:50: tele 0,49,61,5,46\n10/09/2020 14:51:51: tele 0,48,61,55,39\n10/09/2020 14:51:53: tele 0,48,61,41,38\n10/09/2020 14:51:56: tele 0,48,61,44,51\n10/09/2020 14:51:57: tele 0,48,61,57,55\n10/09/2020 14:51:58: tele 0,49,61,8,51\n10/09/2020 14:51:59: tele 0,49,61,24,44\n10/09/2020 14:52:00: tele 0,49,61,39,38\n10/09/2020 14:52:01: tele 0,49,61,53,33\n10/09/2020 14:52:01: tele 0,50,61,2,26\n10/09/2020 14:52:02: tele 0,50,61,16,21\n10/09/2020 14:52:03: tele 0,50,61,30,17\n10/09/2020 14:52:10: tele 0,50,50,22,18\n10/09/2020 16:26:29: tele 0,50,50,32,27\n10/09/2020 16:26:50: teleto test\n10/09/2020 16:26:53: tele 0,39,78,29,10\n10/09/2020 16:27:02: mapfiles\n10/09/2020 16:30:00: tele 0,49,61,53,37\n10/09/2020 16:30:10: mapfiles\n10/09/2020 16:30:40: tele 0,49,61,40,37\n10/09/2020 16:30:41: tele 0,49,61,26,41\n10/09/2020 16:30:50: region\n10/09/2020 16:30:55: tele 0,49,61,10,43\n10/09/2020 16:30:57: tele 0,48,61,60,42\n10/09/2020 16:30:59: region\n10/09/2020 16:31:07: mapdata\n10/09/2020 16:31:19: mapfiles\n10/09/2020 16:35:59: tele 0,48,61,54,40\n10/09/2020 16:36:07: tele 0,48,61,50,45\n10/09/2020 16:36:08: tele 0,48,61,49,50\n10/09/2020 16:36:10: tele 0,48,61,42,51\n10/09/2020 16:36:11: tele 0,48,61,35,53\n10/09/2020 16:36:13: tele 0,48,61,38,50\n10/09/2020 16:36:14: tele 0,48,61,38,46\n10/09/2020 16:36:16: tele 0,48,61,53,44\n10/09/2020 16:36:16: tele 0,49,61,4,42\n10/09/2020 16:36:17: tele 0,49,61,15,44\n10/09/2020 16:36:18: tele 0,49,61,22,43\n10/09/2020 16:36:19: tele 0,49,61,19,31\n10/09/2020 16:36:20: tele 0,49,61,15,19\n10/09/2020 16:36:21: tele 0,49,61,18,7\n10/09/2020 16:36:23: tele 0,49,60,21,59\n10/09/2020 16:36:26: tele 0,49,60,25,46\n10/09/2020 16:36:29: tele 0,49,60,25,34\n10/09/2020 16:36:29: tele 0,49,60,25,22\n10/09/2020 16:36:31: tele 0,49,60,23,8\n10/09/2020 16:36:31: tele 0,49,59,23,59\n10/09/2020 16:36:34: tele 0,49,59,17,45\n10/09/2020 16:36:34: tele 0,49,59,13,31\n10/09/2020 16:36:35: tele 0,49,59,11,17\n10/09/2020 16:36:38: tele 0,49,59,11,3\n10/09/2020 16:36:39: tele 0,49,58,11,53\n10/09/2020 16:36:40: tele 0,49,58,10,45\n10/09/2020 16:36:43: tele 0,49,58,12,31\n10/09/2020 16:36:49: tele 0,50,59,2,42\n10/09/2020 16:36:56: tele 0,49,54,19,53\n10/09/2020 16:36:58: tele 0,49,54,21,43\n10/09/2020 16:37:00: tele 0,49,54,24,37\n10/09/2020 16:37:02: tele 0,49,54,23,33\n10/09/2020 17:43:17: tele 0,50,50,22,19\n10/09/2020 18:38:20: tele 0,51,50,8,27\n10/09/2020 18:39:23: tele 0,51,49,14,38\n10/09/2020 18:39:24: tele 0,51,49,13,53\n10/09/2020 18:39:25: tele 0,51,50,13,4\n10/09/2020 18:39:26: tele 0,51,50,13,19\n10/09/2020 18:39:27: tele 0,51,50,13,34\n10/09/2020 18:39:29: tele 0,51,50,22,47\n10/09/2020 18:40:36: tele 0,51,51,35,2\n10/09/2020 18:40:38: tele 0,51,50,47,59\n10/09/2020 18:40:42: tele 0,51,50,61,49\n10/09/2020 18:40:43: tele 0,52,50,11,49\n10/09/2020 18:40:43: tele 0,52,50,20,56\n10/09/2020 18:40:49: tele 0,52,50,37,55\n10/09/2020 18:40:50: tele 0,52,50,51,50\n10/09/2020 18:40:51: tele 0,52,50,55,39\n10/09/2020 18:42:01: tele 0,50,50,57,27\n10/09/2020 18:44:21: tele 0,50,51,37,42\n10/09/2020 18:49:07: fog\n10/09/2020 18:49:09: fogoff\n10/09/2020 18:49:11: nofog\n10/09/2020 18:49:12: fog\n10/09/2020 23:34:44: debug\n10/09/2020 23:35:03: home\n11/09/2020 00:08:03: debug\n11/09/2020 01:28:13: tele 0,50,50,35,16\n11/09/2020 01:28:16: tele 0,48,49,39,21\n11/09/2020 01:28:19: tele 1,48,49,39,21\n11/09/2020 01:28:20: tele 2,48,49,39,21\n11/09/2020 01:28:21: tele 2,48,49,38,23\n11/09/2020 01:28:54: tele 0,50,50,36,19\n11/09/2020 01:29:24: tele 0,50,50,23,16\n11/09/2020 01:29:26: tele 0,50,50,10,13\n11/09/2020 01:29:28: tele 1,50,50,10,13\n11/09/2020 01:29:30: tele 1,50,50,10,20\n11/09/2020 03:00:08: tele 0,50,50,19,18\n11/09/2020 03:00:09: tele 0,50,50,33,22\n12/09/2020 14:53:26: tele 0,46,51,16,8\n12/09/2020 14:53:37: tele 0,42,52,19,56\n12/09/2020 14:53:41: tele 0,42,52,15,55\n12/09/2020 14:53:54: debug\n12/09/2020 14:56:11: coords\n12/09/2020 14:56:40: tele 0,46,51,14,9\n12/09/2020 14:57:15: coords\n12/09/2020 14:57:35: tele 0,46,50,12,9\n12/09/2020 14:57:44: coords\n12/09/2020 14:57:55: tele 0,47,50,20,35\n12/09/2020 14:57:58: coords\n12/09/2020 14:58:07: tele 0,48,50,8,49\n12/09/2020 14:58:12: coords\n12/09/2020 14:59:33: empty\n12/09/2020 14:59:36: item 10498\n12/09/2020 14:59:48: item 10498\n12/09/2020 15:00:00: item 10499\n12/09/2020 15:01:32: item 13111\n12/09/2020 15:02:14: item 13170\n12/09/2020 15:03:32: item 1011\n12/09/2020 15:05:12: item 9944\n12/09/2020 15:05:14: item 9945\n12/09/2020 15:05:50: item 10863\n12/09/2020 15:06:44: tele 0,47,51,1,14\n12/09/2020 15:06:49: 1hko\n12/09/2020 15:07:16: tele 0,47,51,17,5\n12/09/2020 15:07:17: tele 0,47,50,31,59\n12/09/2020 15:07:17: tele 0,47,50,45,49\n12/09/2020 15:07:18: tele 0,47,50,60,46\n12/09/2020 15:07:19: tele 0,48,50,9,48\n12/09/2020 15:08:48: item 12645\n12/09/2020 15:09:42: item 7535\n12/09/2020 15:10:55: item 10607\n12/09/2020 15:11:02: item 6106\n12/09/2020 15:11:54: item 9470\n12/09/2020 15:15:20: empty\n12/09/2020 15:15:23: item 9096\n12/09/2020 15:15:26: item 9097\n12/09/2020 15:15:29: item 9098\n12/09/2020 15:15:31: item 9099\n12/09/2020 15:15:38: item 9100\n12/09/2020 15:15:42: item 9101\n12/09/2020 15:17:11: item 9068\n12/09/2020 15:17:29: item 9070\n12/09/2020 15:18:20: item 6067\n12/09/2020 15:18:27: item 6066\n12/09/2020 15:19:34: item 8952\n12/09/2020 15:19:43: item 13181\n12/09/2020 15:20:30: empty\n12/09/2020 15:21:31: item 2997\n12/09/2020 15:21:49: item 426\n12/09/2020 15:21:53: item 428\n12/09/2020 15:23:39: item 546\n12/09/2020 15:23:51: item 548\n12/09/2020 15:25:08: item 6335\n12/09/2020 15:25:11: item 6336\n12/09/2020 15:25:15: item 6337\n12/09/2020 15:26:30: empty\n12/09/2020 15:26:34: item 14076\n12/09/2020 15:26:37: item 14077\n12/09/2020 15:26:39: item 14081\n12/09/2020 15:28:06: item 14078\n12/09/2020 15:28:10: item 14079\n12/09/2020 15:28:13: item 14080\n12/09/2020 15:30:04: item 579\n12/09/2020 15:30:19: item 1017\n12/09/2020 15:30:47: item 7394\n12/09/2020 15:31:19: item 2898\n12/09/2020 15:33:22: item 6722\n12/09/2020 15:33:27: item 7592\n12/09/2020 15:34:27: npc 8207\n12/09/2020 15:34:35: npc 922\n12/09/2020 15:34:47: tele 0,48,50,18,54\n12/09/2020 15:34:49: tele 0,48,50,14,59\n12/09/2020 15:34:59: tele 0,48,50,5,48\n12/09/2020 15:36:04: npc 13172\n12/09/2020 15:36:11: npc 13173\n12/09/2020 15:36:28: npc 2634\n12/09/2020 15:36:33: tele 0,48,50,20,48\n12/09/2020 15:37:01: npc 755\n12/09/2020 15:37:06: tele 0,48,51,29,1\n12/09/2020 15:37:07: tele 0,48,51,27,4\n12/09/2020 15:37:19: tele 0,48,50,27,59\n12/09/2020 15:37:36: npc 2692\n12/09/2020 15:37:41: tele 0,48,50,14,60\n12/09/2020 15:37:42: tele 0,47,50,62,61\n12/09/2020 15:37:43: tele 0,47,50,46,62\n12/09/2020 15:37:44: tele 0,47,50,42,58\n12/09/2020 15:37:56: tele 0,47,50,29,55\n12/09/2020 15:37:57: tele 0,47,50,18,47\n12/09/2020 15:37:58: tele 0,47,50,6,58\n12/09/2020 15:38:13: tele 0,47,50,16,51\n12/09/2020 15:38:21: tele 0,47,50,28,54\n12/09/2020 15:38:22: tele 0,47,50,38,57\n12/09/2020 15:38:26: tele 0,47,50,38,47\n12/09/2020 15:38:42: npc 11700\n12/09/2020 15:38:48: npc 11703\n12/09/2020 15:39:02: tele 0,47,50,21,40\n12/09/2020 15:39:02: tele 0,47,50,5,33\n12/09/2020 15:39:04: tele 0,47,50,6,24\n12/09/2020 15:39:18: npc 556\n12/09/2020 15:39:23: tele 0,47,50,10,36\n12/09/2020 15:39:25: tele 0,47,50,4,47\n12/09/2020 15:39:34: tele 0,47,50,17,44\n12/09/2020 15:39:35: tele 0,47,50,28,46\n12/09/2020 15:39:36: tele 0,47,50,41,48\n12/09/2020 15:39:38: tele 0,47,50,39,57\n12/09/2020 15:40:03: pnpc 744\n12/09/2020 15:40:09: npc 744\n12/09/2020 15:40:14: tele 0,47,50,38,46\n12/09/2020 15:40:14: tele 0,47,50,40,36\n12/09/2020 15:40:15: tele 0,47,50,37,24\n12/09/2020 15:40:16: tele 0,47,50,31,13\n12/09/2020 15:40:18: tele 0,47,50,36,3\n12/09/2020 15:40:32: tele 0,46,50,14,3\n12/09/2020 15:40:55: tele 0,46,50,4,4\n12/09/2020 15:41:02: tele 0,46,50,5,15\n12/09/2020 15:41:21: tele 0,46,50,22,6\n12/09/2020 15:41:46: npc 557\n12/09/2020 15:41:54: tele 0,46,50,36,2\n12/09/2020 15:41:55: tele 0,46,49,50,62\n12/09/2020 15:41:56: tele 0,46,49,63,58\n12/09/2020 15:41:57: tele 0,47,50,6,5\n12/09/2020 15:42:23: pnpc 11705\n12/09/2020 15:42:26: pnpc -1\n12/09/2020 15:42:35: tele 0,47,50,16,17\n12/09/2020 15:42:36: tele 0,47,50,26,28\n12/09/2020 15:42:37: tele 0,47,50,35,39\n12/09/2020 15:42:38: tele 0,47,50,43,46\n12/09/2020 15:42:58: npc 2691\n12/09/2020 15:43:02: tele 0,47,50,44,56\n12/09/2020 15:43:47: pnpc 8078\n12/09/2020 15:47:02: obj 32034\n12/09/2020 15:47:10: tele 0,47,50,45,53\n12/09/2020 15:47:16: obj 32041\n12/09/2020 15:47:23: obj 32042\n12/09/2020 15:47:28: obj 32044\n12/09/2020 15:47:50: tele 0,42,52,17,54\n12/09/2020 15:48:02: obj 39240\n12/09/2020 15:48:12: tele 0,42,52,19,56\n12/09/2020 15:48:16: coords\n12/09/2020 15:48:20: tele 0,42,52,19,57\n12/09/2020 15:48:23: obj\n12/09/2020 15:48:25: coords\n12/09/2020 15:48:30: tele 0,42,52,20,58\n12/09/2020 15:48:34: coords\n12/09/2020 15:48:37: tele 0,42,52,15,56\n12/09/2020 15:48:49: coords\n13/09/2020 14:37:06: tele 0,47,50,63,57\n13/09/2020 14:37:07: tele 0,48,51,0,5\n13/09/2020 14:37:21: npc 922\n13/09/2020 14:37:54: npc 970\n13/09/2020 14:38:22: npc 3299\n13/09/2020 14:39:18: npc 2634\n13/09/2020 14:39:57: npc 755\n13/09/2020 14:55:45: npc 743\n13/09/2020 14:56:09: npc 2692\n13/09/2020 14:56:33: npc 583\n13/09/2020 14:58:18: npc 559\n13/09/2020 14:58:41: npc 558\n13/09/2020 14:59:02: npc 556\n13/09/2020 14:59:23: npc 2690\n13/09/2020 14:59:48: npc 744\n13/09/2020 15:00:14: npc 2691\n13/09/2020 15:00:42: npc 744\n13/09/2020 15:00:55: debug\n13/09/2020 15:01:03: npc 375\n13/09/2020 15:01:37: npc 557\n13/09/2020 15:02:06: npc 1860\n13/09/2020 15:02:36: npc 307\n13/09/2020 15:03:12: npc 585\n13/09/2020 15:03:38: npc 531\n13/09/2020 15:04:02: npc 530\n13/09/2020 15:10:31: debug\n13/09/2020 15:12:29: debug\n13/09/2020 15:12:39: npc 307\n13/09/2020 15:14:09: tele 0,48,51,1,17\n13/09/2020 15:19:10: tele 0,43,48,63,8\n13/09/2020 15:19:16: debug\n13/09/2020 15:19:48: remote 899\n13/09/2020 15:19:53: remote 900\n13/09/2020 15:19:56: remote 904\n13/09/2020 15:19:58: remote 902\n13/09/2020 15:20:05: remote901\n13/09/2020 15:20:07: remote 901\n13/09/2020 15:20:09: remote 900\n13/09/2020 15:21:32: remote 666\n13/09/2020 15:21:35: remote 688\n13/09/2020 15:21:38: remote 717\n13/09/2020 15:21:43: remote 718\n13/09/2020 15:21:47: remote 799\n13/09/2020 15:21:59: remote 682\n13/09/2020 15:22:04: remote 771\n13/09/2020 15:22:10: remote 814\n13/09/2020 15:22:18: remote 890\n13/09/2020 15:22:20: remote 883\n13/09/2020 15:23:49: tele 0,50,50,22,17\n13/09/2020 15:23:57: debug\n13/09/2020 15:27:24: pnpc 47\n13/09/2020 15:31:07: tele 0,42,52,15,51\n13/09/2020 15:31:12: debug\n13/09/2020 15:33:50: tele 0,42,52,14,56\n13/09/2020 15:35:33: empty\n13/09/2020 17:02:00: debug\n13/09/2020 17:03:53: item 995\n13/09/2020 17:35:27: debug\n13/09/2020 18:23:37: tele 0,50,53,12,35\n13/09/2020 18:23:38: tele 0,50,53,10,33\n13/09/2020 18:23:40: tele 0,50,53,9,30\n13/09/2020 18:23:43: tele 0,50,53,11,28\n13/09/2020 18:29:48: tele 0,42,52,19,55\n13/09/2020 18:29:52: tele 0,42,52,15,54\n13/09/2020 18:29:54: tele 0,42,52,15,55\n13/09/2020 18:29:55: tele 0,42,52,16,55\n13/09/2020 18:30:02: region\n13/09/2020 18:30:05: coords\n13/09/2020 18:33:00: tele 0,42,52,22,45\n13/09/2020 18:33:01: tele 0,42,52,23,36\n13/09/2020 18:33:08: obj 39233\n13/09/2020 18:34:10: obj 39233\n13/09/2020 18:35:10: tele 0,42,52,18,46\n13/09/2020 18:35:16: tele 0,42,52,18,50\n13/09/2020 18:35:23: obj 39237\n13/09/2020 19:17:21: tele 0,46,50,9,15\n13/09/2020 19:17:46: tele 0,46,50,10,14\n13/09/2020 19:17:48: tele 0,46,50,9,14\n14/09/2020 18:03:49: anim 288\n14/09/2020 18:05:12: anim 13662\n14/09/2020 18:05:20: anim 13710\n14/09/2020 18:05:28: anim 13744\n14/09/2020 18:05:36: anim 13798\n14/09/2020 18:05:40: anim -1\n14/09/2020 18:05:59: anim 12931\n14/09/2020 18:06:01: anim 01\n14/09/2020 18:06:05: anim 12919\n14/09/2020 18:06:17: anim 12594\n14/09/2020 18:06:31: anim 12152\n14/09/2020 18:06:40: anim 12059\n14/09/2020 18:07:29: tele 0,46,50,31,21\n14/09/2020 18:07:30: tele 0,46,50,44,21\n14/09/2020 18:07:31: tele 0,46,50,58,22\n14/09/2020 18:07:45: anim 11809\n14/09/2020 20:07:21: tele 0,47,50,48,53\n14/09/2020 20:07:22: tele 0,47,50,62,57\n14/09/2020 20:07:23: tele 0,48,50,11,53\n14/09/2020 20:07:26: tele 0,48,50,16,48\n14/09/2020 20:08:05: remote 1258\n14/09/2020 20:08:18: remote 1603\n14/09/2020 20:08:55: max\n14/09/2020 20:08:57: master\n14/09/2020 20:09:22: item 4734\n14/09/2020 20:09:38: remote 1603\n14/09/2020 20:09:57: remote 2182\n14/09/2020 20:10:01: remote 1666\n14/09/2020 20:10:18: remote 1547\n14/09/2020 20:10:28: remote 1548\n14/09/2020 20:10:45: remote 1262\n14/09/2020 20:10:54: remote 1185\n14/09/2020 20:11:05: remote 1729\n14/09/2020 20:11:10: remote 1695\n14/09/2020 20:11:16: remote 1695\n14/09/2020 20:12:05: emote 733\n14/09/2020 20:13:55: item 11969\n14/09/2020 20:14:14: itemn whip\n14/09/2020 20:14:18: itemn abyssal whip\n14/09/2020 20:15:09: anim 13036\n14/09/2020 20:15:13: anim 12305\n14/09/2020 20:15:17: anim 13055\n14/09/2020 20:26:35: emote 13190\n14/09/2020 20:26:45: emote 13192\n14/09/2020 20:33:38: tele 0,48,51,16,0\n14/09/2020 20:33:39: tele 0,48,51,20,16\n14/09/2020 20:33:39: tele 0,48,51,24,32\n14/09/2020 20:33:40: tele 0,48,51,28,47\n14/09/2020 20:33:40: tele 0,48,51,32,62\n14/09/2020 20:33:41: tele 0,48,52,36,13\n14/09/2020 20:33:42: tele 0,48,52,43,27\n14/09/2020 20:33:42: tele 0,48,52,51,40\n14/09/2020 20:33:43: tele 0,48,52,59,53\n14/09/2020 20:33:43: tele 0,49,53,3,2\n14/09/2020 20:33:44: tele 0,49,53,10,15\n14/09/2020 20:33:45: tele 0,49,53,17,26\n14/09/2020 20:33:46: tele 0,49,53,24,37\n14/09/2020 20:33:47: tele 0,49,53,31,48\n14/09/2020 20:33:48: tele 0,49,53,36,62\n14/09/2020 20:33:49: tele 0,49,54,26,1\n14/09/2020 20:33:49: tele 0,49,54,15,2\n14/09/2020 20:33:51: tele 0,49,53,3,58\n14/09/2020 20:33:52: tele 0,48,53,62,55\n14/09/2020 20:33:54: tele 0,48,53,63,57\n14/09/2020 20:33:55: tele 1,48,53,63,57\n14/09/2020 20:33:58: tele 2,48,53,63,57\n14/09/2020 20:34:52: remote 1564\n14/09/2020 20:36:04: remote 1569\n14/09/2020 20:36:15: remote 1576\n14/09/2020 20:37:57: tele 2,48,53,55,47\n14/09/2020 20:37:58: tele 2,48,53,45,38\n14/09/2020 20:37:58: tele 2,48,53,36,28\n14/09/2020 20:38:00: tele 2,48,53,25,18\n14/09/2020 20:38:00: tele 2,48,53,18,6\n14/09/2020 20:38:01: tele 2,48,52,13,57\n14/09/2020 20:38:01: tele 2,48,52,14,43\n14/09/2020 20:38:02: tele 2,48,52,16,29\n14/09/2020 20:38:03: tele 2,48,52,18,15\n14/09/2020 20:38:08: tele 2,48,52,15,2\n14/09/2020 20:38:08: tele 2,48,51,10,53\n14/09/2020 20:38:09: tele 2,48,51,5,40\n14/09/2020 20:38:09: tele 2,48,51,3,26\n14/09/2020 20:38:10: tele 2,47,51,63,13\n14/09/2020 20:38:11: tele 2,47,51,57,1\n14/09/2020 20:38:11: tele 2,47,50,50,53\n14/09/2020 20:38:12: tele 2,47,50,41,42\n14/09/2020 20:38:12: tele 2,47,50,32,31\n14/09/2020 20:38:13: tele 2,47,50,20,22\n14/09/2020 20:38:14: tele 2,47,50,7,13\n14/09/2020 20:38:14: tele 2,46,50,56,8\n14/09/2020 20:38:15: tele 2,46,50,43,2\n14/09/2020 20:38:15: tele 2,46,49,28,61\n14/09/2020 20:38:16: tele 2,46,49,12,60\n14/09/2020 20:38:17: tele 2,46,50,0,0\n14/09/2020 20:38:19: tele 2,45,50,60,15\n14/09/2020 20:38:20: tele 2,45,50,59,24\n14/09/2020 20:38:21: tele 2,46,50,1,33\n14/09/2020 20:38:21: tele 2,46,50,14,38\n14/09/2020 20:38:22: tele 2,46,50,27,37\n14/09/2020 20:38:24: tele 2,46,50,26,29\n14/09/2020 20:38:24: tele 1,46,50,26,29\n14/09/2020 20:38:25: tele 0,46,50,26,29\n14/09/2020 20:38:26: tele 0,46,50,14,17\n14/09/2020 20:38:28: tele 0,46,50,13,15\n14/09/2020 20:39:23: tele 0,46,50,12,15\n14/09/2020 20:39:26: tele 0,46,50,3,26\n14/09/2020 20:39:27: tele 0,45,50,57,31\n14/09/2020 20:39:28: tele 0,45,50,54,22\n14/09/2020 20:39:50: remote 1673\n14/09/2020 20:40:09: remote 1695\n14/09/2020 20:40:42: remote 1710\n14/09/2020 20:41:41: remote 1788\n14/09/2020 20:42:08: remote 1841\n14/09/2020 20:42:17: remote 1765\n14/09/2020 22:36:19: tele 0,49,154,13,50\n14/09/2020 23:50:50: tele 0,48,53,63,55\n14/09/2020 23:50:53: tele 1,48,53,63,55\n14/09/2020 23:50:56: tele 2,48,53,63,55\n14/09/2020 23:51:01: debug\n15/09/2020 00:46:51: anim 25\n15/09/2020 00:47:06: tele 2,49,53,4,55\n15/09/2020 00:47:08: tele 2,49,53,2,55\n15/09/2020 00:47:09: tele 2,49,53,3,55\n15/09/2020 00:47:09: tele 2,49,53,2,55\n15/09/2020 00:47:10: tele 2,49,53,3,55\n15/09/2020 00:47:11: tele 2,49,53,2,55\n15/09/2020 00:47:13: tele 2,49,53,1,54\n15/09/2020 00:49:45: tele 1,49,53,1,54\n15/09/2020 00:49:46: tele 0,49,53,1,54\n15/09/2020 00:50:11: tele 0,49,53,10,36\n15/09/2020 00:50:12: tele 0,49,53,20,22\n15/09/2020 00:50:13: tele 0,49,53,33,34\n15/09/2020 00:50:14: tele 0,49,53,49,40\n15/09/2020 00:50:17: tele 0,49,53,49,44\n15/09/2020 00:52:10: anim 12175\n15/09/2020 00:52:15: anim 12174\n15/09/2020 11:58:07: item 14000\n15/09/2020 11:58:16: item 15005\n15/09/2020 11:58:32: item 17333\n15/09/2020 11:58:38: item 16777\n15/09/2020 11:58:42: item 14000\n15/09/2020 11:58:45: item 14002\n15/09/2020 11:58:48: item 15002\n15/09/2020 11:58:57: item 15009\n15/09/2020 11:59:05: item 16002\n15/09/2020 11:59:08: item 15888\n15/09/2020 11:59:11: item 15444\n15/09/2020 11:59:15: item 15111\n15/09/2020 11:59:31: tele 0,49,53,50,36\n15/09/2020 11:59:44: tele 0,50,53,6,37\n15/09/2020 11:59:45: tele 0,50,53,8,37\n15/09/2020 12:02:31: pnpc 8926\n15/09/2020 12:02:38: pnpc -1\n15/09/2020 12:03:17: pnpc 9040\n15/09/2020 12:03:49: pnpc 9172\n15/09/2020 12:06:31: pnpc 9235\n15/09/2020 12:07:13: pnpc 9278\n15/09/2020 12:07:38: pnpc 9176\n15/09/2020 12:08:39: pnpc 8719\n15/09/2020 12:09:05: pnpc 8696\n15/09/2020 12:09:09: pnpc 8695\n15/09/2020 12:09:17: pnpc 8697\n15/09/2020 12:09:22: pnpc 8697\n15/09/2020 12:09:43: pnpc 8689\n15/09/2020 12:39:59: tele 0,46,50,13,16\n15/09/2020 12:41:10: empty\n15/09/2020 12:41:16: empty\n15/09/2020 12:41:20: itemn rune 2h\n15/09/2020 12:41:25: itemn rune scimitar\n15/09/2020 12:41:42: tele 0,46,50,26,20\n15/09/2020 12:41:43: tele 0,46,50,39,26\n15/09/2020 12:42:29: tele 0,47,49,7,48\n15/09/2020 12:43:45: tele 0,46,49,61,47\n15/09/2020 12:43:47: tele 0,47,49,1,60\n15/09/2020 12:43:48: tele 0,47,50,5,9\n15/09/2020 12:43:49: tele 0,47,50,9,22\n15/09/2020 12:43:49: tele 0,47,50,13,35\n15/09/2020 12:43:50: tele 0,47,50,17,48\n15/09/2020 12:43:51: tele 0,47,50,21,61\n15/09/2020 12:43:52: tele 0,47,51,27,9\n15/09/2020 12:43:53: tele 0,47,51,34,11\n15/09/2020 12:43:54: tele 0,47,51,47,10\n15/09/2020 12:43:55: tele 0,47,51,63,4\n15/09/2020 12:44:01: tele 0,48,50,0,60\n15/09/2020 12:44:03: tele 0,48,50,4,51\n15/09/2020 12:44:11: tele 0,48,50,7,49\n15/09/2020 12:44:25: itemn rune full helmet\n15/09/2020 12:44:30: itemn rune full helm\n15/09/2020 12:44:40: itemn rune platebodyu\n15/09/2020 12:44:44: itemn rune platebody\n15/09/2020 12:44:49: quests\n15/09/2020 12:44:53: allquest\n15/09/2020 12:45:07: itemn rune platelegs\n15/09/2020 12:48:16: tween\n15/09/2020 12:48:25: tween\n15/09/2020 12:48:47: tele 0,46,52,2,51\n15/09/2020 12:48:56: item 995 99999\n15/09/2020 12:50:37: tele 0,46,53,27,1\n15/09/2020 12:50:37: tele 0,46,53,34,13\n15/09/2020 12:50:38: tele 0,46,53,41,25\n15/09/2020 12:50:39: tele 0,46,53,48,37\n15/09/2020 12:50:54: tele 0,39,44,60,28\n15/09/2020 12:51:08: tele 0,39,44,60,25\n15/09/2020 12:51:10: tele 0,39,44,60,25\n15/09/2020 12:51:17: tele 0,39,44,58,30\n15/09/2020 12:51:26: anim 9933\n15/09/2020 12:51:30: anim 13000\n15/09/2020 12:51:32: anim 13005\n15/09/2020 12:51:37: anim 12222\n15/09/2020 12:51:41: anim 16000\n15/09/2020 12:51:44: anim -1\n15/09/2020 12:51:50: anim 14888\n15/09/2020 12:51:54: anim 13888\n15/09/2020 12:51:56: anim 12333\n15/09/2020 12:52:01: anim 12888\n15/09/2020 12:52:06: anim 13111\n15/09/2020 12:52:09: anim 13444\n15/09/2020 12:52:12: anim -1\n15/09/2020 12:52:15: render 1422\n15/09/2020 12:52:19: render 1555\n15/09/2020 12:52:24: render 1344\n15/09/2020 12:52:26: render 1345\n15/09/2020 12:52:30: render 1346\n15/09/2020 12:52:34: render 1347\n15/09/2020 12:52:37: render 1349\n15/09/2020 12:52:42: render 1401\n15/09/2020 12:52:44: render 1405\n15/09/2020 12:52:47: render 1506\n15/09/2020 12:52:51: render 1507\n15/09/2020 12:52:55: render 1407\n15/09/2020 12:52:58: render 1406\n15/09/2020 12:53:34: remote 1666\n15/09/2020 12:53:38: remote 1573\n15/09/2020 12:53:41: remote -1\n15/09/2020 12:53:47: emote -1\n15/09/2020 12:53:48: emote 1\n15/09/2020 12:53:50: anim 1\n15/09/2020 12:53:55: remote 1547\n15/09/2020 12:53:57: remote 2\n15/09/2020 12:54:01: remote 1427\n15/09/2020 12:54:20: remote 1672\n15/09/2020 12:54:26: remote 1396\n15/09/2020 12:54:37: remote 1569\n15/09/2020 12:54:42: remote 1564\n15/09/2020 12:54:47: remote 1545\n15/09/2020 12:54:55: remote 1429\n15/09/2020 12:55:19: remote 1382\n15/09/2020 12:55:27: remote 1383\n15/09/2020 12:55:38: remote 1482\n15/09/2020 12:55:43: remote 1549\n15/09/2020 12:55:46: emote 1549\n15/09/2020 12:55:48: remote 2\n15/09/2020 12:55:51: remote 4\n15/09/2020 12:55:54: remote 12\n15/09/2020 12:55:56: remote 15\n15/09/2020 12:55:59: remote 18\n15/09/2020 12:56:01: remote 333\n15/09/2020 12:56:04: remote -1\n15/09/2020 12:56:08: remote 899\n15/09/2020 12:56:34: remote 871\n15/09/2020 12:56:48: remote 1652\n15/09/2020 12:57:00: remote 2003\n15/09/2020 12:57:11: remote 2005\n15/09/2020 12:57:28: remote 2019\n15/09/2020 12:57:35: pnpc 2\n15/09/2020 12:57:46: remote 2043\n15/09/2020 12:57:50: remote -1\n15/09/2020 12:57:53: pnpc -1\n15/09/2020 12:58:10: remote 1094\n15/09/2020 12:58:16: remote 1095\n15/09/2020 12:58:30: remote 1114\n15/09/2020 12:58:37: remote 1121\n15/09/2020 12:58:47: remote 1124\n15/09/2020 12:59:10: remote 1171\n15/09/2020 13:00:00: remote 1485\n15/09/2020 13:00:04: remote 1222\n15/09/2020 13:00:14: remote 1386\n15/09/2020 13:00:38: pnpc -1\n15/09/2020 13:01:03: itemn saradomin godsword\n15/09/2020 13:01:27: tele 0,50,50,22,19\n15/09/2020 13:02:12: remote 78\n15/09/2020 13:02:22: remote 124\n15/09/2020 13:02:31: remote 220\n15/09/2020 13:02:40: remote 326\n15/09/2020 13:02:50: remote 2052\n15/09/2020 13:02:57: remote 366\n15/09/2020 13:03:13: remote 124\n15/09/2020 13:03:19: remote 152\n15/09/2020 13:03:34: remote 79\n15/09/2020 13:04:01: remote 40\n15/09/2020 13:04:23: tele 0,48,54,21,15\n15/09/2020 13:04:31: remote 39\n15/09/2020 13:04:35: remote 31\n15/09/2020 13:04:42: remote 28\n15/09/2020 13:04:45: remote 26\n15/09/2020 13:04:47: remote 28\n15/09/2020 13:04:59: tele 0,48,154,33,53\n15/09/2020 13:05:00: tele 0,48,154,47,59\n15/09/2020 13:05:00: tele 0,48,154,62,56\n15/09/2020 13:05:01: tele 0,49,154,10,51\n15/09/2020 13:05:22: tele 0,50,50,22,17\n15/09/2020 13:05:29: itemn zamorakian spear\n15/09/2020 13:06:04: itemn dragon platebody\n15/09/2020 13:06:14: itemn attack cape\n15/09/2020 13:06:25: itemn fury\n15/09/2020 13:06:29: itemn amulet of fury\n15/09/2020 13:06:36: itemn dragon full helm\n15/09/2020 13:06:44: itemn dragon platelegs\n15/09/2020 13:06:53: itemn dragon gauntlets\n15/09/2020 13:07:00: itemn dragon boots\n15/09/2020 13:07:29: empty\n15/09/2020 13:07:33: itemn red partyhat\n15/09/2020 13:07:59: itemn dragon chainbody\n15/09/2020 13:31:24: tele 0,50,50,21,14\n15/09/2020 13:31:37: tele 0,46,61,60,29\n15/09/2020 13:35:40: tele 0,48,53,12,25\n15/09/2020 13:35:46: itemn rune pickaxe\n15/09/2020 13:36:13: tele 0,48,53,14,28\n15/09/2020 13:47:55: itemn dragon scimitar\n15/09/2020 13:48:02: tele 0,56,54,19,32\n17/09/2020 14:46:11: tele 0,41,51,24,27\n17/09/2020 14:46:18: tele 0,44,49,38,27\n17/09/2020 14:46:26: tele 0,50,50,23,18\n17/09/2020 14:46:39: tele 0,50,50,24,37\n17/09/2020 14:47:17: tele 0,50,48,60,34\n17/09/2020 14:47:22: tele 0,50,50,23,17\n17/09/2020 14:52:10: tele 0,46,51,37,13\n17/09/2020 14:52:16: tele 0,50,50,22,17\n17/09/2020 14:52:43: tele 0,46,50,12,15\n17/09/2020 14:53:20: tele 0,44,50,20,35\n17/09/2020 14:53:35: tele 0,43,45,24,13\n17/09/2020 14:54:00: tele 0,50,50,23,19\n17/09/2020 14:54:05: tele 0,50,50,36,25\n17/09/2020 14:55:14: tele 0,50,50,24,20\n17/09/2020 14:55:16: tele 0,50,50,13,31\n17/09/2020 14:55:17: tele 0,49,50,62,38\n17/09/2020 14:55:19: tele 0,49,50,53,38\n17/09/2020 14:55:21: tele 0,49,50,47,32\n17/09/2020 14:55:24: tele 0,49,50,62,31\n17/09/2020 14:55:25: tele 0,50,50,13,26\n17/09/2020 14:55:26: tele 0,50,50,27,26\n17/09/2020 14:55:28: tele 0,50,50,31,24\n17/09/2020 14:55:33: tele 0,50,50,46,27\n17/09/2020 14:55:33: tele 0,50,50,60,35\n17/09/2020 14:55:35: tele 0,50,50,63,32\n17/09/2020 14:55:36: tele 0,51,50,1,34\n17/09/2020 14:55:38: tele 0,51,50,0,42\n17/09/2020 14:55:44: tele 0,50,50,52,34\n17/09/2020 14:55:45: tele 0,50,50,40,26\n17/09/2020 14:55:46: tele 0,50,50,32,20\n17/09/2020 14:55:47: tele 0,50,50,21,18\n17/09/2020 14:56:56: tele 0,51,48,33,26\n17/09/2020 14:59:28: tele 0,50,50,22,18\n17/09/2020 15:17:37: tele 0,50,50,9,10\n17/09/2020 15:17:44: tele 2,50,50,8,20\n17/09/2020 15:19:24: debug\n17/09/2020 18:26:56: tele 0,51,50,16,16\n17/09/2020 19:34:00: itemn brawling gloves\n17/09/2020 19:34:07: itemn brawling gloves (melee)\n17/09/2020 19:34:19: empty\n17/09/2020 19:34:27: itemn bandos chest plate\n17/09/2020 19:34:31: itemn bandos chestplate\n17/09/2020 19:34:38: itemn bandos tassets\n17/09/2020 19:34:45: itemn bandos boots\n17/09/2020 19:34:54: itemn dragonfire shield\n17/09/2020 19:35:04: itemn abyssal whip\n17/09/2020 19:35:38: itemn third-age full helm\n17/09/2020 19:35:50: itemn verac\'s helm\n17/09/2020 19:36:02: itemn fire cape\n17/09/2020 19:36:14: tele 0,51,61,22,22\n17/09/2020 19:36:35: tele 0,51,61,18,19\n17/09/2020 19:37:05: debug\n17/09/2020 19:37:37: god\n17/09/2020 19:37:39: hp\n17/09/2020 19:37:41: 1hko\n17/09/2020 19:37:53: tele 0,51,61,10,22\n17/09/2020 20:12:12: remtoe 211\n17/09/2020 20:12:16: remote 211\n17/09/2020 20:38:04: tele 0,41,63,15,7\n17/09/2020 20:38:08: tele 1,41,63,15,7\n17/09/2020 20:38:08: tele 2,41,63,15,7\n17/09/2020 20:38:09: tele 1,41,63,15,7\n17/09/2020 20:39:30: tele 1,41,63,16,12\n17/09/2020 20:40:54: pnpc 7895\n17/09/2020 20:40:58: pnpc 7896\n17/09/2020 20:41:02: pnpc 7897\n17/09/2020 20:41:07: pnpc 8093\n17/09/2020 20:41:12: pnpc 8095\n17/09/2020 20:41:17: pnpc 8094\n17/09/2020 20:41:22: pnpc 8097\n17/09/2020 20:41:26: pnpc 8098\n17/09/2020 20:41:30: pnpc 8099\n17/09/2020 20:41:34: pnpc -1\n17/09/2020 20:41:38: pnpc 8100\n17/09/2020 20:41:42: pnpc 8882\n17/09/2020 20:41:46: pnpc 8690\n17/09/2020 20:41:52: pnpc 8663\n17/09/2020 20:42:18: pnpc -1\n17/09/2020 20:42:55: tele 0,41,63,12,22\n17/09/2020 20:42:57: tele 0,41,63,11,23\n17/09/2020 20:43:39: tele 0,41,63,6,25\n17/09/2020 20:43:39: tele 1,41,63,6,25\n17/09/2020 20:43:44: tele 1,41,63,7,25\n17/09/2020 20:43:50: tele 1,41,63,7,27\n17/09/2020 20:43:52: tele 1,41,63,9,27\n17/09/2020 20:43:54: tele 1,41,63,11,27\n17/09/2020 20:43:56: tele 1,41,63,11,29\n17/09/2020 20:43:57: tele 1,41,63,11,31\n17/09/2020 20:43:58: tele 1,41,63,12,33\n17/09/2020 21:03:44: tele 0,50,50,30,31\n17/09/2020 21:03:46: tele 0,50,50,23,20\n', '', '', '', ''),
-('woahscam', '', '', '', '22/09/2020 12:43:45: 127.0.0.1\n22/09/2020 12:43:45: I116264190\n22/09/2020 12:43:45: 30-9C-23-87-89-8E\n', '', '', '', '', '');
-
--- --------------------------------------------------------
-
---
--- Table structure for table `punishments`
---
-
-CREATE TABLE `punishments` (
- `address` varchar(100) NOT NULL DEFAULT '',
- `type` int(11) NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `security`
---
-
-CREATE TABLE `security` (
- `id` int(11) UNSIGNED NOT NULL,
- `ip` longtext NOT NULL,
- `type` int(11) NOT NULL,
- `timestamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `sys_logs`
---
-
-CREATE TABLE `sys_logs` (
- `id` int(11) UNSIGNED NOT NULL,
- `message` longtext NOT NULL,
- `log_type` int(2) DEFAULT NULL,
- `timestamp` timestamp NOT NULL DEFAULT current_timestamp(),
- `IP_ADDRESS` varchar(30) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `validations`
---
-
-CREATE TABLE `validations` (
- `id` int(11) UNSIGNED NOT NULL,
- `username` varchar(20) DEFAULT NULL,
- `code` varchar(30) DEFAULT NULL,
- `type` int(2) NOT NULL DEFAULT 0,
- `timestamp` timestamp NOT NULL DEFAULT current_timestamp(),
- `value` longtext NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `votes`
---
-
-CREATE TABLE `votes` (
- `id` int(11) NOT NULL,
- `username` varchar(50) NOT NULL DEFAULT '',
- `site` varchar(50) NOT NULL,
- `timestamp` timestamp NOT NULL DEFAULT current_timestamp()
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
---
--- Table structure for table `voting_sites`
---
-
-CREATE TABLE `voting_sites` (
- `name` varchar(20) NOT NULL DEFAULT 'Null',
- `wait` int(5) NOT NULL DEFAULT 12,
- `credits` int(2) NOT NULL DEFAULT 1,
- `link` varchar(500) NOT NULL DEFAULT 'http://ariosrsps.com',
- `get_command` varchar(20) NOT NULL DEFAULT '',
- `host_name` varchar(500) NOT NULL DEFAULT ''
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
--- --------------------------------------------------------
-
--
-- Table structure for table `worlds`
--
@@ -348,72 +96,12 @@ INSERT INTO `worlds` (`world`, `ip`, `players`, `country`, `member`, `revision`,
-- Indexes for dumped tables
--
---
--- Indexes for table `dev_log`
---
-ALTER TABLE `dev_log`
- ADD PRIMARY KEY (`id`);
-
---
--- Indexes for table `highscores`
---
-ALTER TABLE `highscores`
- ADD PRIMARY KEY (`id`);
-
--
-- Indexes for table `members`
--
ALTER TABLE `members`
ADD PRIMARY KEY (`UID`);
---
--- Indexes for table `messages`
---
-ALTER TABLE `messages`
- ADD PRIMARY KEY (`id`);
-
---
--- Indexes for table `perks`
---
-ALTER TABLE `perks`
- ADD PRIMARY KEY (`product_id`);
-
---
--- Indexes for table `player_logs`
---
-ALTER TABLE `player_logs`
- ADD PRIMARY KEY (`username`);
-
---
--- Indexes for table `security`
---
-ALTER TABLE `security`
- ADD PRIMARY KEY (`id`);
-
---
--- Indexes for table `sys_logs`
---
-ALTER TABLE `sys_logs`
- ADD PRIMARY KEY (`id`);
-
---
--- Indexes for table `validations`
---
-ALTER TABLE `validations`
- ADD PRIMARY KEY (`id`);
-
---
--- Indexes for table `votes`
---
-ALTER TABLE `votes`
- ADD KEY `id` (`id`);
-
---
--- Indexes for table `voting_sites`
---
-ALTER TABLE `voting_sites`
- ADD PRIMARY KEY (`name`);
-
--
-- Indexes for table `worlds`
--
@@ -424,61 +112,12 @@ ALTER TABLE `worlds`
-- AUTO_INCREMENT for dumped tables
--
---
--- AUTO_INCREMENT for table `dev_log`
---
-ALTER TABLE `dev_log`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=34;
-
---
--- AUTO_INCREMENT for table `highscores`
---
-ALTER TABLE `highscores`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;
-
--
-- AUTO_INCREMENT for table `members`
--
ALTER TABLE `members`
MODIFY `UID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
---
--- AUTO_INCREMENT for table `messages`
---
-ALTER TABLE `messages`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
-
---
--- AUTO_INCREMENT for table `perks`
---
-ALTER TABLE `perks`
- MODIFY `product_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=74;
-
---
--- AUTO_INCREMENT for table `security`
---
-ALTER TABLE `security`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
-
---
--- AUTO_INCREMENT for table `sys_logs`
---
-ALTER TABLE `sys_logs`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
-
---
--- AUTO_INCREMENT for table `validations`
---
-ALTER TABLE `validations`
- MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
-
---
--- AUTO_INCREMENT for table `votes`
---
-ALTER TABLE `votes`
- MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
-COMMIT;
-
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/Server/src/main/java/core/game/component/Component.java b/Server/src/main/java/core/game/component/Component.java
index 83dd11bff..fd8d8f29b 100644
--- a/Server/src/main/java/core/game/component/Component.java
+++ b/Server/src/main/java/core/game/component/Component.java
@@ -125,14 +125,11 @@ public class Component {
* @param c The component.
*/
public static void setUnclosable(Player p, Component c) {
- p.setAttribute("close_c_", false);
+ p.setAttribute("close_c_", true);
c.setCloseEvent(new CloseEvent() {
@Override
public boolean close(Player player, Component c) {
- if (!player.getAttribute("close_c_", false)) {
- return false;
- }
- return true;
+ return !player.getAttribute("close_c_", false);
}
});
}
diff --git a/Server/src/main/java/core/game/node/entity/Entity.java b/Server/src/main/java/core/game/node/entity/Entity.java
index 428c3e9ad..24caeb50d 100644
--- a/Server/src/main/java/core/game/node/entity/Entity.java
+++ b/Server/src/main/java/core/game/node/entity/Entity.java
@@ -20,6 +20,9 @@ import core.game.node.entity.skill.Skills;
import core.game.node.entity.state.EntityState;
import core.game.node.entity.state.StateManager;
import core.game.system.task.Pulse;
+import core.game.world.map.zone.ZoneBorders;
+import org.jetbrains.annotations.NotNull;
+import rs09.game.system.SystemLogger;
import rs09.game.world.GameWorld;
import core.game.world.map.Location;
import core.game.world.map.Viewport;
@@ -33,6 +36,7 @@ import rs09.game.world.update.UpdateMasks;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -780,10 +784,6 @@ public abstract class Entity extends Node {
attributes.setAttribute(key, value);
}
- public void setExpirableAttribute(String key, Object value, Long timeToLive){
- attributes.setExpirableAttribute(key,value,timeToLive);
- }
-
/**
* Gets an attribute.
* @param key The attribute name.
@@ -938,4 +938,34 @@ public abstract class Entity extends Node {
this.invisible = invisible;
}
+ public Location getClosestOccupiedTile(@NotNull Location other) {
+ List occupied = getOccupiedTiles();
+
+ Location closest = location;
+ if (occupied.size() > 1) {
+ double lowest = 9999;
+ for (Location tile : occupied) {
+ double dist = tile.getDistance(other);
+ if (dist < lowest) {
+ lowest = dist;
+ closest = tile;
+ }
+ }
+ }
+
+ return closest;
+ }
+
+ public List getOccupiedTiles() {
+ ArrayList occupied = new ArrayList<>();
+
+ Location northEast = location.transform(size, size, 0);
+
+ for (int x = location.getX(); x < northEast.getX(); x++) {
+ for (int y = location.getY(); y < northEast.getY(); y++) {
+ occupied.add(Location.create(x, y, location.getZ()));
+ }
+ }
+ return occupied;
+ }
}
diff --git a/Server/src/main/java/core/game/node/entity/combat/ImpactHandler.java b/Server/src/main/java/core/game/node/entity/combat/ImpactHandler.java
index 7e1bc91f6..ee9126af5 100644
--- a/Server/src/main/java/core/game/node/entity/combat/ImpactHandler.java
+++ b/Server/src/main/java/core/game/node/entity/combat/ImpactHandler.java
@@ -11,6 +11,7 @@ import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.prayer.PrayerType;
import core.game.node.item.Item;
import core.game.system.task.Pulse;
+import rs09.game.ai.AIPlayer;
import rs09.game.world.GameWorld;
import core.game.world.map.zone.ZoneType;
@@ -144,7 +145,7 @@ public final class ImpactHandler {
if (disabledTicks > GameWorld.getTicks()) {
return null;
}
- if (entity instanceof Player && !(entity.getAttribute("tutorial:complete",false))) {
+ if (entity instanceof Player && !(entity instanceof AIPlayer) && !(entity.getAttribute("tutorial:complete",false))) {
Impact impact = new Impact(source, 0, style, HitsplatType.MISS);
impactQueue.add(impact);
return impact;
diff --git a/Server/src/main/java/core/game/node/entity/impl/GameAttributes.java b/Server/src/main/java/core/game/node/entity/impl/GameAttributes.java
index df82a0e9b..26bb8f348 100644
--- a/Server/src/main/java/core/game/node/entity/impl/GameAttributes.java
+++ b/Server/src/main/java/core/game/node/entity/impl/GameAttributes.java
@@ -136,7 +136,7 @@ public final class GameAttributes {
*/
public void setAttribute(String key, Object value) {
if (key.startsWith("/save:")) {
- key = key.substring(6, key.length());
+ key = key.substring(6);
if (!savedAttributes.contains(key)) {
savedAttributes.add(key);
}
@@ -144,17 +144,6 @@ public final class GameAttributes {
attributes.put(key, value);
}
- /**
- * Sets an inherently temporary (but saved cross-session) key.
- * @param key the key to set
- * @param value the value to assign to the key
- * @param timeToLive the time (in milliseconds) that the key will be valid for
- */
- public void setExpirableAttribute(String key, Object value, Long timeToLive){
- setAttribute(key,value);
- keyExpirations.put(key,System.currentTimeMillis() + timeToLive);
- }
-
/**
* Gets an attribute.
* @param key The attribute name.
@@ -163,9 +152,6 @@ public final class GameAttributes {
@SuppressWarnings("unchecked")
public T getAttribute(String key) {
key = key.replace("/save:","");
- if (!attributes.containsKey(key)) {
- return null;
- }
return (T) attributes.get(key);
}
@@ -182,9 +168,6 @@ public final class GameAttributes {
if (object != null) {
return (T) object;
}
- if(keyExpirations.containsKey(string) && keyExpirations.get(string) < System.currentTimeMillis()){
- return fail;
- }
return fail;
}
diff --git a/Server/src/main/java/core/game/node/entity/npc/NPC.java b/Server/src/main/java/core/game/node/entity/npc/NPC.java
index 80ba045bc..4f6379ed0 100644
--- a/Server/src/main/java/core/game/node/entity/npc/NPC.java
+++ b/Server/src/main/java/core/game/node/entity/npc/NPC.java
@@ -432,6 +432,7 @@ public class NPC extends Entity {
if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) {
dialoguePlayer = null;
if (walks && !getPulseManager().hasPulseRunning() && !getProperties().getCombatPulse().isAttacking() && !getProperties().getCombatPulse().isInCombat() && nextWalk < GameWorld.getTicks()) {
+ if (RandomFunction.nextBool()) return;
setNextWalk();
Location l = getMovementDestination();
if (canMove(l)) {
diff --git a/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java b/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java
index cbc0d6886..e4dbfa934 100644
--- a/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java
+++ b/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java
@@ -193,9 +193,6 @@ public class RevenantNPC extends AbstractNPC {
@Override
public boolean isAttackable(Entity entity, CombatStyle style, boolean message) {
- if (entity.asPlayer().isArtificial()) {
- return false;
- }
if (entity instanceof Player) {
if (!checkCombatLevel(entity.asPlayer()) && !entity.asPlayer().isAdmin()) {
if(message) {
diff --git a/Server/src/main/java/core/game/world/map/BuildRegionChunk.java b/Server/src/main/java/core/game/world/map/BuildRegionChunk.java
index 1d1a24e38..7823180a1 100644
--- a/Server/src/main/java/core/game/world/map/BuildRegionChunk.java
+++ b/Server/src/main/java/core/game/world/map/BuildRegionChunk.java
@@ -90,7 +90,7 @@ public class BuildRegionChunk extends RegionChunk {
objects[i][x][y] = null;
}
plane.getObjects()[baseX + x][baseY + y] = null;
- plane.getFlags().getClippingFlags()[baseX + x][baseY + y] = 0;
+ plane.getFlags().clearFlag(baseX + x, baseY + y);
}
}
clear();
diff --git a/Server/src/main/java/core/game/world/map/Location.java b/Server/src/main/java/core/game/world/map/Location.java
index c6533582d..7e6a32e00 100644
--- a/Server/src/main/java/core/game/world/map/Location.java
+++ b/Server/src/main/java/core/game/world/map/Location.java
@@ -5,8 +5,11 @@ import core.game.node.Node;
import core.game.world.map.path.Path;
import core.game.world.map.path.Pathfinder;
import core.tools.RandomFunction;
+import org.jetbrains.annotations.NotNull;
+import rs09.game.system.SystemLogger;
import java.util.ArrayList;
+import java.util.List;
/**
* Represents a location on the world map.
@@ -491,4 +494,45 @@ public final class Location extends Node {
public void setZ(int z) {
this.z = z;
}
+
+ @NotNull
+ public List getStepComponents(Direction dir) {
+ List output = new ArrayList<>(2);
+ int stepX = dir.getStepX();
+ int stepY = dir.getStepY();
+
+ if (stepX != 0) output.add(transform(stepX, 0, 0));
+ if (stepY != 0) output.add(transform(0, stepY, 0));
+ return output;
+ }
+
+ public Direction deriveDirection(Location location) {
+ int diffX = location.x - this.x;
+ int diffY = location.y - this.y;
+
+ diffX = diffX >= 0 ? Math.min(diffX, 1) : -1;
+ diffY = diffY >= 0 ? Math.min(diffY, 1) : -1;
+
+ StringBuilder sb = new StringBuilder();
+
+ if (diffY != 0) {
+ if (diffY > 0) {
+ sb.append("NORTH");
+ } else {
+ sb.append("SOUTH");
+ }
+ }
+
+ if (diffX != 0) {
+ if (sb.length() > 0) sb.append("_");
+ if (diffX > 0) {
+ sb.append("EAST");
+ } else {
+ sb.append("WEST");
+ }
+ }
+
+ if (sb.length() == 0) return null;
+ return Direction.valueOf(sb.toString());
+ }
}
diff --git a/Server/src/main/java/core/game/world/map/Region.java b/Server/src/main/java/core/game/world/map/Region.java
index d5e89f1d6..898a25879 100644
--- a/Server/src/main/java/core/game/world/map/Region.java
+++ b/Server/src/main/java/core/game/world/map/Region.java
@@ -301,8 +301,8 @@ public class Region {
byte[][][] mapscapeData = new byte[4][SIZE][SIZE];
for (RegionPlane plane : r.planes) {
plane.getFlags().setLandscape(new boolean[SIZE][SIZE]);
- plane.getFlags().setClippingFlags(new int[SIZE][SIZE]);
- plane.getProjectileFlags().setClippingFlags(new int[SIZE][SIZE]);
+ //plane.getFlags().setClippingFlags(new int[SIZE][SIZE]);
+ //plane.getProjectileFlags().setClippingFlags(new int[SIZE][SIZE]);
}
if (mapscapeId > -1) {
ByteBuffer mapscape = ByteBuffer.wrap(Cache.getIndexes()[5].getCacheFile().getContainerUnpackedData(mapscapeId));
diff --git a/Server/src/main/java/core/game/world/map/RegionChunk.java b/Server/src/main/java/core/game/world/map/RegionChunk.java
index 4deaabbab..0d8a6beb7 100644
--- a/Server/src/main/java/core/game/world/map/RegionChunk.java
+++ b/Server/src/main/java/core/game/world/map/RegionChunk.java
@@ -194,7 +194,7 @@ public class RegionChunk {
copy[x][y] = objects[x][y];
staticCopy[x][y] = plane.getObjects()[baseX + x][baseY + y];
objects[x][y] = plane.getObjects()[baseX + x][baseY + y] = null;
- plane.getFlags().getClippingFlags()[baseX + x][baseY + y] = 0;
+ plane.getFlags().clearFlag(baseX + x, baseY + y);
}
}
rotation = direction.toInteger();
diff --git a/Server/src/main/java/core/game/world/map/RegionManager.kt b/Server/src/main/java/core/game/world/map/RegionManager.kt
index 5d1d2912e..6339762db 100644
--- a/Server/src/main/java/core/game/world/map/RegionManager.kt
+++ b/Server/src/main/java/core/game/world/map/RegionManager.kt
@@ -11,6 +11,7 @@ import rs09.game.system.SystemLogger
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock
+import kotlin.collections.HashMap
/**
* Manages the regions.
@@ -21,6 +22,8 @@ object RegionManager {
* The region cache mapping.
*/
private val REGION_CACHE: MutableMap = HashMap()
+ @JvmStatic val CLIPPING_FLAGS = HashMap>()
+ @JvmStatic val PROJECTILE_FLAGS = HashMap>()
public val LOCK = ReentrantLock()
@@ -80,16 +83,50 @@ object RegionManager {
*/
@JvmStatic
fun getClippingFlag(z: Int, x: Int, y: Int): Int {
- var x = x
- var y = y
- val region = forId(((x shr 6) shl 8) or (y shr 6))
- Region.load(region)
- if (!region.isHasFlags) {
- return -1
+ val regionX = x shr 6
+ val regionY = y shr 6
+ val localX = x and 63
+ val localY = y and 63
+ return getClippingFlag(z, regionX, regionY, localX, localY)
+ }
+
+ /**
+ * Gets the clipping flags using Jagex-style coords
+ * e.g 0_50_50_13_13 gets plane 0, region 50-50 (12850), (13, 13) which is in lumbridge.
+ */
+ @JvmStatic
+ fun getClippingFlag(z: Int, regionX: Int, regionY: Int, localX: Int, localY: Int, projectile: Boolean = false) : Int {
+ val (region, index) = getFlagIndex(z, regionX, regionY, localX, localY)
+ var flag = getFlags(region, projectile)[index]
+
+ if (flag == -1) {
+ val r = forId((regionX shr 8) or regionY)
+ if (!r.isLoaded)
+ Region.load(r)
+ if (!r.isHasFlags)
+ return -1
+ flag = getFlags(region, projectile)[index]
}
- x -= (x shr 6) shl 6
- y -= (y shr 6) shl 6
- return region.planes[z].flags.clippingFlags[x][y]
+
+ return flag
+ }
+
+ private fun getFlagIndex(z: Int, regionX: Int, regionY: Int, localX: Int, localY: Int) : Pair {
+ return Pair((regionX shl 8) or regionY, (z * 64 * 64) + (localX * 64) + localY)
+ }
+
+ @JvmStatic
+ fun getFlags(regionX: Int, regionY: Int, projectile: Boolean) : Array {
+ val region = (regionX shl 8) or regionY
+ return getFlags(region, projectile)
+ }
+
+ @JvmStatic
+ fun getFlags(regionId: Int, projectile: Boolean) : Array {
+ return if (projectile)
+ PROJECTILE_FLAGS.getOrPut (regionId) {Array(16384){0}}
+ else
+ CLIPPING_FLAGS.getOrPut (regionId) {Array(16384){-1}}
}
/**
@@ -136,26 +173,6 @@ object RegionManager {
return region.planes[z].flags.landscape[x][y]
}
- /**
- * Sets the clipping flag on the given location.
- * @param l The location.
- * @param flag The flag to set.
- */
- @JvmStatic
- fun setClippingFlag(l: Location, flag: Int) {
- var x = l.x
- var y = l.y
- val z = l.z
- val region = forId(((x shr 6) shl 8) or (y shr 6))
- Region.load(region)
- if (!region.isHasFlags) {
- return
- }
- x -= x shr 6 shl 6
- y -= y shr 6 shl 6
- region.planes[z].flags.clippingFlags[x][y] = flag
- }
-
/**
* Adds a clipping flag.
* @param z The plane.
@@ -217,16 +234,11 @@ object RegionManager {
*/
@JvmStatic
fun getProjectileFlag(z: Int, x: Int, y: Int): Int {
- var x = x
- var y = y
- val region = forId(((x shr 6) shl 8) or (y shr 6))
- Region.load(region)
- if (!region.isHasFlags) {
- return -1
- }
- x -= (x shr 6) shl 6
- y -= (y shr 6) shl 6
- return region.planes[z].projectileFlags.clippingFlags[x][y]
+ val regionX = x shr 6
+ val regionY = y shr 6
+ val localX = x and 63
+ val localY = y and 63
+ return getClippingFlag(z, regionX, regionY, localX, localY, true)
}
/**
diff --git a/Server/src/main/java/core/game/world/map/build/DynamicRegion.java b/Server/src/main/java/core/game/world/map/build/DynamicRegion.java
index a07c24314..2e45a22a8 100644
--- a/Server/src/main/java/core/game/world/map/build/DynamicRegion.java
+++ b/Server/src/main/java/core/game/world/map/build/DynamicRegion.java
@@ -320,8 +320,8 @@ public final class DynamicRegion extends Region {
if (chunk == null) {
for (int i = x << 3; i < (x + 1) << 3; i++) {
for (int j = y << 3; j < (y + 1) << 3; j++) {
- p.getFlags().getClippingFlags()[i][j] = -1;
- p.getProjectileFlags().getClippingFlags()[i][j] = -1;
+ p.getFlags().invalidateFlag(i, j);
+ p.getProjectileFlags().invalidateFlag(i, j);
Scenery object = p.getObjects()[i][j];
if (object != null) {
LandscapeParser.removeScenery(object);
@@ -344,8 +344,8 @@ public final class DynamicRegion extends Region {
int fromX = (l.getX() - regionBase.getX()) + i;
int fromY = (l.getY() - regionBase.getY()) + j;
p.getFlags().getLandscape()[toX][toY] = rp.getFlags().getLandscape()[fromX][fromY];
- p.getFlags().getClippingFlags()[toX][toY] = rp.getFlags().getClippingFlags()[fromX][fromY];
- p.getProjectileFlags().getClippingFlags()[toX][toY] = rp.getProjectileFlags().getClippingFlags()[fromX][fromY];
+ p.getFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY));
+ p.getProjectileFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY));
Scenery[] objects = { rp.getChunkObject(fromX, fromY) };
RegionChunk ch = rp.getChunks()[fromX >> 3][fromY >> 3];
if (ch instanceof BuildRegionChunk) {
diff --git a/Server/src/main/java/core/game/world/map/build/MapscapeParser.java b/Server/src/main/java/core/game/world/map/build/MapscapeParser.java
index 896a464ee..7ecc4c81c 100644
--- a/Server/src/main/java/core/game/world/map/build/MapscapeParser.java
+++ b/Server/src/main/java/core/game/world/map/build/MapscapeParser.java
@@ -60,6 +60,7 @@ public final class MapscapeParser {
for (int z = 0; z < 4; z++) {
for (int x = 0; x < 64; x++) {
for (int y = 0; y < 64; y++) {
+ r.getPlanes()[z].getFlags().flagEmptyTile(x,y);
if ((mapscape[z][x][y] & 0x1) == 1) {
int plane = z;
if ((mapscape[1][x][y] & 0x2) == 2) {
diff --git a/Server/src/main/java/core/game/world/map/build/RegionFlags.java b/Server/src/main/java/core/game/world/map/build/RegionFlags.java
index 131407bca..8b65845ae 100644
--- a/Server/src/main/java/core/game/world/map/build/RegionFlags.java
+++ b/Server/src/main/java/core/game/world/map/build/RegionFlags.java
@@ -1,6 +1,10 @@
package core.game.world.map.build;
import core.game.world.map.RegionManager;
+import kotlin.Pair;
+import rs09.game.system.SystemLogger;
+
+import static java.lang.Math.max;
/**
* Holds a region's flags like clipping flags, members, ...
@@ -9,6 +13,11 @@ import core.game.world.map.RegionManager;
*/
public final class RegionFlags {
+ public static final int TILE_OBJECT = 0x40000;
+ public static final int EMPTY_TILE = 0;
+ public static final int SOLID_TILE = 0x200000;
+ public static final int OBJ_10_PROJECTILE = 0x20000;
+ public static final int OBJ_10 = 0x100;
/**
* The plane.
*/
@@ -28,11 +37,6 @@ public final class RegionFlags {
* The base y-coordinate.
*/
private final int baseY;
-
- /**
- * The clipping flags.
- */
- private int[][] clippingFlags;
/**
* The landscape data.
@@ -42,7 +46,7 @@ public final class RegionFlags {
/**
* If the flags are set for projectile clipping
*/
- private boolean projectile;
+ private final boolean projectile;
/**
* Constructs a new {@code RegionFlags} {@code Object}.
@@ -71,7 +75,11 @@ public final class RegionFlags {
* @param y The y-coordinate.
*/
public void flagSolidTile(int x, int y) {
- clippingFlags[x][y] |= 0x200000;
+ flag(x, y, SOLID_TILE);
+ }
+
+ public void flagEmptyTile(int x, int y) {
+ flag(x, y, EMPTY_TILE);
}
/**
@@ -80,7 +88,7 @@ public final class RegionFlags {
* @param y The y-coordinate.
*/
public void flagTileObject(int x, int y) {
- clippingFlags[x][y] |= 0x40000;
+ flag(x, y, TILE_OBJECT);
}
/**
@@ -89,12 +97,7 @@ public final class RegionFlags {
* @param y The y-coordinate.
*/
public void unflagTileObject(int x, int y) {
- if (clippingFlags == null) {
- return;
- }
- if ((clippingFlags[x][y] & 0x40000) != 0) {
- clippingFlags[x][y] &= ~0x40000;
- }
+ unflag(x, y, TILE_OBJECT);
}
/**
@@ -106,9 +109,9 @@ public final class RegionFlags {
* @param projectileClipped If the object is solid.
*/
public void flagSolidObject(int x, int y, int sizeX, int sizeY, boolean projectileClipped) {
- int clipdata = 0x100;
+ int clipdata = OBJ_10;
if (projectileClipped) {
- clipdata += 0x20000;
+ clipdata += OBJ_10_PROJECTILE;
}
for (int i = x; i < x + sizeX; i++) {
for (int j = y; j < y + sizeY; j++) {
@@ -125,12 +128,11 @@ public final class RegionFlags {
*/
public void flag(int x, int y, int clipdata) {
if (x > -1 && x < 64 && y > -1 && y < 64) {
- clippingFlags[x][y] |= clipdata;
+ addFlag(x, y, clipdata);
} else {
RegionManager.addClippingFlag(plane, baseX + x, baseY + y, projectile, clipdata);
}
}
-
/**
* Unflags a solid object (type 10/11).
@@ -141,9 +143,9 @@ public final class RegionFlags {
* @param projectileClipped If the object is solid.
*/
public void unflagSolidObject(int x, int y, int sizeX, int sizeY, boolean projectileClipped) {
- int clipdata = 0x100;
+ int clipdata = OBJ_10;
if (projectileClipped) {
- clipdata += 0x20000;
+ clipdata += OBJ_10_PROJECTILE;
}
for (int i = x; i < x + sizeX; i++) {
for (int j = y; j < y + sizeY; j++) {
@@ -159,18 +161,47 @@ public final class RegionFlags {
* @param clipdata The clip data.
*/
public void unflag(int x, int y, int clipdata) {
- if (clippingFlags == null) {
- return;
- }
if (x > -1 && x < 64 && y > -1 && y < 64) {
- if ((clippingFlags[x][y] & clipdata) != 0) {
- clippingFlags[x][y] &= ~clipdata;
- }
+ removeFlag(x, y, clipdata);
} else {
RegionManager.removeClippingFlag(plane, baseX + x, baseY + y, projectile, clipdata);
}
}
+ private Pair getFlagIndex(int x, int y) {
+ return new Pair<>(((baseX >> 6) << 8) | (baseY >> 6), (plane * 64 * 64) + (x * 64) + y);
+ }
+
+ public int getFlag(int x, int y) {
+ Pair indices = getFlagIndex(x, y);
+ return RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()];
+ }
+
+ public void addFlag(int x, int y, int clipdata) {
+ int current = getFlag(x, y);
+ Pair indices = getFlagIndex(x, y);
+ RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = max(0, current) | clipdata;
+ }
+
+ public void removeFlag(int x, int y, int clipdata) {
+ int current = getFlag(x, y);
+ Pair indices = getFlagIndex(x, y);
+ if ((current & clipdata) == 0) return;
+ current = max(0, current) & ~clipdata;
+
+ RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = current;
+ }
+
+ public void clearFlag(int x, int y) {
+ Pair indices = getFlagIndex(x, y);
+ RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = 0;
+ }
+
+ public void invalidateFlag(int x, int y) {
+ Pair indices = getFlagIndex(x, y);
+ RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = -1;
+ }
+
/**
* Flags a door object (type 0-3).
* @param x The x-coordinate
@@ -465,13 +496,6 @@ public final class RegionFlags {
}
}
- /**
- * Unloads the clipping flags.
- */
- public void unload() {
- clippingFlags = null;
- }
-
/**
* Gets the members.
* @return The members.
@@ -488,22 +512,6 @@ public final class RegionFlags {
this.members = members;
}
- /**
- * Gets the clippingFlags.
- * @return The clippingFlags.
- */
- public int[][] getClippingFlags() {
- return clippingFlags;
- }
-
- /**
- * Sets the clippingFlags.
- * @param clippingFlags The clippingFlags to set.
- */
- public void setClippingFlags(int[][] clippingFlags) {
- this.clippingFlags = clippingFlags;
- }
-
/**
* Gets the plane.
* @return The plane.
diff --git a/Server/src/main/java/core/game/world/map/path/DumbPathfinder.java b/Server/src/main/java/core/game/world/map/path/DumbPathfinder.java
index 0080f3480..962932ea2 100644
--- a/Server/src/main/java/core/game/world/map/path/DumbPathfinder.java
+++ b/Server/src/main/java/core/game/world/map/path/DumbPathfinder.java
@@ -14,7 +14,6 @@ import java.util.List;
* @author Emperor
*/
public final class DumbPathfinder extends Pathfinder {
-
/**
* If a path can be found.
*/
@@ -103,7 +102,7 @@ public final class DumbPathfinder extends Pathfinder {
found = true;
switch (dir) {
case NORTH:
- if ((clipMaskSupplier.getClippingFlag(z, x, y + 1) & 0x12c0120) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0) {
found = false;
break;
}
@@ -111,7 +110,7 @@ public final class DumbPathfinder extends Pathfinder {
y++;
break;
case NORTH_EAST:
- if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & 0x12c0180) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & 0x12c0120) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y + 1) & 0x12c01e0) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y + 1) & PREVENT_NORTHEAST) != 0) {
found = false;
break;
}
@@ -120,7 +119,7 @@ public final class DumbPathfinder extends Pathfinder {
y++;
break;
case EAST:
- if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & 0x12c0180) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0) {
found = false;
break;
}
@@ -128,7 +127,7 @@ public final class DumbPathfinder extends Pathfinder {
x++;
break;
case SOUTH_EAST:
- if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & 0x12c0180) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c0102) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & 0x12c0183) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & PREVENT_SOUTHEAST) != 0) {
found = false;
break;
}
@@ -137,7 +136,7 @@ public final class DumbPathfinder extends Pathfinder {
y--;
break;
case SOUTH:
- if ((clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c0102) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0) {
found = false;
break;
}
@@ -145,7 +144,7 @@ public final class DumbPathfinder extends Pathfinder {
y--;
break;
case SOUTH_WEST:
- if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c0108) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c0102) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y - 1) & 0x12c010e) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y - 1) & PREVENT_SOUTHWEST) != 0) {
found = false;
break;
}
@@ -154,7 +153,7 @@ public final class DumbPathfinder extends Pathfinder {
y--;
break;
case WEST:
- if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c0108) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0) {
found = false;
break;
}
@@ -162,7 +161,7 @@ public final class DumbPathfinder extends Pathfinder {
x--;
break;
case NORTH_WEST:
- if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c0108) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & 0x12c0120) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & 0x12c0138) != 0) {
+ if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & PREVENT_NORTHWEST) != 0) {
found = false;
break;
}
diff --git a/Server/src/main/java/core/game/world/map/path/Pathfinder.java b/Server/src/main/java/core/game/world/map/path/Pathfinder.java
index 7d0a81d23..1f75d3dc8 100644
--- a/Server/src/main/java/core/game/world/map/path/Pathfinder.java
+++ b/Server/src/main/java/core/game/world/map/path/Pathfinder.java
@@ -9,6 +9,15 @@ import core.game.world.map.RegionManager;
import rs09.game.world.map.path.SmartPathfinder;
public abstract class Pathfinder {
+ public static final int PREVENT_NORTH = 0x12c0120;
+ public static final int PREVENT_EAST = 0x12c0180;
+ public static final int PREVENT_NORTHEAST = 0x12c01e0;
+ public static final int PREVENT_SOUTH = 0x12c0102;
+ public static final int PREVENT_SOUTHEAST = 0x12c0183;
+ public static final int PREVENT_WEST = 0x12c0108;
+ public static final int PREVENT_SOUTHWEST = 0x12c010e;
+ public static final int PREVENT_NORTHWEST = 0x12c0138;
+
/**
* The smart path finder.
diff --git a/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java b/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java
index 0359526c8..545a93a0a 100644
--- a/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java
+++ b/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java
@@ -7,6 +7,8 @@ import core.game.node.item.Item;
import core.net.packet.IncomingPacket;
import core.net.packet.IoBuffer;
+import static api.ContentAPIKt.getAttribute;
+
/**
* Represents the packet to handle an item slot switch.
* @author 'Vexia
@@ -82,7 +84,7 @@ public class SlotSwitchPacket implements IncomingPacket {
final Item item = container.get(slot);
final Item second = container.get(secondSlot);
- if (player.getInterfaceManager().hasChatbox()) {
+ if (player.getInterfaceManager().hasChatbox() && !getAttribute(player, "close_c_", false)) {
player.getInterfaceManager().closeChatbox();
switchItem(secondSlot,slot,container,insert,player);
container.refresh();
diff --git a/Server/src/main/kotlin/rs09/ServerConstants.kt b/Server/src/main/kotlin/rs09/ServerConstants.kt
index 165c9f8f3..c38e41c10 100644
--- a/Server/src/main/kotlin/rs09/ServerConstants.kt
+++ b/Server/src/main/kotlin/rs09/ServerConstants.kt
@@ -217,5 +217,8 @@ class ServerConstants {
@JvmField
var DISCORD_GE_WEBHOOK = ""
+
+ @JvmField
+ var PRELOAD_MAP = false
}
}
diff --git a/Server/src/main/kotlin/rs09/game/ai/general/ScriptAPI.kt b/Server/src/main/kotlin/rs09/game/ai/general/ScriptAPI.kt
index 892ce6dfa..9a448795e 100644
--- a/Server/src/main/kotlin/rs09/game/ai/general/ScriptAPI.kt
+++ b/Server/src/main/kotlin/rs09/game/ai/general/ScriptAPI.kt
@@ -24,7 +24,9 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation
+import core.game.world.update.flag.context.ChatMessage
import core.game.world.update.flag.context.Graphics
+import core.game.world.update.flag.player.ChatFlag
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -99,6 +101,11 @@ class ScriptAPI(private val bot: Player) {
return entity
}
+ fun sendChat(message: String) {
+ bot.sendChat(message)
+ bot.updateMasks.register(ChatFlag(ChatMessage(bot, message, 0, 0)))
+ }
+
/**
* Gets the nearest node with a name contained in the list of acceptable names
* @param acceptedNames the list of accepted npc/object names
@@ -422,7 +429,10 @@ class ScriptAPI(private val bot: Player) {
* A function for teleporting the bot to the GE
* @author Ceikry
*/
- fun teleportToGE(){
+ fun teleportToGE() : Boolean{
+ if (bot.isTeleBlocked) {
+ return false
+ }
bot.lock()
bot.visualize(ANIMATIONUP, GRAPHICSUP)
bot.impactHandler.disabledTicks = 4
@@ -435,6 +445,7 @@ class ScriptAPI(private val bot: Player) {
return true
}
})
+ return true
}
/**
@@ -548,7 +559,10 @@ class ScriptAPI(private val bot: Player) {
* @param loc the location to teleport to
* @author Ceikry
*/
- fun teleport(loc: Location){
+ fun teleport(loc: Location) : Boolean {
+ if (bot.isTeleBlocked) {
+ return false
+ }
bot.lock()
bot.visualize(ANIMATIONUP, GRAPHICSUP)
bot.impactHandler.disabledTicks = 4
@@ -561,6 +575,7 @@ class ScriptAPI(private val bot: Player) {
return true
}
})
+ return true
}
/**
diff --git a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/Adventurer.kt b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/Adventurer.kt
index 46ea0e1e1..cbb0f36d6 100644
--- a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/Adventurer.kt
+++ b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/Adventurer.kt
@@ -457,8 +457,7 @@ class Adventurer(val style: CombatStyle): Script() {
.replace("@name", localPlayer.username)
.replace("@timer", until.toString())
- bot.sendChat(chat)
- bot.updateMasks.register(ChatFlag(ChatMessage(bot, chat, 0, 0)))
+ scriptAPI.sendChat(chat)
}
enum class State{
diff --git a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/GreenDragonKiller.kt b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/GreenDragonKiller.kt
index 7142f2d1d..278120b0d 100644
--- a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/GreenDragonKiller.kt
+++ b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/GreenDragonKiller.kt
@@ -8,6 +8,7 @@ import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.combat.InteractionType
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
+import core.game.node.entity.skill.prayer.BoneBuryingOptionPlugin
import core.game.node.entity.state.EntityState
import core.game.node.item.Item
import core.game.system.task.Pulse
@@ -15,6 +16,7 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.impl.WildernessZone
+import core.tools.RandomFunction
import org.rs09.consts.Items
import rs09.game.ai.AIRepository
import rs09.game.ai.pvmbots.CombatBotAssembler
@@ -25,16 +27,24 @@ import rs09.game.node.entity.combat.handlers.RangeSwingHandler
import kotlin.random.Random
/**
- * A bot script for killing green dragons in the wilderness.. Capable of banking, selling on ge, buying on ge, eating and more.
+ * A bot script for killing green dragons in the wilderness.. Capable of banking, selling on ge, eating, trash talking, buries bones when fleeing and more.
* @param style The combat style the bot is going to use.
* @param area (optional) What area the bot tries to kill dragons in.
* @author Ceikry
*/
class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Script() {
- var state = State.KILLING
+ companion object {
+ val westDragons = ZoneBorders(2971,3606,2991,3628)
+ val wildernessLine = ZoneBorders(3078,3523,3096,3523)
+ val edgevilleLine = ZoneBorders(3078,3520,3096,3520)
+ val bankZone = ZoneBorders(3092,3489,3094,3493)
+ val trashTalkLines = arrayOf("Bro, seriously?", "Ffs.", "Jesus christ.", "????", "Friendly!", "Get a life dude", "Do you mind??? lol", "Lol.", "Kek.", "One sec burying all the bones.", "Yikes.", "Yeet", "Ah shit, here we go again.", "Cmonnnn", "Plz", "Do you have nothing better to do?", "Cmon bro pls", "I just need to get my prayer up bro jesus", "Reeeeeee", "I cant believe you've done this", "Really m8", "Zomg", "Aaaaaaaaaaaaaaaaaaaaa", "Rofl.", "Oh god oh fuck oh shit", "....", ":|", "A q p", "Hcim btw", "I hope the revenants kill your mum", "Wrap your ass titties", "Why do this", "Bruh", "Straight sussin no cap fr fr", "This ain't bussin dawg", "Really bro?")
+ }
+ var state = State.TO_BANK
var handler: CombatSwingHandler? = null
var lootDelay = 0
var offerMade = false
+ var trashTalkDelay = 0
var food = if (Random.nextBoolean()){
Items.LOBSTER_379
@@ -45,28 +55,18 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
}
var myBorders: ZoneBorders? = null
- val type = when(style){
- CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE
- CombatStyle.MAGIC -> CombatBotAssembler.Type.MAGE
- CombatStyle.RANGE -> CombatBotAssembler.Type.RANGE
- }
+ val type = CombatBotAssembler.Type.MELEE
- val westDragons = ZoneBorders(2971,3606,2991,3628)
- val wildernessLine = ZoneBorders(3078,3523,3096,3523)
- val edgevilleLine = ZoneBorders(3078,3520,3096,3520)
- val bankZone = ZoneBorders(3092,3489,3094,3493)
override fun tick() {
if(!bot.isActive){
running = false
return
}
- if(bot.inventory.getAmount(food) < 3 && state == State.KILLING)
- state = State.TO_BANK
- scriptAPI.eat(food)
+
+ checkFoodStockAndEat()
+
when(state){
-
-
State.KILLING -> {
bot.properties.combatPulse.temporaryHandler = handler
scriptAPI.attackNpcInRadius(bot,"Green dragon",20)
@@ -86,11 +86,13 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
if(players.isEmpty()){
state = State.TO_DRAGONS
} else {
- if(bot.skullManager.level < 21 && bot.stateManager.get(EntityState.TELEBLOCK) != null){
- scriptAPI.teleportToGE()
- state = State.REFRESHING
+ if(bot.skullManager.level < 21){
+ if (scriptAPI.teleportToGE())
+ state = State.REFRESHING
return
}
+ sendTrashTalk()
+ attemptToBuryBone()
scriptAPI.walkTo(WildernessZone.getInstance().borders.random().randomLoc)
}
}
@@ -107,7 +109,7 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
}
return
}
- items.forEach {it: Item -> scriptAPI.takeNearestGroundItem(it.id)}
+ items.toTypedArray().forEach {it: Item -> scriptAPI.takeNearestGroundItem(it.id)}
}
State.TO_BANK -> {
@@ -157,25 +159,10 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
}
State.BUYING_FOOD -> {
- if(!offerMade)
- {
- scriptAPI.buyFromGE(bot, food, 100)
- offerMade = true
- } else
- {
- val offer = AIRepository.getOffer(bot)
- if (offer == null) {
- offerMade = false
- } else {
- if (offer.completedAmount == offer.amount) {
- state = State.TO_DRAGONS
- offer.offerState = OfferState.REMOVED
- bot.bank.add(Item(offer.itemID, offer.completedAmount))
- bot.bank.refresh()
- scriptAPI.withdraw(food, 10)
- }
- }
- }
+ state = State.TO_DRAGONS
+ bot.bank.add(Item(food,50))
+ bot.bank.refresh()
+ scriptAPI.withdraw(food, 10)
}
State.TO_DRAGONS -> {
@@ -236,13 +223,29 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
}
}
+ private fun attemptToBuryBone() {
+ if (bot.inventory.containsAtLeastOneItem(Items.DRAGON_BONES_536)) {
+ BoneBuryingOptionPlugin().handle(bot, bot.inventory.get(Item(Items.DRAGON_BONES_536)), "bury")
+ }
+ }
+
+ private fun checkFoodStockAndEat() {
+ if (bot.inventory.getAmount(food) < 3 && state == State.KILLING)
+ state = State.TO_BANK
+ scriptAPI.eat(food)
+ }
+
+ private fun sendTrashTalk() {
+ if (trashTalkDelay-- == 0)
+ scriptAPI.sendChat(trashTalkLines.random())
+ else
+ trashTalkDelay = RandomFunction.random(10, 30)
+ }
+
override fun newInstance(): Script {
val script = GreenDragonKiller(style)
- val tier = CombatBotAssembler.Tier.HIGH
- if(type == CombatBotAssembler.Type.RANGE)
- script.bot = CombatBotAssembler().assembleRangeDragonBot(tier,bot.startLocation)
- else
- script.bot = CombatBotAssembler().assembleMeleeDragonBot(tier, bot.startLocation)
+ val tier = CombatBotAssembler.Tier.MED
+ script.bot = CombatBotAssembler().assembleMeleeDragonBot(tier, bot.startLocation)
return script
}
@@ -262,11 +265,7 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
}
init {
- handler = when(style){
- CombatStyle.MELEE -> MeleeSwinger(this)
- CombatStyle.MAGIC -> MageSwinger(this)
- CombatStyle.RANGE -> RangeSwinger(this)
- }
+ handler = MeleeSwinger(this)
equipment.add(Item(Items.ANTI_DRAGON_SHIELD_1540))
myBorders = westDragons
skills[Skills.AGILITY] = 99
@@ -276,22 +275,10 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
internal class MeleeSwinger(val script: GreenDragonKiller) : MeleeSwingHandler() {
override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
- if(script.state == State.TO_BANK) {script.bot.pulseManager.current.stop()}
- if(victim is Player) {script.state = State.RUNNING; script.bot.pulseManager.current.stop()}
- return super.canSwing(entity, victim)
- }
- }
-
- internal class MageSwinger(val script: GreenDragonKiller) : MagicSwingHandler() {
- override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
- if(victim is Player) {script.state = State.RUNNING; script.bot.pulseManager.current.stop()}
- return super.canSwing(entity, victim)
- }
- }
-
- internal class RangeSwinger(val script: GreenDragonKiller) : RangeSwingHandler() {
- override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
- if(victim is Player) {script.state = State.RUNNING; script.bot.pulseManager.current.stop()}
+ if(victim is Player || victim.name.contains("revenant", ignoreCase = true)) {
+ script.state = State.RUNNING
+ script.bot.pulseManager.current.stop()
+ }
return super.canSwing(entity, victim)
}
}
diff --git a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt
index 57008405e..c8030de35 100644
--- a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt
+++ b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt
@@ -5,9 +5,11 @@ import core.game.content.dialogue.FacialExpression
import core.game.content.global.action.ClimbActionHandler
import core.game.content.global.action.DoorActionHandler
import core.game.node.scenery.Scenery
+import core.game.system.task.Pulse
import core.game.world.map.Location
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
+import rs09.game.world.repository.Repository
/**
* Handles tutorial-specific node interactions
@@ -19,6 +21,7 @@ class TutorialListeners : InteractionListener {
val COOKS_EXIT = 3018
val QUEST_ENTER = 3019
val QUEST_LADDER = 3029
+ val QUEST_EXIT_LADDER = 3028
val COMBAT_EXIT = 3030
val BANK_EXIT = 3024
val FINANCE_EXIT = 3025
@@ -80,14 +83,30 @@ class TutorialListeners : InteractionListener {
}
on(QUEST_LADDER, SCENERY, "climb-down") {player, ladder ->
- if(getAttribute(player, "tutorial:stage", 0) != 29)
+ if(getAttribute(player, "tutorial:stage", 0) < 29)
return@on true
- setAttribute(player, "tutorial:stage", 30)
- TutorialStage.load(player, 30)
+ if (getAttribute(player, "tutorial:stage", 0) == 29) {
+ setAttribute(player, "tutorial:stage", 30)
+ TutorialStage.load(player, 30)
+ }
ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-down")
}
+ on(QUEST_EXIT_LADDER, SCENERY, "climb-up") { player, ladder ->
+ ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-up")
+
+ submitWorldPulse(object : Pulse(2) {
+ override fun pulse(): Boolean {
+ val questTutor = Repository.findNPC(NPCs.QUEST_GUIDE_949) ?: return true
+ sendChat(questTutor, "What are you doing, ${player.username}? Get back down the ladder.")
+ return true
+ }
+ })
+
+ return@on true
+ }
+
on(COMBAT_GATES, SCENERY, "open"){player, gate ->
if(getAttribute(player, "tutorial:stage", 0) != 43)
return@on true
diff --git a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialMagicTutorDialogue.kt b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialMagicTutorDialogue.kt
index d42b1f6ad..4e80fcba3 100644
--- a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialMagicTutorDialogue.kt
+++ b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialMagicTutorDialogue.kt
@@ -10,15 +10,19 @@ import core.game.node.entity.player.link.InterfaceManager
import core.game.node.entity.player.link.IronmanMode
import core.game.node.entity.player.link.TeleportManager
import core.game.node.item.Item
+import core.game.system.communication.ClanRepository
import core.game.world.map.Location
import core.net.amsc.MSPacketRepository
import core.net.amsc.WorldCommunicator
import core.plugin.Initializable
import org.rs09.consts.Items
import org.rs09.consts.NPCs
+import proto.management.JoinClanRequest
+import rs09.ServerConstants
import rs09.game.interaction.inter.RulesAndInfo
import rs09.game.world.GameWorld
import rs09.tools.END_DIALOGUE
+import rs09.worker.ManagementEvents
/**
* Handles the magic tutor's dialogue
@@ -179,6 +183,16 @@ class TutorialMagicTutorDialogue(player: Player? = null) : DialoguePlugin(player
player.unhook(TutorialInteractionReceiver)
player.unhook(TutorialButtonReceiver)
RulesAndInfo.openFor(player)
+
+ if (GameWorld.settings!!.enable_default_clan) {
+ player.communication.currentClan = ServerConstants.SERVER_NAME
+
+ val clanJoin = JoinClanRequest.newBuilder()
+ clanJoin.clanName = ServerConstants.SERVER_NAME
+ clanJoin.username = player.name
+
+ ManagementEvents.publish(clanJoin.build())
+ }
}
12 -> {
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/combat/CombatSwingHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/combat/CombatSwingHandler.kt
index 04ae9f39b..7334df20c 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/combat/CombatSwingHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/combat/CombatSwingHandler.kt
@@ -1,7 +1,6 @@
package rs09.game.node.entity.combat
import core.game.component.Component
-import core.game.container.Container
import core.game.container.impl.EquipmentContainer
import core.game.node.Node
import core.game.node.entity.Entity
@@ -15,8 +14,12 @@ import core.game.node.entity.player.link.audio.Audio
import core.game.node.entity.player.link.prayer.PrayerType
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.summoning.familiar.Familiar
+import core.game.world.map.Direction
+import core.game.world.map.Location
import core.game.world.map.RegionManager
+import core.game.world.map.RegionManager.getClippingFlag
import core.game.world.map.path.Pathfinder
+import core.game.world.map.path.Pathfinder.*
import core.game.world.update.flag.context.Animation
import core.tools.RandomFunction
import rs09.game.system.SystemLogger
@@ -207,6 +210,11 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
* @return `True` if so.
*/
open fun isAttackable(entity: Entity, victim: Entity): InteractionType? {
+ if (type == CombatStyle.MELEE) {
+ val stepType = canStepTowards(entity, victim)
+ if (stepType != InteractionType.STILL_INTERACT) return stepType
+ }
+
val comp = entity.getAttribute("autocast_component",null) as Component?
if((comp != null || type == CombatStyle.MAGIC) && (entity.properties.autocastSpell == null || entity.properties.autocastSpell.spellId == 0) && entity is Player){
val weapEx = entity.getExtension(WeaponInterface::class.java) as WeaponInterface?
@@ -235,6 +243,74 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
return InteractionType.STILL_INTERACT
}
+ private fun canStepTowards(entity: Entity, victim: Entity): InteractionType {
+ val closestVictimTile = victim.getClosestOccupiedTile(entity.location)
+ val closestEntityTile = entity.getClosestOccupiedTile(closestVictimTile)
+ val dir = closestEntityTile.deriveDirection(closestVictimTile)
+ ?: return InteractionType.STILL_INTERACT //if we cannot derive a direction, it's because both tiles are the same, so hand off control to the main logic which already handles this case
+ var next = closestEntityTile
+
+ while (next.getDistance(closestVictimTile) > 3) { //skip the initial gap in distance if it exists, because standard pathfinding would already stop us before this point if something was between us and the NPC or vice versa
+ next = next.transform(dir)
+ }
+
+ var result: InteractionType = InteractionType.STILL_INTERACT
+ val maxIterations = next.getDistance(closestVictimTile).toInt()
+ for (i in 0..maxIterations) { //step towards the target tile, checking if anything would obstruct us on the way, and immediately breaking + returning if it does.
+ next = next.transform(dir)
+ result = checkStepInterval(dir, next)
+ if (result == InteractionType.NO_INTERACT) break
+ }
+
+
+ return result
+ }
+
+ private fun checkStepInterval(
+ dir: Direction,
+ next: Location
+ ): InteractionType {
+ val components = next.getStepComponents(dir)
+
+ when (dir) {
+ Direction.NORTH -> if (getClippingFlag(next) and PREVENT_NORTH != 0) return InteractionType.NO_INTERACT
+ Direction.EAST -> if (getClippingFlag(next) and PREVENT_EAST != 0) return InteractionType.NO_INTERACT
+ Direction.SOUTH -> if (getClippingFlag(next) and PREVENT_SOUTH != 0) return InteractionType.NO_INTERACT
+ Direction.WEST -> if (getClippingFlag(next) and PREVENT_WEST != 0) return InteractionType.NO_INTERACT
+
+ Direction.NORTH_EAST -> {
+ if (getClippingFlag(components[0]) and PREVENT_EAST != 0
+ || getClippingFlag(components[1]) and PREVENT_NORTH != 0
+ || getClippingFlag(next) and PREVENT_NORTHEAST != 0
+ ) return InteractionType.NO_INTERACT
+ }
+
+ Direction.NORTH_WEST -> {
+ if (getClippingFlag(components[0]) and PREVENT_WEST != 0
+ || getClippingFlag(components[1]) and PREVENT_NORTH != 0
+ || getClippingFlag(next) and PREVENT_NORTHWEST != 0
+ ) return InteractionType.NO_INTERACT
+ }
+
+ Direction.SOUTH_EAST -> {
+ if (getClippingFlag(components[0]) and PREVENT_EAST != 0
+ || getClippingFlag(components[1]) and PREVENT_SOUTH != 0
+ || getClippingFlag(next) and PREVENT_SOUTHEAST != 0
+ ) return InteractionType.NO_INTERACT
+ }
+
+ Direction.SOUTH_WEST -> {
+ if (getClippingFlag(components[0]) and PREVENT_WEST != 0
+ || getClippingFlag(components[1]) and PREVENT_SOUTH != 0
+ || getClippingFlag(next) and PREVENT_SOUTHWEST != 0
+ ) return InteractionType.NO_INTERACT
+ }
+
+ }
+
+ return InteractionType.STILL_INTERACT
+ }
+
/**
* Gets the dragonfire message.
* @param protection The protection value.
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt
index 644d6a884..8ec41e551 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt
@@ -55,6 +55,9 @@ class ModernListeners : SpellListener("modern"){
override fun defineListeners() {
onCast(Modern.HOME_TELEPORT,NONE){player, _ ->
+ if (!getAttribute(player, "tutorial:complete", false)) {
+ return@onCast
+ }
requires(player)
player.teleporter.send(ServerConstants.HOME_LOCATION,TeleportManager.TeleportType.HOME)
setDelay(player,true)
diff --git a/Server/src/main/kotlin/rs09/game/system/config/ServerConfigParser.kt b/Server/src/main/kotlin/rs09/game/system/config/ServerConfigParser.kt
index e88c06ac7..4bc385a8a 100644
--- a/Server/src/main/kotlin/rs09/game/system/config/ServerConfigParser.kt
+++ b/Server/src/main/kotlin/rs09/game/system/config/ServerConfigParser.kt
@@ -115,6 +115,7 @@ object ServerConfigParser {
ServerConstants.SERVER_GE_NAME = data.getString("world.name_ge") ?: ServerConstants.SERVER_NAME
ServerConstants.RULES_AND_INFO_ENABLED = data.getBoolean("world.show_rules", true)
ServerConstants.BOTS_INFLUENCE_PRICE_INDEX = data.getBoolean("world.bots_influence_ge_price", true)
+ ServerConstants.PRELOAD_MAP = data.getBoolean("server.preload_map", false)
ServerConstants.REVENANT_POPULATION = data.getLong("world.revenant_population", 30L).toInt()
ServerConstants.BANK_BOOTH_QUICK_OPEN = data.getBoolean("world.bank_booth_quick_open", false)
ServerConstants.DISCORD_GE_WEBHOOK = data.getString("server.discord_webhook", "")
diff --git a/Server/src/main/kotlin/rs09/game/world/GameWorld.kt b/Server/src/main/kotlin/rs09/game/world/GameWorld.kt
index 81a5bb729..0f6c743d5 100644
--- a/Server/src/main/kotlin/rs09/game/world/GameWorld.kt
+++ b/Server/src/main/kotlin/rs09/game/world/GameWorld.kt
@@ -9,6 +9,7 @@ import core.game.system.SystemState
import core.game.system.task.Pulse
import core.game.system.task.TaskExecutor
import core.game.world.map.Location
+import core.game.world.map.Region
import core.game.world.map.RegionManager
import core.plugin.CorePluginTypes.StartupPlugin
import core.tools.RandomFunction
@@ -179,6 +180,12 @@ object GameWorld {
SystemManager.flag(if (settings?.isDevMode == true) SystemState.PRIVATE else SystemState.ACTIVE)
}
SceneryDefinition.getDefinitions().values.forEach(Consumer { obj: SceneryDefinition -> obj.examine })
+
+ if (ServerConstants.PRELOAD_MAP) {
+ //force early loading of all commonly accessed regions to improve performance at the cost of memory usage
+ (7483..15420).forEach { id -> RegionManager.forId(id).also { Region.load(it) } }
+ }
+
System.gc()
SystemLogger.initTradeLogger()
}
diff --git a/Server/src/main/kotlin/rs09/game/world/ImmerseWorld.kt b/Server/src/main/kotlin/rs09/game/world/ImmerseWorld.kt
index fd1504e92..43711d8d6 100644
--- a/Server/src/main/kotlin/rs09/game/world/ImmerseWorld.kt
+++ b/Server/src/main/kotlin/rs09/game/world/ImmerseWorld.kt
@@ -31,7 +31,7 @@ class ImmerseWorld : StartupListener {
immerseSeersAndCatherby()
immerseLumbridgeDraynor()
immerseVarrock()
- // immerseWilderness() temp disabled due to unbalanced exchange rates
+ immerseWilderness()
immerseFishingGuild()
immerseAdventurer()
// immerseSlayer()
@@ -193,20 +193,13 @@ class ImmerseWorld : StartupListener {
}
fun immerseWilderness() {
- val wilderness = Location.create(2979, 3603, 0)
- for (i in (0..1)) {
- GeneralBotCreator(
- GreenDragonKiller(CombatStyle.MELEE),
- assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.HIGH, wilderness)
- )
- GeneralBotCreator(
+ val wilderness = Location.create(3092, 3493, 0)
+
+ repeat(6) {
+ GeneralBotCreator (
GreenDragonKiller(CombatStyle.MELEE),
assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.MED, wilderness)
)
- GeneralBotCreator(
- GreenDragonKiller(CombatStyle.RANGE),
- assembler.assembleRangedBot(CombatBotAssembler.Tier.HIGH, wilderness)
- )
}
}
diff --git a/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt b/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt
index 1e82f3395..438c9223d 100644
--- a/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt
+++ b/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt
@@ -106,7 +106,7 @@ class MajorUpdateWorker {
//remove all null or finished pulses from the list
rmlist.forEach {
- if (GameWorld.Pulser.TASKS.contains(it)) GameWorld.Pulser.TASKS.remove(it)
+ GameWorld.Pulser.TASKS.remove(it)
}
rmlist.clear()
diff --git a/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt b/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt
index 472fca3e6..585e74d53 100644
--- a/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt
+++ b/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt
@@ -30,6 +30,8 @@ import proto.management.SendClanInfo
import proto.management.SendClanInfo.ClanMember
import proto.management.SendContactInfo
import proto.management.SendContactInfo.Contact
+import rs09.ServerConstants
+import rs09.auth.UserAccountInfo
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import rs09.game.world.repository.Repository
@@ -262,40 +264,29 @@ object ManagementEvents {
is SendClanInfo -> {
if (event.hasInfo) {
- val clan = ClanRepository.getClans().getOrPut(event.clanOwner) { ClanRepository(event.clanOwner) }
- clan.name = event.clanName
- clan.joinRequirement = ClanRank.values()[event.joinRequirement]
- clan.kickRequirement = ClanRank.values()[event.kickRequirement]
- clan.messageRequirement = ClanRank.values()[event.messageRequirement]
- clan.lootRequirement = ClanRank.values()[event.lootRequirement]
-
- for (member in event.membersList) {
- val entry = ClanEntry(member.username, member.world)
- clan.ranks[member.username] = ClanRank.values()[member.rank]
- if (member.world == GameWorld.settings!!.worldId) {
- val p = Repository.getPlayerByName(member.username)
- entry.player = p
- p?.communication?.clan = clan
- }
- clan.players.add(entry)
- }
-
- clan.update()
+ initializeClanFrom(event)
} else {
- val info = GameWorld.accountStorage.getAccountInfo(event.clanOwner)
+ var info = GameWorld.accountStorage.getAccountInfo(event.clanOwner)
if (info.clanName.isNotEmpty()) {
- val reqs = CommunicationInfo.parseClanRequirements(info.clanReqs)
- val c = ClanRepository(event.clanOwner)
- val contacts = CommunicationInfo.parseContacts(info.contacts)
- c.name = info.clanName
- c.joinRequirement = reqs[0]
- c.messageRequirement = reqs[1]
- c.kickRequirement = reqs[2]
- c.lootRequirement = reqs[3]
- for ((username, contact) in contacts) {
- c.ranks[username] = contact.rank
+ initializeClanWith(info)
+ } else {
+ SystemLogger.logMS("Creating default server clan")
+ if (GameWorld.settings!!.enable_default_clan && event.clanOwner == ServerConstants.SERVER_NAME) {
+ //Create a user with the default clan and some basic settings and stick them in the account storage
+ if (info == UserAccountInfo.createDefault()) {
+ info.username = ServerConstants.SERVER_NAME
+ info.password = ServerConstants.MS_SECRET_KEY
+ info.rights = 2
+ SystemLogger.logAlert("Creating default server account: ${info.username}, password is your MS_SECRET_KEY!")
+ GameWorld.authenticator.createAccountWith(info)
+ info = GameWorld.accountStorage.getAccountInfo(event.clanOwner)
+ }
+
+ info.clanName = "Global"
+ info.clanReqs = "-1,-1,7,7" //Any join, any message, owner kick, owner loot
+ GameWorld.accountStorage.update(info)
+ initializeClanWith(info)
}
- ClanRepository.getClans()[event.clanOwner] = c
}
}
@@ -323,7 +314,44 @@ object ManagementEvents {
}
}
-
+
+ private fun initializeClanFrom(event: SendClanInfo) {
+ val clan = ClanRepository.getClans().getOrPut(event.clanOwner) { ClanRepository(event.clanOwner) }
+ clan.name = event.clanName
+ clan.joinRequirement = ClanRank.values()[event.joinRequirement]
+ clan.kickRequirement = ClanRank.values()[event.kickRequirement]
+ clan.messageRequirement = ClanRank.values()[event.messageRequirement]
+ clan.lootRequirement = ClanRank.values()[event.lootRequirement]
+
+ for (member in event.membersList) {
+ val entry = ClanEntry(member.username, member.world)
+ clan.ranks[member.username] = ClanRank.values()[member.rank]
+ if (member.world == GameWorld.settings!!.worldId) {
+ val p = Repository.getPlayerByName(member.username)
+ entry.player = p
+ p?.communication?.clan = clan
+ }
+ clan.players.add(entry)
+ }
+
+ clan.update()
+ }
+
+ private fun initializeClanWith(info: UserAccountInfo) {
+ val reqs = CommunicationInfo.parseClanRequirements(info.clanReqs)
+ val c = ClanRepository(info.username)
+ val contacts = CommunicationInfo.parseContacts(info.contacts)
+ c.name = info.clanName
+ c.joinRequirement = reqs[0]
+ c.messageRequirement = reqs[1]
+ c.kickRequirement = reqs[2]
+ c.lootRequirement = reqs[3]
+ for ((username, contact) in contacts) {
+ c.ranks[username] = contact.rank
+ }
+ ClanRepository.getClans()[info.username] = c
+ }
+
private fun queueUntilClanInfo(clanName: String, message: Message) {
val queue = waitingOnClanInfo.getOrPut(clanName) {LinkedList()}
queue.offer(message)
diff --git a/Server/worldprops/default.conf b/Server/worldprops/default.conf
index 52a6ca919..467a96e60 100644
--- a/Server/worldprops/default.conf
+++ b/Server/worldprops/default.conf
@@ -4,6 +4,9 @@
secret_key = "2009scape_development"
write_logs = true
msip = "127.0.0.1"
+#preload the map (Increases memory usage by 2GB but makes game ticks smoother)
+preload_map = false
+
[database]
database_name = "global"
@@ -15,6 +18,8 @@ database_port = "3306"
[world]
name = "2009scape"
+#name used for announcements of bots selling items on the GE
+name_ge = "2009scape"
debug = true
dev = true
start_gui = false
@@ -49,6 +54,12 @@ wild_pvp_enabled = false
jad_practice_enabled = true
personalized_shops = true
bots_influence_ge_price = true
+#verbose cutscene logging (for cutscenes in the new system)
+verbose_cutscene = false
+#show the rules the first time a player logs in
+show_rules = true
+#the number of revenants active at a time
+revenant_population = 30
[paths]
#path to the data folder, which contains the cache subfolder and such