Jump to content

meko

Core Developers
  • Content Count

    363
  • Joined

  • Days Won

    46

Posts posted by meko


  1. This whole script is very ugly, but if you want a quick, dirty patch just change line 125 from 

    .@point = .gold_amount[0];
    

     

    to 

    .@point = rand(1, .gold_amount[0]);
    

    And then on line 45 change the value of .gold_amount to the max value you want (ie 5)


  2. Handling of item storage has been split into a separate packet, but while this fixed a bug, it introduced a race condition, which when exploited allows to duplicate items.

     

    A new patch has been issued and the exploit is no longer reproducible. If you are using a version between e8affc4 and f30edc7 (inclusive) make sure you update ASAP to d2af893 (stable) or later version and compile it.

     

     

    Affected versions, from oldest to most recent:

    • e8affc41f106503b530abaa7faa20d6e63b727b8
    • d966a8e6860d418bb3a235e57928436127eba555
    • cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2
    • 50848cc7f79aa516351e4a4d673df53f4881eb4d
    • 5383a14853327c123cbb037d3680aaa3d8c3e724
    • 8c5b8ac7d87d8d4dc49d3ff1768f8884a0d75d72
    • 7c6673e13fdd75a4137a9d7ef94e04d96e053422
    • d90e8ce0d8ba8677567a5a5adebb62ba97e8a0b3
    • b950a589e59e2bf074f67c75aaacf3f82424d4fe
    • 4b208e41d1d5cc995c2816e8f34c1ad8b0a7327d
    • 47a1e679cd35dc2e524fbeb31891d85e497821ce
    • f30edc7f02fb0c290d302d9abc77d970bb05fb62

     

     

     

    To know which version you are on:

    • start Hercules (login server, char server or map server)
    • it will say something like the following:
      [Info]: Git revision (src): 'e6ab2a9ec6f5be8927eeca667ff477086f5e2e8e'

     

     

    If any other issue is found, this post will be updated.

     

     

    Want to receive email notifications about important issues in the future?

    Go to Repository News and hit the follow button

     

     

    Need help updating to a newer version?

    You can get free support in the #Hercules channel of the Rizon network.


  3. Bots will always be there no matter what you do; even if you manually do botchecks

     

    Let's say I am a bot user, even if your questions are unpredictable and change every single time, nothing prevents me from creating a remote-controlled bot. I could set up a bot that automatically farms and whenever a botcheck is performed the bot would stop completely and send me a text message. I would then remotely answer the botcheck question and the bot would resume operation and you would have no way to differentiate this from a normal player.

     

    Plus, botchecking only ends up annoying legitimate users: not everybody is good at math, or has good eyesight to solve captchas


  4.  

     

    Very nice, haven't updated my herc files in a while, glad to see some awesome changes. Thanks for the summary. 

     

    I concur. Last updated Herc October 2016, seems there's tons of new stuff since then. In the process of getting up to speed.

     

    I suggest stay on your version :) updated one seems very unstable.

     

    Actually there was an issue with item cloning; but this was resolved


  5. if you absolutely refuse to use git at all then the only way is to download a zip file (highly not recommended, because you loose the history)

     

    else, see http://herc.ws/board/topic/14830-updating-hercules-git-pull-problem/#entry82925

    if you don't want to use the command-line interface I recommend Github Desktop instead of TortoiseGIT

     

     

    If you encounter a problem I can give step-by-step instructions on IRC: #Hercules @ Rizon

    make sure to say "meko" in the channel so I get notified


  6. It seems you did not hear my advise and learn the basics of git;

     

    The reason you cannot pull is because you do not have a git environment: you downloaded a zip instead of cloning.

     

    Do the following:

    1. Delete the folder you unzipped to (it's likely too messy by now)
    2. Create a github account
    3. Make note of your github username
    4. Log in to your github account
    5. Go to https://github.com/HerculesWS/Hercules and click the Fork button
    6. Open an ssh connection to your VPS and use the following commands one by one:
      git clone --origin upstream git://github.com/HerculesWS/Hercules.git
      
      git config --global url."https://".pushinsteadOf git://
      
      cd Hercules
      
      git remote add origin git://github.com/<your github username>/Hercules.git
      
      git fetch --all
      
    7. Now that you have a clean environment set up, build Hercules from this Hercules directory

     

     

    And thereafter, whenever you want to update:

    1. Connect through ssh to your vps:
      cd Hercules
      git pull upstream master
    2. ... and then build again

     

     

     

    PS- forking is usually not necessary if you just want to run a vanilla server, but if you ever want to make modifications you'll have this fork ready

     

    PS2- I noticed you are logged in to your VPS as root; running a publicly accessible server (ie Hercules) from a superuser account is very bad practice, as if any vulnerability is found the attacker would gain FULL ACCESS to your VPS


  7. Array manipulation functions


    This script provides various array manipulation functions, and more might be added in the future.
    All of those functions (except the arithmetic ones) work with both integer and string arrays.

    The start of the array is always implicitly index 0, unless an index is specified, ie @array[index]



    array_pad(<array>, <size>, <value>)
    pads the array left or right with <value> until it reaches <size> size. If <size> is negative it will pad left.
    > returns the number of added entries

    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_pad(.@foo, 8, 69); // => 3
    
    // array is now: 1, 2, 3, 4, 5, 69, 69, 69
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_pad(.@foo, -8, 69); // => 3
    
    // array is now: 69, 69, 69, 1, 2, 3, 4, 5



    array_replace(<array>, <needle>, <replacement>{, <neq>})
    finds every occurrence of <needle> within the array and replaces it with <replacement>. if <neq> is true, finds entries that do not match instead
    > returns the number of changed entries
    setarray(.@foo, 1, 1, 3, 1, 5); // initialize the array
    array_replace(.@foo, 1, 69); // => 3
    
    // array is now: 69, 69, 3, 69, 5



    array_find(<array>, <needle>{, <neq>})
    finds the first occurrence of <needle> within the array. if <neq> is true, finds entries that do not match instead
    > returns the index, or if none is found returns -1
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_find(.@foo, 3); // => 2
    array_find(.@foo, 1); // => 0
    array_find(.@foo, 6); // => -1



    array_rfind(<array>, <needle>{, <neq>})
    like array_find, but finds the last occurrence. if <neq> is true, finds entries that do not match instead
    > returns the index, or if none is found returns -1
    setarray(.@foo, 1, 2, 3, 4, 3); // initialize the array
    array_rfind(.@foo, 3); // => 4
    array_rfind(.@foo, 4); // => 3
    array_rfind(.@foo, 6); // => -1



    array_exists(<array>, <needle>{, <neq>})
    very similar to array_find() but it instead just checks if it exists or not. if <neq> is true, finds entries that do not match instead
    > returns true or false
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_exists(.@foo, 3); // => true
    array_exists(.@foo, 6); // => false



    array_count(<array>, <needle>{, <neq>})
    similar to array_find() but iterates through the whole array. if <neq> is true, finds entries that do not match instead
    > returns the total number of occurrences of <needle>
    setarray(.@foo, 1, 69, 3, 69, 5); // initialize the array
    array_count(.@foo, 69); // => 2



    array_entries(<array>)
    a wrapper around array_count(). behaves similarly to getaraysize() but does not count holes
    > returns the number of non-empty entries
    setarray(.@foo, 1, 2, 0, 0, 5); // initialize the array
    getarraysize(.@foo); // => 5
    array_entries(.@foo); // => 3




    array_remove(<array>, <needle>{, <neq>})
    finds and removes every occurrence of <needle> from the array, while shifting left. if <neq> is true, finds entries that do not match instead
    > returns the number of removed entries
    setarray(.@foo, 1, 69, 3, 69, 5); // initialize the array
    array_remove(.@foo, 69); // => 2
    
    // array is now: 1, 3, 5



    array_reverse(<array>)
    reverses the array
    > returns true
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_reverse(.@foo); // => true
    
    // array is now: 5, 4, 3, 2, 1



    array_sum(<array>)
    iterates through the whole array to perform an arithmetic addition
    > returns the sum of every entries of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_sum(.@foo); // ((((1 + 2) + 3) + 4) + 5) => 15



    array_difference(<array>)
    iterates through the whole array to perform an arithmetic subtraction
    > returns the difference of every entries of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_difference(.@foo); // ((((1 - 2) - 3) - 4) - 5) => -13



    array_product(<array>)
    iterates through the whole array to perform an arithmetic multiplication
    > returns the product of every entries of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_product(.@foo); // ((((1 * 2) * 3) * 4) * 5) => 120



    array_quotient(<array>)
    iterates through the whole array to perform an arithmetic division
    > returns the quotient of every entries of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_quotient(.@foo); // ((((1 / 2) / 3) / 4) / 5) => 0



    array_shift(<array>)
    removes the first entry of the array, while shifting left
    > returns the value of the removed entry
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_shift(.@foo); // => 1
    
    // array is now: 2, 3, 4, 5



    array_unshift(<array>, <value>)
    adds <value> to the start of the array, while shifting right
    > returns the new size of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_unshift(.@foo, 69); // => 6
    
    // array is now: 69, 1, 2, 3, 4, 5



    array_pop(<array>)
    removes the last entry of the array
    > returns the value of the removed entry
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_pop(.@foo); // => 5
    
    // array is now: 1, 2, 3, 4



    array_push(<array>, <value>)
    adds <value> to the end of the array
    > returns the new size of the array
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_push(.@foo, 69); // => 6
    
    // array is now: 1, 2, 3, 4, 5, 69



    array_shuffle(<array>)
    shuffles the array
    > returns true
    setarray(.@foo, 1, 2, 3, 4, 5); // initialize the array
    array_shuffle(.@foo); // => true
    
    // array is now: 1, 4, 2, 3, 5 (example, unpredictable)




    array_unique(<array>{, <threshold>})
    allows array entries to appear up to <threshold> times (1 by default) and removes the extraneous ones. useful to remove duplicate entries
    > returns the number of removed entries

    setarray(.@foo, 1, 3, 3, 4, 5); // initialize the array
    array_unique(.@foo); // => 1
    
    // array is now: 1, 3, 4, 5




    array_diff(<base array>, <array>{, <array>...}, <result array>)
    compares the base array against one or more other arrays and fills the result array with the entries in base array that are not present in any of the other arrays
    > returns the number of entries not found in other arrays

    setarray(.@base, 1, 2, 3, 4, 5, 6, 7, 8); // initialize the base array
    
    // fill the arrays to compare with the base array:
    setarray(.@foo, 2, 3, 4, 5, 6, 7, 8); // missing "1"
    setarray(.@bar, 1, 2, 3, 4, 6, 7, 8); // missing "5"
    setarray(.@baz, 1, 2, 3, 4, 5, 6, 7); // missing "8"
    
    // compare foo, bar and baz against base, and fill result:
    array_diff(.@base, .@foo, .@bar, .@baz, .@result); // => 3
    
    // .@result is now: 1, 5, 8




    array_filter(<array>, "<function>")
    filters the array using a function that is tested against every entries. if the function returns false, the relevant entry is removed and the array is shifted left
    > returns the number of removed entries

    function	script	is_prime	{
    	if (getarg(0) <= 1)
    		return false;
    
    	for (.@i = 2; .@i <= getarg(0) / 2; ++.@i)
    		if ((getarg(0) % .@i) == 0)
    			return false;
    
    	return true;
    }
    
    setarray(.@foo, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    array_filter(.@foo, "is_prime"); // => 9
    
    // array is now: 2, 3, 5, 7, 11, 13




    array_sort(<array>)
    sorts the array in ascending order
    > returns true

    setarray(.@foo, 2, 1, 8, 4, 5, 7, 6, 3); // initialize the array
    array_sort(.@foo); // => true
    
    // array is now: 1, 2, 3, 4, 5, 6, 7, 8




    array_rsort(<array>)
    sorts the array in descending order
    > returns true

    setarray(.@foo, 2, 1, 8, 4, 5, 7, 6, 3); // initialize the array
    array_rsort(.@foo); // => true
    
    // array is now: 8, 7, 6, 5, 4, 3, 2, 1





    Requires Hercules of June 24 2017 or newer version



     

    --------------------------------------------------------------------------------------

    This script was made by me, for The Mana World + Evol.
    L
    icense: public domain (CC0)


     


  8. Randomization helper functions


    This script provides syntactic sugar for randomization.
    Works fine with both strings and integers.

     

     

    any(<arg>{, <arg>{, ...}})
    > returns a random argument from the passed arguments

    emotion(any(e_hmm, e_grat, e_yawn)); // do any of those 3 emotes
     



    any_of(<array>)
    > returns a random entry from the passed array
    setarray(.@foo, 1, 2, 3, 4); // build the array
    
    // ... later in the code:
    mes(any_of(.@foo)); // print any number from the array

     



    relative_array_random(<array: 0, {[value, probability]...}>{, <recalculate>})
    a more powerful version of any_of(), which allows to assign arbitrary probabilities to every entry instead of being rand(size) for every one.
    the first value of the array is reserved and must be 0, and every entry must be a tuple of [value, probability].
    if the array is modified between invocations please pass true as second argument to re-calculate the total probability.
    probabilities are arbitrary and can be any number between 1 and INT_MAX.
    > returns the random entry

    setarray(.@foo, 0, // <= always 0
    	111,  6,
    	222, 12, // <= [value, probability]
    	333, 20,
    	444,  4);
    
    relative_array_random(.@foo); // => 333 (example, unpredictable)

     

     

     

    --------------------------------------------------------------------------------------
    This script was made by me, for The Mana World + Evol.
    License: public domain (CC0)


     


  9. Safe string manipulation functions


    This script provides safe string manipulation functions that do not require PCRE to be enabled at compile time, making your scripts more portable.



    startswith("<string>", "<substring>")
    returns true if <string> begins with <substring>

    startswith("hypothermia", "hypo") // true
    startswith("hypothermia", "hyper") // false



    endswith("<string>", "<substring>")
    returns true if <string> ends with <substring>
    endswith("hypothermia", "thermia") // true
    endswith("hypothermia", "glycemia") // false



    capitalize("<string>")
    returns <string> with its first letter being capitalized
    capitalize("the quick brown fox") // The quick brown fox



    titlecase("<string>")
    returns <string> with the first letter of every word capitalized
    titlecase("the quick brown fox") // The Quick Brown Fox



    camelcase("<string>")
    returns <string> concatenated in a camelCase fashion
    camelcase("the quick brown fox") // theQuickBrownFox



    zfill("<string>"{, <width>{, "<padding>"}})
    returns <string> padded to the left up to <width> with <padding>
    zfill(69, 6, "0"); // 000069
    zfill(1337, 6, "0"); // 001337



    format_number(<number>{, "<separator>"})
    formats a number with <separator>
    format_number(50) // 50
    format_number(50000) // 50,000
    format_number(5000000) // 5,000,000



    strip("<string>")
    returns <string> without spaces at the beginning or end
    strip("  the quick brown fox") // "the quick brown fox"
    strip("the quick brown fox  ") // "the quick brown fox"
    strip(" the quick brown fox ") // "the quick brown fox"



    reverse("<string>")
    returns <string> reversed
    reverse("Hello world!") // !dlrow olleH



    repeat("<string>", <multiplier>)
    repeats <string> <multiplier> times
    repeat("Foo", 4) // FooFooFooFoo




    shuffle("<string>")
    returns <string> shuffled

    shuffle("abcdefg") // dgabefc (example, unpredictable)


     


     


  10. Area timer functions


    This script provides functions to add (or remove) timers to every player in the area or map.

     

     

     

    areatimer("<map>", <x1>, <y1>, <x2>, <y2>, <tick>, "<event>")
    makes all players in the square area call <event> after <tick> ms
    > returns the number of affected players

    areatimer("prontera", 55, 60, 150, 180, 500, "MyNPC:MyEvent");
     

     

     

    areatimer2("<map>", <x1>, <y1>, <x2>, <y2>, <tick>, "<event>")
    identical to areatimer, but also removes any existing timer before adding the new one
    > returns the number of affected players

    areatimer2("prontera", 55, 60, 150, 180, 500, "MyNPC:MyEvent");
     

     

     

    areadeltimer("<map>", <x1>, <y1>, <x2>, <y2>, "<event>")
    makes all players in the square area remove their timers for <event>
    > returns the number of affected players

    areadeltimer("prontera", 55, 60, 150, 180, "MyNPC:MyEvent");
     

     

     

    maptimer("<map>", <tick>, "<event>")
    makes all players in the map call <event> after <tick> ms
    > returns the number of affected players

    maptimer("prontera", 500, "MyNPC:MyEvent");
     

     

     

    maptimer2("<map>", <tick>, "<event>")
    identical to maptimer() but also removes any existing timer before adding the new one
    > returns the number of affected players

    maptimer2("prontera", 500, "MyNPC:MyEvent");
     

     

     

    mapdeltimer("<map>", "<event>")
    makes all players on the map remove their timers for <event>
    > returns the number of affected players

    mapdeltimer("prontera", "MyNPC:MyEvent");
     
     
     
     
    globaltimer(<tick>, "<event>")
    makes all players everywhere call <event> after <tick> ms
    > returns the number of affected players
    globaltimer(500, "MyNPC:MyEvent");

     

     

     

     

    Requires Hercules v2018.06.03 or newer version

     

     

    --------------------------------------------------------------------------------------
    This script was made by me, for The Mana World + Evol.
    License: public domain (CC0)


     


  11. There is no need to use global variables ($@) or to use attachrid

    	getmapxy(@evt_map$, @evt_x, @evt_y, UNITTYPE_PC); // save the previous position
    	warp(.map$, .warp_x, .warp_y); // warp the player to your event
    	end;
    
    OnWarpBack:
    	warp(@evt_map$, @evt_x, @evt_y);
    	end;
    
    OnEventEnd:
    	.@count = getunits(BL_PC, .@players, false, .map$);
    	for (.@i = 0; .@i < .@count; .@i++) {
    		addtimer(rand(500), strnpcinfo(0) + "::OnWarpBack", .@players[.@i]);
    	}
    	end;
    
    
    OnInit:
    	.map$ = "the-map"; // map of the event
    	.warp_x = 50; // the x position to warp the player to
    	.warp_y = 50; // the y position to warp the player to
    

  12. File Name: Soul Menhir

    File Submitter: meko

    File Submitted: 29 May 2017

    File Category: Utility

     

    The Soul Menhir slowly regenerates the SP of anyone sitting near it.

     

    Make sure to change the map, x, y and the sprite.

     

     

    Requires Hercules of April 8th 2017 or newer version

     

     

    --------------------------------------------------------------------------------------

    This script was made by me, for The Mana World + Evol.

    License: public domain (CC0)

     

    Click here to download this file


  13. An SSD (solid-state disk) is much much faster at reading and writing than a traditional HDD (hard disk drive), and generally more stable since it has no moving parts.

     

    The difference between KVM and OpenVZ is that KVM uses hardware virtualization (aka an hypervisor) while OpenVZ uses OS-level virtualization (aka a container).

    A hypervisor basically emulates the whole machine while a container just emulates the user-space and runs it on top of a shared kernel. Because of the added layer of abstraction offfered by hypervisors the performance is slightly worse than for containers. 

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.