Author Topic: [Coding help] Reading A File?  (Read 1339 times)

I have no real idea how saving / loading files works but I've read every topic I could find with openForWrite and openForRead functions to try and figure out. I've now got the file being written correctly but I can't find out how to apply this to a client. Here's one of the things I tried:

Quote from: The written file
Jervan- 's Achievements

Achievement1   0
Achievement2   0
Achievement3   0
Achievement4   0
Achievement5   0
Achievement6   0
Achievement7   0
Achievement8   0
Achievement9   0
Achievement10   0
Achievement11   0
Achievement12   0
Achievement13   0
Achievement14   0
Achievement15   0
Achievement16   0
Achievement17   0
Achievement18   0
Achievement19   0
Achievement20   0
Achievement21   0
Achievement22   0
Achievement23   0
Achievement24   0
Achievement25   0

Code: [Select]
   function GameConnection::loadAchievements(%client)
   {
      %file = new FileObject();
      %filename = "config/server/Rosemarble/Achievements/" @ %client.getBLID() @ ".txt";
      %file.openForRead(%filename);

      if(!%file)
      {
         error("Erorr with GameConnection::loadAchievements(" @ %client @ " (BLID: " @ %client.getBLID() @ ")) - failed to open file '" @ %filename @ "' for read");
         %file.delete();
         return;
      }
      echo("Loading Achievements for BLID " @ %client.getBLID());

      while(!%file.isEOF())//no idea what it is but every other load has it
      {
         %line = %file.readLine(); //since it's a while statement i hope it loops through each line

switch$(getWord(%line,0))
         {
case "Achievement1":
   %client.achievement1 = getWord(%line,1);
   echo("It read the first line");
case "Achievement2":
   %client.achievement2 = getWord(%line,1);
case "Achievement3":
   %client.achievement3 = getWord(%line,1);
case "Achievement4":
   %client.achievement4 = getWord(%line,1);
case "Achievement5":
   %client.achievement5 = getWord(%line,1);
case "Achievement6":
   %client.achievement6 = getWord(%line,1);
case "Achievement7":
   %client.achievement7 = getWord(%line,1);
case "Achievement8":
   %client.achievement8 = getWord(%line,1);
case "Achievement9":
   %client.achievement9 = getWord(%line,1);
case "Achievement10":
   %client.achievement10 = getWord(%line,1);
case "Achievement11":
   %client.achievement11 = getWord(%line,1);
case "Achievement12":
   %client.achievement12 = getWord(%line,1);
case "Achievement13":
   %client.achievement13 = getWord(%line,1);
case "Achievement14":
   %client.achievement14 = getWord(%line,1);
case "Achievement15":
   %client.achievement15 = getWord(%line,1);
case "Achievement16":
   %client.achievement16 = getWord(%line,1);
case "Achievement17":
   %client.achievement17 = getWord(%line,1);
case "Achievement18":
   %client.achievement18 = getWord(%line,1);
case "Achievement19":
   %client.achievement19 = getWord(%line,1);
case "Achievement20":
   %client.achievement20 = getWord(%line,1);
case "Achievement21":
   %client.achievement21 = getWord(%line,1);
case "Achievement22":
   %client.achievement22 = getWord(%line,1);
case "Achievement23":
   %client.achievement23 = getWord(%line,1);
case "Achievement24":
   %client.achievement24 = getWord(%line,1);
case "Achievement25":
   %client.achievement25 = getWord(%line,1);
   }
      }

      //close file
      %file.close();
      %file.delete();

      %client.scheduleAchievementsSave(1);
   }

https://forum.blockland.us/index.php?topic=151078.0

some things are outdated though; if anyone could chime in what's outdated/not that would be great.

specific things:
  • while(!%file.isEOF())//no idea what it is but every other load has it

%file.isEOF() returns true when you're at the end of the file. files are read line by line in code.

  • %line = %file.readLine(); //since it's a while statement i hope it loops through each line

%file.readLine(); will return the next line in the file. this progresses in order until it reaches EOF. if you try to read a line past the end of the file, it'll error. idk if it will crash BL though.

That was really helpful, fixed it :)

- %file is your file object id, so !%file is always false. If you want to detect a fail to read, use if(!%file.openForRead(...)) instead

- that giant switch is slow and extremely overcomplicated. I'd just write the values (without "achievementx") and increment an index each time which achievement you're currently reading, or find some other more intelligent format.

yeah, switches are slow. port mentioned once it actually runs slower than if statements if you put the getword(%line, 0) inside of the switch() cause every time it checks a case, it runs whatever is in the switch() parens. otherwise, its exactly the same performance as setting up a set of if-statements.

%word = getWord(%line, 0);
switch(%word)
{
    etc...


going with zeblotes idea sacrifices file readability with performance, which can become an issue if you plan on adding a ton of things to this file.

Store them as global vars.
giving:
$Achievement[%achievement,%client.bl_id] = 1;
saving:
export("$Achievement*_" @ %client.bl_id,"config/server/Rosemarble/Achievements/" @ %client.bl_id @ ".cs");
when they leave:
deleteVariables("$Achievement*_" @ %client.bl_id);
loading:
exec("config/server/Rosemarble/Achievements/" @ %client.bl_id @ ".cs");

Runs faster. Shorter and cleaner code. The one and only minuscule difference is that the saves have a larger size.

Runs faster. Shorter and cleaner code. The one and only minuscule difference is that the saves have a larger size.

That depends. If you have a lot of data exec will run hundreds of times slower than parsing a simple text based format.

It was more for my benefit I did it this way, cause if it isn't simple then setting up the input for each achievement will be more of a pain.

It'll probably end up about 50-60 achievements (a lot of which are non-boolean).

I believe what he meant was having the file structured like this:

Code: [Select]
1
0
0
0
5
0
1
26
The first line would set Achievement1, the second line would set Achievement2, etc.

if it's structured like that

for(%i = 0; !%file.isEOF(); %i++) {
   %client.achievement[%i] = %file.readLine();
}

would be fine

He's starting it at 1, so %i = 1; would probably be better.

He's starting it at 1, so %i = 1; would probably be better.
curse habits

I've used all of these suggestions, thanks guys :)

Works perfectly now