├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── src
├── main
│ └── java
│ │ └── com
│ │ └── rs
│ │ ├── plugin
│ │ ├── EventListener.java
│ │ ├── event
│ │ │ ├── ReportAbuseEvent.java
│ │ │ ├── PlayerLoggedOutEvent.java
│ │ │ ├── PlayerEvent.java
│ │ │ ├── PlayerLoggedInEvent.java
│ │ │ ├── ActionButtonEvent.java
│ │ │ ├── PublicMessageEvent.java
│ │ │ ├── ModifyPlayerListEvent.java
│ │ │ ├── CommandEvent.java
│ │ │ ├── PrivateMessageEvent.java
│ │ │ └── ModifyChatModeEvent.java
│ │ ├── Event.java
│ │ ├── listener
│ │ │ ├── TickListener.java
│ │ │ ├── PluginStateListener.java
│ │ │ ├── CommandListener.java
│ │ │ ├── ReportAbuseListener.java
│ │ │ ├── ActionButtonListener.java
│ │ │ ├── MessageListener.java
│ │ │ ├── PlayerConnectivityListener.java
│ │ │ └── MessageConfigListener.java
│ │ ├── Bootstrap.java
│ │ └── PluginHandler.java
│ │ ├── util
│ │ ├── Tickable.java
│ │ ├── OverflowException.java
│ │ ├── AbstractCredentialValidator.java
│ │ ├── LenientCredentialValidator.java
│ │ └── WeaponDefinition.java
│ │ ├── service
│ │ ├── Service.java
│ │ ├── GameService.java
│ │ └── NetworkService.java
│ │ ├── io
│ │ ├── JsonUtils.java
│ │ ├── PlayerFileHandler.java
│ │ └── JsonPlayerFileHandler.java
│ │ ├── entity
│ │ ├── action
│ │ │ ├── Animation.java
│ │ │ ├── Graphics.java
│ │ │ ├── Hit.java
│ │ │ ├── PublicChat.java
│ │ │ └── AsyncMovement.java
│ │ ├── player
│ │ │ ├── infractions
│ │ │ │ ├── ReportAbuse.java
│ │ │ │ ├── ReportAbuseRule.java
│ │ │ │ └── PlayerInfractions.java
│ │ │ ├── skills
│ │ │ │ ├── SkillType.java
│ │ │ │ ├── Skill.java
│ │ │ │ └── Skills.java
│ │ │ ├── PlayerSettings.java
│ │ │ └── PlayerUpdateContext.java
│ │ ├── npc
│ │ │ ├── NpcUpdateContext.java
│ │ │ └── Npc.java
│ │ ├── Entity.java
│ │ ├── EntityUpdateContext.java
│ │ ├── MovementHandler.java
│ │ └── Position.java
│ │ ├── net
│ │ ├── ConnectionThrottle.java
│ │ └── HostGateway.java
│ │ ├── Settings.java
│ │ ├── task
│ │ ├── TaskHandler.java
│ │ └── Task.java
│ │ ├── ServerModule.java
│ │ ├── Server.java
│ │ └── WorldHandler.java
└── test
│ └── java
│ └── com
│ └── rs
│ └── entity
│ └── player
│ └── skills
│ └── SkillsTest.java
├── data
├── settings.json
├── stackable.dat
└── characters
│ └── mopar.json
├── CHANGELOG
├── plugins
├── scripts
│ ├── PublicMessaging.groovy
│ ├── CharacterDesign.groovy
│ ├── ReportAbuse.groovy
│ ├── Emotes.groovy
│ ├── PlayerSettings.groovy
│ └── Infractions.groovy
├── SamplePlugin.groovy
├── packets
│ ├── ActionButtonHandler.groovy
│ └── CommandHandler.groovy
└── GroovyBootstrap.groovy
├── USEGUIDE.md
├── gradlew.bat
├── README.md
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'runesource'
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dozmus/runesource/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IDEA project files
2 | out
3 | build
4 | .idea
5 | .gradle
6 | META-INF
7 | runesource.iml
8 |
9 | # Server log files
10 | data/logs
11 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/EventListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin;
2 |
3 | /**
4 | * An event listener, all listeners which correspond to events must extend this.
5 | */
6 | public interface EventListener {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/data/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "@type":"com.rs.Settings",
3 | "serverName":"RuneSource",
4 | "startPosition":{
5 | "x":3222,
6 | "y":3222,
7 | "z":0
8 | },
9 | "maxConsPerHost": 2,
10 | "hashPasswords": false,
11 | "dateFormat": "dd-MM-yyyy HH:mm:ss"
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/ReportAbuseEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 |
3 | import com.rs.entity.player.Player;
4 | import com.rs.entity.player.infractions.ReportAbuse;
5 |
6 | /**
7 | * A report abuse event.
8 | */
9 | public class ReportAbuseEvent extends PlayerEvent {
10 |
11 | private final ReportAbuse reportAbuse;
12 |
13 | public ReportAbuseEvent(Player player, ReportAbuse reportAbuse) {
14 | super(player);
15 | this.reportAbuse = reportAbuse;
16 | }
17 |
18 | public ReportAbuse getReportAbuse() {
19 | return reportAbuse;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/Event.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | /**
20 | * An event.
21 | */
22 | public interface Event {
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/util/Tickable.java:
--------------------------------------------------------------------------------
1 | package com.rs.util;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public interface Tickable {
20 |
21 | void tick() throws Exception;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/TickListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.util.Tickable;
21 |
22 | public interface TickListener extends Tickable, EventListener {
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/service/Service.java:
--------------------------------------------------------------------------------
1 | package com.rs.service;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.util.Tickable;
20 |
21 | public interface Service extends Tickable {
22 |
23 | void init() throws Exception;
24 |
25 | void tick();
26 |
27 | void cleanup();
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/PluginStateListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 |
21 | public interface PluginStateListener extends EventListener {
22 |
23 | void loaded();
24 |
25 | void unloaded();
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/CommandListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.CommandEvent;
21 |
22 | public interface CommandListener extends EventListener {
23 |
24 | void command(CommandEvent e);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/ReportAbuseListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.ReportAbuseEvent;
21 |
22 | public interface ReportAbuseListener extends EventListener {
23 |
24 | void reportAbuse(ReportAbuseEvent e);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/ActionButtonListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.ActionButtonEvent;
21 |
22 | public interface ActionButtonListener extends EventListener {
23 |
24 | void actionButton(ActionButtonEvent e);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/io/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package com.rs.io;
2 |
3 | import com.cedarsoftware.util.io.JsonWriter;
4 |
5 | import java.io.File;
6 | import java.io.FileWriter;
7 | import java.io.IOException;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class JsonUtils {
12 |
13 | private static final Map WRITER_ARGS = new HashMap<>();
14 |
15 | static {
16 | WRITER_ARGS.put("JsonWriter.PRETTY_PRINT", true);
17 | }
18 |
19 | public static void write(String fileName, boolean overwrite, Object object) throws IOException {
20 | File file = new File(fileName);
21 |
22 | // Overwrite
23 | if (overwrite && file.exists()) {
24 | file.delete();
25 | }
26 |
27 | // Generating pretty json
28 | String json = JsonWriter.objectToJson(object, WRITER_ARGS);
29 | json = JsonWriter.formatJson(json);
30 |
31 | // Writing json
32 | FileWriter writer = new FileWriter(file);
33 | writer.write(json);
34 | writer.close();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/PlayerLoggedOutEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * Player logged out event.
23 | */
24 | public final class PlayerLoggedOutEvent extends PlayerEvent {
25 |
26 | public PlayerLoggedOutEvent(Player player) {
27 | super(player);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | v1.0.2 (unreleased)
2 | * Gradle build system (#30)
3 | * Bump json-io v3.3.1 -> v4.9.12
4 | * Bump groovy v2.4.3 -> v2.5.2
5 | * Multi-threaded updating (courtesy @lare96)
6 | * Fix total level and combat level (#28) - NOTE: In the default RS #317 client, farming is disabled client-side.
7 | * Revert java target from 1.10 to 1.8 (bug introduced in #30)
8 |
9 | v1.0.1
10 | * Powerful Plugins using Groovy (#2)
11 | * Task System
12 | * Full Player Support (#8)
13 | * Full Npc Support (#11)
14 | * Friends List and Private Messaging (with privacy settings) (#4, #5, #17)
15 | * JSON Data Serialization (optional: passwords are hashed using SHA-256)
16 | * Banning and muting with expiration dates (#18, #19)
17 | * Misc stuff
18 | * Validate equipped items, weapon stack merging, and correct weapon interfaces (#9)
19 | * Emotes
20 | * Running
21 | * Persistent settings (#6)
22 | * Buffer caching (#10)
23 | * Login attempt throttling (#13)
24 | * Report abuse interface (#7)
25 | * Saves all players on shutdown (e.g. if you use Ctrl+C) (#25)
26 | * Commands - ::hide ::unhide (#27)
27 |
28 | v1.0.0
29 | The original RuneSource project.
30 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/MessageListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.PrivateMessageEvent;
21 | import com.rs.plugin.event.PublicMessageEvent;
22 |
23 | public interface MessageListener extends EventListener {
24 |
25 | void publicMessage(PublicMessageEvent e);
26 |
27 | void privateMessage(PrivateMessageEvent e);
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/util/OverflowException.java:
--------------------------------------------------------------------------------
1 | package com.rs.util;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class OverflowException extends RuntimeException {
20 |
21 | private final int remainder;
22 |
23 | public OverflowException(int remainder) {
24 | super("Overflow by: " + remainder);
25 | this.remainder = remainder;
26 | }
27 |
28 | public int getRemainder() {
29 | return remainder;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/PlayerConnectivityListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.PlayerLoggedInEvent;
21 | import com.rs.plugin.event.PlayerLoggedOutEvent;
22 |
23 | public interface PlayerConnectivityListener extends EventListener {
24 |
25 | void logIn(PlayerLoggedInEvent e);
26 |
27 | void logOut(PlayerLoggedOutEvent e);
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/util/AbstractCredentialValidator.java:
--------------------------------------------------------------------------------
1 | package com.rs.util;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public abstract class AbstractCredentialValidator {
20 |
21 | public boolean validate(String username, String password) {
22 | return validateUsername(username) && validatePassword(password);
23 | }
24 |
25 | public abstract boolean validateUsername(String username);
26 |
27 | public abstract boolean validatePassword(String password);
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/action/Animation.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.action;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class Animation {
20 |
21 | private final int id;
22 | private final int delay;
23 |
24 | public Animation(int id, int delay) {
25 | this.id = id;
26 | this.delay = delay;
27 | }
28 |
29 | public int getId() {
30 | return id;
31 | }
32 |
33 | public int getDelay() {
34 | return delay;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/action/Graphics.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.action;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class Graphics {
20 |
21 | private final int id;
22 | private final int delay;
23 |
24 | public Graphics(int id, int delay) {
25 | this.id = id;
26 | this.delay = delay;
27 | }
28 |
29 | public int getId() {
30 | return id;
31 | }
32 |
33 | public int getDelay() {
34 | return delay;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/action/Hit.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.action;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class Hit {
20 |
21 | private final int damage;
22 | private final int type; // XXX document types
23 |
24 | public Hit(int damage, int type) {
25 | this.damage = damage;
26 | this.type = type;
27 | }
28 |
29 | public int getDamage() {
30 | return damage;
31 | }
32 |
33 | public int getType() {
34 | return type;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/service/GameService.java:
--------------------------------------------------------------------------------
1 | package com.rs.service;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.WorldHandler;
20 |
21 | public class GameService implements Service {
22 |
23 | public void init() throws Exception {
24 | }
25 |
26 | public void tick() {
27 | try {
28 | WorldHandler.getInstance().tick();
29 | } catch (Exception ex) {
30 | ex.printStackTrace();
31 | }
32 | }
33 |
34 | public void cleanup() {
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/PlayerEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 | import com.rs.plugin.Event;
21 |
22 | /**
23 | * An {@link Event} triggered by a {@link Player}.
24 | */
25 | public abstract class PlayerEvent implements Event {
26 |
27 | protected final Player player;
28 |
29 | public PlayerEvent(Player player) {
30 | this.player = player;
31 | }
32 |
33 | public Player getPlayer() {
34 | return player;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/PlayerLoggedInEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * Player logged in event.
23 | */
24 | public final class PlayerLoggedInEvent extends PlayerEvent {
25 |
26 | private final boolean newPlayer;
27 |
28 | public PlayerLoggedInEvent(Player player, boolean newPlayer) {
29 | super(player);
30 | this.newPlayer = newPlayer;
31 | }
32 |
33 | public boolean isNewPlayer() {
34 | return newPlayer;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/Bootstrap.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.listener.*;
20 |
21 | /**
22 | * A bootstrap, which dispatches events from the core of the server to third-party plugins.
23 | *
24 | * @author Pure_
25 | */
26 | public interface Bootstrap extends ActionButtonListener, CommandListener, MessageConfigListener,
27 | MessageListener, PlayerConnectivityListener, PluginStateListener, ReportAbuseListener, TickListener {
28 |
29 | /**
30 | * Loads its dependencies.
31 | */
32 | void load();
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/ActionButtonEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * An action button click event.
23 | */
24 | public final class ActionButtonEvent extends PlayerEvent {
25 |
26 | private final int actionButtonId;
27 |
28 | public ActionButtonEvent(Player player, int actionButtonId) {
29 | super(player);
30 | this.actionButtonId = actionButtonId;
31 | }
32 |
33 | public int getActionButtonId() {
34 | return actionButtonId;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/PublicMessageEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.action.PublicChat;
20 | import com.rs.entity.player.Player;
21 |
22 | /**
23 | * Public message event.
24 | */
25 | public final class PublicMessageEvent extends PlayerEvent {
26 |
27 | private final PublicChat publicChat;
28 |
29 | public PublicMessageEvent(Player player, PublicChat publicChat) {
30 | super(player);
31 | this.publicChat = publicChat;
32 | }
33 |
34 | public PublicChat getPublicChat() {
35 | return publicChat;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/listener/MessageConfigListener.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.listener;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.plugin.EventListener;
20 | import com.rs.plugin.event.ModifyChatModeEvent;
21 | import com.rs.plugin.event.ModifyPlayerListEvent;
22 |
23 | public interface MessageConfigListener extends EventListener {
24 |
25 | void modifyChatMode(ModifyChatModeEvent e);
26 |
27 | void addFriend(ModifyPlayerListEvent e);
28 |
29 | void removeFriend(ModifyPlayerListEvent e);
30 |
31 | void addIgnore(ModifyPlayerListEvent e);
32 |
33 | void removeIgnore(ModifyPlayerListEvent e);
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/ModifyPlayerListEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * An event representing a username in hashed format.
23 | */
24 | public final class ModifyPlayerListEvent extends PlayerEvent {
25 |
26 | private final long target;
27 |
28 | public ModifyPlayerListEvent(Player player, long target) {
29 | super(player);
30 | this.target = target;
31 | }
32 |
33 | /**
34 | * The player's username id who was added or removed from the friends list.
35 | */
36 | public long getTarget() {
37 | return target;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/plugins/scripts/PublicMessaging.groovy:
--------------------------------------------------------------------------------
1 | import com.rs.entity.player.Player
2 | import com.rs.plugin.event.PrivateMessageEvent
3 | import com.rs.plugin.event.PublicMessageEvent
4 | import com.rs.plugin.listener.MessageListener
5 |
6 | /*
7 | * This file is part of RuneSource.
8 | *
9 | * RuneSource is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * RuneSource is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License
20 | * along with RuneSource. If not, see .
21 | */
22 |
23 | class PublicMessaging implements MessageListener {
24 |
25 | void publicMessage(PublicMessageEvent e) {
26 | Player player = e.getPlayer()
27 |
28 | if (!player.getAttributes().getInfractions().isMuted()) {
29 | player.setPublicChat e.getPublicChat()
30 | player.getUpdateContext().setPublicChatUpdateRequired()
31 | }
32 | }
33 |
34 | void privateMessage(PrivateMessageEvent e) {
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/action/PublicChat.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.action;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class PublicChat {
20 |
21 | private final int color; // XXX document color
22 | private final int effects; // XXX document effects
23 | private final byte[] text;
24 |
25 | public PublicChat(int color, int effects, byte[] text) {
26 | this.color = color;
27 | this.effects = effects;
28 | this.text = text;
29 | }
30 |
31 | public int getColor() {
32 | return color;
33 | }
34 |
35 | public int getEffects() {
36 | return effects;
37 | }
38 |
39 | public byte[] getText() {
40 | return text;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/CommandEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * A player command event.
23 | */
24 | public final class CommandEvent extends PlayerEvent {
25 |
26 | private final String commandName;
27 | private final String[] args;
28 |
29 | public CommandEvent(Player player, String commandName, String[] args) {
30 | super(player);
31 | this.commandName = commandName;
32 | this.args = args;
33 | }
34 |
35 | public String getCommandName() {
36 | return commandName;
37 | }
38 |
39 | public String[] getArgs() {
40 | return args;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/io/PlayerFileHandler.java:
--------------------------------------------------------------------------------
1 | package com.rs.io;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.PlayerAttributes;
20 |
21 | /**
22 | * A player loader, and saver.
23 | *
24 | * @author Pure_
25 | */
26 | public interface PlayerFileHandler {
27 |
28 | /**
29 | * Saves the argument attributes.
30 | */
31 | void save(PlayerAttributes attributes) throws Exception;
32 |
33 | /**
34 | * Returns the player attributes associated with the argument username.
35 | */
36 | PlayerAttributes load(String username) throws Exception;
37 |
38 | /**
39 | * Returns the directory this will store player flat files in.
40 | */
41 | String getStorageDirectory();
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/PrivateMessageEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * Private message event.
23 | */
24 | public final class PrivateMessageEvent extends PlayerEvent {
25 |
26 | private final long target;
27 | private final byte[] text;
28 |
29 | public PrivateMessageEvent(Player player, long target, byte[] text) {
30 | super(player);
31 | this.target = target;
32 | this.text = text;
33 | }
34 |
35 | /**
36 | * The player's username id who is being messaged.
37 | */
38 | public long getTarget() {
39 | return target;
40 | }
41 |
42 | public byte[] getText() {
43 | return text;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/infractions/ReportAbuse.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.infractions;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public final class ReportAbuse {
20 |
21 | private final String username;
22 | private final ReportAbuseRule rule;
23 | private final boolean muteFor48Hours;
24 |
25 | public ReportAbuse(String username, ReportAbuseRule rule, boolean muteFor48Hours) {
26 | this.username = username;
27 | this.rule = rule;
28 | this.muteFor48Hours = muteFor48Hours;
29 | }
30 |
31 | public String getUsername() {
32 | return username;
33 | }
34 |
35 | public ReportAbuseRule getRule() {
36 | return rule;
37 | }
38 |
39 | public boolean isMuteFor48Hours() {
40 | return muteFor48Hours;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/skills/SkillType.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.skills;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public enum SkillType {
20 |
21 | ATTACK(true),
22 | DEFENCE(true),
23 | STRENGTH(true),
24 | HITPOINTS(true),
25 | RANGED(true),
26 | PRAYER(true),
27 | MAGIC(true),
28 | COOKING,
29 | WOODCUTTING,
30 | FLETCHING,
31 | FISHING,
32 | FIREMAKING,
33 | CRAFTING,
34 | SMITHING,
35 | MINING,
36 | HERBLORE,
37 | AGILITY,
38 | THIEVING,
39 | SLAYER,
40 | FARMING,
41 | RUNECRAFTING;
42 |
43 | private final boolean combatSkill;
44 |
45 | SkillType() {
46 | this(false);
47 | }
48 |
49 | SkillType(boolean combatSkill) {
50 | this.combatSkill = combatSkill;
51 | }
52 |
53 | public boolean isCombatSkill() {
54 | return combatSkill;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/USEGUIDE.md:
--------------------------------------------------------------------------------
1 | # USEGUIDE
2 |
3 | ## What is the 'mopar' account's password?
4 | `test`
5 |
6 | ## Modifying server variables
7 | You can change the:
8 | * Server name
9 | * Starting position
10 | * Maximum number of connections per host
11 | * Whether passwords are hashed
12 |
13 | by editting the server config file in `/data/settings.json`.
14 |
15 | Note: If you change the hash passwords variable any existing accounts will be
16 | rendered inaccessible, unless if you change it back.
17 |
18 | ## How to save a new variable in a player file?
19 | Add a new variable into the PlayerAttributes class (under com.rs.entity.player).
20 | The next time a player logs in and out it their save file will be updated with no problems!
21 |
22 | ## How to add a new command?
23 | Add any commands into the Groovy script in the CommandHandler class (under /plugins/bindings/packets/).
24 |
25 | ## How to add a new plugin?
26 | Create a Groovy class file (i.e. something `.groovy`) extending an `EventListener` (or multiple) under `/plugins/`.
27 | You can find a full list of listeners under `com.rs.plugin.listener`.
28 | Each listener will give your script some information regarding the server.
29 |
30 | ## How to create a new listener?
31 | Firstly, create a new subclass of `EventListener` in `com.rs.plugin.listener`.
32 |
33 | Next, add this interface to the `Bootstrap` interface.
34 | Make sure you implement and handle this method, analogously to the others in `GroovyBootstrap`.
35 |
36 | Finally, create a corresponding static `dispatch*` in `PluginHandler`.
37 | Make sure that this dispatch method is called whenever this event occurs.
38 |
--------------------------------------------------------------------------------
/plugins/SamplePlugin.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.plugin.listener.PluginStateListener
18 | import com.rs.plugin.listener.TickListener
19 |
20 | /**
21 | * A sample plugin, which extends TickListener which tells it when a server tick occurs, and PluginStateListener
22 | * which tells it when it is loaded or unloaded.
23 | * It can know when more events occur by implementing interfaces from the com.rs.plugin.listener package.
24 | */
25 | class SamplePlugin implements TickListener, PluginStateListener {
26 |
27 | @Override
28 | void tick() throws Exception {
29 | // Code to execute on tick
30 | }
31 |
32 | @Override
33 | void loaded() throws Exception {
34 | // Code to execute when plugin is enabled
35 | }
36 |
37 | @Override
38 | void unloaded() throws Exception {
39 | // Code to execute when plugin is disabled
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/plugins/packets/ActionButtonHandler.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.entity.player.Player
18 | import com.rs.plugin.event.ActionButtonEvent
19 | import com.rs.plugin.listener.ActionButtonListener
20 |
21 | class ActionButtonHandler implements ActionButtonListener {
22 |
23 | void actionButton(ActionButtonEvent evt) {
24 | Player player = evt.getPlayer()
25 |
26 | switch (evt.getActionButtonId()) {
27 | case 9154:
28 | player.sendLogout()
29 | break
30 | case 153:
31 | player.getAttributes().getSettings().setRunToggled true
32 | break
33 | case 152:
34 | player.getAttributes().getSettings().setRunToggled false
35 | break
36 | default:
37 | println "Unhandled button: ${evt.getActionButtonId()}"
38 | break
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/net/ConnectionThrottle.java:
--------------------------------------------------------------------------------
1 | package com.rs.net;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import java.util.HashMap;
20 | import java.util.Map;
21 |
22 | /**
23 | * A failed connection attempt recorder, used to throttle failed login attempts.
24 | * Note: The cool down is not 100% accurate.
25 | */
26 | public final class ConnectionThrottle {
27 |
28 | public static final int COOLDOWN = 60_000;
29 | private static final int MAX_ATTEMPTS = 5;
30 | private static final Map map = new HashMap<>();
31 |
32 | public static void enter(String host) {
33 | if (map.containsKey(host)) {
34 | map.put(host, map.get(host) + 1);
35 | } else {
36 | map.put(host, 1);
37 | }
38 | }
39 |
40 | public static boolean throttled(String host) {
41 | return map.containsKey(host) && map.get(host) >= MAX_ATTEMPTS;
42 | }
43 |
44 | public static void clear() {
45 | map.clear();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/plugin/event/ModifyChatModeEvent.java:
--------------------------------------------------------------------------------
1 | package com.rs.plugin.event;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | /**
22 | * An event representing a change in chat mode.
23 | */
24 | public final class ModifyChatModeEvent extends PlayerEvent {
25 |
26 | private final int publicChatMode;
27 | private final int privateChatMode;
28 | private final int tradeMode;
29 |
30 | public ModifyChatModeEvent(Player player, int publicChatMode, int privateChatMode, int tradeMode) {
31 | super(player);
32 | this.publicChatMode = publicChatMode;
33 | this.privateChatMode = privateChatMode;
34 | this.tradeMode = tradeMode;
35 | }
36 |
37 | public int getPublicChatMode() {
38 | return publicChatMode;
39 | }
40 |
41 | public int getPrivateChatMode() {
42 | return privateChatMode;
43 | }
44 |
45 | public int getTradeMode() {
46 | return tradeMode;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/infractions/ReportAbuseRule.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.infractions;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public enum ReportAbuseRule {
20 | OffensiveLanguage(0),
21 | ItemScamming(1),
22 | PasswordScamming(2),
23 | BugAbuse(3),
24 | JagexStaffImpersonation(4),
25 | AccountSharingOrTrading(5),
26 | Macroing(6),
27 | MultipleLoggingIn(7),
28 | EncouragingRuleBreaking(8),
29 | MisuseOfCustomerSupport(9),
30 | Advertising(10),
31 | RealWorldItemTrading(11);
32 |
33 | private final int ruleId;
34 |
35 | ReportAbuseRule(int ruleId) {
36 | this.ruleId = ruleId;
37 | }
38 |
39 | public static ReportAbuseRule ofId(int ruleId) {
40 | for (ReportAbuseRule rule : values()) {
41 | if (rule.getRuleId() == ruleId) {
42 | return rule;
43 | }
44 | }
45 | throw new IllegalArgumentException("invalid rule id");
46 | }
47 |
48 | public int getRuleId() {
49 | return ruleId;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/plugins/scripts/CharacterDesign.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.entity.player.Player
18 | import com.rs.plugin.event.ActionButtonEvent
19 | import com.rs.plugin.event.PlayerLoggedInEvent
20 | import com.rs.plugin.event.PlayerLoggedOutEvent
21 | import com.rs.plugin.listener.ActionButtonListener
22 | import com.rs.plugin.listener.PlayerConnectivityListener
23 |
24 | class CharacterDesign implements PlayerConnectivityListener, ActionButtonListener {
25 |
26 | void actionButton(ActionButtonEvent evt) {
27 | Player player = evt.getPlayer()
28 |
29 | if (evt.getActionButtonId() == 14067) { // Design character interface accept button
30 | player.sendClearScreen()
31 | player.setCurrentInterfaceId(-1)
32 | }
33 | }
34 |
35 | void logIn(PlayerLoggedInEvent evt) {
36 | Player player = evt.getPlayer()
37 |
38 | if (evt.isNewPlayer()) {
39 | player.sendInterface 3559
40 | player.setCurrentInterfaceId 3559
41 | }
42 | }
43 |
44 | void logOut(PlayerLoggedOutEvent evt) {
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/skills/Skill.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.skills;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | public class Skill {
20 |
21 | private final SkillType type;
22 | private int level;
23 | private int maxLevel;
24 | private int experience;
25 |
26 | public Skill(SkillType type) {
27 | this(type, 1, 1, 0);
28 | }
29 |
30 | public Skill(SkillType type, int level, int maxLevel, int experience) {
31 | this.type = type;
32 | this.level = level;
33 | this.maxLevel = maxLevel;
34 | this.experience = experience;
35 | }
36 |
37 | public SkillType getType() {
38 | return type;
39 | }
40 |
41 | public int getLevel() {
42 | return level;
43 | }
44 |
45 | public void setLevel(int level) {
46 | this.level = level;
47 | }
48 |
49 | public int getMaxLevel() {
50 | return maxLevel;
51 | }
52 |
53 | public void setMaxLevel(int maxLevel) {
54 | this.maxLevel = maxLevel;
55 | }
56 |
57 | public int getExperience() {
58 | return experience;
59 | }
60 |
61 | public void setExperience(int experience) {
62 | this.experience = experience;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/action/AsyncMovement.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.action;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.Position;
20 |
21 | public final class AsyncMovement {
22 |
23 | private final Position startPosition;
24 | private final Position endPosition;
25 | private final int startToEndSpeed;
26 | private final int endToStartSpeed;
27 | private final int direction;
28 |
29 | public AsyncMovement(Position startPosition, Position endPosition, int startToEndSpeed, int endToStartSpeed,
30 | int direction) {
31 | this.startPosition = startPosition;
32 | this.endPosition = endPosition;
33 | this.startToEndSpeed = startToEndSpeed;
34 | this.endToStartSpeed = endToStartSpeed;
35 | this.direction = direction;
36 | }
37 |
38 | public Position getStartPosition() {
39 | return startPosition;
40 | }
41 |
42 | public Position getEndPosition() {
43 | return endPosition;
44 | }
45 |
46 | public int getStartToEndSpeed() {
47 | return startToEndSpeed;
48 | }
49 |
50 | public int getEndToStartSpeed() {
51 | return endToStartSpeed;
52 | }
53 |
54 | public int getDirection() {
55 | return direction;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/io/JsonPlayerFileHandler.java:
--------------------------------------------------------------------------------
1 | package com.rs.io;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.cedarsoftware.util.io.JsonReader;
20 | import com.rs.entity.player.PlayerAttributes;
21 |
22 | import java.io.File;
23 | import java.io.FileInputStream;
24 | import java.nio.file.NoSuchFileException;
25 |
26 | /**
27 | * An {@link PlayerFileHandler} implementation for JSON player attribute saving/loading.
28 | *
29 | * @author Pure_
30 | */
31 | public final class JsonPlayerFileHandler implements PlayerFileHandler {
32 |
33 | @Override
34 | public void save(PlayerAttributes attributes) throws Exception {
35 | String fileName = getStorageDirectory() + attributes.getUsername() + ".json";
36 | JsonUtils.write(fileName, true, attributes);
37 | }
38 |
39 | @Override
40 | public PlayerAttributes load(String username) throws Exception {
41 | // Checking if file exists
42 | File file = new File(getStorageDirectory() + username + ".json");
43 |
44 | if (!file.exists()) {
45 | throw new NoSuchFileException(file.getAbsolutePath());
46 | }
47 |
48 | // Reading file
49 | JsonReader reader = new JsonReader(new FileInputStream(file));
50 | PlayerAttributes attributes = (PlayerAttributes) reader.readObject();
51 | reader.close();
52 | return attributes;
53 | }
54 |
55 | @Override
56 | public String getStorageDirectory() {
57 | return "./data/characters/";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/Settings.java:
--------------------------------------------------------------------------------
1 | package com.rs;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.cedarsoftware.util.io.JsonReader;
20 | import com.rs.entity.Position;
21 |
22 | import java.io.File;
23 | import java.io.FileInputStream;
24 | import java.io.FileNotFoundException;
25 |
26 | /**
27 | * A collection of server settings, loaded from json.
28 | */
29 | public final class Settings {
30 |
31 | private String serverName;
32 | private Position startPosition;
33 | private int maxConsPerHost;
34 | private boolean hashPasswords;
35 | private String dateFormat;
36 |
37 | public static Settings load(String fileName) throws Exception {
38 | // Checking if file exists
39 | File file = new File(fileName);
40 |
41 | if (!file.exists()) {
42 | throw new FileNotFoundException("The settings file was not found");
43 | }
44 |
45 | // Reading file
46 | JsonReader reader = new JsonReader(new FileInputStream(file));
47 | Settings settings = (Settings) reader.readObject();
48 | reader.close();
49 | return settings;
50 | }
51 |
52 | public String getServerName() {
53 | return serverName;
54 | }
55 |
56 | public Position getStartPosition() {
57 | return startPosition;
58 | }
59 |
60 | public int getMaxConsPerHost() {
61 | return maxConsPerHost;
62 | }
63 |
64 | public boolean isHashingPasswords() {
65 | return hashPasswords;
66 | }
67 |
68 | public String getDateFormat() {
69 | return dateFormat;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/task/TaskHandler.java:
--------------------------------------------------------------------------------
1 | package com.rs.task;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.player.Player;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Iterator;
23 |
24 | /**
25 | * A simple task handler.
26 | *
27 | * @author Pure_
28 | */
29 | public final class TaskHandler {
30 |
31 | /**
32 | * A collection of tasks.
33 | */
34 | private static final ArrayList tasks = new ArrayList<>();
35 |
36 | /**
37 | * Performs a processing task on all active tasks.
38 | */
39 | public static void tick() {
40 | for (Iterator itr = tasks.iterator(); itr.hasNext(); ) {
41 | Task task = itr.next();
42 |
43 | // Removing completed tasks
44 | if (!task.isActive()) {
45 | itr.remove();
46 | continue;
47 | }
48 |
49 | // Processing task
50 | try {
51 | task.tick();
52 | } catch (Exception ex) {
53 | ex.printStackTrace();
54 | }
55 | }
56 | }
57 |
58 | /**
59 | * Deactivates all tasks which belong to the given player.
60 | */
61 | public static void remove(Player player) {
62 | for (Task task : tasks) {
63 | if (task.getPlayer().equals(player)) {
64 | task.setInactive();
65 | }
66 | }
67 | }
68 |
69 | /**
70 | * Adds a task to the execution list.
71 | */
72 | public static void submit(Task task) {
73 | tasks.add(task);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/net/HostGateway.java:
--------------------------------------------------------------------------------
1 | package com.rs.net;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import java.util.concurrent.ConcurrentHashMap;
20 |
21 | /**
22 | * A static gateway type class that is used to limit the maximum amount of connections per host.
23 | *
24 | * @author blakeman8192
25 | */
26 | public final class HostGateway {
27 |
28 | /**
29 | * Used to keep track of hosts and their amount of connections.
30 | */
31 | private static final ConcurrentHashMap map = new ConcurrentHashMap<>();
32 |
33 | /**
34 | * Checks the host into the gateway.
35 | *
36 | * @param host the host
37 | */
38 | public static void enter(String host) {
39 | if (map.containsKey(host)) {
40 | map.put(host, map.get(host) + 1);
41 | } else {
42 | map.put(host, 1);
43 | }
44 | }
45 |
46 | /**
47 | * Unchecks the host from the gateway.
48 | *
49 | * @param host the host
50 | */
51 | public static void exit(String host) {
52 | Integer amount = map.get(host);
53 |
54 | if (amount == null)
55 | return;
56 |
57 | // Remove the host from the map if it's at 1 connection.
58 | if (amount == 1) {
59 | map.remove(host);
60 | return;
61 | }
62 |
63 | // Otherwise decrement the amount of connections stored.
64 | map.put(host, amount - 1);
65 | }
66 |
67 | /**
68 | * @return The number of connections from the given host.
69 | */
70 | public static int count(String host) {
71 | return map.getOrDefault(host, 0);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/ServerModule.java:
--------------------------------------------------------------------------------
1 | package com.rs;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.google.inject.AbstractModule;
20 | import com.google.inject.Singleton;
21 | import com.google.inject.multibindings.Multibinder;
22 | import com.google.inject.name.Names;
23 | import com.rs.io.JsonPlayerFileHandler;
24 | import com.rs.io.PlayerFileHandler;
25 | import com.rs.service.NetworkService;
26 | import com.rs.service.GameService;
27 | import com.rs.service.Service;
28 | import com.rs.util.AbstractCredentialValidator;
29 | import com.rs.util.LenientCredentialValidator;
30 |
31 | public class ServerModule extends AbstractModule {
32 |
33 | private final String host;
34 | private final int port;
35 | private final int tickRate;
36 |
37 | public ServerModule(String host, int port, int tickRate) {
38 | this.host = host;
39 | this.port = port;
40 | this.tickRate = tickRate;
41 | }
42 |
43 | protected void configure() {
44 | Multibinder serviceBinder = Multibinder.newSetBinder(binder(), Service.class);
45 | serviceBinder.addBinding().to(NetworkService.class).in(Singleton.class);
46 | serviceBinder.addBinding().to(GameService.class).in(Singleton.class);
47 | bind(String.class).annotatedWith(Names.named("host")).toInstance(host);
48 | bind(Integer.class).annotatedWith(Names.named("port")).toInstance(port);
49 | bind(Integer.class).annotatedWith(Names.named("tickRate")).toInstance(tickRate);
50 |
51 | bind(PlayerFileHandler.class).to(JsonPlayerFileHandler.class).in(Singleton.class);
52 | bind(AbstractCredentialValidator.class).to(LenientCredentialValidator.class).in(Singleton.class);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/util/LenientCredentialValidator.java:
--------------------------------------------------------------------------------
1 | package com.rs.util;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | /**
20 | * A lenient credential validator, which enforces a character whitelist, as well as length
21 | * limits on both username and passwords.
22 | */
23 | public class LenientCredentialValidator extends AbstractCredentialValidator {
24 |
25 | private static final char[] VALID_PASSWORD_CHARACTERS = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
26 | + "0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| ").toCharArray();
27 | private static final char[] VALID_USERNAME_CHARACTERS = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
28 | + "0123456789! ").toCharArray();
29 |
30 | public boolean validateUsername(String username) {
31 | // Length check
32 | if (username.length() == 0 || username.length() > 12) {
33 | return false;
34 | }
35 |
36 | // Checking each character
37 | for (int i = 0; i < username.length(); i++) {
38 | if (!Misc.contains(VALID_USERNAME_CHARACTERS, username.charAt(i))) {
39 | return false;
40 | }
41 | }
42 | return true;
43 | }
44 |
45 | public boolean validatePassword(String password) {
46 | // Length check
47 | if (password.length() == 0 || password.length() > 20) {
48 | return false;
49 | }
50 |
51 | // Checking each character
52 | for (int i = 0; i < password.length(); i++) {
53 | if (!Misc.contains(VALID_PASSWORD_CHARACTERS, password.charAt(i))) {
54 | return false;
55 | }
56 | }
57 | return true;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/infractions/PlayerInfractions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | package com.rs.entity.player.infractions;
18 |
19 | import com.rs.Server;
20 |
21 | import java.text.DateFormat;
22 | import java.text.SimpleDateFormat;
23 | import java.util.Date;
24 |
25 | /**
26 | * The infractions associated with a given player, this does not support any IP-based infractions.
27 | */
28 | public final class PlayerInfractions {
29 |
30 | private static final DateFormat DATE_FORMAT = new SimpleDateFormat(Server.getInstance().getSettings().getDateFormat());
31 | private boolean banned;
32 | private boolean muted;
33 | private Date banExpirationDate;
34 | private Date muteExpirationDate;
35 |
36 | public void setBanned(boolean banned) {
37 | this.banned = banned;
38 | }
39 |
40 | public void setMuted(boolean muted) {
41 | this.muted = muted;
42 | }
43 |
44 | public void setBanExpirationDate(Date banExpirationDate) {
45 | this.banExpirationDate = banExpirationDate;
46 | }
47 |
48 | public void setMuteExpirationDate(Date muteExpirationDate) {
49 | this.muteExpirationDate = muteExpirationDate;
50 | }
51 |
52 | public boolean isBanned() {
53 | return banned && (banExpirationDate == null || new Date().before(banExpirationDate));
54 | }
55 |
56 | public boolean isMuted() {
57 | return muted && (muteExpirationDate == null || new Date().before(muteExpirationDate));
58 | }
59 |
60 | public String banExpiration() {
61 | return banExpirationDate != null ? DATE_FORMAT.format(banExpirationDate) : "never";
62 | }
63 |
64 | public String muteExpiration() {
65 | return muteExpirationDate != null ? DATE_FORMAT.format(muteExpirationDate) : "never";
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/plugins/scripts/ReportAbuse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.Server
18 | import com.rs.entity.player.Player
19 | import com.rs.entity.player.infractions.ReportAbuseRule
20 | import com.rs.plugin.PluginHandler
21 | import com.rs.plugin.event.ReportAbuseEvent
22 | import com.rs.plugin.listener.ReportAbuseListener
23 |
24 | import java.text.DateFormat
25 | import java.text.SimpleDateFormat
26 |
27 | class ReportAbuse implements ReportAbuseListener {
28 |
29 | File logFile = new File("./data/logs/report-abuse.log")
30 | DateFormat dateFormat = new SimpleDateFormat(Server.getInstance().getSettings().getDateFormat())
31 |
32 | void reportAbuse(ReportAbuseEvent e) {
33 | Player player = e.getPlayer()
34 | com.rs.entity.player.infractions.ReportAbuse abuse = e.getReportAbuse()
35 | boolean muted = abuse.muteFor48Hours
36 |
37 | // Mute using command - should remove this once we allow plugins to interact with each other
38 | if (muted) {
39 | Calendar expiration = Calendar.getInstance()
40 | expiration.setTime(new Date())
41 | expiration.add(Calendar.HOUR_OF_DAY, 48)
42 | PluginHandler.dispatchCommand(e.getPlayer(), "mute", dateFormat.format(expiration.getTime()))
43 | }
44 |
45 | log(player.getAttributes().getUsername(), abuse.username, abuse.rule, muted)
46 | player.setCurrentInterfaceId(-1)
47 | }
48 |
49 | void log(String author, String target, ReportAbuseRule rule, boolean muted) {
50 | String appDate = dateFormat.format(new Date())
51 | String log = "[$appDate]: [$author -> $target] $rule muted=$muted"
52 |
53 | FileWriter writer = new FileWriter(logFile, true)
54 | writer.write(log + System.lineSeparator())
55 | writer.flush()
56 | writer.close()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | RuneSource
2 | =======================
3 |
4 | ### What is RuneSource?
5 | RuneSource is an [open-source](http://www.opensource.org/) server for the popular game [RuneScape](https://runescape.com),
6 | written in the Java programming language.
7 | It is important to note that RuneSource is in no way endorsed or affiliated with RuneScape or its creator company,
8 | Jagex. Use of RuneSource is also against the RuneScape Terms of Service (which you may be bound by).
9 | RuneSource is licensed via the GNU General Public License Version 3.
10 | Please note that this server is not ready for production - it has minimal content implemented.
11 |
12 | ### Why was RuneSource made?
13 | RuneSource was made by [blakeman8192](https://github.com/blakeman8192) for the general RuneScape emulation community,
14 | which is spread across many internet forums and IRC channels.
15 | The purpose of RuneSource is to provide a stable, high-performance, and simple RuneScape server emulator for people to
16 | use.
17 | At the current time of release (late 2010), all existing RuneScape server emulators are either very unstable and slow,
18 | or very complicated and hard to work with.
19 | RuneSource aims to solve these problems by being a stable and efficient server, and above all, by being simple and
20 | easy to use.
21 |
22 | ### New Features
23 | * Powerful Plugins using Groovy
24 | * Task System
25 | * Full Player Support
26 | * Full Npc Support
27 | * Friends List and Private Messaging (with privacy settings)
28 | * JSON Data Serialization (optional: passwords are hashed using SHA-256)
29 | * Banning and muting with expiration dates
30 | * Misc stuff
31 | * Validate equipped items
32 | * Emotes
33 | * Running
34 | * Correct weapon interfaces
35 | * Persistent settings
36 | * Buffer caching
37 | * Weapon stack merging (i.e. if you have 10 arrows equipped, and equip 5 more they combine into 15)
38 | * Login attempt throttling
39 | * Report abuse interface
40 | * Saves all players on shutdown (e.g. if you use Ctrl+C)
41 | * [More planned...](https://github.com/PureCS/runesource/issues)
42 |
43 | ### Configuration
44 | You can configure your RuneSource by reading the [use guide](USEGUIDE.md).
45 |
46 | ### Copyright
47 | Copyright (c) 2010 [Blake Beaupain](https://github.com/blakeman8192)
48 | Copyright (c) 2015-2018 [PureCS](https://github.com/purecs)
49 | RuneScape is copyright and a registered trademark of Jagex Ltd.
50 | RuneSource and its authors are in no way affiliated with Jagex or RuneScape.
51 | RuneSource exists solely for educational purposes, and is licensed via GPLv3.
52 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/npc/NpcUpdateContext.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.npc;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.EntityUpdateContext;
20 | import com.rs.net.StreamBuffer;
21 |
22 | /**
23 | * The update flags and buffer caches for a {@link Npc}.
24 | */
25 | public final class NpcUpdateContext extends EntityUpdateContext {
26 |
27 | private final StreamBuffer.BufferCache bufferCache = new StreamBuffer.BufferCache();
28 | private boolean npcDefinitionUpdateRequired = false;
29 |
30 | public int mask() {
31 | int mask = 0x0;
32 |
33 | if (isAnimationUpdateRequired()) {
34 | mask |= 0x10;
35 | }
36 |
37 | if (isPrimaryHitUpdateRequired()) {
38 | mask |= 0x40;
39 | }
40 |
41 | if (isGraphicsUpdateRequired()) {
42 | mask |= 0x80;
43 | }
44 |
45 | if (isInteractingNpcUpdateRequired()) {
46 | mask |= 0x20;
47 | }
48 |
49 | if (isForcedChatUpdateRequired()) {
50 | mask |= 0x1;
51 | }
52 |
53 | if (isSecondaryHitUpdateRequired()) {
54 | mask |= 0x8;
55 | }
56 |
57 | if (isNpcDefinitionUpdateRequired()) {
58 | mask |= 0x2;
59 | }
60 |
61 | if (isFaceCoordinatesUpdateRequired()) {
62 | mask |= 0x4;
63 | }
64 | return mask;
65 | }
66 |
67 | public void setUpdateRequired() {
68 | super.setUpdateRequired();
69 | bufferCache.setOutdated();
70 | }
71 |
72 | public void setNpcDefintionUpdateRequired() {
73 | setUpdateRequired();
74 | npcDefinitionUpdateRequired = true;
75 | }
76 |
77 | public void resetFlags() {
78 | super.resetFlags();
79 | bufferCache.setOutdated();
80 | }
81 |
82 | public boolean isNpcDefinitionUpdateRequired() {
83 | return npcDefinitionUpdateRequired;
84 | }
85 |
86 | public StreamBuffer.BufferCache getBufferCache() {
87 | return bufferCache;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/Entity.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity;
2 |
3 | import com.rs.util.Tickable;
4 |
5 | /**
6 | * An in-game entity.
7 | */
8 | public abstract class Entity implements Tickable {
9 |
10 | private final MovementHandler movementHandler = new MovementHandler(this);
11 | private final EntityUpdateContext updateContext;
12 | private Position currentRegion = new Position(0, 0, 0);
13 | private int slot = -1;
14 | private int primaryDirection = -1;
15 | private int secondaryDirection = -1;
16 | private boolean needsPlacement = false;
17 | private boolean resetMovementQueue = false;
18 |
19 | public Entity(EntityUpdateContext updateContext) {
20 | this.updateContext = updateContext;
21 | }
22 |
23 | public abstract Position getPosition();
24 |
25 | /**
26 | * Resets the entity after updating.
27 | */
28 | public void reset() {
29 | setPrimaryDirection(-1);
30 | setSecondaryDirection(-1);
31 | setResetMovementQueue(false);
32 | setNeedsPlacement(false);
33 | updateContext.resetFlags();
34 | }
35 |
36 | public MovementHandler getMovementHandler() {
37 | return movementHandler;
38 | }
39 |
40 | public int getPrimaryDirection() {
41 | return primaryDirection;
42 | }
43 |
44 | /**
45 | * Sets the player's primary movement direction.
46 | */
47 | public void setPrimaryDirection(int primaryDirection) {
48 | this.primaryDirection = primaryDirection;
49 | }
50 |
51 | public int getSecondaryDirection() {
52 | return secondaryDirection;
53 | }
54 |
55 | /**
56 | * Sets the player's secondary movement direction.
57 | */
58 | public void setSecondaryDirection(int secondaryDirection) {
59 | this.secondaryDirection = secondaryDirection;
60 | }
61 |
62 | /**
63 | * Gets the current region.
64 | */
65 | public Position getCurrentRegion() {
66 | return currentRegion;
67 | }
68 |
69 | public void setCurrentRegion(Position currentRegion) {
70 | this.currentRegion = currentRegion;
71 | }
72 |
73 | public boolean isResetMovementQueue() {
74 | return resetMovementQueue;
75 | }
76 |
77 | public void setResetMovementQueue(boolean resetMovementQueue) {
78 | this.resetMovementQueue = resetMovementQueue;
79 | }
80 |
81 | public void setNeedsPlacement(boolean needsPlacement) {
82 | this.needsPlacement = needsPlacement;
83 | }
84 |
85 | /**
86 | * Gets whether or not the player needs to be placed.
87 | */
88 | public boolean needsPlacement() {
89 | return needsPlacement;
90 | }
91 |
92 | /**
93 | * Gets the player slot.
94 | */
95 | public int getSlot() {
96 | return slot;
97 | }
98 |
99 | public void setSlot(int slot) {
100 | this.slot = slot;
101 | }
102 |
103 | public EntityUpdateContext getUpdateContext() {
104 | return updateContext;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/util/WeaponDefinition.java:
--------------------------------------------------------------------------------
1 | package com.rs.util;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | /**
20 | * A weapon's definition.
21 | */
22 | public final class WeaponDefinition implements Comparable {
23 |
24 | private final int id;
25 | private final String name;
26 | private final Type type;
27 |
28 | public WeaponDefinition(int id, String name, Type type) {
29 | this.id = id;
30 | this.name = name;
31 | this.type = type;
32 | }
33 |
34 | public int getId() {
35 | return id;
36 | }
37 |
38 | public String getName() {
39 | return name;
40 | }
41 |
42 | public Type getType() {
43 | return type;
44 | }
45 |
46 | @Override
47 | public int compareTo(WeaponDefinition o) {
48 | return id - o.id;
49 | }
50 |
51 | public enum Type {
52 | UNARMED(5855, 5857, -1),
53 | STAFF(328, 331, 329),
54 | WARHAMMER(425, 428, 426),
55 | SYTHE(776, 779, 777),
56 | BATTLE_AXE(1698, 1701, 1699),
57 | BOW(1764, 1767, 1765),
58 | CROSSBOW(1749, 1752, 1750),
59 | SWORD(2423, 2426, 2424),
60 | FLOWERS(2423, 2426, 2424),
61 | DAGGER(2276, 2279, 2277),
62 | MACE(3796, 3799, 3797),
63 | KNIFE(4446, 4449, 4447),
64 | DART(4446, 4449, 4447),
65 | JAVELIN(4446, 4449, 4447),
66 | THROWNAXE(4446, 4449, 4447),
67 | SPEAR(4679, 4682, 4680),
68 | SWORD_2H(4705, 4708, 4706),
69 | LONGSWORD(4705, 4708, 4706),
70 | PICKAXE(5570, 5573, 5571),
71 | CLAW(7762, 7765, 7763),
72 | HALBERD(8460, 8463, 8461),
73 | WHIP(12290, 12293, 12291),
74 | UNKNOWN(-1, -1, -1);
75 |
76 | private final int interfaceId;
77 | private final int weaponNameId;
78 | private final int weaponImageId;
79 |
80 | Type(int interfaceId, int weaponNameId, int weaponImageId) {
81 | this.interfaceId = interfaceId;
82 | this.weaponNameId = weaponNameId;
83 | this.weaponImageId = weaponImageId;
84 | }
85 |
86 | public int getInterfaceId() {
87 | return interfaceId;
88 | }
89 |
90 | public int getWeaponNameId() {
91 | return weaponNameId;
92 | }
93 |
94 | public int getWeaponImageId() {
95 | return weaponImageId;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.rs.task;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.util.Tickable;
20 | import com.rs.entity.player.Player;
21 |
22 | /**
23 | * A simple task base class.
24 | *
25 | * @author Pure_
26 | */
27 | public abstract class Task implements Tickable {
28 |
29 | private boolean active;
30 | private int currentDelay;
31 | private final int delay;
32 | private final boolean runOnce;
33 | private final Player player;
34 | private final Object[] args;
35 | private int ticks;
36 |
37 | /**
38 | * Creates a new task instance which will run once with no arguments.
39 | */
40 | public Task(int delay, Player player) {
41 | this(delay, true, player);
42 | }
43 |
44 | /**
45 | * Creates a new task instance.
46 | *
47 | * @param delay the delay (in server ticks) until the task is to be executed
48 | * @param runOnce if the task should only be executed once
49 | * @param player the player this task is bound to
50 | * @param args the args to provide to the instance
51 | */
52 | public Task(int delay, boolean runOnce, Player player, Object... args) {
53 | this.delay = delay;
54 | this.runOnce = runOnce;
55 | this.player = player;
56 | this.args = args;
57 | this.active = true;
58 | currentDelay = delay;
59 | }
60 |
61 | /**
62 | * Contains the task's executable code, this is executed once the delay is depleted.
63 | */
64 | protected abstract void process();
65 |
66 | /**
67 | * Performs a logic tick, this checks if the task can be executed yet.
68 | */
69 | public void tick() throws Exception {
70 | if (active && currentDelay-- <= 0) {
71 | process();
72 | ticks++;
73 | currentDelay = delay;
74 |
75 | if (runOnce) {
76 | active = false;
77 | }
78 | }
79 | }
80 |
81 | /**
82 | * Whether or not the task should be removed next tick.
83 | */
84 | public boolean isActive() {
85 | return active;
86 | }
87 |
88 | /**
89 | * Sets the task as inactive.
90 | */
91 | public void setInactive() {
92 | this.active = false;
93 | }
94 |
95 | /**
96 | * Gets the array of arguments passed to the task upon creation.
97 | */
98 | public Object[] getArgs() {
99 | return args;
100 | }
101 |
102 | /**
103 | * The player this task is bound to.
104 | */
105 | public Player getPlayer() {
106 | return player;
107 | }
108 |
109 | /**
110 | * The amount of times this task has been executed.
111 | */
112 | public int getTicks() {
113 | return ticks;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/PlayerSettings.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | /**
20 | * A {@link Player}'s in-game settings.
21 | */
22 | public final class PlayerSettings {
23 |
24 | private MouseButtons mouseButtons = MouseButtons.TWO;
25 | private Brightness brightness = Brightness.NORMAL;
26 | private boolean chatEffects = true;
27 | private boolean splitPrivateChat = false;
28 | private boolean acceptAid = false;
29 | private boolean runToggled = false;
30 | private boolean autoRetaliate = true;
31 | private int publicChatMode = 0;
32 | private int privateChatMode = 0;
33 | private int tradeMode = 0;
34 |
35 | public MouseButtons getMouseButtons() {
36 | return mouseButtons;
37 | }
38 |
39 | public void setMouseButtons(MouseButtons mouseButtons) {
40 | this.mouseButtons = mouseButtons;
41 | }
42 |
43 | public Brightness getBrightness() {
44 | return brightness;
45 | }
46 |
47 | public void setBrightness(Brightness brightness) {
48 | this.brightness = brightness;
49 | }
50 |
51 | public boolean isChatEffects() {
52 | return chatEffects;
53 | }
54 |
55 | public void setChatEffects(boolean chatEffects) {
56 | this.chatEffects = chatEffects;
57 | }
58 |
59 | public boolean isSplitPrivateChat() {
60 | return splitPrivateChat;
61 | }
62 |
63 | public void setSplitPrivateChat(boolean splitPrivateChat) {
64 | this.splitPrivateChat = splitPrivateChat;
65 | }
66 |
67 | public boolean isAcceptAid() {
68 | return acceptAid;
69 | }
70 |
71 | public void setAcceptAid(boolean acceptAid) {
72 | this.acceptAid = acceptAid;
73 | }
74 |
75 | public boolean isRunToggled() {
76 | return runToggled;
77 | }
78 |
79 | public void setRunToggled(boolean runToggled) {
80 | this.runToggled = runToggled;
81 | }
82 |
83 | public boolean isAutoRetaliate() {
84 | return autoRetaliate;
85 | }
86 |
87 | public void setAutoRetaliate(boolean autoRetaliate) {
88 | this.autoRetaliate = autoRetaliate;
89 | }
90 |
91 | public int getPublicChatMode() {
92 | return publicChatMode;
93 | }
94 |
95 | public void setPublicChatMode(int publicChatMode) {
96 | this.publicChatMode = publicChatMode;
97 | }
98 |
99 | public int getPrivateChatMode() {
100 | return privateChatMode;
101 | }
102 |
103 | public void setPrivateChatMode(int privateChatMode) {
104 | this.privateChatMode = privateChatMode;
105 | }
106 |
107 | public int getTradeMode() {
108 | return tradeMode;
109 | }
110 |
111 | public void setTradeMode(int tradeMode) {
112 | this.tradeMode = tradeMode;
113 | }
114 |
115 | public enum MouseButtons {
116 | ONE, TWO
117 | }
118 |
119 | public enum Brightness {
120 | DARK, NORMAL, BRIGHT, VERY_BRIGHT;
121 |
122 | public int settingValue() {
123 | return ordinal() + 1;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/EntityUpdateContext.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | /**
20 | * The update flags for an {@link com.rs.entity.Entity}.
21 | */
22 | public abstract class EntityUpdateContext {
23 |
24 | private boolean updateRequired = false;
25 | private boolean graphicsUpdateRequired = false;
26 | private boolean animationUpdateRequired = false;
27 | private boolean forcedChatUpdateRequired = false;
28 | private boolean faceCoordinatesUpdateRequired = false;
29 | private boolean primaryHitUpdateRequired = false;
30 | private boolean secondaryHitUpdateRequired = false;
31 | private boolean interactingNpcUpdateRequired = false;
32 |
33 | public abstract int mask();
34 |
35 | public void setUpdateRequired() {
36 | updateRequired = true;
37 | }
38 |
39 | public void setGraphicsUpdateRequired() {
40 | setUpdateRequired();
41 | graphicsUpdateRequired = true;
42 | }
43 |
44 | public void setAnimationUpdateRequired() {
45 | setUpdateRequired();
46 | animationUpdateRequired = true;
47 | }
48 |
49 | public void setForcedChatUpdateRequired() {
50 | setUpdateRequired();
51 | forcedChatUpdateRequired = true;
52 | }
53 |
54 | public void setInteractingNpcUpdateRequired() {
55 | setUpdateRequired();
56 | interactingNpcUpdateRequired = true;
57 | }
58 |
59 | public void setFaceCoordinatesUpdateRequired() {
60 | setUpdateRequired();
61 | faceCoordinatesUpdateRequired = true;
62 | }
63 |
64 | public void setPrimaryHitUpdateRequired() {
65 | setUpdateRequired();
66 | primaryHitUpdateRequired = true;
67 | }
68 |
69 | public void setSecondaryHitUpdateRequired() {
70 | setUpdateRequired();
71 | secondaryHitUpdateRequired = true;
72 | }
73 |
74 | public boolean isUpdateRequired() {
75 | return updateRequired;
76 | }
77 |
78 | public boolean isGraphicsUpdateRequired() {
79 | return graphicsUpdateRequired;
80 | }
81 |
82 | public boolean isAnimationUpdateRequired() {
83 | return animationUpdateRequired;
84 | }
85 |
86 | public boolean isForcedChatUpdateRequired() {
87 | return forcedChatUpdateRequired;
88 | }
89 |
90 | public boolean isInteractingNpcUpdateRequired() {
91 | return interactingNpcUpdateRequired;
92 | }
93 |
94 | public boolean isFaceCoordinatesUpdateRequired() {
95 | return faceCoordinatesUpdateRequired;
96 | }
97 |
98 | public boolean isPrimaryHitUpdateRequired() {
99 | return primaryHitUpdateRequired;
100 | }
101 |
102 | public boolean isSecondaryHitUpdateRequired() {
103 | return secondaryHitUpdateRequired;
104 | }
105 |
106 | /**
107 | * Resets all update flags.
108 | */
109 | public void resetFlags() {
110 | updateRequired = false;
111 | graphicsUpdateRequired = false;
112 | animationUpdateRequired = false;
113 | forcedChatUpdateRequired = false;
114 | interactingNpcUpdateRequired = false;
115 | faceCoordinatesUpdateRequired = false;
116 | primaryHitUpdateRequired = false;
117 | secondaryHitUpdateRequired = false;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/plugins/scripts/Emotes.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.entity.player.Player
18 | import com.rs.plugin.event.ActionButtonEvent
19 | import com.rs.plugin.listener.ActionButtonListener
20 |
21 | class Emotes implements ActionButtonListener {
22 |
23 | void actionButton(ActionButtonEvent evt) {
24 | Player player = evt.getPlayer()
25 |
26 | switch (evt.getActionButtonId()) {
27 | case 168: // Yes
28 | player.startAnimation 855
29 | break
30 | case 169: // No
31 | player.startAnimation 856
32 | break
33 | case 162: // Think
34 | player.startAnimation 857
35 | break
36 | case 164: // Bow
37 | player.startAnimation 858
38 | break
39 | case 165: // Angry
40 | player.startAnimation 859
41 | break
42 | case 161: // Cry
43 | player.startAnimation 860
44 | break
45 | case 170: // Laugh
46 | player.startAnimation 861
47 | break
48 | case 171: // Cheer
49 | player.startAnimation 862
50 | break
51 | case 163: // Wave
52 | player.startAnimation 863
53 | break
54 | case 167: // Beckon
55 | player.startAnimation 864
56 | break
57 | case 172: // Clap
58 | player.startAnimation 865
59 | break
60 | case 166: // Dance
61 | player.startAnimation 866
62 | break
63 | case 52050: // Panic
64 | player.startAnimation 2105
65 | break
66 | case 52051: // Jig
67 | player.startAnimation 2106
68 | break
69 | case 52052: // Spin
70 | player.startAnimation 2107
71 | break
72 | case 52053: // Head Bang
73 | player.startAnimation 2108
74 | break
75 | case 52054: // Joy Jump
76 | player.startAnimation 2109
77 | break
78 | case 52055: // Rasp'berry
79 | player.startAnimation 2110
80 | break
81 | case 52056: // Yawn
82 | player.startAnimation 2111
83 | break
84 | case 52057: // Salute
85 | player.startAnimation 2112
86 | break
87 | case 52058: // Shrug
88 | player.startAnimation 2113
89 | break
90 | case 43092: // Blow Kiss
91 | player.startAnimation 1368
92 | break
93 | case 2155: // Glass Box
94 | player.startAnimation 1131
95 | break
96 | case 2154: // Glass Wall
97 | player.startAnimation 1128
98 | break
99 | case 25103: // Climb Rope
100 | player.startAnimation 1130
101 | break
102 | case 25106: // Lean
103 | player.startAnimation 1129
104 | break
105 | case 52071: // Goblin Bow
106 | player.startAnimation 2127
107 | break
108 | case 52072: // Goblin Dance
109 | player.startAnimation 2128
110 | break
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/test/java/com/rs/entity/player/skills/SkillsTest.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.skills;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import org.junit.jupiter.api.BeforeEach;
20 | import org.junit.jupiter.api.Test;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | import static org.junit.jupiter.api.Assertions.assertEquals;
26 |
27 | final class SkillsTest {
28 |
29 | private Skills skills;
30 |
31 | @BeforeEach
32 | void setUp() {
33 | skills = new Skills();
34 | }
35 |
36 | @Test
37 | void testLevels_NewAccount() {
38 | assertEquals(3, skills.getCombatLevel());
39 | assertEquals(30, skills.getTotalLevel());
40 | }
41 |
42 | @Test
43 | void testLevels_MaxedAccount() {
44 | List skillList = new ArrayList<>();
45 |
46 | for (SkillType type : SkillType.values()) {
47 | skillList.add(new Skill(type, 99, 99, 13034431));
48 | }
49 |
50 | Skills skills = new Skills(skillList);
51 | assertEquals(126, skills.getCombatLevel());
52 | assertEquals(2079, skills.getTotalLevel());
53 | }
54 |
55 | @Test
56 | void testAddExperience() {
57 | skills.addExperience(SkillType.ATTACK, 50);
58 | assertEquals(1, skills.level(SkillType.ATTACK));
59 | assertEquals(1, skills.maxLevel(SkillType.ATTACK));
60 | assertEquals(30, skills.getTotalLevel());
61 | }
62 |
63 | @Test
64 | void testAddExperience_LevelUp_OneLevel() {
65 | skills.addExperience(SkillType.ATTACK, 83);
66 | assertEquals(2, skills.level(SkillType.ATTACK));
67 | assertEquals(2, skills.maxLevel(SkillType.ATTACK));
68 | assertEquals(31, skills.getTotalLevel());
69 | }
70 |
71 | @Test
72 | void testAddExperience_LevelUp_TwoLevels() {
73 | skills.addExperience(SkillType.ATTACK, 174);
74 | assertEquals(3, skills.level(SkillType.ATTACK));
75 | assertEquals(3, skills.maxLevel(SkillType.ATTACK));
76 | assertEquals(32, skills.getTotalLevel());
77 | }
78 |
79 | @Test
80 | void testCombatLevel() {
81 | assertEquals(3, Skills.combatLevel(1, 1, 1, 1, 1, 10, 1));
82 | assertEquals(126, Skills.combatLevel(99, 99, 99, 99, 99, 99, 99));
83 | }
84 |
85 | @Test
86 | void testLevelForExp() {
87 | assertEquals(1, Skills.levelForExp(0));
88 | assertEquals(2, Skills.levelForExp(83));
89 | assertEquals(99, Skills.levelForExp(13034431));
90 | assertEquals(99, Skills.levelForExp(20000000));
91 | }
92 |
93 | @Test
94 | void testAddExperience_RemoveExperience() {
95 | assertEquals(3, skills.getCombatLevel());
96 | assertEquals(30, skills.getTotalLevel());
97 |
98 | for (SkillType type : SkillType.values()) {
99 | skills.addExperience(type, 13034431);
100 | }
101 | assertEquals(126, skills.getCombatLevel());
102 | assertEquals(2079, skills.getTotalLevel());
103 |
104 | for (SkillType type : SkillType.values()) {
105 | skills.addExperience(type, -13034431);
106 | }
107 | assertEquals(3, skills.getCombatLevel());
108 | assertEquals(30, skills.getTotalLevel());
109 | }
110 |
111 | @Test
112 | void testNormalizeExp() {
113 | assertEquals(0, Skills.normalizeExp(-1));
114 | assertEquals(0, Skills.normalizeExp(0));
115 | assertEquals(100_000, Skills.normalizeExp(100_000));
116 | assertEquals(200_000_000, Skills.normalizeExp(200_000_000));
117 | assertEquals(200_000_000, Skills.normalizeExp(200_000_001));
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/npc/Npc.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.npc;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.Entity;
20 | import com.rs.entity.Position;
21 | import com.rs.entity.action.*;
22 |
23 | /**
24 | * A Non-Player Character.
25 | *
26 | * @author blakeman8192
27 | */
28 | public final class Npc extends Entity {
29 |
30 | private final int id;
31 | private boolean visible = true;
32 | private Position position = new Position(0, 0);
33 | // Various npc update data.
34 | private String forceChatText;
35 | private Animation animation;
36 | private Graphics graphics;
37 | private Hit primaryHit;
38 | private Hit secondaryHit;
39 | private Position facingPosition;
40 | private Npc interactingNpc;
41 | private int npcDefinitionId;
42 |
43 | /**
44 | * Creates a new Npc.
45 | *
46 | * @param id the NPC ID
47 | */
48 | public Npc(int id) {
49 | super(new NpcUpdateContext());
50 | this.id = id;
51 | }
52 |
53 | @Override
54 | public void tick() {
55 | getMovementHandler().tick();
56 | }
57 |
58 | public void reset() {
59 | super.reset();
60 | }
61 |
62 | /**
63 | * Gets the NPC ID.
64 | */
65 | public int getId() {
66 | return id;
67 | }
68 |
69 | public boolean isVisible() {
70 | return visible;
71 | }
72 |
73 | public void setVisible(boolean visible) {
74 | this.visible = visible;
75 | }
76 |
77 | @Override
78 | public Position getPosition() {
79 | return position;
80 | }
81 |
82 | public NpcUpdateContext getUpdateContext() {
83 | return (NpcUpdateContext)super.getUpdateContext();
84 | }
85 |
86 | public String getForceChatText() {
87 | return forceChatText;
88 | }
89 |
90 | public void setForceChatText(String forceChatText) {
91 | this.forceChatText = forceChatText;
92 | }
93 |
94 | public Animation getAnimation() {
95 | return animation;
96 | }
97 |
98 | public void setAnimation(Animation animation) {
99 | this.animation = animation;
100 | }
101 |
102 | public Graphics getGraphics() {
103 | return graphics;
104 | }
105 |
106 | public void setGraphics(Graphics graphics) {
107 | this.graphics = graphics;
108 | }
109 |
110 | public Hit getPrimaryHit() {
111 | return primaryHit;
112 | }
113 |
114 | public void setPrimaryHit(Hit primaryHit) {
115 | this.primaryHit = primaryHit;
116 | }
117 |
118 | public Hit getSecondaryHit() {
119 | return secondaryHit;
120 | }
121 |
122 | public void setSecondaryHit(Hit secondaryHit) {
123 | this.secondaryHit = secondaryHit;
124 | }
125 |
126 | public Position getFacingPosition() {
127 | return facingPosition;
128 | }
129 |
130 | public void setFacingPosition(Position facingPosition) {
131 | this.facingPosition = facingPosition;
132 | }
133 |
134 | public Npc getInteractingNpc() {
135 | return interactingNpc;
136 | }
137 |
138 | public void setInteractingNpc(Npc interactingNpc) {
139 | this.interactingNpc = interactingNpc;
140 | }
141 |
142 | public int getNpcDefinitionId() {
143 | return npcDefinitionId;
144 | }
145 |
146 | public void setNpcDefinitionId(int npcDefinitionId) {
147 | this.npcDefinitionId = npcDefinitionId;
148 | }
149 |
150 | public int getCurrentHealth() {
151 | return 0;
152 | }
153 |
154 | public int getMaximumHealth() {
155 | return 0;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/plugins/scripts/PlayerSettings.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 | import com.rs.entity.player.Player
18 | import com.rs.plugin.event.ActionButtonEvent
19 | import com.rs.plugin.event.PlayerLoggedInEvent
20 | import com.rs.plugin.event.PlayerLoggedOutEvent
21 | import com.rs.plugin.listener.ActionButtonListener
22 | import com.rs.plugin.listener.PlayerConnectivityListener
23 |
24 | class PlayerSettings implements PlayerConnectivityListener, ActionButtonListener {
25 |
26 | void logIn(PlayerLoggedInEvent evt) throws Exception {
27 | Player player = evt.getPlayer()
28 | com.rs.entity.player.PlayerSettings settings = player.getAttributes().getSettings()
29 |
30 | // Send initial setting states
31 | player.sendClientSetting(166, settings.getBrightness().settingValue())
32 | sendBooleanSetting(player, 170, settings.getMouseButtons() == com.rs.entity.player.PlayerSettings.MouseButtons.ONE)
33 | sendBooleanSetting(player, 171, settings.isChatEffects())
34 | sendBooleanSetting(player, 172, settings.isAutoRetaliate())
35 | sendBooleanSetting(player, 173, settings.isRunToggled())
36 | sendBooleanSetting(player, 287, settings.isSplitPrivateChat())
37 | sendBooleanSetting(player, 427, settings.isAcceptAid())
38 |
39 | // Send chat mode
40 | player.sendChatModes()
41 | }
42 |
43 | void logOut(PlayerLoggedOutEvent evt) {
44 | }
45 |
46 | void sendBooleanSetting(Player player, int settingId, boolean condition) {
47 | player.sendClientSetting(settingId, condition ? 1 : 0)
48 | }
49 |
50 | void actionButton(ActionButtonEvent evt) {
51 | Player player = evt.getPlayer()
52 | com.rs.entity.player.PlayerSettings settings = player.getAttributes().getSettings()
53 |
54 | switch (evt.getActionButtonId()) {
55 | case 153:
56 | settings.setRunToggled true
57 | break
58 | case 152:
59 | settings.setRunToggled false
60 | break
61 | case 150:
62 | settings.setAutoRetaliate true
63 | break
64 | case 151:
65 | settings.setAutoRetaliate false
66 | break
67 | case 21076:
68 | settings.setBrightness com.rs.entity.player.PlayerSettings.Brightness.DARK
69 | break
70 | case 24129:
71 | settings.setBrightness com.rs.entity.player.PlayerSettings.Brightness.NORMAL
72 | break
73 | case 24131:
74 | settings.setBrightness com.rs.entity.player.PlayerSettings.Brightness.BRIGHT
75 | break
76 | case 24133:
77 | settings.setBrightness com.rs.entity.player.PlayerSettings.Brightness.VERY_BRIGHT
78 | break
79 | case 24134:
80 | settings.setMouseButtons com.rs.entity.player.PlayerSettings.MouseButtons.TWO
81 | break
82 | case 24135:
83 | settings.setMouseButtons com.rs.entity.player.PlayerSettings.MouseButtons.ONE
84 | break
85 | case 24136:
86 | settings.setChatEffects true
87 | break
88 | case 24137:
89 | settings.setChatEffects false
90 | break
91 | case 3184:
92 | settings.setSplitPrivateChat true
93 | break
94 | case 3185:
95 | settings.setSplitPrivateChat false
96 | break
97 | case 49047:
98 | settings.setAcceptAid true
99 | break
100 | case 49046:
101 | settings.setAcceptAid false
102 | break
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/service/NetworkService.java:
--------------------------------------------------------------------------------
1 | package com.rs.service;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.Server;
20 | import com.rs.entity.player.Client;
21 | import com.rs.entity.player.Player;
22 | import com.rs.net.ConnectionThrottle;
23 | import com.rs.net.HostGateway;
24 |
25 | import java.io.IOException;
26 | import java.nio.channels.SelectionKey;
27 | import java.nio.channels.Selector;
28 | import java.nio.channels.ServerSocketChannel;
29 | import java.nio.channels.SocketChannel;
30 | import java.util.HashMap;
31 | import java.util.List;
32 | import java.util.Map;
33 | import java.util.stream.Collectors;
34 |
35 | /**
36 | * A service which accepts connections, and handles data reading.
37 | */
38 | public class NetworkService implements Service {
39 |
40 | private ServerSocketChannel serverChannel;
41 | private Map clientMap;
42 | private Selector selector;
43 |
44 | public void init() throws Exception {
45 | // Initialize the networking objects.
46 | selector = Selector.open();
47 | serverChannel = ServerSocketChannel.open();
48 |
49 | // ... and configure them!
50 | serverChannel.configureBlocking(false);
51 | serverChannel.socket().bind(Server.getInstance().getAddress());
52 | serverChannel.register(selector, SelectionKey.OP_ACCEPT);
53 |
54 | // Finally, initialize whatever else we need.
55 | clientMap = new HashMap<>();
56 | }
57 |
58 | public void tick() {
59 | // Remove disconnected clients
60 | clientMap.entrySet().removeIf(e -> !e.getKey().isValid());
61 |
62 | // Remove clients which timed out during login
63 | List timedOutKeys = clientMap.entrySet().stream()
64 | .filter(e -> e.getValue().getTimeoutStopwatch().elapsed() > 5000)
65 | .map(Map.Entry::getKey)
66 | .collect(Collectors.toList());
67 | timedOutKeys.forEach(e -> {
68 | clientMap.get(e).disconnect();
69 | clientMap.remove(e);
70 | e.cancel();
71 | });
72 |
73 | // Handle all network events
74 | try {
75 | selector.selectNow();
76 |
77 | for (SelectionKey selectionKey : selector.selectedKeys()) {
78 | if (selectionKey.isAcceptable()) { // Accept new connections.
79 | accept(10);
80 | }
81 |
82 | if (selectionKey.isReadable()) { // Client handles the packet.
83 | clientMap.get(selectionKey).handleIncomingData();
84 | }
85 | }
86 | } catch (Exception ex) {
87 | ex.printStackTrace();
88 | }
89 |
90 | // Check if connection throttling needs a clear
91 | if (System.currentTimeMillis() % ConnectionThrottle.COOLDOWN == 0) {
92 | ConnectionThrottle.clear();
93 | }
94 | }
95 |
96 | public void cleanup() {
97 | Map client = new HashMap<>(clientMap);
98 | client.forEach((k, v) -> {
99 | if (v.getConnectionStage() != Client.ConnectionStage.LOGGED_OUT) {
100 | v.disconnect();
101 | }
102 | });
103 | }
104 |
105 | /**
106 | * Accepts up to n incoming connections.
107 | */
108 | private void accept(int n) throws IOException {
109 | SocketChannel socket;
110 |
111 | /*
112 | * Here we use a for loop so that we can accept multiple clients per
113 | * tick for lower latency. We limit the amount of clients that we
114 | * accept per tick to better combat potential denial of service type
115 | * attacks.
116 | */
117 | for (int i = 0; i < n; i++) {
118 | socket = serverChannel.accept();
119 |
120 | if (socket == null) {
121 | // No more connections to accept (as this one was invalid).
122 | break;
123 | }
124 |
125 | // Register the connection
126 | HostGateway.enter(socket.socket().getInetAddress().getHostAddress());
127 |
128 | // Set up the new connection.
129 | socket.configureBlocking(false);
130 | SelectionKey key = socket.register(selector, SelectionKey.OP_READ);
131 | Client client = new Player(key);
132 | System.out.println("Accepted " + client + ".");
133 | clientMap.put(key, client);
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/skills/Skills.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player.skills;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import static com.rs.entity.player.skills.SkillType.*;
23 |
24 | public class Skills {
25 |
26 | public static final int MAX_EXPERIENCE = 200_000_000;
27 | public static final int MIN_EXPERIENCE = 0;
28 | /**
29 | * A mapping of level i to the experience required to achieve it.
30 | */
31 | public static final int[] EXPERIENCE_TABLE = {
32 | 0, 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584, 1833, 2107, 2411, 2746, 3115, 3523, 3973,
33 | 4470, 5018, 5624, 6291, 7028, 7842, 8740, 9730, 10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406,
34 | 24815, 27473, 30408, 33648, 37224, 41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014, 91721, 101333,
35 | 111945, 123660, 136594, 150872, 166636, 184040, 203254, 224466, 247886, 273742, 302288, 333804, 368599,
36 | 407015, 449428, 496254, 547953, 605032, 668051, 737627, 814445, 899257, 992895, 1096278, 1210421, 1336443,
37 | 1475581, 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373, 3258594, 3597792, 3972294, 4385776,
38 | 4842295, 5346332, 5902831, 6517253, 7195629, 7944614, 8771558, 9684577, 10692629, 11805606, 13034431
39 | };
40 | private final List skills;
41 | private transient int combatLevel;
42 | private transient int totalLevel;
43 |
44 | public Skills(List skills) {
45 | this.skills = skills;
46 | updateTotalLevel();
47 | updateCombatLevel();
48 | }
49 |
50 | public Skills() {
51 | skills = new ArrayList<>();
52 | reset();
53 | }
54 |
55 | public void reset() {
56 | skills.clear();
57 |
58 | for (SkillType type : SkillType.values()) {
59 | Skill skill = new Skill(type);
60 | skills.add(skill);
61 | }
62 | addExperience(HITPOINTS, 1154);
63 | updateTotalLevel();
64 | updateCombatLevel();
65 | }
66 |
67 | public int experience(SkillType type) {
68 | return skill(type).getExperience();
69 | }
70 |
71 | public int level(SkillType type) {
72 | return skill(type).getLevel();
73 | }
74 |
75 | public int maxLevel(SkillType type) {
76 | return skill(type).getMaxLevel();
77 | }
78 |
79 | public void addExperience(SkillType type, int experience) {
80 | Skill skill = skill(type);
81 | setExperience(type, normalizeExp(skill.getExperience() + experience));
82 | }
83 |
84 | public void setExperience(SkillType type, int newExperience) {
85 | newExperience = normalizeExp(newExperience);
86 |
87 | Skill skill = skill(type);
88 | int newLevel = levelForExp(newExperience);
89 | int levelChange = newLevel - skill.getMaxLevel();
90 | skill.setExperience(newExperience);
91 |
92 | if (levelChange != 0) {
93 | updateTotalLevel(levelChange);
94 | skill.setMaxLevel(skill.getMaxLevel() + levelChange);
95 | skill.setLevel(skill.getLevel() + levelChange);
96 |
97 | if (type.isCombatSkill()) {
98 | updateCombatLevel();
99 | }
100 | }
101 | }
102 |
103 | private void updateTotalLevel(int change) {
104 | totalLevel += change;
105 | }
106 |
107 | public void updateTotalLevel() {
108 | totalLevel = skills.stream().mapToInt(Skill::getMaxLevel).sum();
109 | }
110 |
111 | public void updateCombatLevel() {
112 | combatLevel = combatLevel(maxLevel(ATTACK), maxLevel(STRENGTH), maxLevel(MAGIC), maxLevel(RANGED),
113 | maxLevel(DEFENCE), maxLevel(HITPOINTS), maxLevel(PRAYER));
114 | }
115 |
116 | private Skill skill(SkillType type) {
117 | return skills.get(type.ordinal());
118 | }
119 |
120 | public int getCombatLevel() {
121 | return combatLevel;
122 | }
123 |
124 | public int getTotalLevel() {
125 | return totalLevel;
126 | }
127 |
128 | public static int combatLevel(double atk, double str, double mag, double rng, double def, double hp, double pry) {
129 | // Source: http://runescape.wikia.com/wiki/Combat_level#History
130 | double k = 1.3d * Math.max(atk + str, Math.max(2 * mag, 2 * rng));
131 | double total = k + def + hp + Math.floor(0.5d * pry);
132 | return (int) Math.floor(total / 4);
133 | }
134 |
135 | public static int levelForExp(int exp) {
136 | // Source: https://www.reddit.com/r/2007scape/comments/3idn2b/exp_to_lvl_formula/cufhr5q
137 | for (int level = 0; level < EXPERIENCE_TABLE.length - 1; level++) {
138 | if (EXPERIENCE_TABLE[level + 1] > exp)
139 | return level;
140 | }
141 | return 99;
142 | }
143 |
144 | public static int normalizeExp(int exp) {
145 | return Math.min(MAX_EXPERIENCE, Math.max(exp, MIN_EXPERIENCE));
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/main/java/com/rs/entity/player/PlayerUpdateContext.java:
--------------------------------------------------------------------------------
1 | package com.rs.entity.player;
2 | /*
3 | * This file is part of RuneSource.
4 | *
5 | * RuneSource is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * RuneSource is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with RuneSource. If not, see .
17 | */
18 |
19 | import com.rs.entity.EntityUpdateContext;
20 | import com.rs.net.StreamBuffer;
21 |
22 | import java.nio.ByteBuffer;
23 |
24 | /**
25 | * The update flags and buffer caches for a {@link Player}.
26 | */
27 | public final class PlayerUpdateContext extends EntityUpdateContext {
28 |
29 | private final StreamBuffer.BufferCache regularBufferCache = new StreamBuffer.BufferCache();
30 | private final StreamBuffer.BufferCache forcedAppearanceBufferCache = new StreamBuffer.BufferCache();
31 | private final StreamBuffer.BufferCache noChatBufferCache = new StreamBuffer.BufferCache();
32 | private final StreamBuffer.BufferCache forcedAppearanceNoChatBufferCache = new StreamBuffer.BufferCache();
33 | private boolean asyncMovementUpdateRequired = false;
34 | private boolean publicChatUpdateRequired = false;
35 | private boolean appearanceUpdateRequired = false;
36 |
37 | public int mask() {
38 | return mask(false, false);
39 | }
40 |
41 | public int mask(boolean forceAppearance, boolean noPublicChat) {
42 | int mask = 0x0;
43 |
44 | if (isAsyncMovementUpdateRequired()) {
45 | mask |= 0x400;
46 | }
47 |
48 | if (isGraphicsUpdateRequired()) {
49 | mask |= 0x100;
50 | }
51 |
52 | if (isAnimationUpdateRequired()) {
53 | mask |= 0x8;
54 | }
55 |
56 | if (isForcedChatUpdateRequired()) {
57 | mask |= 0x4;
58 | }
59 |
60 | if (isPublicChatUpdateRequired() && !noPublicChat) {
61 | mask |= 0x80;
62 | }
63 |
64 | if (isInteractingNpcUpdateRequired()) {
65 | mask |= 0x1;
66 | }
67 |
68 | if (isAppearanceUpdateRequired() || forceAppearance) {
69 | mask |= 0x10;
70 | }
71 |
72 | if (isFaceCoordinatesUpdateRequired()) {
73 | mask |= 0x2;
74 | }
75 |
76 | if (isPrimaryHitUpdateRequired()) {
77 | mask |= 0x20;
78 | }
79 |
80 | if (isSecondaryHitUpdateRequired()) {
81 | mask |= 0x200;
82 | }
83 | return mask;
84 | }
85 |
86 | public void setUpdateRequired() {
87 | super.setUpdateRequired();
88 | setAllBuffersOutdated();
89 | }
90 |
91 | public void setAsyncMovementUpdateRequired() {
92 | setUpdateRequired();
93 | asyncMovementUpdateRequired = true;
94 | }
95 |
96 | public void setPublicChatUpdateRequired() {
97 | setUpdateRequired();
98 | publicChatUpdateRequired = true;
99 | }
100 |
101 | public void setAppearanceUpdateRequired() {
102 | setUpdateRequired();
103 | appearanceUpdateRequired = true;
104 | }
105 |
106 | public boolean isAsyncMovementUpdateRequired() {
107 | return asyncMovementUpdateRequired;
108 | }
109 |
110 | public boolean isPublicChatUpdateRequired() {
111 | return publicChatUpdateRequired;
112 | }
113 |
114 | public boolean isAppearanceUpdateRequired() {
115 | return appearanceUpdateRequired;
116 | }
117 |
118 | /**
119 | * Resets all update flags.
120 | */
121 | public void resetFlags() {
122 | super.resetFlags();
123 | asyncMovementUpdateRequired = false;
124 | publicChatUpdateRequired = false;
125 | appearanceUpdateRequired = false;
126 | setAllBuffersOutdated();
127 | }
128 |
129 | public void setBuffer(boolean forceAppearance, boolean noPublicChat, ByteBuffer buffer) {
130 | if (!forceAppearance && !noPublicChat) {
131 | regularBufferCache.setBuffer(buffer);
132 | } else if (forceAppearance && !noPublicChat) {
133 | forcedAppearanceBufferCache.setBuffer(buffer);
134 | } else if (!forceAppearance && noPublicChat) {
135 | noChatBufferCache.setBuffer(buffer);
136 | } else {
137 | forcedAppearanceNoChatBufferCache.setBuffer(buffer);
138 | }
139 | }
140 |
141 | public ByteBuffer getBuffer(boolean forceAppearance, boolean noPublicChat) {
142 | if (!forceAppearance && !noPublicChat && !regularBufferCache.isOutdated()) {
143 | return regularBufferCache.getBuffer();
144 | } else if (forceAppearance && !noPublicChat && !forcedAppearanceBufferCache.isOutdated()) {
145 | return forcedAppearanceBufferCache.getBuffer();
146 | } else if (!forceAppearance && noPublicChat && !noChatBufferCache.isOutdated()) {
147 | return noChatBufferCache.getBuffer();
148 | } else if (forceAppearance && noPublicChat && !forcedAppearanceNoChatBufferCache.isOutdated()) {
149 | return forcedAppearanceNoChatBufferCache.getBuffer();
150 | }
151 | return null;
152 | }
153 |
154 | private void setAllBuffersOutdated() {
155 | regularBufferCache.setOutdated();
156 | forcedAppearanceBufferCache.setOutdated();
157 | noChatBufferCache.setOutdated();
158 | forcedAppearanceNoChatBufferCache.setOutdated();
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/plugins/GroovyBootstrap.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of RuneSource.
3 | *
4 | * RuneSource is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * RuneSource is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with RuneSource. If not, see .
16 | */
17 |
18 |
19 | import com.rs.plugin.EventListener
20 | import com.rs.plugin.PluginHandler
21 | import com.rs.plugin.Bootstrap
22 | import com.rs.plugin.event.*
23 | import com.rs.plugin.listener.*
24 | import groovy.io.FileType
25 |
26 | /**
27 | * The plugin bootstrap, this is the object which receives events from the Java portion of the server.
28 | * It then forwards these events to the groovy plugins which it has loaded, depending on which interfaces
29 | * each extends.
30 | * Plugins extending Bootstrap are not loaded by this class, they are only loaded in the PluginHandler.
31 | * This must extend and implement the methods of each interface in com.rs.plugin.listener which it desires to handle.
32 | */
33 | class GroovyBootstrap implements Bootstrap {
34 |
35 | private static final GroovyClassLoader CLASS_LOADER = new GroovyClassLoader()
36 | Map> plugins = new HashMap<>()
37 |
38 | void resetPlugins() {
39 | getPlugins(PluginStateListener.class).forEach { l -> l.unloaded() }
40 | plugins.clear()
41 | }
42 |
43 | void addPlugin(Class interfaceClass, Object instance) {
44 | getPlugins(interfaceClass).add(instance)
45 | }
46 |
47 | List