Jump to content

eressea

Legendary Member
  • Posts

    534
  • Credits

  • Joined

  • Last visited

  • Days Won

    7
  • Feedback

    0%

Posts posted by eressea

  1. 6 minutes ago, Geosniffer said:

    Hello,

     

    I have few questions if you allow me:

     

    • Can a person run live server with this files or not yet ?
    • Is EXT built on RPG-Club GF files ?
    • If we measure this files with advext where does your files stand in terms of stability and retails functionality, same , better or still new ?

     

    Hi,

     

    we run L2 Shrine on it for more than 15 months now and we don't have any troubles.

     

    It's based on leaked Gracia Final PTS (l2server_l2off_gracia_final_83), I'm not sure if it differs from RPG Club binaries.

     

    As for AdvExt - it's mature commercial product with lot of custom features, support for SmartGuard and supports Gracia Final, Gracia Epilogue and H5.

     

    MyExt64 is 18 months old open-source project  with fewer custom features (we primarily develop it for use on our retail-like server) that supports Gracia Final and most of Gracia Epilogue (Command Channel feature is still missing and active quest count is still limited to 26 [which should be 40 on Epilogue]) and probably will support Freya and maybe H5 in the future.

     

    Regarding stability - it's basically the same. There are almost no crashes for both (in fact the rate of Windows Server crashes is similar to rate of L2server crashes). AdvExt just requires little bit more memory to run (the difference is around 1-2 GB, nothing big, it's probably caused by H5 support so if MyExt will support H5 in the future, this difference may diminish).

     

    If you have enough money and want to have commercial support, go for AdvExt (and don't forget to buy updates periodically). If you don't want to spend any money for extender or want to make changes inside the core, you should get MyExt. Or maybe Vanganth's last sources (but that supports only Gracia Final and contains some bugs already fixed in MyExt and AdvExt, currently the most serious of them probably being crashing clients via specially crafted crest packet, on the other side, it wouldn't be hard to port these fixes from MyExt).

    • Like 1
  2. 2 minutes ago, sepultribe said:

    @eressea you are a rare gem in the l2 community, thanks a lot for your great work and willingness to share with an open heart. I feel really lucky that you are with us here and I think so should the rest of the people in this forum.

     

    I also played on shrine for a bit but had to quit L2 alltogether, all the people there deserve big congrats too. Best uncorrupted server I ever played since 2005, just for the pure love of it.

     

    Thanks :)

  3. Interesting work, however

     

    12 hours ago, Gttsu said:
    • don`t exists full compiler

     

    Exists and you have it right under your nose - in l2npc.exe. You just need to know how to use it.

     

    12 hours ago, Gttsu said:
    • standard ai.obj byte code not optimized

     

    And bridging back and forth between C# and C++ will be much better...

     

    12 hours ago, Gttsu said:
    • Problem with variables local and globals

     

    Just extend CNPCEvent and/or GlobalObject and add whatever you want

     

    12 hours ago, Gttsu said:
    • Problem with adding extra native method or events

     

    Problem?

     

    12 hours ago, Gttsu said:
    • Can`t add inner methods

     

    Could be done in some preprocessor

     

  4. The fourth number in territory definition isn't direction but maxZ - it's x, y, minZ, maxZ for each point.

    If you need to spawn NPC on specific location, go there, get your /loc and use it. Z coordinate should be within minZ and maxZ from territory (and X and Y coordinates should be inside territory).

    Direction is 16384 per 90° so 0 ~ 0°, 16384 ~ 90°, 32768 ~ 180°, 49152 ~ 270°.

    Ignore that malloc, it's just for developers (NCsoft) to see how many memory they allocate - they just log all allocations larger than 32 KB.

    You can use as many points as you need (of course at least 3) but I'm not sure if it requires them to be clock-wise or whether it doesn't matter (in some systems when you make polygon counter-clock-wise, it's area is outside, when you make it clock-wise, it's area is inside) - not sure how this works, I haven't tried to reverse engineer any of these (it always just worked for me)

     

    • Upvote 1
  5. Probably something like this but I can't figure out what variable is 144 on talker (CSharedCreatureData + 0x90) - you'll have to find it in your extender (it doesn't seem to be in C4 l2npc.exe):

    set_compiler_opt base_event_type(@NTYPE_NPC_EVENT)
    
    class sia_premium : citizen {
    parameter:
    	int nMoneyId1 = 4037;
    	int nAmount1 = 150;
    	int nDuration1 = 604800;
    	float nAdenaRate1 = 1.500000;
    	float nItemRate1 = 1.500000;
    	float nSpoilRate1 = 1.500000;
    	float nExpRate1 = 1.500000;
    	float nSpRate1 = 1.500000;
    
    	int nMoneyId2 = 4037;
    	int nAmount2 = 250;
    	int nDuration2 = 1296000;
    	float nAdenaRate2 = 1.500000;
    	float nItemRate2 = 1.500000;
    	float nSpoilRate2 = 1.500000;
    	float nExpRate2 = 1.500000;
    	float nSpRate2 = 1.500000;
    
    	int nMoneyId3 = 4037;
    	int nAmount3 = 450;
    	int nDuration3 = 2592000;
    	float nAdenaRate3 = 1.500000;
    	float nItemRate3 = 1.500000;
    	float nSpoilRate3 = 1.500000;
    	float nExpRate3 = 1.500000;
    	float nSpRate3 = 1.500000;
    	string fnOk = "gmshop_premium_activated.htm";
    	string fnError = "gmshop_premium_error.htm";
    	string fnAll = "gmshop_premium_already.htm";
    
    handler:
    	EventHandler MENU_SELECTED(talker, ask, reply)
    	{
    		if (ask == 360) {
    			if (GetInventoryInfo(talker, 0) >= GetInventoryInfo(talker, 1) * 0.8
    				|| GetInventoryInfo(talker, 2) >= GetInventoryInfo(talker, 3) * 0.8) {
    
    				ShowSystemMessage(talker, 1118);
    				return;
    			}
    
    			if (talker.unknown144 == 0) { // COULDN'T FIND OUT WHAT IS THIS - It's INT32 on CSharedCreatureData+0x90
    				if (reply == 1) {
    					if (OwnItemCount(talker, nMoneyId1) >= nAmount1) {
    						DeleteItem1(talker, nMoneyId1, nAmount1)
    						ChangeDynamicRates(talker, nAdenaRate1, nItemRate1,
    							nSpoilRate1, nExpRate1, nSpRate1, nDuration1);
    						ShowPage(talker, fnOk);
    						return;
    					} else {
    						ShowPage(talker, fnError);
    						return;
    					}
    				} else if (reply == 2) {
    					if (OwnItemCount(talker, nMoneyId2) >= nAmount2) {
    						DeleteItem1(talker, nMoneyId2, nAmount2)
    						ChangeDynamicRates(talker, nAdenaRate2, nItemRate2,
    							nSpoilRate2, nExpRate2, nSpRate2, nDuration2);
    						ShowPage(talker, fnOk);
    						return;
    					} else {
    						ShowPage(talker, fnError);
    						return;
    					}
    				} else if (reply == 3) {
    					if (OwnItemCount(talker, nMoneyId3) >= nAmount3) {
    						DeleteItem1(talker, nMoneyId3, nAmount3)
    						ChangeDynamicRates(talker, nAdenaRate3, nItemRate3,
    							nSpoilRate3, nExpRate3, nSpRate3, nDuration3);
    						ShowPage(talker, fnOk);
    						return;
    					} else {
    						ShowPage(talker, fnError);
    						return;
    					}
    				}
    			} else {
    				ShowPage(talker, fnAll);
    			}
    			return;
    		}
    		super();
    	}
    }

     

  6. 2 hours ago, Jojo_ said:

    1. Do you think we could send item with mail from SQL? (similar to dimensional merchant)
    2. The date a mail stay can be changed? (If I am right on official that 30 days) But here will you add a param in .ini to configure the delay before delete (like 0 = never and next that counted in day?)
    3. Not a suggestion just a question, will you check if we can send item in mail with the params is tradable from itemdata.txt?
    4. Really thank you for your extender I know I can seem intrusive but really you do something wonderful ! 

     

    Hi,

     

    1. First I need to get it running without items - just pure mail, then add items and then maybe sending via SQL or Cached admin socket

    2. Probably yes (and if not, I would gladly accept a patch for it :D)

    3. Of course, you will be able to send only items that are tradeable and usable in private store

    4. Thanks :)

  7. 17 hours ago, iPlay.gg said:

    1. Compiler - "a tool that can be used to have "ready for game files", for L2OFF can be used Microsoft Visual Studio."

     

    Hi, this depends on whether you're speaking about extender compiler or AI compiler. Extenders* are written in ASM, C++ or combination of both and usually it's compiled with Visual Studio. AI is written in NASC language (made by NCsoft) and there are multiple compilers available - some of them based on NCsoft binaries, some of them written from scratch.

     

    * explanation about extenders: There are some files from NCsoft that leaked out. We know at least about C0 files, C4 PTS files and GF PTS files. All these contain EXE files that you can use - but they're full of bugs etc. Here comes the extender - it's some DLL file that attaches to server EXE file and does some changes and fixes. Usually it's very difficult to find out how to change something so I won't recommend trying this if you're beginner and don't have good experience with ASM and C++.

     

    17 hours ago, iPlay.gg said:

    2.Decompiler - "Vise versa of compiler, also can be used with Microsoft Visual Studio?"

     

    Probably decompiler for AI - in L2OFF there are leaked obj files (compiled AI), if you want to work with it, you need to get decompiled AI somewhere or decompile it yourself. If you're beginner, you should find already decompiled AI.

    As for server itself - it can't be decompiled, programmers have to reverse engineer it (see explanation about extenders in previous answer)

     

    17 hours ago, iPlay.gg said:

    3. L2OFF Language - is it C++ and PHP ?

     

    The original servers are written in C++ and AI is written in NASC language

     

    17 hours ago, iPlay.gg said:

    4. Advised OS to run L2OFF server would be Microsoft Server 2008 RS 32 bit version? - can end up having memory limit issues

     

    Only C0 server was 32bit, all newer versions are 64bit so they require 64bit system. GF-based servers run fine on all Windows Servers 2008+ (64bit). You definitely don't want to use C0 based server if you're a beginner.

     

    17 hours ago, iPlay.gg said:

    5. How to understand if user has compiled or non compiled ? - I would assume by looking at file extensions like .class, that probably is not possible to open? or can?

     

    I would guess it's again about compiled AI (obj files using simple stack language, hard to read and update) and source AI (NASC files, easy to read and update, have to be compiled before use on server) but I'm not sure.

     

    17 hours ago, iPlay.gg said:

    6. Alright, i have shared OFF source, what is the first thing developers normally do? - I mean i want to have clean files with what to learn to, i think i found some

     

    You don't have server source, you have only extender source. You probably want to compile it (in Visual Studio) and use it with your server files. Pay attention to picking right binaries (EXE files) as it must match extender base version (C4/GF) - extender for GF won't work with C4 EXE files and vice versa.

     

    17 hours ago, iPlay.gg said:

    7. Lets say im interested to create ALT+B panel onto L2OFF source, where should i start? (ingame ALTB is disabled), does it use html language for community board?

     

    You would have to add handling for all bypasses for community board into the extender. Maybe few days of work for someone who is experienced with L2OFF core development - there are not many people who can do this. You can try to learn it slowly (get IDA Pro, create database for your l2server.exe and try to comprehend what your extender is doing there) but you stand no chance if you're not ASM/C++ programmer.

     

    17 hours ago, iPlay.gg said:

    8. How does scripts work? with source i have, there are scripts, are they run automatically, or there are certain functions that will call them? For example (i dont have it), lets say i got TvT script, how could i run it? or there is some global function that read everything thats inside "scripts folder", and is activated based on command or time?

     

    You should get decopiled AI somewhere and try to learn from it. There are AI classes defined and NPCs can use them. For TvT event you would probably create some NPC (manager who would manage the event) and write an AI class for it to handle everything.

     

    17 hours ago, iPlay.gg said:

    9. lets assume, im interested to write whole TvT script from scratch, where could i start? is there a library that can be used ? Should i be using Microsoft Visual? is there a functions library?

     

    If it will need some core support, you'll have to implement it in your extender. If you're ok with features that are already there, you need just to write the AI class (in NASC language), create NPC(s) for it, write HTML dialogs etc.

     

    17 hours ago, iPlay.gg said:

    Some Advise for installation, right now ive managed to run off, but without NPC exe,  for some reason VM Machine that im running (windows server 2008 RS 64Bit) is not showing BOOT.INI, ive  already tried to reveal the hidden content, but its just missing, i would assume its because of VMware-is there anyways possible to run directly from windows 10 machine (64bit), also does anyone know direct link for windows server 32 bit or 86bit ? ISOs ive downloaded from MS did not get installed by Vmware for some reason.

    Another issue was about IP Configuration, i mean on VM ware i would not use WAN (whatsmyip lookup) to setup over lan ? - ive tried Bridge, host, NAT (definitely not working :D). But seemed to be not working, Running on L2 on same VmMachine , it works, when i either use: 10.0.2.24 (Virtual IP) or 127.0.0.1, i did try with WAN aswell, but on host machine still does not connect through, any advise? - Im bit confident that i missed something really tiny and easy.

    Also could or would, anyone share Interlude, HF or GF source that is not "TOO TERRIBLE", but is clean from customization, so i could use that as my first files to learn and train on top of these (i believe i would need decompiled?, what would be the compiler?)


    Thanks for the efford folks!

     

    You can run it on W10 64bit so you don't need any VM. As for Visual Studio, you'll probably need exactly Visual Studio 2005 SP1 64bit.

     

    As for clean GF - google for l2server_l2off_gracia_final_83, that's the original leak. Don't run live server (with players) on it as it's full of dupes and other security bugs (and many other bugs). As for some extender source - you can get my opensource extender or download Vanganth's extender somewhere, if I remember correctly, someone has shared it here on this forum.

    • Like 1
    • Upvote 2
  8. Hi everyone, apart of L2, I also work on many different things and I'd like to share one example I wrote (because it's not so easy finding out how to  do it properly).

     

    When you need to render some text that requires more complex rendering than Latin - for example Hebrew, Arabic and Devanagari (Hindi) - you'll have to do some text shaping. It's not so difficult for Hebrew and Arabic (if you don't mind sometimes wrong niqqud, you can implement subset of OpenType and use fribidi) but for Devanagari it's almost impossible to implement again (too much work).

     

    If you're on Windows platform only, you can use Microsoft's Uniscribe which works perfectly, on OS X/iOS you can use Apple's Coretext which works very well too.

     

    But what if you need it to be platform agnostic? Then you can use FreeType and HarfBuzz :) Also, HarfBuzz can use native (Uniscribe/Coretext) shapers on given platform (depends how you compile it) instead of it's own shaper.

     

    So the example here, as for fonts, you can download them from Google, if you want to see output without compiling, scroll down.

    
    #include <iostream>
    #include <harfbuzz/hb.h>
    #include <harfbuzz/hb-ft.h>
    #include <ft2build.h>
    #include <freetype.h>
    
    // Input texts in UTF-8 (without Byte Order Mask)
    static const char *texts[] = {
        "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d \xd7\xa2\xd7\x95\xd7\x9c\xd7\x9d",
        "\xd9\x85\xd8\xb1\xd8\xad\xd8\xa8\xd8\xa7 \xd8\xa8\xd8\xa7\xd9\x84\xd8\xb9\xd8\xa7\xd9\x84\xd9\x85",
        "\xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87 \xe0\xa4\xa6\xe0\xa5\x81\xe0\xa4\xa8\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xbe"
    };
    
    // Font sizes in points
    static const size_t fontSizes[] = {
        16,
        16,
        16
    };
    
    // Font filenames
    static const char *fontFiles[] = {
        "NotoSansHebrew-Regular.ttf",
        "NotoSansArabic-Regular.ttf",
        "NotoSansDevanagari-Regular.ttf"
    };
    
    int main(int argc, char **argv)
    {
        // Freetype library handle
        FT_Library library;
    
        // Initialize FreeType
        if (FT_Init_FreeType(&library)) {
            std::cerr << "Can't initialize FreeType" << std::endl;
            return 1;
        }
    
        // Go through all input texts
        for (size_t textIndex = 0 ; textIndex < sizeof(texts) / sizeof(texts[0]) ; ++textIndex) {
            // Current input text
            const char *text = texts[textIndex];
            const size_t fontSize = fontSizes[textIndex];
            const char *fontFile = fontFiles[textIndex];
    
            // FreeType font face handle
            FT_Face face;
    
            // Load font
            if (FT_New_Face(library, fontFile, 0, &face)) {
                std::cerr << "Can't load font " << fontFile << std::endl;
                return 1;
            }
    
            // Set character size
            if (FT_Set_Char_Size(face, fontSize << 6, fontSize << 6, 0, 0)) {
                std::cerr << "Can't set character size" << std::endl;
                return 1;
            }
    
            // Set no transform (identity)
            FT_Set_Transform(face, 0, 0);
    
            // Load font into HarfBuzz
            hb_font_t *hbFont = hb_ft_font_create(face, 0);
    
            // Create buffer for our text
            hb_buffer_t *hbBuffer = hb_buffer_create();
    
            // Add our text to buffer
            hb_buffer_add_utf8(hbBuffer, text, -1, 0, -1);
    
            // Detect direction etc
            hb_buffer_guess_segment_properties(hbBuffer);
    
            // Shape our text
            hb_shape(hbFont, hbBuffer, 0, 0);
    
            // Shaped text info
            unsigned int len = hb_buffer_get_length(hbBuffer);
            hb_glyph_info_t *info = hb_buffer_get_glyph_infos(hbBuffer, 0);
            hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(hbBuffer, 0);
    
            // Compute text width and origin (from min and max X and Y drawing coordinate)
            int originX = 0, originY = 0;
            int minX = INT_MAX, maxX = INT_MIN, minY = INT_MAX, maxY = INT_MIN;
    
            // Go through all glyphs and find minimum and maximum X and Y coordinate
            for (size_t i = 0 ; i < len ; ++i) {
                // Load glyph
                if (FT_Load_Glyph(face, info[i].codepoint, FT_LOAD_RENDER)) {
                    std::cerr << "Can't load glyph " << info[i].codepoint << std::endl;
                    return 1;
                }
    
                // Glyph data
                FT_GlyphSlot slot = face->glyph;
    
                // Get X and Y offset
                int offsetX = ((pos[i].x_offset + slot->metrics.horiBearingX) >> 6);
                int offsetY = ((pos[i].y_offset + slot->metrics.horiBearingY) >> 6);
    
                // Compute minimum and maximum X and Y for this glyph
                int glyphMinX = originX + offsetX;
                int glyphMaxX = originX + slot->bitmap.width + offsetX;
                int glyphMinY = originY - slot->bitmap.rows + offsetY;
                int glyphMaxY = originY + offsetY;
    
                // Update minimum and maximum X and Y for text
                if (glyphMinX < minX) minX = glyphMinX;
                if (glyphMaxX > maxX) maxX = glyphMaxX;
                if (glyphMinY < minY) minY = glyphMinY;
                if (glyphMaxY > maxY) maxY = glyphMaxY;
    
                // Advance
                originX += pos[i].x_advance >> 6;
            }
    
            // Text will start on 0
            originX = -minX;
            originY = -minY;
    
            // Compute width and height
            size_t width = maxX - minX + 1;
            size_t height = maxY - minY + 1;
    
            // Allocate buffer for image
            unsigned char *image = new unsigned char[width * height];
    
            // Clear image bufer
            memset(image, 0, width * height);
    
            // Go through glyphs and draw them
            for (size_t i = 0 ; i < len ; ++i) {
                // Load glyph
                if (FT_Load_Glyph(face, info[i].codepoint, FT_LOAD_RENDER)) {
                    std::cerr << "Can't load glyph " << info[i].codepoint << std::endl;
                    return 1;
                }
    
                // Glyph data
                FT_GlyphSlot slot = face->glyph;
    
                // Pointer to bitmap data
                unsigned char *ptr = slot->bitmap.buffer;
    
                // Get real offset
                int drawX = originX + ((pos[i].x_offset + slot->metrics.horiBearingX) >> 6);
                int drawY = originY + ((pos[i].y_offset + slot->metrics.horiBearingY) >> 6);
    
                // Copy bitmap
                for (size_t y = 0 ; y < slot->bitmap.rows ; ++y) {
                    // Copy row
                    for (size_t x = 0 ; x < slot->bitmap.width ; ++x) {
                        if (drawX + x < 0) {
                            std::cerr << "drawX (" << drawX << ") + x (" << x << ") < 0" << std::endl;
                            abort();
                        }
                        if (drawX + x >= width) {
                            std::cerr << "drawX (" << drawX << ") + x (" << x << ") > width (" << width << ")" << std::endl;
                            abort();
                        }
                        if (drawY - y < 0) {
                            std::cerr << "drawY (" << drawY << ") - y (" << y << ") < 0" << std::endl;
                            abort();
                        }
                        if (drawY - y >= height) {
                            std::cerr << "drawY (" << drawY << ") - y (" << y << ") > height (" << height << ")" << std::endl;
                            abort();
                        }
                        image[(drawY - y) * width + drawX + x] = ptr[x];
                    }
                    // Advance pointer
                    ptr += slot->bitmap.pitch;
                }
    
                // Advance
                originX += pos[i].x_advance >> 6;
            }
    
            // Output rendered text
            for (size_t y = 0 ; y < height ; ++y) {
                for (size_t x = 0 ; x < width ; ++x) {
                    unsigned char value = image[(height - y - 1) * width + x];
                    if (value >= 0x80) {
                        std::cout << "XX"; // if it's 128+
                    } else if (value >= 0x40) {
                        std::cout << ".."; // if it's 64+
                    } else {
                        std::cout << "  "; // if its under 64
                    }
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
    
            // Delete image buffer
            delete [] image;
    
            // Destroy buffer for text
            hb_buffer_destroy(hbBuffer);
    
            // Destroy HarfBuzz font
            hb_font_destroy(hbFont);
    
            // Destroy FreeType font
            FT_Done_Face(face);
        }
    
        // Destroy FreeType
        FT_Done_FreeType(library);
    
        return 0;
    }
    
                      XXXX                                                                          XXXX
                      XXXX                                                                          XXXX
                      XXXX                                                                          XXXX
    XXXXXXXXXXXXXX    XXXXXXXXXXXXXXXX  XXXX    XXXX          XX          XXXXXXXXXXXXXX      XXXX  XXXXXXXXXXXXXXXX..XX      XXXX    XXXX
    XXXX........XXXX  ............XX..  XXXX    XXXX        ..XX          XXXX........XXXX    XXXX  ............XX..  XX      XXXX    XXXX
    XXXX        ..XX            ..XX    XXXX    ..XX        ..XX          XXXX        ..XX    XXXX            ..XX    XX..    XX..    XXXX
    XXXX        ..XX            XXXX    XXXX      XX..      XXXX          XXXX        ..XX    XXXX            XXXX    XX..  ..XX      XX..
    XXXX        ..XX            XX..    XXXX      XXXX      XXXX          XXXX        ..XX    XXXX            XX..    XXXXXXXXXX      XX..
    XXXX        ..XX          XXXX      XXXX      XXXX      XXXX          XXXX        ..XX    XXXX          XXXX      XXXXXX        XXXX
    XXXX        ..XX          XXXX      XXXX      ..XX    XXXX            XXXX        ..XX    XXXX          XXXX      XXXX        ..XXXX
    XXXX........XXXX        ..XX        XXXX    ....XXXXXXXX..            XXXX........XXXX    XXXX        ..XX        XXXX......XXXXXX
    XXXXXXXXXXXXXXXX        XXXX        XXXX  XXXXXXXXXXXX                XXXXXXXXXXXXXXXX    XXXX        XXXX        XXXXXXXXXXXX..
    
    
                      ..XX    XX..                    ..XX    XX..                    XX..
                      ..XX    XXXX                    ..XX    XXXX                    XXXX
                      ..XX    XXXX                    ..XX    XXXX                    XXXX
                      ..XX    XXXX                    ..XX    XXXX                    XXXX
                      ..XX    XXXX      XXXXXXXX..    ..XX    XXXX      ..            XXXX
          ..XXXX..      XX    XXXX    XXXX....XXXX      XX    XXXX    ..XX            XXXX              XXXXXXXX..          ..          XXXXXX
        XXXX..XXXX      XX    XXXX    XX..      XX      XX    XXXX      XX..          XXXX      ....    ......XXXXXX      ..XX        ..XX..XXXX
      XXXX      XX..    XX    XXXX    ..XX..  XXXX      XX    XXXX      XX..          XXXX      XXXX              XX        XXXX      XX..    XX..
      XXXXXX    XXXX    XX    XXXX      ..XXXXXX        XX    XXXX      XX..          XXXX      XX..          ..XXXX        ..XX    ..XX      XX..
    XXXX  XXXX..XXXX..XXXX    ..XXXX....XXXXXXXXXX....XXXX    ..XXXX....XX            ..XXXX..XXXXXX......XXXXXX..          ..XXXX..XXXXXX....XX
    XXXX    XXXXXXXXXXXX..      XXXXXXXXXX..  XXXXXXXXXX..      XXXXXXXX..              XXXXXXXX..XXXXXXXXXX..              XXXXXXXXXX  XXXXXXXX
    XX..                                                                                                                  ..XX
    XXXX                                                                                                                ..XX..
    XXXX                                                              ..XX                      ..XX                  XXXX..
    ..XX                                                                                                              ..
      XX
      XX..
    
    
    
    
                                                      ..XXXXXX                                  XXXXXXXXXX..
                                                            XX..                              XXXX..  ..XXXXXX
                                                            ..XX                              XX            XXXX
                                                              XX                              XX..            XXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX        ..  XX..      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..
                XXXX    XX..    ..XX..      XXXX              XXXX                  ..XX      XXXX              XXXX    XXXX    XXXX    XXXX
                XX..    XX..      XX        XXXX              XXXX                  ..XX      XXXX              XX..    ..XX    ..XX    XXXX
                XX..    XX..      XX        XXXX              XXXX              XXXXXXXX      XXXX              XX..    XXXX    ..XX    XXXX
    ..XXXXXXXXXXXX..    XX..      XX  ..XXXXXX..    ..XXXXXXXXXXXX            XXXX..          XXXX  ..XXXXXXXXXXXX..  XXXX..    ..XX    XXXX
      XXXX..    XX....XXXXXXXXXXXXXX    XXXXXXXXXX  XXXX      XXXX            XX              XXXX    XXXX..    XX..  XX..      XXXX    XXXX
      ..XX      XX..  XXXX..      XX    ..XX        XX        XXXX            XX      XXXX    XXXX    ..XX      XX..  XXXX    ..XXXX    XXXX
                XX..    XX        XX      XXXX      XX..      XXXX            XXXX    XXXX..  XXXX              XX..    XXXXXXXXXXXX    XXXX
                XX..              XX        XXXX    ..XX..    XXXX              XXXXXXXXXX    XXXX              XX..            ..XX    XXXX
                XX..              XX          XXXX    ..XX    XXXX                      XX    XXXX              XX..            ..XX    XXXX
                                                                                      XXXXXX..
                                                                              ..XX        ..XX
                                                                                XXXX..    XXXX
                                                                                  ..XXXXXXXX
    
    
    

     

    • Thanks 1
  9. 17 hours ago, bit said:

    If you know better solution please share, because this one sucks.

     

    How about

    • install VirtualBox (or use Hyper-V but I don't have any experience with it)
    • create virtual machine with 1 core, 512 MB RAM and 10 GB disk image
    • install Debian Stretch with just only ssh server
    • configure networking so
      • host (windows) will have no IP address set on the primary NIC
      • guest (linux) will have eth0 bridged with windows primary NIC and will have IP address that your windows server had
      • guest (linux) will have eth1 just between host and guest and set some internal address on it (10.0.0.1/24)
      • host (windows) virtual NIC (linux eth1) will have internal address in the same segment (10.0.0.2/24) and default gateway set to linux IP (10.0.0.1)

    Then you would have real linux router so you can do all the stuff needed (policy-based routing). But you need to find some way how to start that VM when windows start.

    • Upvote 1
  10. 11 minutes ago, GamePsychology said:

     

    ok thanks, very informative.

    So the 4 hours is perfectly. And i also added the broadcast upon login if is night only cause i believe broadcast SunRise when is day is not good since the default weather is day and the sunrise looks redish. So ill just broadcast sunrise upon day change only and new login players will just see blue sky.

     

    The other question is whats the best option to broadcast the dark elf skill upon change. Currently i simply did a for and just re-add the skill to those who have it to get the new effect. I havent try if getEffects work. Any other proper way?

     

    Sorry, I wrote it wrong, time info is sent on login (not sunset/sunrise), it's part of CharSelected packet

  11. 52 minutes ago, bit said:

    Would this work with single proxy and no router machine? I am kind of banging my head here trying to make that setup work.

     

    My setup: 1 linux proxy running ppp server.

    Proxy ppp0 interface with ip 192.168.0.1, windows server client with ip 192.168.0.234.

    $ip in the commands is external proxy server ip.

     

    
    iptables -t nat    -A PREROUTING         -p tcp -m multiport --dport 2106,7777        -j DNAT     --to-dest 192.168.0.234
    iptables -t mangle -A PREROUTING -i eth0 -p tcp -m multiport --dport 2106,7777 -m tcp -j CONNMARK --set-mark 101
    iptables -t mangle -A PREROUTING -i ppp0 -p tcp -m multiport --sport 2106,7777 -m tcp -j CONNMARK --restore-mark
    ip rule add fwmark 101 table 101
    ip route add default via $ip table 101

    Any idea what i do wrong here?

     

    This works, but server sees proxy IP as player IP:

    
    iptables -t nat -A PREROUTING  -p tcp -m multiport --dport 2106,7777 -j DNAT       --to-dest 192.168.0.234
    iptables -t nat -A POSTROUTING                                       -j MASQUERADE

     

    By the way first post has some typos. Chain is missing in commands with "--restore-mark"

     

    You can't do it without Linux router - Windows can't do policy-based routing.

     

    You would have to set default gateway on Windows Server to 192.168.0.1 and make all packets out go through it (but you would lose connectivity to it from internet, so you would have to create static route via previous default gateway to your proxy; even that would be very inconvenient because you would have to access your server only from proxy or via the proxy - because there would be no other way to it).

     

    Without right default gateway your only option is to use MASQUERADE or SNAT (it's the same, masquerade just automatically assumes new source IP address) which changes sender IP address to proxy IP - that you then see on Windows server.

  12. HOWTO - L2 server with (transparent) proxies

    DISCLAIMER: I wrote this HOWTO without really testing it (I've configured it for my server more than year ago), so if you find any mistake, feel free to comment/ask, I'll try to update this HOWTO appropriately.

    Purpose of using proxies

    The standard old way of setting up L2off server involves one Windows Server that is connected directly to internet and players connect directly to it's IP address. While it's enough for a small server, it may bring few problems:

    • If someone wants to DDoS your server, he just pays for some attack to your IP address. You're screwed.
    • There may be players who experience lags because route from their network to your server isn't perfect (because of bad peering between player's ISP and your datacenter etc). You can't just tell those players "Try better ISP".
    • Players from foreign countries may have good ping to datacenters in their country but not to your data center.

    Some of these problems can be mitigated by using proxies for your server:

    • When someone buys DDoS attack to your login server on first proxy, you can just change IP address in your DNS and let your players login on your second proxy (you need to have domain name instead of IP address in your l2.ini).
    • When someone buys DDoS attack to your game server on first proxy, players can still play on second proxy.
    • When player has bad ping on first proxy, login will be bit slower but player can select second proxy with better ping and play on it

    You can also do the same with your website, just replace ports 2106 and 7777 with 80 and 443...

    What will you need

    • Some basic knowledge about L2off, Linux and networking. Also you'll have to read few manuals.
    • Linux router between your L2 server and internet, you can do it two ways (of course it must be configured to forward IPv4 traffic):
      • real physical Linux router between them
      • Linux as main operating system on your server hardware + L2 server in virtual machine (kvm-qemu).
    • Linux servers (1 core & 512 MB RAM is usually enough) for proxies
    • Copy of patched hauthd - READ INSTRUCTIONS THERE
    • Script that will be able to restart hauthd when L2 server crashes/exits

    How to do it

    I will use following IP networks and addresses in this example:

    • Networks:
      • Local network 10.0.0.0/24 between Linux router and Windows VM
      • Virtual network 10.0.1.0/24 between Linux router and proxies
    • Addresses:
      • 1.2.3.4 on Linux router eth0
      • 2.3.4.5 on first proxy eth0
      • 3.4.5.6 on second proxy eth0
      • 4.5.6.7 on third proxy eth0
      • 10.0.0.1 on Linux router eth1 (for physical router) or tap0 (for kvm-qemu variant)
      • 10.0.0.2 on Windows server Local network interface
      • 10.0.1.1 on Linux router tun0 (OpenVPN server 1)
      • 10.0.2.1 on Linux router tun1 (OpenVPN server 2)
      • 10.0.3.1 on Linux router tun2 (OpenVPN server 3)
      • 10.0.1.2 on first proxy tun0 (OpenVPN client)
      • 10.0.2.2 on second proxy tun0 (OpenVPN client)
      • 10.0.3.2 on third proxy tun0 (OpenVPN client)

     

    Physical network:

     

    l2-proxies-physical-network.png.aced8219e6456f630529db2754136d09.png

     

    Logical network:

     

    l2-proxies-logical-network.png.8dc15fb59fab157a254514dddca94364.png

     

    Now proceed with installation and configuration:

    • ROUTER + PROXIES: Install OpenVPN
    • ROUTER: For each proxy, configure one instance of OpenVPN server with static key (it will have to run on different ports, for example 1194, 1195, 1196)
    • PROXY: Copy static key from router, configure OpenVPN client
    • WINDOWS: Make sure windows server can ping linux router (ping 10.0.0.1)
    • PROXY: Make sure proxies can ping server (ping 10.0.1.1 / ping 10.0.2.1 / ping 10.0.3.1)
    • PROXY: Setup NAT (find some way how to run it on every start!)
      iptables -t nat -A PREROUTING -m tcp -p tcp --dport 2106 -j DNAT --to-destination 10.0.0.2:2106
      iptables -t nat -A PREROUTING -m tcp -p tcp --dport 7777 -j DNAT --to-destination 10.0.0.2:7777
      
      You need this to make proxies forward traffic on ports 2106 and 7777 to windows server.
       
    • ROUTER: Setup connmark (find some way how to run it on every start! If it's physical router, use eth1 instead of tap0!):
      iptables -t mangle -A PREROUTING -i tun0 -p tcp -m tcp --dport 7777 -j CONNMARK --set-mark 100
      iptables -t mangle -A PREROUTING -i tun1 -p tcp -m tcp --dport 2106 -j CONNMARK --set-mark 101
      iptables -t mangle -A PREROUTING -i tun1 -p tcp -m tcp --dport 7777 -j CONNMARK --set-mark 101
      iptables -t mangle -A PREROUTING -i tun2 -p tcp -m tcp --dport 2106 -j CONNMARK --set-mark 101
      iptables -t mangle -A PREROUTING -i tun2 -p tcp -m tcp --dport 7777 -j CONNMARK --set-mark 101
      iptables -t mangle -i tap0 -p tcp -m tcp --sport 2106 -j CONNMARK --restore-mark
      iptables -t mangle -i tap0 -p tcp -m tcp --sport 7777 -j CONNMARK --restore-mark
      You need this to mark connections so you know where they came from.
       
    • ROUTER: Setup policy-based routing (find some way how to run it on every start!):
      ip rule add fwmark 100 table 100
      ip route add default via 10.0.1.2 table 100
      ip rule add fwmark 101 table 101
      ip route add default via 10.0.2.2 table 101
      ip rule add fwmark 102 table 102
      ip route add default via 10.0.3.2 table 102

      You need this to make packets go back through the right proxy. Otherwise you'll send those packets out via your router public interface which won't work.
       

    • WINDOWS: Setup hauthd to use multiple proxies and add servers appropriately to dbo.server table
    • WINDOWS: Make sure hauthd restarts every time L2 server restarts

     

    Useful resources

     

     

    • Like 1
    • Thanks 3
    • Upvote 2
  13. Hi, in l2off (at least in leaked Gracia Final) it works this way:

    1. there's class CL2Time that manages this, game time runs 6 times faster than real time so each game day is 3 hours long and night 1 hour long
    2. it runs a timer each 10 seconds and checks whether day or night started, day starts at 6:00 game time, night starts at 0:00 game time
    3. when that 10 second timer expires and night changes to day or vice versa, server broadcasts SunRise packet (0x12) or SunSet packet (0x13)
    4. these packets are sent to player upon login as well
  14. 6 hours ago, DavidRoss said:

    Seems all try, we play l2evoke and now afraid to join...

     

    http://forum.l2evoke.net/

    @  ReaLH : (30 November 2017 - 03:57 PM)

    you have to know , already TheSaints community are worried to login the server and to use evoke client for lineage. Any answers for that ?

    @  ReaLH : (30 November 2017 - 03:55 PM)

    using lineage2 game to made server players miners . Is that was the new server project ?

     

      @  DEV Devon : (30 November 2017 - 04:02 PM)

    You should not be worried about anything, we are very transparent in what we do and that is the reason we added the "ask for user permission" if you use common sense.

     

    We have no plans to do anything at the client. This will be only used on Account Panel for players to gather gems if they want by using this method, or they can vote or they can donate.

     

    When they inform you about it and don't do it in such stupid way (you can use only idle CPU, throttle it somehow etc) and give you something as reward - then it's OK.

  15. 23 minutes ago, icarka said:

    yeah i need npc with s grade recipes armor and weps

     

    Then you need to do following:

    1. Decide whether you really need brand new NPC - it's MUCH easier to do with existing NPC. If you can use existing NPC, go to step 8
    2. Decide which NPC you will copy - just find proper NPC that suits you and pick a new name for it, I'll use recipe_seller as name on server side in this example (generally you can pick name as you need but use only small letters, numbers and underscore "_" character)
    3. Get some tools to edit client stuff
    4. Client - edit npcgrp.dat and npcname-e.dat
      1. find the original NPC you're copying
      2. copy it and give it unique ID (for example 32000)
      3. in npcname-e.dat also change the name; don't change anything else
    5. Server - edit npcdata.txt and npc_pch.txt, again as in client
      1. find the original NPC you're copying
      2. copy the line and give it same ID as in client (32000)
      3. in both npcdata.txt and npc_pch.txt pick change name to recipe_seller
      4. in npcdata.txt change npc_ai=... to npc_ai={[citizen];{[fnHi]=[recipe_seller.htm];{[MoveAroundSocial]=0};{MoveAroundSocial1]=90}}
    6. Server - create html/recipe_seller.htm and use this link there:
      <a action="bypass -h menu_select?ask=-303&reply=1000">Buy recipes</a>

       

    7. Now continue with step 9
    8. Select some NPC where you want to add the multisell and find it's HTML file in html/ folder, add link from step 6 there
    9. Create your multisell - edit multisell.txt and add this (and change price etc, also _i versions are 60/70%, the other ones are 100% - use what you need):
      MultiSell_begin	[s_recipes] 1000
      is_dutyfree = 1
      selllist={
      {{{[[rp_sealed_sanddragon's_earing_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_sanddragon's_earing];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_ring_of_aurakyria_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_ring_of_aurakyria];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_dragon_necklace_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_dragon_necklace];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_armor_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_armor];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_gaiters_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_gaiters];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_gauntlet_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_gauntlet];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_boots_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_boots];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_shield_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_shield];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_imperial_crusader_helmet_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_imperial_crusader_helmet];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_draconic_leather_armor_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_draconic_leather_armor];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_draconic_leather_gloves_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_draconic_leather_gloves];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_draconic_leather_boots_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_draconic_leather_boots];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_draconic_leather_helmet_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_draconic_leather_helmet];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_major_arcana_robe_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_major_arcana_robe];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_major_arcana_gloves_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_major_arcana_gloves];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_major_arcana_boots_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_major_arcana_boots];1}};{{[adena];10000000}}};
      {{{[[rp_sealed_major_arcana_hood_i];1}};{{[adena];1000000}}};
      {{{[[rp_sealed_major_arcana_hood];1}};{{[adena];10000000}}};
      {{{[[rp_forgotten_blade_i];1}};{{[adena];1000000}}};
      {{{[[rp_forgotten_blade];1}};{{[adena];10000000}}};
      {{{[[rp_basalt_battlehammer_i];1}};{{[adena];1000000}}};
      {{{[[rp_basalt_battlehammer];1}};{{[adena];10000000}}};
      {{{[[rp_imperial_staff_i];1}};{{[adena];1000000}}};
      {{{[[rp_imperial_staff];1}};{{[adena];10000000}}};
      {{{[[rp_angel_slayer_i];1}};{{[adena];1000000}}};
      {{{[[rp_angel_slayer];1}};{{[adena];10000000}}};
      {{{[[rp_shining_bow_i];1}};{{[adena];1000000}}};
      {{{[[rp_shining_bow];1}};{{[adena];10000000}}};
      {{{[[rp_dragon_hunter_axe_i];1}};{{[adena];1000000}}};
      {{{[[rp_dragon_hunter_axe];1}};{{[adena];10000000}}};
      {{{[[rp_saint_spear_i];1}};{{[adena];1000000}}};
      {{{[[rp_saint_spear];1}};{{[adena];10000000}}};
      {{{[[rp_demon_splinter_i];1}};{{[adena];1000000}}};
      {{{[[rp_demon_splinter];1}};{{[adena];10000000}}};
      {{{[[rp_heavens_divider_i];1}};{{[adena];1000000}}};
      {{{[[rp_heavens_divider];1}};{{[adena];10000000}}};
      {{{[[rp_arcana_mace_i];1}};{{[adena];1000000}}};
      {{{[[rp_arcana_mace];1}};{{[adena];10000000}}}
      }
×
×
  • Create New...