Code Monkey home page Code Monkey logo

Comments (6)

shoftee avatar shoftee commented on July 19, 2024

I'm not sure what you mean by "actual network endpoints".

In any case, you are looking at a very incomplete codebase, only a small part of my design is actually implemented here.
There is no single entry point to the server. The server, if it is ever implemented in this design. would consist of a few separate processes, a few of which you already named. Initially the idea came (as you can expect) from the older revisions of Odin, where the Login/World were separated. The RMI architecture of Java is very painful to use, however, so people never managed to improve the code in that direction, and some even decided (rightfully so) that RMI was not worth it and that for their purposes one process was enough.
WCF alleviates this issue greatly, so I figured I should do it properly.
The design would consist of the following:
Authentication service, which is basically your silly ol' Login Server with a WCF wrapper on top.
Account service, which keeps track of active accounts, so you don't need to do the painful database tracking that you see in the Odin codebase, or at least recent versions of it, and also because the Cash Shop needs the same account information to work properly.
Cash Shop service, which is mostly obvious
World service, which handles world-wide broadcasting (in the general sense, of packets) and player groups which can span multiple channels.
Channel service, which would contain a huge chunk of code involving game maps and everything that resides in them. The other notable piece here would be keeping track of some channel-only subsets player groups for convenience. This category includes parties involved in party quests, expedition teams, etc. This should also involve some forms of chat, like megaphones and if possible map-wide messages, though I think you could get away with putting that into the map layer.

And last and probably least expected, Universe service. Now this is a rather curious thing, since people don't generally think multi-World when they think about coding a private server. If you are however going multi-world, this service is actually on the necessary side, since things can get messy when you need to pass multi-world information to the Auth server. The world servers should not have anything at all to do with the Auth server. They are separate things. The active accounts would be handled by the Account service. The active world data would be cached/updated in the Universe service. The Universe service would be responsible for responding to world data requests from the Auth service.

Now, as you can see the auth and account services are separate processes. There is good reason behind this, though now that I think about it, it may be wise to clump Auth/Account/Universe in the same process, since they are closely related. But otherwise, you want separate channels to be separate domains, or processes. The design I envisioned was to have all of these pieces in separate app domains, so you can arrange them as you please, but there is merit behind separating them into multiple processes. If you use ngen'd assemblies there is really no overhead to it either.

And there is an idea to make a management tool for these. In general I am strongly opposed to having the nodes be controlled from inside the game - it causes weird scenarios where you can disconnect the world/channel you're on, bugs in the code can bring down the world/channel you're on, etc. Management should be remote and secure, and most of all inaccessible to idiots.

from openstory.

shoftee avatar shoftee commented on July 19, 2024

Ahhhhhh network entry points. Gotcha.

The services which need to handle sockets are:

Auth, Cash Shop, Channel

The World, Account and Universe services are behind the scenes, serving shared information on demand.

There is actually a class in there for a network-connected server, I think it's called AbstractServer
Note that in this case "server" and "service" are different things.
"Service" refers to the WCF wrapper which handles communication between the nodes.
"Server" refers to the network servers you're interested in, and they handle player sockets and the like. Look at AbstractServer and related for details, comments should be enough.

from openstory.

strax avatar strax commented on July 19, 2024

Thanks for the detailed reply, that helped clear things a lot about the general architecture :)
You're right about the management tool, I actually started thinking about a Windows service but that doesn't allow the flexibility a GUI / CLI interface would offer. Then again is OpenStory.Server.Emulation your unfinished "manager" module - taking care of the service & server initialisation and such? Are there any missing pieces in the puzzle then I should be aware of? I plan to hack on it every now and then, the point being that I can retain the general architecture design.

from openstory.

shoftee avatar shoftee commented on July 19, 2024

Yes, Server.Emulation is supposed to be the bootstrap module. Like you tell it "start" and everything just works.
Currently it only makes some app domains for the worlds and starts stubs in there, but in the end you'll wanna have separate app domains for channels as well.
This is actually another interesting point, the other reason I went for the separate AppDomain/process architecture is because they have separate global variables.
So for each ChannelServer you can have like a Singleton for the server instance and access it from anywhere you want in the Channel server code. It's generally bad practice, but it's the most feasible way to do it without using dependency injection. Which I can actually recommend for some other parts of the architecture, but for this case in particular I figured that the advantages of splitting them up were sufficient.

And as for the management tool, a Windows service is what I would do, but don't use the communication architecture provided by the Windows API, make your own with WCF. Much more flexible. :P

I can also give you more hints on the player group architecture I had in mind, it's actually quite nifty, I am worried about it being a resource hog however.

from openstory.

strax avatar strax commented on July 19, 2024

Alright, I understand. A manager process could auto reload the managed app domains in case of a crash or something. Does the server work on any version (I see you had .68 as a target version, would it work on .83 without any modifications)?

from openstory.

shoftee avatar shoftee commented on July 19, 2024

The server is much too incomplete to be related to any version in particular, and there was no real target version, what you saw was only there because the version is required for the encryption of the packets.
And in case it's confusing, that's EMS 0.68, not GMS.

There is also an idea to make a database containing all the op codes for all the versions. Supposedly this suggestion would be better aimed at MCDB.
The AbstractServer type has a property for the packets the server endpoint supports. OpCodeTable is the type that stores them. It has two dictionaries, one that maps incoming op code to label, so you can handle by label instead of op code, and one that maps label to outgoing op code, so you can add the op code to the packet by its label. I think it's quite nifty. The naming is Outgoing/Incoming because this is supposed to be used for both endpoints of the socket connection. You can use the same type if you ever want to make an OpenStory-based client.

... And I think if you actually want to get this thing working, you'll wanna do a lot of other things before making the management tool. You still need to wrap the Channel and World servers in WCF wrappers. I was actually planning on doing that one of these days, since you went and got me talking about this project again :P

My problem with making a working server is that I actually need to test if everything works, and to do that I need to do quite a few hacks on the client side of things, none of which I'm really comfortable with. For example, there's a certain app which redirects packets, but its code is quite horrid, the only reason people use it is because "it works", and that is very much below my standards. The reasonable solution would be to rewrite the redirector on top of OpenStory.Common/Cryptography/Networking and include the redirector into OpenStory, but that would probably be in another repository if it ever happens, and I can barely stand to look at that horrible code, even less make sense of it and rewrite it.

from openstory.

Related Issues (3)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.