jnharton / mud-server Goto Github PK
View Code? Open in Web Editor NEWA MUD server written in Java w/basic OLC and a channel-based chat system.
License: MIT License
A MUD server written in Java w/basic OLC and a channel-based chat system.
License: MIT License
Basically, the code can be told to use a different database, but any other data which is dependent on a database is not necessarily kept separate.
The internal game mail is one such piece of data.
I happened to have two database files, DB1 and DB2 respectively, then user 'admin' on DB1 would have access to the mail of any user 'admin' and vice versa. I.e. no matter how many databases I use there is only one mail file for user 'admin'. The first one will be a new mail file and thereafter all other admins will get that, barring creating a new character with that name.
Consequently, that file might get overwritten if another DB is used and a new character is created with the same name as an existing character in another one.
Obviously this is something that ought to be dealt with, because it's really dumb.
For whatever reason, I opted at some point to prevent exits with special characters in their name from working somehow. For example if the exit's name was 'shining_blade' I can't use it, but if it was 'shiningblade' it would work fine. At the moment that seems somewhat silly, so I should review my reasoning if I can remember and the code if not.
This occasionally happens after connecting and logging in with one player and the connecting another client (before they would login). Also can happen on the first login when no one is connected.
Exception(MAIN): null
--- Stack Trace ---
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at mud.MUDServer.run(MUDServer.java:1317)
at mud.MUDServer.init(MUDServer.java:567)
at mud.MUDServer.main(MUDServer.java:550)
It leads back to here:
while (running) {
for (final Client client : s.getClients()) {
runHelper(client);
}
ALSO, when using the command '@shutdown' to shutdown the server
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at mud.MUDServer.shutdown(MUDServer.java:10464)
at mud.MUDServer.cmd_shutdown(MUDServer.java:6357)
at mud.MUDServer.cmd(MUDServer.java:2023)
at mud.CommandExec.run(CommandExec.java:73)
at java.lang.Thread.run(Unknown Source)
That leads back to here ( in shutdown() ):
// disconnect any connected clients
for (Client client1 : s.getClients()) {
init_disconn(client1);
}
For some reason, trying to use an exit now results in the game trying to send a message on a channel with the exit name as the channel name.
As I just realized today while pulling a fresh copy of the repository from GitHub I seem to have left a glaring mess in the form of the nearly useless zone editor. Until this gets fixed it would be necessary to institute a few zones by hand using a text editor...
My copy of the code seems to endlessly repeat the connect command once it is sent, resulting in it creating new players endlessly. At the same time it appears to lock up the command processer/parser on account of that.
Example output as of the connection command. Continues to infinity potentially.
connect Nathan iota
Connected!
Connected to WaterdeepMUD as Nathan
Checking for unread messages...
You have no unread messages.
OOC chat enabled.
STAFF chat enabled.
Nathan's_Test_Room
--------------------------------------------------------------------------------
You see nothing.
--------------------------------------------------------------------------------
Exits: next
Contents:
With:
[IC] Nathan
Connected!
Connected to WaterdeepMUD as Nathan
Checking for unread messages...
You have no unread messages.
OOC chat enabled.
STAFF chat enabled.
Nathan's_Test_Room
--------------------------------------------------------------------------------
You see nothing.
--------------------------------------------------------------------------------
Exits: next
Contents:
With:
[IC] Nathan
[IC] Nathan
The amount of data persisted for an object right now is fairly limited. The reason for this is that a text file is used to store data and uses a single line per object. While this approach was easy early on, it becomes painful to store additional data and avoiding ending up with massive lines of data that are difficult to understand visually as was the nominal idea originally. It is particularly problematic since all the data is stored in one file (very monolithic...) and any corrupted data requires careful handling or loading anything in the database after it might potentially not work right.
The ideal solution is to migrate data storage to a different model, whether it be some form of database (SQLite) or a more standardized form of structured text (XML, JSON).
I don't really like the XML properties style of mail, joshgit, moved the system to. That and the saving and loading of mail isn't in the clear. So I need to review it and either fix it up or revert to my system, plus maybe some improvements if I think of anything.
Whether the help command ought to be available isn't really the question. However, the current system utilizes, for the sake of amusement and perhaps to be less spammy/more controlled, a system akin to a pager (in the sense of the linux command 'more' or 'less').
Since the pager is stored per player (in the player object) there isn't a convention for allowing a not logged-in client a pager and thus any help file longer than 25 lines is not viewable for them.
Obviously if I maintain access to this command for that group of clients, then I need either alternate storage to keep pagers for all clients, to make paging not the default, or to rethink paging as a strategy. Perhaps, though, the modality through which pagers are accessed for players is not the best. The pager itself could, for instance, exist in a separate collection and the player merely hold another reference to it. [ I like the existence of setPager(...), getPager(...) in Player personally). Then the client could be afforded it's own pager in that collection.
There is evidently an issue with having ripped the guts out of the Server and Client classes as that has mangled the structure that support the serverEvent method and whatever infrastructure triggered it.
Possible Fixes?
I recently discovered that as it is, the Greet Command has a problem if there are, for example, two unknown players whose class is Ranger (this goes for any class. They will both have their names shown as 'Ranger' when you haven't greeted and they haven't greeted you. Thus the code will not allow you to greet the second 'Ranger' assuming that you have already greeted them (which is in fact not true). Thus the 'nicknaming' system is insufficient to distinguish two players of the same class.
Bug Level: Critical? (This makes the greet command and a mechanic based on introductions unlikely to be successful in most cases)
Despite having a barebones set-up in place and the ability to view Quest data, the current editor doesn't really support creating one from scratch. As the whole point of an editor is to be able to create new quests from scratch, this really needs to be fixed.
Something is wrong with the client handling and getting the client array from the server. Likely related to a bunch of stuff having been ripped out of Server.
Possible fixes?
I've replaced the name ref evaluation in my code with a better version (still buggy though) as a separate function. That is to say that the function takes in the argument string and resolves name references (ex. '$house') into database references (a.k.a. dbrefs, i.e. integers) using the current player's nameref table.
Not sure if you have this, are still using old one, or replaced with your own. Just a heads up in case you don't read all my commits.
I'd like to add this kind of functionality. Since this exists already I'd like to use an existing set of code.
There is some I3 code from a mud that was in development ca. 2005 called Aelfengard that is GPL licensed and is available for download at MUDBytes.net
DEPENDENCY: a working internal/local chat system
So the idea at the moment is store and load some of the game data from JSON. In particular, my intention is to store spells either as individual json files (one json object per file) or as one big file containing a json object per spell. Some of the code to handle this is written using google-gson, however that library has it's own license (Apache License 2.0). The compatibility of that license with the MIT license the codebase and how the code can be used together without any relicensing is yet to be determined.
DEPENDENCY: determine license compatibility
Code that uses said library will not work without it and sort of depends on differently licensed code/works.
The present quest system ought to make a deep copy of the Quest object each a player is given a quest by a quest giver (usu. an NPC). In theory it does, but apparently, the Task objects that belong to a particular Quest are not being copied in such a manner and so an update to the Quest for one player is an update to that Quest for all players.
(11/13/2013)
There is a problem regarding using the getObject(...) method of MUDServer that takes a String, namely that it retrieves the first object with the specified name. This remains true even for objects not considered to be in the room... As a result AttackCommand, given the same name of the object to target, always finds and attacks the same target, even when not in the room the Player is in or when it's dead (if Creature/NPC/Player).
This is in part because on their deaths, they are not removed from the database.
(11/12/2013)
I just started to overhaul the Quest class and the Task class tree. These changes necessitated some adjustments in the main MUDServer class and may have broken Task and Quest resolution for the time being. So, this needs to be finished soon.
NOTE: in the future, I need to do this kind of stuff on a -BRANCH-
At the moment, there is a method, initCreatedItem(...), which does makes sure the item is in the database and places it in the room with the dbref zero. Unfortunately, it does not place the item in the arraylist which holds the items in the room. As such those items cannot be seen by looking at the room and cannot be picked up at all. Obviously this is a problem. The solution is a crossroads issue that's been sticking around for a while. If I want to remain with the arraylist approach then I need to have that method (noted above) add the item to the room's arraylist. Otherwise, I must totally redo the system for "virtual" location, so that items with the location number are considered to be there. This could be awkward for containers, or maybe not, because then the item would have it's location inside an item, not in the player's inventory in a sense. That might be okay, and could be similar to present, but whatever.
The current system uses the text "NEW" in the status space to figure this out. Turns out this is really pointless, since chargen (like all editors) sets the status to EDT to indicate that the player is editing something. This occurs right before the check that expects to "NEW" and will otherwise deny use of chargen. So, it will never work, an alternate mechanism will be required.
The newly added 'setflag' command in the room editor is not properly handled. In principle, none of the changes in the editor are propagated to the actual room until
either the 'save' command is sent or the 'done' command which indicates that we are done editing and the changes should be finalized.
At the moment, however, the use of 'setflag' has an immediate effect on the flag settings of the room being edited that is perceivable by others. That should not be the case.
The command does not transfer control of an npc to the player as expected. It appears that this is in part because the game ought to see the npc in place of the player (as in getPlayer(client) should return an npc if I am controlling one). Also, it does not mark the player as controlling an npc.
Why have both?
Prior to a recent pull request, the server had an implemented partially working chat system. Now it has the beginnings of a reworking. As such it is in need of work to restore it to a similar level of functionality.
And other similar files?
The nameref analysis code is getting stuck in a loop if you execute a command such as
ex $NULLOBJECT$
The problem is that it hits another $, which implies a new nameref. For some reason, instead of seeing empty space, looking for a second nameref and just evaluating that second $ as nothing it loops and tries to re-evaluate the whole string (infinite loop).
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.