Jump to content

Elfo

Legendary Member
  • Posts

    2,009
  • Credits

  • Joined

  • Last visited

  • Days Won

    51
  • Feedback

    0%

Posts posted by Elfo

  1. Changed the way handlers are registered. Now they will be scanned automatically during server startup and they will be registered based on their annotation. This means that all you have to do to add a new endpoint is to create a request handler and add the Get, Post etc annotation.

  2. 1 minute ago, Tryskell said:

    PlayerInfoTable retains some informations (cause player names are needed for stuff like friendlist), you probably can add missing ones, but it means you have to update it in same time otherwise you will refer to wrong values.

     

    That whole class probably can be enhanced or used differently (maybe part of Player, once player is loaded ? Like loading an id card, which avoid duplicates variables).

    The problem with having multiple points of truth is that you don't have a single one you can fully trust, that's why i trust nothing but the database and the World class. I also don't wanna touch the core at all so if I do any caching it will happen in the API level.

  3. 52 minutes ago, Lioy said:

    Thank you a lot for that. That's what I was searching. I have one question

     

    
    L2DatabaseFactory.getInstance().connection.use { con ->
                    val statement = con.prepareStatement(SqlQueries.GetAllPlayers)
                    val resultSet = statement.executeQuery()
    
                    var player: PlayerResponse? = null
                    if (resultSet.next())
                    {
                        val id = resultSet.getInt("obj_Id")
                        val name = resultSet.getString("char_name")
                        val level = resultSet.getInt("level")
                        val isOnline = resultSet.getInt("online") == 1
                        val pvpKills = resultSet.getInt("pvpkills")
                        val pkKills = resultSet.getInt("pkkills")
                        val isNobless = resultSet.getInt("nobless") == 1
                        player = PlayerResponse(id, name, level, isOnline, pvpKills, pkKills, isNobless)

     

     

    Wouldn't be better to take these infos from the player object itself for example?(if player is online) So it would be real time , because database values are not always real time on L2J due to delay of updating. This specific feature may isn't the best example to what I mean actually but propably you got the point.

     

    Also practically could we extend this to create token authentication and the ACP(or whatever) to be just a cool SPA with front end framework(react,vue,etc)? 

    The problem is that the offline players are not loaded in memory so the dB call is inevitable. Everything that is loaded in the in memory cache will be served by the cache when possible. If the endpoint was get online players only then yeah it would be coming from the World class.

     

    Auth is very simple to add. It’s basically a simple middleware.

     

    originally when I started this it was to actually make a new ACP but it’s too much work and I don’t really wanna do front end anymore so I just created the api. If people wanna make their front end that’s fine by me. 

     

    EDIT: Oh I now see what you mean, I read it wrong the first time. Yes it would make sense to get that info from the cache if the player is online. I will add that.

  4. So I was bored again...

     

    L2jRest is a RESTful API for L2j

     

    It is created for latest aCis but you should be able to adapt it is you wanna use it for other projects.

     

    L2jRest is an open source project licensed under MIT. You can find the source here: https://github.com/Elfocrash/L2jRest

     

    Why use it?

    • You can use the data of your server in your website
    • You can create an account control panel with it
    • You can expose data to your community to allow them to make third party apps

     

    Technical stuff

    • It is written in Kotlin.
    • It is using the Ktor framework. Ktor is using coroutines to achieve asynchronous request handling. It is very efficient and very fast.
    • It is using Netty as the underlying server.
    • It is written in a CQRS manner with query handlers for get endpoints and command handlers for post, put, patch, delete etc.
    • It is using Koin as the IoC framework.

     

    How to setup

    • Download and install Intellij IDEA
    • Git clone the project and open it with Intellij
    • Run the build Gradle task. It is configured to create a fat jar with all the dependencies included
    • Paste the jar in your project, add it in your classpath and add the following line at the bottom of your Gameserver.java: L2jRestApi.INSTANCE.start();
    • Running the gameserver will also run the api. It is running under port 6969

     

    How to extend it

    • All you need to do if you wanna add more endpoints is to add a new handler and then add the Get, Post etc annotation depending on what endpoint you want this to be.

     

    Current endpoints:

    http://localhost:6969/api/players

    http://localhost:6969/api/players/{id}

     

    A couple of endpoint examples

     

    Endpoints: http://localhost:6969/api/players

    Response:

    {
        players: [
    		{
    			"id": 268480927,
                "name": "Test",
                "level": 1,
                "isOnline": false,
                "pvpKills": 0,
                "pkKills": 0,
                "isNobless": false
    		},
    		{
    			"id": 268480924,
                "name": "Test2",
                "level": 1,
                "isOnline": true,
                "pvpKills": 0,
                "pkKills": 0,
                "isNobless": false
    		}
    	]
    }

     

    Endpoint: http://localhost:6969/api/players/268480927

    Response:

    {
        "id": 268480927,
        "name": "Test",
        "level": 1,
        "isOnline": false,
        "pvpKills": 0,
        "pkKills": 0,
        "isNobless": false
    }

     

    Currently it just supports two endpoints and no authentication. I am planning to add more endpoints and ApiKey based auth tomorrow.

     

    If you can't be arsed to build the project yourself but you wanna take a look anyway you can download the jar here

     

    • Like 3
    • Upvote 2
  5. 15 minutes ago, Rootware said:

     

    It's all what you can says in arguments for my proof? Thanks for your time, so.

    That’s what you call proof? I guess you don’t do programming for a living.

     

    The single request response times with a single db query for microframeworks and full web frameworks with a combination of different databases such as postgres and MySQL with no proof that a cp is configured to be used is what you call proof? On top of that the Spring framework in this example is configured to work with Postgres not MySQL and there is no clarity on which cp is used or how it’s configured. ALSO you can see that the leading Microframeworks have better performance because: 

     

    1. They are not using an ORM and they are executing their DB queries raw so OFC they will have optimal performance

    2. They have the 1/1000 of the codebase that Spring has and they can do a very limited amount of things.

     

    i also find it very funny that you choose to know single query (which doesn’t even make sense for the CP) and not multiple because in multiple is the top most performing full web framework. 

     

    Seriously i am wasting my time with this joker. I would be ashamed if I were you.

  6. 16 minutes ago, Tryskell said:

    So add that packet into the given client state, and if it's not that, you are basically screwed if you don't know how to client edit.

    The client can handle bypass packets fine at this stage. aCis acks the packet only as a packet you can send while INGAME so you need to add the exception in the packet handler to accept the bypass

    • Like 1
×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock