apollo-rsps / apollo Goto Github PK
View Code? Open in Web Editor NEWAn open-source Java game server suite designed to be lightweight, fast, and secure.
License: ISC License
An open-source Java game server suite designed to be lightweight, fast, and secure.
License: ISC License
Apache Commons is now 1.9 - Fixes
Netty is 4.0.25 - Mainly new features
jRuby is now 1.7.19 - Loads of fixes
For the FirstObjectActionEvent, this code won't work:
on :event, :object_action do |ctx, player, event|
if event.option == 1
player.send_message("You clicked the first action for object #{event.id}.")
end
end
This does:
on :event, :first_object_action do |ctx, player, event|
player.send_message("You clicked the first action for object #{event.id}.")
end
The latest version of Apollo has a bug with objects messing up, these are some pictures in Edgeville.
No errors are printed, and this was not the case 1-2 days ago. I suspect that the region updates could be faulty?
https://i.gyazo.com/6ab07f85f480c8575571189598110ffb.png
https://i.gyazo.com/fe9c80c6226c82a3edf3d1f4a0b059a2.png
https://i.gyazo.com/20cf4969922be76cfba7ae16a237698e.png
https://i.gyazo.com/40d3e38b3b55d36e54e6865cf4a11a0d.png
Apollo with the latest update(Rubocop) gives an error on startup:
When adding players to the World, they should be added to a queue which is processed every tick, rather than added immediately. This reduces the amount of locking required, and also prevents lots of new players from delaying the server pulse.
Issue in the plugin where message.compressed_message should be changed to message.compressed_chat
------ This will fix it
require 'java'
java_import 'org.apollo.game.message.impl.ForwardPrivateChatMessage'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.setting.PrivacyState'
on :message, :private_chat do |ctx, player, message|
friend = $world.get_player(message.username)
friend.send(ForwardPrivateChatMessage.new(player.username, player.privilege_level, message.compressed_chat)) if interaction_permitted(player, friend)
end
def interaction_permitted(sender, friend)
if friend == nil || friend.has_ignored(sender.username)
return false
end
return friend.friends_with(sender.username) ? friend.friend_privacy != PrivacyState::OFF : friend.friend_privacy == PrivacyState::ON
end
Many of the ruby plugins, particularly some of the skills, suffer from poor/outdated code that needs to be improved.
I think one of the clunkier feelings to Apollo when developing for it is the fact that each packet has a one to one class representation of a message (sometimes its one to many since an option field can be attributed say option packets), a one to one class representation of a message to an encoder/decoder, and a one to one class representation of a handler. When it comes down to brass tacks it feels very clunky and in my opinion is one of the greatest design flops with the source.
I'm proposing that with the found knowledge of the real packet ids which is represented in the PacketConstant class in the older Runetek engine that in the session pipeline that all packets be normalized before decoding to cut down on some of this class overhead. The strategy for this would be to rearrange the bytes in logical and homogeneous order of similarly structured packets. For example: ItemOptionOne/ItemOptionTwo
The server should avoid sending the appearance block if the player has already seen the other player and the other player's appearance hasn't changed since that time.
Server is unable to send the sound data to the client via request.
There is a file (data/login.xml) missing in the repository which mean that the server cannot successfully run.
The Animation
class contains instances of various Animations like so:
/**
* The angry animation.
*/
public static final Animation ANGRY = new Animation(859);
These are only used in the emote_tab plugin and should be removed from the core server.
From what I see, the SimplePathfindingAlgorithm only supports 4 way movements. This doesn't look right to me. Is it normal? If deltaX and deltaY are both > than 0, it should move diagonally.
maven-compiler-plugin (3.1)
commons-compress (1.8.1)
netty-all (4.0.20.Final)
Shocked this never got done just making this a suggestion but I will write when I get time
A couple of bugs with this, and it's not particularly pleasant to look at currently.
Apollo adds a lot of unnecessary (and frankly confusing to some) bloat with the current hack-job implementation of multi-revision support. I say hack-job as it is not actual multi-revision support which people think of (running 1 server, connecting to it via multiple revision clients).
Don't get me wrong, Apollo's multi-revision idea is nice,... but it isn't ideal.
There are several alternative solutions that can be brought to the table that will work much nicely.
Discuss, ask questions, propose your own solution or otherwise
How do you plan to make releases without automated tests? This is your chance to change the private server scene for the better so I must insist that you add testing.
When you try to go to height level 4 it will not let you go and there are a few castles like rouges castle in the wilderness that does need this fixed if you want to go all the way too the top.
Affects all versions of apollo including the original release. Would appear to only happen on some occasions.
getHeight and getWidth methods are incorrectly listed in the return field
In Release317 it imports a few classes from r377.
register(72, new FirstNpcActionEventDecoder());
register(155, new SecondNpcActionEventDecoder());
register(17, new ThirdNpcActionEventDecoder());
This is probably intentional for a reason, but in all the Apollo code I've seen, I haven't seen anyone use decoders from the other class (not to say it doesn't work -- it probably does)
http://puu.sh/jTddZ/0b2af2f1a5.jpg
Tried logging in and no player or tabs got sent. I tested several times & yes this is the current one
This is a copy of the most recent version of apollo and found this issue happen when messing around making trading. This has happened a few times and this is one of the times I have been able to get a screen shot of it happening
Issue in method "withdraw"
"EnterAmountListener listener = new BankDepositEnterAmountListener(player, message.getSlot(), message.getId());"
Change to
"EnterAmountListener listener = new BankWithdrawEnterAmountListener(player, message.getSlot(), message.getId());"
Issue using the wrong listener.
Apollo currently has no support for npc shops.
This should probably be done in ruby.
Fix planned but unimplemented.
id is being set to (:id, :experience), causing the item option event listener to break.
https://github.com/apollo-rsps/apollo/blob/master/data/plugins/skill-prayer/bury.rb#L59
id = hash[:id], experience = hash[:experience]
id = hash[:id]
BONES[id] = Bone.new(id, hash[:experience])
Edit: Forgot tag sorry.
NpcActionVerificationHandler
contains a check that will never pass, because the interaction count is always set to 5. The Handler must check that the option is valid (i.e. that the option is not set to "null"), which may also require some form of player-local state, as some npcs may have right-click options that are only visible if a specific varp is set.
This is the statement that will always evaluate to true
:
if (message.getOption() >= definition.getInteractions().length) {
message.terminate();
return;
}
The fletching.rb
script referenced in the fletching plugin definition file is missing.
public <M extends Message> boolean notify(Player player, M message) {
Deque<Class<? extends Message>> classes = this.classes.computeIfAbsent(message.getClass(),
this::getMessageClasses);
for (Class<? extends Message> type : classes) {
MessageHandlerChain<? super M> chain = (MessageHandlerChain<? super M>) chains.get(type);
if (chain != null && !chain.notify(player, message)) {
return false;
}
}
return true;
}
This line in particular
Deque<Class<? extends Message>> classes = this.classes.computeIfAbsent(message.getClass(),
this::getMessageClasses);
What fixes it is
Deque<Class<? extends Message>> classes = this.classes.computeIfAbsent(message.getClass(),
it -> getMessageClasses(it));
Which doesn't make sense because they're exactly the same thing
public T get(int index) {
index = index - 1;
if (index < 0 || index >= mobs.length) {
throw new IndexOutOfBoundsException("Mob index is out of bounds.");
}
return (T) mobs[index];
}
Needs to be change to this because before it would grab the wrong object
Every time I run ::lookup npc <name>
or ::lookup object <name>
(::lookup item works, oddly enough!) I get an error in the server console:
Jan 20, 2014 1:28:13 AM org.apollo.net.session.GameSession handlePendingEvents
SEVERE: Error handling event.
org.jruby.exceptions.RaiseException: (NameError) uninitialized constant Kernel::NpcDefinition
at org.jruby.RubyModule.const_missing(org/jruby/RubyModule.java:2684)
at org.jruby.RubyModule.const_get(org/jruby/RubyModule.java:2599)
at RUBY.(root)(data\plugins\cmd-lookup\lookup.rb:19)
at org.jruby.RubyProc.call(org/jruby/RubyProc.java:271)
at RUBY.execute(data\plugins\bootstrap.rb:44)
Line 19 of lookup.rb:
Kernel.const_get("#{type.capitalize}Definition").definitions.each do |definition|
I've manually tried NpcDefinition and ObjectDefinition to determine if it was a spelling error, and ItemDefinition is the only one that works.
On a side note, I also get
Jan 20, 2014 1:29:47 AM org.apollo.net.session.GameSession handlePendingEvents
SEVERE: Error handling event.
org.jruby.exceptions.JumpException$ReturnJump
from ::lookup if it's ran without any arguments.
EDIT
Fix for the uninitialized constant was adding some java imports to the ruby code.
Fix for the jump exception was changing return to next (though line 25 can't be changed from "return" to "next" or else it will just keep going through the array so you'll still get that outputted after a successful execution of ::lookup)
NPC head animations do not work on both 377 and 317. When using the dialogue plugin, only a static image of the NPC head is shown.
Should this be fixed plugin-wise or in core?
Apollo needs combat support.
Apollo, as you may know, employs a handler chain for most content where a message is propagated downward until it meets its destination handler and the message is handled there. This design has a lot of benefits, like employing methods of validation to stop message propagation. However, in the scripting system it fragments logic between various scripts and even has issues with plugin dependency in situations where handler priority is not properly sorted. For this case I state the usage of items for quests versus other functions where a quest plugin may handle the logic for an item for a quest but in cases where other functionality needs to be deployed there have to be extraneous cases where conditions are placed to specifically state which handler has priority. Also the design does not appropriately manage future content implementations without having to take into account special considerations which reference to the cited example. The design also fails to keep logic centralized and in an essence of the fact of the idea, 'clean'. However I think the plugin system also fails this purpose, even if that purpose isn't intended I feel as if the plugin system fails in assisting the developer an easier way to develop content. Just an opinion though.
When speaking of propagating messages, the efficiency of finding the appropriate message handler for a specific message has as a worst case scenario is O(N). Theoretically when there are hundreds of handlers, or even a few thousand, is not efficient compared to O(1) when using a map collection structure.
For these reasons I think the handler chain should be converted to a one to one representation of a message to message dispatcher, and for each message dispatcher a one to one representation of handler conditions to a handler should be employed. Such in the case of the message dispatcher, similar methods could be deployed to all message sub-types.
The proposal would be wide spread and I don't really expect it to be accepted right away however I feel the benefits outweigh the current implementation. A solution to this would include a logical centralized representation of all content, which the organization of such could be debated. Perhaps by category, or some other means.
Add support for banning/muting users.
The grouped region update frame will sometimes reset an object to its default state when the player walks a reasonable distance away.
The object should not be reset.
Currently it look like this
"} else if (opcode == 78 || opcode == 79 || opcode >= 90 || opcode <= 93 || opcode == 95) {"
Needs to be
"} else if (opcode == 78 || opcode == 79 || opcode == 90|| opcode == 91|| opcode == 92 || opcode == 93 || opcode == 95) {"
or
"} else if (opcode == 78 || opcode == 79 || (opcode >= 90 && opcode <= 93) || opcode == 95) {"
The BinaryPlayerSaver is writing the number of attributes the player has, however only writing the attributes which are of type SERIALIZED. Because of this, there will be a buffer underflow exception if any non-saved attributes are saved.
Additionally, BinaryPlayerSaver should use DataOutputStream's writeUTF method for continuity.
Issue with players that walk away from another player in a negative distance causing the flag to never catch more then 15 squares away. Issue is in position class and tut posted on r-s. http://www.rune-server.org/runescape-development/rs2-server/snippets/560387-apollo-player-updating-issue.html
When you currently try to equip the same weapon that you're currently wearing like a whip for example it will spaz out the weapon in the inventory for a quick second.
This does not happen with other things like hats,capes,shields, etc... only weapons
Not really an "Issue" but still something that is bothering me, found here:
public final List<Player> getLocalPlayerList() {
I mentioned this on Skype but I haven't gotten a chance to write an implementation yet. I don't imagine it would be too difficult (could just use a comparator). If done, someone would have to do a benchmark to see if it has any negative effects on performance.
Order of prioritization
I've tried several checks in the EquipItemHandler class and it seems like its not even sending it at all not sure if anyone else has had problems with this.
Although the NullPointerException is caught, there is still an error that gets raised when wielding two handed weapons. The error comes from adding an item to your inventory via the Inventory#add(Item)
method. This error is only raised when wielding two handed weapons, such as bows or two handed swords.
My guess at how this happens is when the two handed weapon is being equipped, it's trying to un-equip both the current equipped weapon and shield, and one (or both) are empty slots, thus the return value is null.
The solution I've found to work is just to just change this code (org.apollo.game.model.Inventory.java
):
// ... line 254 below
public Item add(Item item) {
int id = item.getId();
boolean stackable = isStackable(item.getDefinition());
if (stackable) {
// ...
to this:
// ... line 254 below
public Item add(Item item) {
if (item == null)
return null;
int id = item.getId();
boolean stackable = isStackable(item.getDefinition());
if (stackable) {
// ...
But just to be safe and make sure this isn't the only problem, here's the output:
Stack:
SEVERE: Error handling event.
java.lang.NullPointerException
at org.apollo.game.model.Inventory.add(Inventory.java:255)
at org.apollo.game.event.handler.impl.EquipEventHandler.handle(EquipEventHandler.java:128)
at org.apollo.game.event.handler.impl.EquipEventHandler.handle(EquipEventHandler.java:1)
at org.apollo.game.event.handler.chain.EventHandlerChain.handle(EventHandlerChain.java:64)
at org.apollo.net.session.GameSession.handlePendingEvents(GameSession.java:112)
at org.apollo.game.GameService.pulse(GameService.java:138)
at org.apollo.game.GamePulseHandler.run(GamePulseHandler.java:35)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
When the entity is teleported he isnt removed from the last sector they where in and they are not added into the new sector until they walk.
Fix:
public void teleport(Position position) {
if (SectorCoordinates.fromPosition(this.position) != SectorCoordinates.fromPosition(position)) {
SectorRepository repository = World.getWorld().getSectorRepository();
Sector newSector = repository.fromPosition(position);
Sector oldSector = repository.fromPosition(this.position);
oldSector.removeEntity(this);
newSector.addEntity(this);
}
this.position = position;
teleporting = true;
walkingQueue.clear();
stopAction();
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.