• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

SC2 Bank files - Critics

Status
Not open for further replies.
Level 6
Joined
Sep 28, 2009
Messages
222
SC2 Bank files - Critics

WARNING: This post is outdated and its not all true whats said in here. Please read the entire thread or at least the last pages to get the latest informations, thanks!

Introduction

Hello everyone!
In WC3 it was very hard to save heroes or other things after map close. In that time we used "save codes" that every player had to write down and type in later if he wanted to load his hero. So Blizzard gave us some new method to save our heroes/map progress: The bank files.


Bank-files basics

In fact, the bank files are nothing else than XML files located in your documents folder. The difference to WC3-GC is, that you can use Bank-files in multiplayer, because you can load/save them for specific players. The bank files itself are not encrypted and can be edited with the normal windows text editor.


How to use Bank files:

The bank files are quite easy to use. If you for example want to save an integer to a bank file, you have to do the following:

1) save integer to bank
  • save int
    • Events
    • Local Variables
      • int = 1337 <Integer>
    • Conditions
    • Actions
      • Bank - Open bank "testbank" for player 1
      • Bank - Store integer int as "integer" of section "integers" in bank (Last opened bank)
      • Bank - Save bank (Last opened bank)
2) load integer
  • load int
    • Events
      • Game - Map initialization
    • Local Variables
      • int = 0 <Integer>
    • Conditions
    • Actions
      • Bank - Open bank "testbank" for player 1
      • Variable - Set int = (Load "integer" of section "integers" from bank (Last opened bank) as integer value)
Thats it, quite easy, huh? ok, if we test this it works quite well, but there is a difference:

  • If we only restart the map and dont close sc2, it works perfect
  • if we close sc2 and reopen it, the integer value wont be loaded

so why is this? why does it work if we only restart the map and not if we restart the entire game? the reason is, that bank files get written to your cache while playing. if you only restart the map the bank is still in your cache and can be loaded. but if you restart the entire game the cache will be deleted and you cant load your bank value any more.

So what can we do about it? no need to be worried, we can fix this issue with one simple action:

  • load int
    • Events
      • Game - Map initialization
    • Local Variables
      • int = 0 <Integer>
    • Conditions
    • Actions
      • Bank - Preload and synchronize bank "testbank" for player 1
      • Bank - Open bank "testbank" for player 1
      • Variable - Set int = (Load "integer" of section "integers" from bank (Last opened bank) as integer value)
because of the preloading action we can now load the bank value even if we restart the entire game.


Bank-files advanced

Ok, until now its all good and easy. now we will go a bit more advanced :)
at first i want to rewrite the code, so that it works for all 16 players. i just change the int to an int array and save/load the bank for all players.

1) save:
  • save int
    • Events
    • Local Variables
      • int = 1337 <Integer[16]>
    • Conditions
    • Actions
      • ------- note: players are integers now!
      • Player Group - Pick each player in (All players) and do (Actions)
        • Actions
          • Bank - Open bank "testbank" for player (Picked player)
          • Bank - Store integer int[(Picked player)] as "integer" of section "integers" in bank (Last opened bank)
          • Bank - Save bank (Last opened bank)
2) load
  • load int
    • Events
      • Game - Map initialization
    • Local Variables
      • int = 0 <Integer[16]>
    • Conditions
    • Actions
      • ------- note: players are integers now!
      • Player Group - Pick each player in (All players) and do (Actions)
        • Actions
          • Bank - Preload and synchronize bank "testbank" for player (Picked player)
          • Bank - Open bank "testbank" for player (Picked player)
          • Variable - Set int[(Picked player)] = (Load "integer" of section "integers" from bank (Last opened bank) as integer value)
in fact we didnt change anything, only that we do it for all players in a loop right now, so all should be good.
if we test this new triggers we will be quite surprised:
  • it will work with restarting the map
  • it WONT work with restarting the game

so why is this? didnt we preload the bank files? yes we did, but we are not allowed to do it in a loop. bank-name and player must be LITERAL values, no variables or expressions are allowed. so we have to do it like this:

  • Actions
    • Bank - Preload and synchronize bank "testbank" for player 0
    • Bank - Preload and synchronize bank "testbank" for player 1
    • Bank - Preload and synchronize bank "testbank" for player 2
    • Bank - Preload and synchronize bank "testbank" for player 3
  • ...
this is the first thing that i dont like about banks and i want to critisize this. why we have to do it manually? what if one player has more then one bank? its alot of work and not really necessary, its just annoying. but ok, its only a bit typing work, its not a really serious problem.


Bank-files - Multiplayer

in singleplayer the bank files seem to work quite well, so i decided to do some multiplayer testing about them. if we take the code from above and load the map in multiplayer it works very good, the bank gets loaded and the integer restored, all fine.

in reality, you wont store only one integer value in a bank file. for example if you want to do an ORPG (like me), you have to save a lot more to the bank files, for example hero attributes, position, if hes alive, player property, option settings, ... and so on. addicionally, you might not only have one character in an rpg, but more. so you would need more then one bank file to save all characters individually. ok, so what? were is the problem in this?

at first we will again rewrite the code a little bit. instead of storing one integer value, i now want to store much more in the bank files to simulate an RPG game.

1 save int
  • bt
    • Events
      • Game - Player Any Player types a chat message containing "-bt ", matching Partially
    • Local Variables
      • int = 0 <Integer[500]>
      • string = (Substring((Entered chat string), 4, 10)) <String>
    • Conditions
    • Actions
      • Bank - Open bank "bt" for player (Triggering player)
      • Bank - Remove section "test" from bank (Last opened bank)
      • ------- Comment
      • General - Pick each integer from 0 to (Integer(string)), and do (Actions)
        • Actions
          • Variable - Set int[(Picked integer)] = (Integer(string))
          • UI - Display (Text(int[(Picked integer)])) for (All players) to Subtitle area
          • Bank - Store integer int[(Picked integer)] as (String((Picked integer))) of section "test" in bank (Last opened bank)
      • ------- Comment
      • Bank - Save bank (Last opened bank)
      • UI - Display "saved" for (All players) to Subtitle area
if we enter "-bt " in the chat the trigger gets activated. after this we have to enter the number of integers we want to store in the bank. so if we for example write "-bt 50", there will be 50 integer values with value 50 stored into the bank.

our load trigger will be very simple:
  • load
    • Events
      • Game - Map initialization
    • Local Variables
    • Conditions
    • Actions
      • Bank - Preload and synchronize bank "bt" for player 1
the only thing we want to do is preloading the bank for player 1, because otherwise we are not able to use it later.


Bank-files - The problem

ok, if we test the triggers from above in battle net we will get the following results:

  • if we save 1-80 integer values, its all fine
  • if we save >80 integer values, the game WONT LOAD ANYMORE

so whats wrong now? why cant he preload the bank if we save >80 values to it? (the bank size is around 6KB then)
please keep in mind, that loading <80 values goes without problems and without any delay, so why he just cant load >80 values?
my conclusion is, that blizzard set some limit. i dont know why, maybe because of net-traffic, i dont know. but im quite sure in theory its no problem to load 80 values or more, just because a lower value goes without any problems. so we have a LIMIT here of ~80 values in a bank, otherwise our map WILL NOT EVEN LOAD!

ok, now you might say its not a such big problem. 80 values is quite much for one hero in an rpg, and we could use more banks to split them up a little bit and reduce the amount of values every bank ha to save.
so lets modify the trigger a bit to see what will happen if we load 2 banks with <80 values:

save:
  • bt 2
    • Events
      • Game - Player Any Player types a chat message containing "-bt2 ", matching Partially
    • Local Variables
      • int = 0 <Integer[500]>
      • string = (Substring((Entered chat string), 5, 10)) <String>
    • Conditions
    • Actions
      • Bank - Open bank "bt" for player (Triggering player)
      • Bank - Remove section "test" from bank (Last opened bank)
      • General - Pick each integer from 0 to (Integer(string)), and do (Actions)
        • Actions
          • Variable - Set int[(Picked integer)] = (Integer(string))
          • UI - Display (Text(int[(Picked integer)])) for (All players) to Subtitle area
          • Bank - Store integer int[(Picked integer)] as (String((Picked integer))) of section "test" in bank (Last opened bank)
      • Bank - Save bank (Last opened bank)
      • UI - Display "saved" for (All players) to Subtitle area
      • ------- Comment
      • Bank - Open bank "bt2" for player (Triggering player)
      • Bank - Remove section "test" from bank (Last opened bank)
      • General - Pick each integer from 0 to (Integer(string)), and do (Actions)
        • Actions
          • Variable - Set int[(Picked integer)] = (Integer(string))
          • UI - Display (Text(int[(Picked integer)])) for (All players) to Subtitle area
          • Bank - Store integer int[(Picked integer)] as (String((Picked integer))) of section "test" in bank (Last opened bank)
      • Bank - Save bank (Last opened bank)
      • UI - Display "saved2" for (All players) to Subtitle area
in fact, this trigger does exactly the same as the first one, the only difference is that we use 2 banks now. so if we enter "-bt2 50" we will create 2 banks, each of them containing 50 int values with value 50.

load:
  • load
    • Events
      • Game - Map initialization
    • Local Variables
    • Conditions
    • Actions
      • Bank - Preload and synchronize bank "bt" for player 1
      • Bank - Preload and synchronize bank "bt2" for player 1
the load trigger should be self explaining.

remember: loading ONE bank with 50 values was no problem!

ok, if we type "-bt2 45" now and try to restart the map... it WONT LOAD!

so what does this mean? this means that not only the values every SINGLE bank can load are limited - the values of ALL BANKS TOGETHER are limited to 80!

so what does this mean for an orpg game? if we have for example 5 character slots for each player, there could only ~80/5 values be saved for each character! its a joke. if you want to save quest progress, property, attributes, level, position and so on its just not enaugh.

by the way: in singleplayer its no problem to load a bank with >80 values. even 400 values are no problem. so this problem is ONLY multiplayer. test it yourself, and you will see its no joke. you cant load >80 values in multiplayer from banks.


Bank files - Conclusion

Bank files are a very good idea of blizzard and im really thankful that they gave them to us. But if we are not able to load >80 values from bank files in multiplayer, they are sensless. i can just hope that blizzard will fix this. its the dead for nice orpgs.

not only that blizzard limited map size, tilesets and has quite bad hero support and is completly leaking the hero triggers, now we also have this bank limit.

I can only hope this is a beta-issue. If not:
Please blizzard, stop killing ORPGS!


PS: please dont complain about any trigger optimizing, this triggers here are just examples to show you the problem.
 
Last edited:
Level 4
Joined
Aug 14, 2005
Messages
49
Nice report, my thanks.

I also hope that blizzard is reading this, but maybe it's possible to send them an e-mail AND a bug report. You know, just to be sure.

So say, Mille25, since you already have dived into bank files: How safe are they versus hacking?

Their advantages are obvious for ORPGs, but I have to say they would also work quite nicely with other maps, like the one I am currently working on.

However, in almost all maps, if you are able to edit your hero to have 10k stats and 200k HP, well, the game is over.

So, is it possible to simply edit this file (if it is unencrypted), or, if it is encrypted, is it possible to easily break the encryption by a little programming work? (I realize that it's nigh-impossible to make it COMPLETELY unbreakable, but a little bit of safety would be nice...)

Thanks in advance.

yours,

Ouguiya
 
Level 6
Joined
Sep 28, 2009
Messages
222
Well since you need encryption, as robbepop mentioned, you'll need to store all data into one string, so you only really need one value per hero. The only problem would be if every character of string did count towards 80 values limit...

where is the sense of bank files if we again have to generate a save code? that would really suck.

i have no problem with encrypting my bank to make it a bit saver (see my project thread for some examples) but i dont want to code a savecodesystem, really not ~~
 
Level 4
Joined
Jul 11, 2006
Messages
38
Seems you could just dump all the data into one long series of bytes, then run an algorithm on the bytes. Solves both the hacking and limit issues. Substitution-permutation with a hill cipher on top are very easy to code, and fast for a program to compute. An algorithm that combines all three would frustrate most hackers, and if they REALLY want to hack it that badly, they'll find a way no matter what you do.

http://en.wikipedia.org/wiki/Substitution_cipher
http://en.wikipedia.org/wiki/Permutation_cipher
http://en.wikipedia.org/wiki/Hill_cipher
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
Well the problem is that, if I remember correctly, it uses 2 xml tags to save a single value.. so saving a boolean (1 bit) needs like 100 characters (100 bytes?)... so technically it would be "correct" to compress it into few larger values even without any limit.
(I will be saving ship models into banks, 100x(boolean+2xinteger)=300x100=30 KB, and I was going to use some string generating system anyway 100x(1+2x8 bits)=1,7KB )
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,190
I say the cap is with the fact that the packets are restricted to certain sizes or the internet servers will refuse to redirect them correctly.

Also I belive your multiplayer use of the banks is incorrect. Have you even tried using banks with more than 1 player? No? Well ofcourse not as you can not run multiplayer custom map tests currently and any loophole method is not supported by blizzard and so may or may not be present when custom map support is included.

I think what happens is when you load a bank, it takes that bank for the player and then syncronizes it with everyone. The key word is syncronizes, it does not say merge or anything. Thus what probably happens is by doing that for a bank like "bt" of Player 1, it would load that bank for everyone with Player 1's bt bank. Thus you might find you are actually limited to 80 values per player or something however that can not be proved as you can not test custom maps with more than 1 player (third party does not really count as that might cause its own bugs). Setting it to load Player 2's "bt" bank would discard the entire contense of previous "bt" bank and then load Player 2's or something like that. It might get even more extreem and actually overwrite all other player's banks with that of the source player.

80 values should be more than enough. You can get 32 flags per value. If strings are an axcepted value you can store endless quantities of data.
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
Well it seems that you can save strings to banks, so there shouldn't be a problem in generating old-fashioned save code and saving that, putting limitless amount of information into one variable.
And yes, Dr Super God already mentioned that:
You can get 32 flags per value. If strings are an axcepted value you can store endless quantities of data.
Also, if you were to save multiple values into an integer, you should better use bit separation rather then decimal. (I used such system in my warcraft code generator, except the separation was totally irregular, and I was able to save 6 bits into one value (one character of 64)
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,190
The World Is Flat, why would you want to do that?

An IP addresses is nothing more than an address used to represent a desternation mac when passed through IP tables. Its sole purpose is to make transfer through the internet easier and not act as a reference for who someone is.

Your IP address can change, EG if I restart my router my ISP throws me a completly new IP address (from a pool of IPs for this area). Thus storing it in a bank would be stupid as what would it achieve?
 
Level 10
Joined
Nov 28, 2008
Messages
655
The World Is Flat, why would you want to do that?

An IP addresses is nothing more than an address used to represent a desternation mac when passed through IP tables. Its sole purpose is to make transfer through the internet easier and not act as a reference for who someone is.

Your IP address can change, EG if I restart my router my ISP throws me a completly new IP address (from a pool of IPs for this area). Thus storing it in a bank would be stupid as what would it achieve?

LOL!

Try going through the stack next time, you will get the same response out of people, :thumbs_up:

You need to understand that most people that mod are not computer people, lol
 
LOL don't expect me to know. I dont study computers. or even care that much really. its only becaue a system id of interest.
(wtf are ip bans effective then o_O?)

What i want is a system where only one specific person can type in one specific code, and if somone else types in that same code it would fail if the game could not identify that computer as attached to that code.

But w/e.
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
Well IP bans can work, as some people have static IP adress (I theoretically have dynamic, but it hasn't changed for like 4 years), so IP banning me would work. Also you can order static IP adress from your provider.

Also, saving IP adress into bank is unnecessary, as the bank is saved locally on the computer, so if you want an unique computer identifier, just generate a random integer and save it into bank. You have a better chance that two computers will have different identifier than by using IP's (two users can play through same internet connection)
 
Level 6
Joined
Sep 28, 2009
Messages
222
as far as i know its not possible yet to make a player name check with bank files, because you just cant compare 2 texts and cant convert a text into a string.

so you could store the player name in the bank but could not check if its correct after that ~~
 
Level 6
Joined
Sep 28, 2009
Messages
222
the player names are returned as text. so you cant check it because you cant compare text and cant convert text to string.

i already made a topic in the english eu forum but didnt get any replies.

you can test this yourself by just creating a global text variable. then create a new trigger and try to select this variable in conditions. while every other variable, like strings and so on are there, the text variable is missing. dunno why^^ you also wont find any functions that return text in condidions.
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
Also the names aren't unique, only identifiers are, and you can't get identifiers in script.

And btw, what is the difference between string and text? It seemed to me that texts are in some table, saved under their indexes (the Param/ValueXX/whatever), but in that case it would make no sence that you could convert TO texts and not from them (even if the table was static, it would only be possible the other way), and they should be easily compareable (however I would expect it to compare the ID, not the actual content of the text)
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,190
It depends on how texts are allocated. Due to the better programming of SC2, objects like text may be hashed and recycled instead of recreated. As such like conditions in WC3 and strings, the same representation will return the same object and thus be comparable. However I still need to look into this sort of thing.
 
Level 10
Joined
Nov 28, 2008
Messages
655
Are texts not an object type?

They are but they are different from strings.

And instead of being smart and making text and string interchangeable (like making text a child of string with more methods, which would be logical to me) They didn't give us a conversion method.

I am sure this is just an "oops" on their part, and will be fixed. That is quite an annoying thing.
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
Well the blizard file says this:
JASS:
// -- Complex types and equality --
// 
// Normally, comparing two "complex" objects with the == or != operators will only compare the
// object reference, not the contained object data.  However, a few types will compare the contained
// data instead.  These types are:
//
//      abilcmd, point, string, unitfilter, unitref
So it seems that comparing text would be pointless anyway, it wouldn't work for player names or any in-game created texts. However I still see no reason why text->string conversion shouldn't be possible.

EDIT: I just though of a reason: If it was like Dr Super God said, which seems likely, text->string would return different value for each player (based on their localization) and cause desync.
 
Level 6
Joined
Sep 28, 2009
Messages
222
sry but my results are very different!

did you restart the map and preload the bank? :)
(cause as long the bank is in your cache its no problem to save (nearly) infinite values to it. you must completly restart the map)

i could only preload up to 30 string values, othewise it would crash. (seems like the amount of values you can preload in mp depend on the value type, for example you can store 80 bools but only ~30 strings)
 
Last edited:
Level 6
Joined
Sep 28, 2009
Messages
222
hey guys,

for all of you who havent tested yet or dont have a beta key yet - here is my 7 minutes long video that explains the bank limit and shows what happens if you save to much values to the bank.

its quite long but its worth it :)

please watch 480p + fullscreen!


 
Level 2
Joined
May 15, 2008
Messages
22
So does anybody know if the string length affects the max limit of values you're allowed to store before a game crash?
If it doesn't, then it won't be a problem at all..

But people will have to be careful of scam maps. I can already see people distributing fake maps adding values to bank files of popular maps in order to crash their games. X.X
 
Level 12
Joined
Apr 15, 2008
Messages
1,063
But people will have to be careful of scam maps. I can already see people distributing fake maps adding values to bank files of popular maps in order to crash their games. X.X

Assuming the map protection will work, you could add a simple bank name generator, that will create some random string, based on player name. You could use the same code between your maps, but anyone who wanted to create this scam map would have to figure the algorithm out.
 
Level 6
Joined
Sep 28, 2009
Messages
222
Assuming the map protection will work, you could add a simple bank name generator, that will create some random string, based on player name. You could use the same code between your maps, but anyone who wanted to create this scam map would have to figure the algorithm out.

impossible because when you preload a bank you arent allowed to enter a variable as name.

so yes: its possible to delete all game data you want of every map.
 
Level 9
Joined
Nov 28, 2008
Messages
704
Also impossible because the name of the bank is stored as an XML file.

Just make it long and unique so that people don't accidently overwrite it, you can't really do anything about douchebags.

We could complain to Blizzard to let us use variables in bank names.

Seriously, why cant we? Seems silly.

Maybe it's an anti virus feature...?
 
Status
Not open for further replies.
Top