Jump to content

Salty Mike

Members
  • Posts

    137
  • Credits

  • Joined

  • Last visited

  • Days Won

    9
  • Feedback

    0%

Posts posted by Salty Mike

  1. You are not parsing the HTML, or at least that's what the error states.

    I assume the issue might lie here:

     

    return HTMLTemplateParser.fromCache(Path.of("/data/scripts/" + SCRIPT_SUBFOLDER + "/data/html/" + dialogType.toString().toLowerCase(Locale.ENGLISH) + "/" + path).toString(), player, placeholders, IncludeFunc.INSTANCE, IfFunc.INSTANCE, ForeachFunc.INSTANCE, ExistsFunc.INSTANCE, IfChildsFunc.INSTANCE, ChildsCountFunc.INSTANCE)
    
  2. 6 hours ago, Drazeal said:

    Hello, ive added some customs and  cant find the file that allows augmentation to finalize.

    i've added them on life stones but effects dont seem to apply.

    Animation plays fine but gets stuck as shown in the image.

    [Source of Flame-Aden Assassin protocol 418]

    Sry if its the wrong section but if im not wrong it should be clientside problem.

    aug-min.png


    If you hover over the weapon and you can see the augment, then it is client side, indeed. Else, it is server side, most definitely.

    Fact of the matter is, there is a whole chain of packets that are responsible for handling the new Augmentation system. The easiest way to keep track of them is by activating the NETCHAT packet debugger from ALT+G. It is not a debugger per-se, but it would help you see the packet exchange between client and server, which should then show you where the issue lies, namely the client->server packet, whose trail you should follow until you find your issue.

    If the other weapons are working, then it is quite possible that you have missed adding the new custom weapons somewhere in the datapack (in some xml or wherever your server pack keeps such data).

  3. One of the main issues with HTML on Interlude is that you can only have a few very specific basic colors and nothing in-between.
    However, there is an approach you can take to make it so that you have custom colors for your table background.

    To do this, you would have to stack a bunch of tables with different background colors up. Here is an example of the code:
     

    <table width="274" cellpadding="0" cellspacing="0" height="32" border="0" bgcolor="FF0000">
        <tr>
            <td width="242">
                <table width="242" cellpadding="0" cellspacing="0" height="33" bgcolor="FAFAFA">
                    <tr>
                        <td>
                            <!-- FF0000 = RED -->
                            <!-- 000400 = GREEN -->
                            <table width="242" cellpadding="0" cellspacing="0" height="33" bgcolor="FF0000">
                                <tr>
                                    <td>
                                        <table width="242" cellpadding="0" cellspacing="0" height="33" bgcolor="FAFAFA">
                                            <tr>
                                                <td>
                                                    <table width="242" cellpadding="0" cellspacing="0" height="33" bgcolor="000000">
                                                        <tr>
                                                            <td>
                                                                <table width="242" cellpadding="0" cellspacing="0" height="33" bgcolor="000000">
                                                                    <tr>
                                                                        <td width="90">
                                                                            <table width="242" cellpadding="0" cellspacing="0" height="33" >
                                                                                <tr>
                                                                                    <td height="5"> </td>
                                                                                    <td height="5"> </td>
                                                                                    <td height="11"> </td>
                                                                                </tr>
                                                                            </table>
                                                                        </td>
                                                                    </tr>
                                                                </table>
                                                            </td>
                                                        </tr>
                                                    </table>
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>


    The end result will be this nice dark-red or red-brownish background color (disregard the buttons and text):
    image.png.fd1145775879d60922ad60e758aef2a9.png

    PLEASE NOTE!
    This will make your HTML explode in length/size! To help with the increased size, you can follow this guide to reduce it by about 30-35%.

     

    • Like 1
    • Upvote 1
  4. One of the two major issues with HTML on Interlude has been the absence of `background` option for tables. However, there is a way to manipulate the HTML code so that you can achieve the same effect as `<table background=" "` on newer chronicles.

    A little known fact is that the <img /> tag does not necessarily has to have an `src` element. On top of that, we can set a negaive value for height, which would bring the next <img /> element up in the Z direction by the height we have set.

    Here is an example of how we do that:

    <img height=-34>
    <img src=L2UI_CH3.multisell_plusicon height=32 width=32>



    It is important to note that this code has to be placed outside of the table that you want to set the image as background.

    This is how the code would look like, if we are to add an <img /> as background to a button:

    <td width=36>
        <table cellpadding=0 cellspacing=0>
            <tr>
                <td>
                    <button value=\" \" action=\" \" height=35 width=35 back=L2UI_CH3.inventory_outline_down fore=L2UI_CH3.inventory_outline>
                </td>
            </tr>
        </table>
        <img height=-34>
        <img src=L2UI_CH3.multisell_plusicon height=32 width=32>
    </td>



    Here is the resulting button with its background being the + sign and the OVER being taken from the inventory_outline.
    image.png.9d73c330327615b62dcb2752ee0e95dd.png

    This is another example of utilizing this exact same code with different images/textures:
    image.png.19a80515ba4a0ecf392ec3d11e539c46.png

    And this is what it would look like if we were to stack a bunch of TDs in the same table:
    image.png.d2f9cecff01442c7c6848e0748e15096.png

  5. 25 minutes ago, xdem said:

    I would also advice you to experiment with

     

    replaceAll("\\s+", " ");

     

    s+ will automatically match any whitespace character (including \r \n etc)
     



    I have, as evident from the posted screenshot, see a copy below.

    The bottom-most line is No White-Spaces, at all.
    However, the 5% gain is not worth the risk, in my personal opinion. The Tab-Spaces and New Rows reduces the overall length by quite a lot as is.

    image.png.748e32247416b582de08a1491e88a5da.png

    Here is a list of all four methods that I used in the screenshot.

    	public static String removeTabSpaces(String text)
    	{
    		return text.replaceAll("\\t", "");
    	}
    
    	public static String removeNewRows(String text)
    	{
    		return text.replaceAll("\\n", "");
    	}
    
    	public static String removeTabSpacesAndNewRows(String text)
    	{
    		return text.replaceAll("[\\t\\n]", "");
    	}
    
    	public static String removeAllWhiteSpacing(String text)
    	{
    		return text.replaceAll("\\s+", "");
    	}

     

  6. Greetings, folks!

    Here is a way to optimise the HTML length by up to 30%, depending on the nesting.

    The examples I give are taken from an old Interlude core, but the general idea is applicable to all java-based cores.

    Proof of concept!
    The two important bits in the screenshot below are the (1) Original HTML size row and the (4) No Tabs/Rows size row, which represent the before and after, respectively.

    image.png.79a2d793c47dfd3fabd786d0b6cd2399.png

    STEPS:

     1. locate the `setHtml(String text)` method inside `NpcHtmlMessage.java`.

     2. add the following bit of code as a standalone method:

    /**
     * Replaces all occurrences of New Rows and Tab spaces in the string.
     * @param text the string that may contain invalid characters
     * @return the string with invalid character replaced by underscores
     */
    public static String removeTabSpacesAndNewRows(String text)
    {
    	return text.replaceAll("[\\t\\n]", "");
    }


     3. find the last ocurence of the `text` String variable in the `setHtml()` method, and push it through this newly created method like so: `removeTabSpacesAndNewRows(text);`.
     
    4. example of the final result.
     

    /**
     * Sets the html.
     * @param text the new html
     */
    public void setHtml(String text)
    {
    	if (text == null)
    	{
    		LOGGER.warning("Html is null! this will crash the client!");
    		_html = "<html><body></body></html>";
    		return;
    	}
    	
    	if (text.length() > 8192)
    	{
    		LOGGER.warning("Html is too long! this will crash the client!");
    		_html = "<html><body>Html was too long,<br>Try to use DB for this action</body></html>";
    		return;
    	}
    		
    	_html = removeTabSpacesAndNewRows(text); // html code must not exceed 8192 bytes
    }
    
    /**
     * Replaces all occurrences of New Rows and Tab spaces in the string.
     * @param text the string that may contain invalid characters
     * @return the string with invalid character replaced by underscores
     */
    public static String removeTabSpacesAndNewRows(String text)
    {
    	return text.replaceAll("[\\t\\n]", "");
    }



    5. You could further refine it by processing the `text` variable between the two IF clauses by creating a new local variable, assigning it a value of `text` and then replacing the subsequent  `text` mentions in the `setHtml()` method with this new local var. Here's what it would look like:
     

    /**
     * Sets the html.
     * @param text the new html
     */
    public void setHtml(String text)
    {
    	if (text == null)
    	{
    		LOGGER.warning("Html is null! this will crash the client!");
    		_html = "<html><body></body></html>";
    		return;
    	}
    
    	String refinedText = removeTabSpacesAndNewRows(text);
    	if (refinedText.length() > 8192)
    	{
    		LOGGER.warning("Html is too long! this will crash the client!");
    		_html = "<html><body>Html was too long,<br>Try to use DB for this action</body></html>";
    		return;
    	}
    		
    	_html = refinedText; // html code must not exceed 8192 bytes
    }



    UPDATE:
    (thanks to @xdem for pointing it out)

    You can instead apply the same logic/method to the HTMCache.java
    To do so, locate the loadFile() method and recycle the String/Text/Content through the removeTabSpacesAndNewRows method.

    KEEP IN MIND that you might want to move the removeTabSpacesAndNewRows method in another java class, preferrably in some UTILITY class.
    Here is an example:
     

    	public String loadFile(File file)
    	{
    		final HtmFilter filter = new HtmFilter();
    		String content = null;
    		if (file.exists() && filter.accept(file) && !file.isDirectory())
    		{
    			FileInputStream fis = null;
    			BufferedInputStream bis = null;
    			try
    			{
    				fis = new FileInputStream(file);
    				bis = new BufferedInputStream(fis);
    				final int bytes = bis.available();
    				final byte[] raw = new byte[bytes];
    				bis.read(raw);
    				
    				content = new String(raw, StandardCharsets.UTF_8);
    				content = content.replaceAll("\r\n", "\n");
    				content = content.replaceAll("(?s)<!--.*?-->", ""); // Remove html comments
    				content = NpcHtmlMessage.removeTabSpacesAndNewRows(content);
    				
    				final String relpath = Util.getRelativePath(Config.DATAPACK_ROOT, file);
    				final int hashcode = relpath.hashCode();
    				if (Config.CHECK_HTML_ENCODING && !StandardCharsets.US_ASCII.newEncoder().canEncode(content))
    				{
    					LOGGER.warning("HTML encoding check: File " + relpath + " contains non ASCII content.");
    				}
    				
    				final String oldContent = _cache.get(hashcode);
    				if (oldContent == null)
    				{
    					_bytesBuffLen += bytes;
    					_loadedFiles++;
    				}
    				else
    				{
    					_bytesBuffLen = (_bytesBuffLen - oldContent.length()) + bytes;
    				}
    				
    				_cache.put(hashcode, content);
    			}
    			catch (Exception e)
    			{
    				LOGGER.warning("Problem with htm file " + e);
    			}
    			finally
    			{
    				if (bis != null)
    				{
    					try
    					{
    						bis.close();
    					}
    					catch (Exception e1)
    					{
    						LOGGER.warning("Problem with HtmCache: " + e1.getMessage());
    					}
    				}
    				
    				if (fis != null)
    				{
    					try
    					{
    						fis.close();
    					}
    					catch (Exception e1)
    					{
    						LOGGER.warning("Problem with HtmCache: " + e1.getMessage());
    					}
    				}
    			}
    		}
    		
    		return content;
    	}


     

    • Like 1
    • Thanks 1
  7. 35 minutes ago, Nightw0lf said:

    560


    If your source is java-based, then it is quite easy. Each source comes with a ReceivablePacket.java whose read() function is being overwritten by its sub-classes, one of which is something related to Game Client. This class, let's call it GameClientPacket.java, also has sub-classes, the actual client->server packets, which extend its secondary read method.

    From here, you have 2 options.

    1 - Enable the Net Stats(Chat) feature in the client to see the name of the sendable/receivable packets (Client <-> Server, where C_ = sent by the client and S_ = sent by the server).
    2 - Rely on the source's exception-handler, which will show the ID of the packet, if it is unknown, or the IDE's (IntelliJ/Eclipse) debug feature to figure out which packet is being sent.

    Then, you also have multiple options, with the easiest one being to search for the packet structure in the client itself, or brute-force the incoming data from the server-side by utilising the aforementioned IDE debug feature with breakpoints.

    • Thanks 1
  8. 19 minutes ago, Nightw0lf said:

    Hello,

     

    I am looking for a way to capture and translate somehow the client packets like int, string, float... and the sequence (or at least thats what i think i need)

    I would like any kind of way or any information on how to achieve that, maybe what programs could help me or what direction should i look into


    I'm fairly certain I can help. But which protocol version are we talking about?

  9. 11 minutes ago, Orochy said:

    Hi maxcheaters, I recently added some code to my l2jacis revision and everything works fine with the .siege commands but when I click on the html options to open the registry I don't succeed!

     

    <button value="Giran" action="bypass voiced_siege_giran" width=75 height=22 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal">



    You have to create the "voiced" handler in the core too, or at the very least make sure that the delimiter is underscore and not an empty space.

    Alternatively, you can try changing all references of the strings below to start with "voiced_", or remove the "voiced_" portion from the button bypass.
     

    private static final String[] VOICED_COMMANDS =

    {

    "siege",

    "siege_gludio",

    "siege_dion",

    "siege_giran",

    "siege_oren",

    "siege_aden",

    "siege_innadril",

    "siege_goddard",

    "siege_rune",

    "siege_schuttgart"

    };

    • Like 1
  10. 2 hours ago, xristoeli1994 said:

    Annyone have or know how make Bomb Spoil and mass sweeper skill from H5 to Interlude?


    Аз ще ти свърша по-добра работа.

    Ако усетиш, че тоя иска да ти подлива вода - дискорд инфото ми е на профила.

  11. I'm interested in the solution too, out of pure curiosity.

    The flood protector will work only if the macro is being sent non-stop, which I don't think any Client Dev would be stupid enough to do. Instead, I'd expect that it is being sent every X ms, which would mean you wouldn't be able to reasonably differentiate between genuine MacroSpamming and auto-macroing.

    One rather reasonable assumption would be to monitor and record the difference between UseMacro requests for each individual player and to disconnect them based on certain criteria.
    Example - (MarcoUseRequestTime_1 - MacroUseRequestTime_2) != (MarcoUseRequestTime_3 - MarcoUseRequestTime_4) + X_miliseconds_to_account_for_network_delay.

    [note]: Just note that a skilled client dev could simply add a random delay to macro-looping to bypass the above method.

    As far as my knowledge goes, the ultimate solution should be in the client.
    Maybe you can add something to your interface, some check that will be done through a packet every X seconds, similarly to how pinging works, but this one will just make sure that the player is using your interface and not another modified version.

  12. 2 hours ago, l2viserion said:

    There are new changes in hopzone but I'm unable to fix it, not sure what I do wrong, can anybody help with below code to read the current votes?

     

        protected static int getVotes()
        {
        InputStreamReader isr = null;
        BufferedReader br = null;

        try
        {
        if(!hopzoneUrl.endsWith(".html"))
        hopzoneUrl+=".html";

        URLConnection con = new URL(hopzoneUrl).openConnection();


        con.addRequestProperty("User-Agent", "Mozilla/5.0");
        isr = new InputStreamReader(con.getInputStream());
        br = new BufferedReader(isr);

        String line;
        while ((line = br.readLine()) != null)
        {
            if (line.contains(":server-votes")||line.contains(":server-votes=")||line.contains("server-votes")||line.contains("server-votes=")||line.contains(":server-votes=\""))
        {
        int votes = Integer.valueOf(line.split("\"")[1].split("\"")[0].split("\"")[2]);
        
        
    //Hopzone line source code:
    //   :server-votes="228"
     

        return votes;
        }
        }

        br.close();
        isr.close();
        }
        catch (Exception e)
        {
        System.out.println("[VoteRewardManager]: Problem occured while getting Hopzone votes. Error Trace: " + e.getMessage());
        }
        return -1;
        }



    1. Replace the int votes expression with this:

    int votes = Integer.parseInt(line.split("\"")[1]);



    2. expand your IF(line.contains(...)) with an additional condition -

    || line.contains("vote-count")



    3. Finally, make sure that you exit the loop on the first match, just in case.

     

  13. 24 minutes ago, Smokey1337 said:

    You are completely right it didn't sound good like i write it. I mean someone who works with a pack and make it kind of bugless or anyone who can solve most of bugs they will appear in our way. I rly don't know what is better. Maybe to buy something ready or create a server from scratch and then develop everything. I'm here to talk about this 😄


    Buying a ready-made thing is never a good idea, because you leave yourself exposed to scammers, who are always lurking in the shadows, as you've probably already noticed. 
    Moreover, you can never be sure of what you are buying, how good it is, even if they show "proof" or offer tests. You can never know how many backdoors they have implement/left, or if they have actually done anything notable to the source.

    The cheap usually costs you more in the end, so you should be extra vigilant. 

    With that being said, I would go for one of the well-established names in the community - L2jSunrise and/or L2jEternity, if I were you. They offer cheap and stable builds, as far as I know, with a bunch of custom features, probably most, if not all, of what you've described above. For the features they do not have, you can always pay a reputable developer to write and/or implement the feature to your source, or adapt from a similar one.

    This way you may pay as much as you would for a ready-made server, but you will establish connections (with programmers and developers) and have access to updates and technical support for several months, at the very least.

    The last thing I'd like to add is that you CAN, in fact, find good developers here, as long as you opt for a well-trusted and reputable one. You can always ask for opinions in the discord server or here.

    • Upvote 1
  14. Apologies for my ignorance, but I could not quite get what you are looking for, apart from several functionalities, which are present on 99.9% of the servers/cores.

    Like, could you define what bugless means to you?

    Also, does the quote below mean that you are NOT providing the source, and instead, the DEV would have to have a "bugless" source that they would then be giving to you? Would you be paying for the source that they would be working on?

    If not, then it makes little to no sense to me, personally, since such a core/source would probably cost more than what the DEV would be getting for the work they would be doing for you.
     

    On 8/11/2023 at 9:04 PM, Smokey1337 said:

    I wan't someone who works with a bugless patch + source 

  15. L2g is a custom type, similar to how L2d and L2s are. As such, they have their own custom converters. If the converter has never been leaked or isn't open source, nobody can have it, as simple as that. 🙂


    I would suggest you go through the configs and make sure that there is no way to change the default geodata format from L2g to L2j or L2off.

  16. 31 minutes ago, Booker Dewitt said:

    I can in private. Aint share info in public to toxic people like the one above you. Thanks and i stop this here. 


    You keep referring to me and you are forcing my hand to respond.

    You are the one being toxic and trying to blatantly scam people. And the only response you have is - if you are not interested - don't spam, which is the typical response of a low IQ, high self-esteem individual (with nothing to show for it) who thinks everyone is as dumb as they are and would fall for something like this.

    Fact of the matter is that if you've been doing it for 10 years, you should have obtained a very very good knowledge in programming.

    And if you had that, it would've been a matter of accepting 2-3 freelance jobs for the random Joe here on the forum, of which there are many, and gathered the needed 200e in a matter of 1-2 weeks.

    Fact of the matter is that you haven't done so, which begs the question why would you be willing to share the profits of your 10-year-old "child" instead of doing the odd-job for the needed funds if it wasn't a scam?

    Not to mention that a 10-year-old source is probably full of unpatched holes, since you've obviously spent your time implementing the customs.

    In fact, I'm even willing to wager 10 euro that you didn't even implemented these yourself. You've most likely took some free-shared pack with a sh1t-load of custom add-ons, such as L2j-Master, and appropriated it by renaming each and every reference to the original developer, so that it looks like yours.

    This is my last response to your provocations. Have an enjoyful life!
     

    • Haha 1
    • Upvote 2
  17. 8 minutes ago, Booker Dewitt said:

     

    Whoever want to participate he will chat with me in private and see that is not fraud including my capabilities and also he is able to join and play. Also a vps and some advertisement is not huge deal. VPS can cost less than 30 euro. 

     

    Also i can prove the purchases by showing history. So if you are not interest do not comment please. 

     


    My sense of duty to the community would not let me stay quiet.
    Instead, I feel obligated to call this for what it seems like - a scam, until proven otherwise.

  18. 21 hours ago, Booker Dewitt said:

    I've been working on a HighFive source since 2013, and I have currently compiled it fully and am ready to go online. I need someone to support me financially.

    I offer the server itself and the client files inside bought for about 300 euros. I want someone who will pay for the VPS, protection, and advertisement.

     

    Things to know regarding project:

     

    1. It's a HighFive project, and I plan to go for mid-rate (x40–70). It's a million custom systems, including custom A. I will accompany players for the first few weeks (not trick them).

    2. Files have been tested for a few months at a local internet cafe with an average of 3–4 people for 5 hours per day.

    3. I don't provide access to the source. Regarding your donation income and your server rights we talk in private and base on our deal we will decide.

     

    If you're interested send me a private message here and I'll send you my discord (including my community to check about my work)

     


    You have been working on it since 2013 and you are creating an MxC account just now?

    Newly created account (today), 0 credibility, 0 status, 0 return on investment in the near term, 0 protection for the potential whale. Yet you claim to have EUR 300 of client modding. Even if that was the case, the fact that you've just made your account is SUS AF. It suggests that you are hiding your true identity.

    In conclusion:
    You offer nothing, you lose nothing, the entire risk is on the potential investor with nothing to even resell in case of a fraud. Why do you think anybody would agree to support you under these conditions?

    • Like 3
    • Upvote 3
  19. Long story:
    Open this LINK and at the TOP of the page click DISCORD. Join the server, and read through the channels named #download and #subscribers.

    Short story - there are 2 options:
    - entirely free version, accessible here: BITBUCKET_DIRECT_LINK 
    - Premium version, for which you pay 1-time fee of EUR 120 (i think), and then a monthly fee (EUR 20, i think?). And if you fail to pay the monthly fee, you would have to pay another EUR 120 to rejoin.

  20. 2 hours ago, KevinS said:

    Thanks for the answer, and I've already found those threads searching for info before I came here, but the thing is that I don't have empty spaces in my folders or file names. I believe that Java version was selected wrong, so it can't recognize something, but I tried a few different JDK versions starting from 8.0 to 8u381 but still no luck


    Both errors are indicative of your ant BUILD configuration being messed up.
    The first one indicates that your ${manifest.libs} variable is either not defined or being resolved properly.
    The second one indicates that the <javac /> element's bootstrap class path is not properly configured - it should point to the libs folder within the MAIN java folder.

  21. You won't find sources, and even if you do, they come with HWID/IP binding.
    I'm fairly certain that nobody, even if they do have it and are willing to sell it, would do so with the binding removed/disabled.
    It would make no sense, since that would allow you to resell at will. In fact, if they did, the price would have to be greater than what you would have to pay the owner of L2jEternity to buy lifetime access to SVN, but with bindings.

    Regarding the leaked version you mentioned, I've extracted and rebuilt the sources. However, I'm not distributing it.

×
×
  • Create New...