Saturday, November 7, 2020

Linux compiler error that never shown on Visual Studio

let's just admit Visual Studio sux ... ok ?

right now, if you want to host a Private Ragnarok Online server, its just better to choose Debian or CentOS option
the reason is because if you choose Windows Server Edition on VPS,
the cost of running on Windows is often double or triple compare to Linux environment

because of this, programmer like me who write and compile their plugin/source code with Visual Studio,
it will work fine on Windows environment.
But when apply the code on Live server (Linux environment), it will throw non-sensible error

No.1
warning: implicit declaration of function ‘atoi’ [-Wimplicit-function-declaration]

Avoid using atoi like plague !!
in npc scripting its the only script command to convert string into int
yes, this actually working fine with Visual Studio, but on Linux ...



No.2
error: a label can only be part of a statement and a declaration is not a statement

Sample



this case have to be enclose with curly bracket, like this


No.3
warning: unused variable ‘len’ [-Wunused-variable]

Sample
this is very annoying, because I want to output the value from 4th argument, but the 2nd argument isn't use
on Windows this is fine, but on Linux it throws that error throw off my guard

change


there might be more, will keep this update

Monday, November 2, 2020

Page by page

*mes

sometimes you want to display a long long array list of objects,
for example print out all values from a table
this will throw infinite loop ERROR

the reason is because the script engine has some protection against infinite loop check
conf\map\script.conf
even if you put a *freeloop there, it might still lag the server

in this case, its better to just display page by page


if the *query_sql still cause lag, have to use OFFSET


and this is with page input for your amusement :)



*select

same as above this will throw infinity loop ERROR
even if you put a LIMIT syntax this will throw menu length too long / too many options ERROR

this is because the maximum limit of menu length in string (eg: *getstrlen) is 2047
and the maximum limit of menu options is 254
src\map\script.h
and I don't recommend changing this, as you also have to change the packet structure etc ...

so the only way to remedy this ... is again ... page by page

if the query_sql still cause lag, have to use OFFSET


and the page select display for your amusement :)


External Links:
Help - Array in menu

Wednesday, October 14, 2020

How to send Weekly Rewards to players

now I have this script I want to send the weekly reward to players by mail, here's my take on how to tackle this problem yup, basically I just added a few more line down there

now, this is what happen when the script first loaded

1. when the server load the script for the first time, it will execute OnInit: and try to save the date of Sunday on that week

  • CURDATE() means today is '20201014'
  • DAYOFWEEK(CURDATE()) means today is Wednesday(4) -> Sunday is (1)
  •  that's why needs a -1 , DAYOFWEEK(CURDATE())-1 means -3
  • SUBDATE(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) -1) DAY)
    • SUBDATE('20201014', INTERVAL (3) DAY)
    • return '2020-10-11' is the Sunday of that week
  •  since it return '2020-10-11', have to kill the '-' symbol, use REPLACE syntax to remove that symbol

this value '20201011' is save into $poring_rank_1st_sunday and remain unchange forever
and the script will always try to compare to this value in DATEDIFF

now, this is what happen on the next week when triggering OnSun0000: label
"SELECT DATEDIFF(CURDATE(), '"+ $poring_rank_1st_sunday +"')/7"

  • CURDATE() is '20201018', the Sunday on the next week
  • DATEDIFF('20201018', '20201011') return 7, since we need to compare in weeks, do a /7, 7/7 = 1
  • .this_week_index = 1, $poring_rank_week_index = 0, the value are different now, thus it will try to reset the ladder

and once the ladder is reset, set $poring_rank_week_index(0) into .this_week_index(1) so it won't trigger on OnInit: label again
even doing a @reloadscript, it will compare the week index as 1 == 1, and won't execute ladder reset
only the next week again, compare the week index as 2 == 1, only will execute ladder reset

unlike the monthly reset, which save the actual date,
this one has to increase the week index counter even if there are no ranking in that week

External Links:
Weekly MVP Rewards

See Also:
How to send Monthly Rewards to players

How to send Monthly Reward to players

now I have this script I want to send the monthly reward to players by mail, here's my take on how to tackle this problem
yup, basically I just added a few more line down there

now break it into 3 parts

  1. when the server first load the script, it will execute OnInit: and store the $poringkill_last_given variable
    it will store the value as '202010', 2020 is the year, and 10 is the current month
  2.  then on 12:00am, it will execute OnClock0000: label,
    with the if (gettime(GETTIME_DAYOFMONTH) != 1) end; to halt the script if it isn't the day 1 of the month
    since it is a new month, '202011' is different from '202010' and thus execute the condition below
  3. The second condition of OnInit: label is to make sure it will run L_GiveMonthlyReward: label IF the server isn't online during 12:00am of day 1 of the month.
    It will compare to the $poringkill_last_given variable every time, if it is different month, then it will execute the statement below
    it has to bypass the if (gettime(GETTIME_DAYOFMONTH) != 1) end; so even if the server somehow didn't even online on day 1 of the month, it will still giving out monthly reward for previous month

External Link:
Monthly MVP Rank

See Also:
How to send Weekly Rewards to players

Thursday, October 8, 2020

compare regular expression on rAthena & Hercules

The most famous script that uses Regular Expression is GmOcean's Disguise Event
to learn more about Regular Expression, refer to Wikipedia
Visit this site for more in-depth tutorial

This NPC will Copy whatever you type
It's common practice that you should include ^ at the beginning and $ at the end
without it, players can input whitespace to bypass the check

Example:
(.@a$ ~= "asdf") = it can be "asdf", "aaasdf", "asdfffff", " asdf   " and so on
(.@a$ ~= "^asdf") = it can be "asdf", "asdffffff", "asdfasdf", "asdf   " <-- this just check the begining string
(.@a$ ~= "^asdf$") = it can only be "asdf", no other match

defpattern 1, "([^:]+): asdf","L_0"; <-- it can be "asdf", "asdfffffff", "asdfasdf", "asdf    " and so on
defpattern 1, "([^:]+): asdf$","L_0"; <-- only "asdf" will trigger the label L_0, OR "ASDF", "AsDf" and so on ...

yup, *pcre_match is case-sensitive, but *defpattern isn't, remember to keep this in mind
to make *pcre_match case-insensitive, use (?i) flag
to make *defpattern case-sensitive, use (?-i) flag


in practice, this command is most useful to check invalid character input
- only allow 0-9, a-z, A-Z or follow a format, like MySQL datetime format

for rAthena counterpart, rAthena has *preg_match instead, which follow PHP style input
However unlike Hercules, there are no way to capture the strings within a bracket
rAthena's *preg_match can only returns 0 or 1
correct me if I'm wrong, the source code seems to indicate it can return 0~10 but I couldn't get it display 2 or above



Some older client that diff with multi-language support will return |00 in front of character speech
try check it with *consolemes with the very first script (rAthena is *debugmes)
if that happens, your syntax has to change into


External Links:
Disguise Event fix
defpattern regexp
ignore case sensitive in regexp

Linux compiler error that never shown on Visual Studio

let's just admit Visual Studio sux ... ok ? right now, if you want to host a Private Ragnarok Online server, its just better to choose...