Beiträge von VegaS

    C
    1. if (d && strcmp(d->GetAccountTable().status, "OK") != 0)
    2. {
    3. d->SetPhase(PHASE_CLOSE);
    4. return;
    5. }


    You can do it with the default code, without extra queries.

    The only thing is that you need to initialize it properly since it's missing some parts on (db.cpp, ClientManager.cpp, ClientManagerLogin.cpp, tables.h)


    Thanks for the release, but this is a totally bad solution and useless code.

    Already there's a function that checking if the application is active or not in Bitte melden Sie sich an, um diesen Link zu sehen.

    The variable m_isActive is set when WM_ACTIVATEAPP it's called, basically when a window belonging to a different application than the active window is about to be activated.

    If you read a little bit the documentation of Win32 Api, you can find those.

    WA_ACTIVE

    • Activated by some method other than a mouse click (for example, by a call to the SetActiveWindow function or by use of the keyboard interface to select the window)

    WA_CLICKACTIVE

    • Activated by a mouse click.

    So, all what you've to use, it's just 2 lines:

    C
    1. bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim)
    2. {
    3. [...]
    4. if (!CPythonApplication::Instance().IsActive())
    5. return true;
    6. [...]
    7. }


    This method doesn't make sense for the metin2 gameplay anyway.

    Next time, do better research on metin2 source, nobody cares about those "HIGH" inventions of you that are totally ...great.



    Also, this is something that made my day:

    Eine richtige Lösung ist ein gutes Anticheat.

    *hust hust* z.b. Hawkeye *hust hust*

    Bitte melden Sie sich an, um dieses Bild zu sehen.

    You could check the method that I did for item award.

    Zitat

    2018-04-02 14:02:11 Monday Bitte melden Sie sich an, um diesen Link zu sehen.

    • Added a check for attr types and values min - max.
    • You can't insert wrong bonuses into a specific item.
    • Eg. Add 2000 MAX_HP on your Sword+9, was possible, now not.
    • Eg. Add +500 INT to your shield, now there's a check for min-max value of player.item_attr Lv.1 - Lv.5 and your 500 INT value will be replaced with max value from lvl5 of bonus, like 12 (lv5), that happen with all the bonuses, same thing with the values lower than lvl1, like 5 HP_REGEN on your neck, when the minimum (lv1) is 10, the value will be replaced with 10.
    • If the bonus type can't be added into a specific item, the bonus will be ignored > deleted. (example: critical pct to armor)
    • Refactorized all the code and moved all features into Bitte melden Sie sich an, um diesen Link zu sehen..
    • C++11 or higher is required for checking attributes.


    I just wanted to kindly ask why you don't use the name conventions given by ymir or just any convention for yourself. Is there any reason to call the variable m_EnterToken instead of m_bEnterToken for example? Or naming the vector multi_line instead of m_vecMultiLine?

    They're called hungarian notation (1972–1981), here you can find everything about it.

    Bitte melden Sie sich an, um diesen Link zu sehen.


    Bitte melden Sie sich an, um diesen Link zu sehen.

    No I don't recommend 'Hungarian'. I regard 'Hungarian' (embedding an abbreviated version of a type in a variable name) as a technique that can be useful in untyped languages, but is completely unsuitable for a language that supports generic programming and object-oriented programming — both of which emphasize selection of operations based on the type and arguments (known to the language or to the run-time support). In this case, 'building the type of an object into names' simply complicates and minimizes abstraction.


    Bitte melden Sie sich an, um diesen Link zu sehen.

    Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged—the compiler knows the types anyway and can check those, and it only confuses the programmer.


    Bitte melden Sie sich an, um diesen Link zu sehen.

    ... nowadays HN and other forms of type encoding are simply impediments. They make it harder to change the name or type of a variable, function, member or class. They make it harder to read the code. And they create the possibility that the encoding system will mislead the reader.


    Bitte melden Sie sich an, um diesen Link zu sehen.

    Design Guidelines[14] discourage developers from using Systems Hungarian notation when they choose names for the elements in .NET class libraries, although it was common on prior Microsoft development platforms like Visual Basic 6 and earlier. These Design Guidelines are silent on the naming conventions for local variables inside functions.

    Thanks for the remark, but I never used this command in game as a player, this should be active just for debug as GM's, no sense for players.

    About the fix, could be done directly from here too:

    • cmd_general.cpp

    Search for: (do_hair too)

    C
    1. snprintf(buf, bufferSize, FN_point_string(attr.bType), attr.sValue);

    Replace it with:

    C
    1. const char * cPointString = FN_point_string(attr.bType);
    2. if (!*cPointString)
    3. continue;
    4. snprintf(buf, bufferSize, cPointString, attr.sValue);

    There's no sense for showing to a player 'UNK... 23%' since he don't know what it's..

    I think it's better just to ignore the type if doesn't exist and don't show it in the chat.

    If you really want to do something like this, you can add a sys_log as an error to see the bonus missing and add it into the function.

    Thanks for thread, here's a trick that you don't have specify the index, already can get it automatically.

    Instead of:

    Zitat
    Python
    1. self.categories = (["Ente 1", 0],["Ente 2", 1],["Ente 3", 2],["Ente 4", 3],["Ente 5", 4],["Ente 6", 5],["Ente 7", 6])
    2. for category in self.categories:
    3. comboBox.InsertItem(category[1], category[0])
    4. def OnSelectItem(self, id):
    5. category = self.categories[id]
    6.     # You know that you could use "id" instead of list[1]
    7. self.textLine.SetText('["%s",%d]' %(category[0], category[1]))

    You can do it as:

    Python
    1. self.categories = ("Ente 1", "Ente 2", "Ente 3", "Ente 4", "Ente 5", "Ente 6", "Ente 7")
    2. for categoryIndex, categoryName in enumerate(self.categories):
    3. comboBox.InsertItem(categoryIndex, categoryName)
    4. def OnSelectItem(self, categoryIndex):
    5. categoryName = self.categories[categoryIndex]
    6. self.textLine.SetText('["%s",%d]' % (categoryName, categoryIndex))
    Python3.0 because of the print statements.

    getopt exists since over 15 years ago, if i'm not mistake.

    If you code in Python, you should know that in each version of python you can use print (something). In Python3 you're forced to use it, but in the previous versions you're not, print is just a normal function, which calling the sys.stdout.write(string).

    Zitat

    You should read Bitte melden Sie sich an, um diesen Link zu sehen.:

    The print statement has been replaced with a print() function, with keyword arguments to replace most of the special syntax of the old print statement (Bitte melden Sie sich an, um diesen Link zu sehen.).


    Bitte melden Sie sich an, um diesen Link zu sehen.:

    The changes proposed in this PEP will render most of today's print statements invalid. Only those which incidentally feature parentheses around all of their arguments will continue to be valid Python syntax in version 3.0, and of those, only the ones printing a single parenthesized value will continue to do the same thing.

    Also in all of these years I didn't heard about this error, but instead of doing a tool to rename all of your file names into lower case, you could check your client source or the EterManager source (is public), and just convert the file name to lower name, in one line, no tools, no anything.

    But you guys always prefer the hardest method, it's fine.

    Version?

    Python >= 3.0

    That's wrong, you don't have any features from Python 3.

    Zitat

    When packing, the EterManager makes the file name small and then packs, the client cannot find the file, because upper and lower case was probably not found in Japan in 2004. (Strangely, it works if you write it down yourself before packing. And that's where my tool comes in.)

    I don't have this problem and I don't think that somebody have it, because metin2 reading file from pack or whatever, doesn't have case sensitivity for file names Bitte melden Sie sich an, um diesen Link zu sehen. Bitte melden Sie sich an, um diesen Link zu sehen., already they're readed in lower case. So, you don't need this "Pythonskript", everything works fine.


    Bitte melden Sie sich an, um dieses Bild zu sehen.

    Hello cowboys, since i was at job and i was bored while coding in other languages, i thought would be funny if i code something in Python, so an idea came in mind, doing a general text file loader for parsing different data, with different structs, normal variables, groups and lists, like ymir idea for parsing the files (.mse, .msa, .msm, .txt like mob_drop_item.txt, group.txt, etc)

    This tool can be used everywhere, for metin2 or else, i wrote this from scratch using ymir idea, also you can run it in any version of Python.

    If you use this for metin2, change USING_METIN2_CLIENT to True.


    • Bitte melden Sie sich an, um diesen Link zu sehen.
    • Bitte melden Sie sich an, um diesen Link zu sehen.


    Source repository:

    If someone want to use it in client too:

    Bitte melden Sie sich an, um diesen Link zu sehen.

    • root/localeInfo.py

    How-To-Use:

    your_script.py < import localeInfo

    • Bitte melden Sie sich an, um dieses Bild zu sehen.
    Python
    1. self.timeTextLine.SetText(localeInfo.GetCurrentServerTime12H())
    2. # 06:00:08 PM
    • Bitte melden Sie sich an, um dieses Bild zu sehen.
    Python
    1. self.timeTextLine.SetText(localeInfo.GetCurrentServerTime12H())
    2. # 04:30:56 AM
    • Bitte melden Sie sich an, um dieses Bild zu sehen.
    Python
    1. self.timeTextLine.SetText(localeInfo.GetCurrentServerTime24H())
    2. # 21:05:03

    Bitte melden Sie sich an, um diesen Link zu sehen.


    How-To-Use-Ex:


    Bitte melden Sie sich an, um dieses Bild zu sehen.

    Update:

    • Fixed non-returning time for processing, if the specific event function has no value from returning, it runs continuously.
    • Fixed the check if an event exist, now will be replaced with the new one.
    • Removed Bitte melden Sie sich an, um diesen Link zu sehen.library (i heard that some people don't have it) and using builtin functions, instead of Bitte melden Sie sich an, um diesen Link zu sehen. now we're using Bitte melden Sie sich an, um diesen Link zu sehen.(object), which check if the event function can be called, now you can insert classes and others callable methods, not just simple functions.
    • Added a reset time event function.

    Next update: (when i'll have some free time again)

    • Insert a new type of event, which you can run an event by specific counter like:
    Python
    1. t.AppendEvent(eventName='RUN', eventStartTime=5, eventRunCount=10, eventFunc=self.Run, eventFuncArgs=player.GetLevel())

    The following things will happen:

    • The function Run(args), will start to run in 5 seconds for 10 times.
    Zitat

    Can you maybe tell how to do the Video with escape key, like official ?
    I mean being able to cancel the Video with escape key.

    As the title says, here's the simple method how you can skip the video without waiting until is finished, like official did long time ago.

    Bitte melden Sie sich an, um diesen Link zu sehen., right now these are by default:

    • VK_LBUTTON 0x01 - Left mouse button
    • VK_ESCAPE 0x1B - ESC key
    • VK_SPACE 0x20 - SPACEBAR

    Srcs/Client/UserInterface/Locale_inc.h

    Srcs/Client/UserInterface/MovieMan.cpp

    Zitat
    How to do it when i press any key/mouse etc to skip it? Not only by specific keys, people don't know those keys maybe

    Thanks for release, the idea isn't bad, but there're some bad things.

    I'll show you the problems part and how can be improved, there're just advices, i hope you'll get them.

    • Python
      1. def __del__(self):
      2. if len(self.eventList) > 0:
      3. self.eventList.clear()

      If you're using Python 2+ or Python 3.2 and below, you can't use the clear() method (allowed on 3.3+), also as i said in the second message you don't need to check the length of the list, already the clear() method doing that inside and there's no reason to put it to __del__ method, it will be called when the object is garbage collected. if you really want to use in future, something outside of this and want just to check the list if isn't empty, is enough to do it just with if some_list, like a normal boolean, there no need to check the length of the list if you don't use it in your code.

    • Python
      1. if len(self.eventList) > 0:
      2. for j in xrange(len(self.eventList)):
      3. [...]

      You don't have to check the list if you already did a numeric range loop or iterator based loop.

    • Python
      1. app.GetTime() + time

      I would say to use app.GetGlobalTimeStamp() instead of app.GetTime(), if you teleport while the event is running, the event function will run after 10 seconds like. While app.GetGlobalTimeStamp() will run after the specific time, because is the server timestamp and is updated on each enter in game.

    • Python
      1. if i == 0:
      2. self.eventList[j].clear()

      I would put here an big exclamation, with this you creating 999999999 lines in syserr, what you do here is like: While Process() function is called in OnUpdate, so, your condition trying to get the returned value from an specific function, what means the next update time or 0 to destroy the event/clear it. Everything's fine until you return 0 and event should be stopped yes? But there is a problem, you clear the specific dictionary of event and still remained in the list [{}], and the Process() function will take your self.eventList with the items included, the empty dictionaries from your events, and of course even if you've [{}, {}, {}], that doesn't mean your list is empty, have 3 items, so, the loop will trying to read an empty dictionary and you'll get key errors in each milisecond. The method which you need is to delete the dictionary itself from the list after the result value from the function is 0, like this:

    _______________________________________

    I wrote fast some self extensions, if somebody is interested i'll do another updates in the next days.

    • You can use unlimited arguments on functions, now is using the apply method which returns the result of a function or class object called with supplied arguments, with the old structure you could use just one argument.
    • You can lock/unlock an event for being processed, it's like a prevent in some actions, if the event is created and you want to do something, you should lock the event, do some actions then you can unlock it again and the process function will run where remained.
    • Delete an event instantly and force it to stop the process.
    • Adding return t.EXIT inside of the running function, will delete the event too.
    • Functions to check if an event exists or is locked or not.
    • Check if the function is a Bitte melden Sie sich an, um diesen Link zu sehen..
    • Delete the events with a properly method.
    • Using app.GetGlobalTimeStamp() now will give you the chance to run the event after teleport where timer remained instantly.

    _______________________________________

    The code:

    PS: Don't quote this reply, will be updated.