Adding /commands

PalasX

Member
I wasn't sure if this post should be in Installation, or Troubleshooting. I chose Installation because the code works, and im not asking for help FIXING anything, per se. I would very much appreciate opinions on whether this is the "best" way to implement these things though.

I'm just adding some "missing" commands to the old ship_server.c, specifically to the source from Theodis that compiles nicely on linux. I'll update this thread if/as i add more. If anyone see's something just DRASTICALLY stupid with my code, or would like to offer a better way of doing things, i'm all ears!

/showmats, takes no arguments, shows players used materials, except HP and TP. Can this actually be used in lobby?
C:
      if ( !strcmp ( myCommand, "showmats" ) )
      {
        if ( client->lobbyNum < 0x10 )
          SendB0 ("Can't show mats in the lobby!!!", client);
        else
        {
          char usedmats[45];
          sprintf(usedmats, "ATP:%d MST:%d EVP:%d DFP:%d LCK:%d\n", client->matuse[0], client->matuse[1], client->matuse[2], client->matuse[3], client->matuse[4]);
          SendB0 (usedmats, client);
        }
      }

/resetmymaterials, takes no arguments, resets materials used to 0, except HP and TP. Reduces stats accordingly. Kindly asks player to logoff. Should i force a disconnect here?
Code:
      if ( !strcmp ( myCommand, "resetmymaterials" ) )
      {
        if ( client->lobbyNum < 0x10 )
          SendB0 ("Can't reset mats in the lobby!!!", client);
        else
        {
          client->character.ATP -= ( client->matuse[0] * 2 );
          client->matuse[0] = 0;
          client->character.MST -= ( client->matuse[1] * 2 );
          client->matuse[1] = 0;
          client->character.EVP -= ( client->matuse[2] * 2 );
          client->matuse[2] = 0;
          client->character.DFP -= ( client->matuse[3] * 2 );
          client->matuse[3] = 0;
          client->character.LCK = 10;
          client->matuse[4] = 0;
          char resetmats[60];
          sprintf(resetmats, "Reset Complete: ATP:%d MST:%d EVP:%d DFP:%d LCK:%d\n", client->matuse[0], client->matuse[1], client->matuse[2], client->matuse[3], client->matuse[4]);
          SendB0 (resetmats, client);
          SendB0 ("Please LOGOFF and reconnect!", client);
        }
      }

/modsectionid, takes one argument 0-8, changes your section id. Credit to Tofuman! I wrote this up, and then found his, and it looked much nicer and using the ID_NAMES for the section ids instead of their index values. Hope he doesnt mind me putting it here with the rest of them.
C:
      //Credit: TOFUMAN, who posted this on the Ephiniea forums
      if (!strcmp(myCommand, "modsectionid"))
      {
        if ( myCmdArgs == 0 )
          SendB0 ("Need to specify Section ID, 0-8", client);
        else
        {
          unsigned int sectionID = atoi(myArgs[0]);
          if ((sectionID >= ID_Viridia) && (sectionID <= ID_Whitill))
          {
            client->character.sectionID = sectionID;
            SendB0 ("Please change blocks to reflect changes...", client);
          }
          else
            SendB0 ("Invalid Section ID specified...", client);
        }
      }

***DOESNT WORK CORRECTLY!*** /modcharname, takes one arguement, a new character name up to 10 characters. Keeps changing the character name to some chinese/japanese glyph? Am i not formatting the string correctly? i could REALLY use some advice on this one! Its not SUPER important, since i have unlocked the full dressing room on my PSOBB client, but would be nice to have. THANKS!!!
C:
      if (!strcmp(myCommand, "modcharname"))
      {
        if ( myCmdArgs == 0 )
          SendB0 ("Need to specify new name...", client);
        else
        {
          if ( strlen ( myArgs[0] ) > 10)
          {
            SendB0 ("Name can only be up to 10 characters...", client);
          }
          else
          {
            strcpy ( client->character.name, myArgs[0] );
            SendB0 ("Character name changes to: ", client);
            SendB0 (client->character.name, client);
            SendB0 ("\nPlease change blocks to reflect changes...", client);
          }
        }
      }
 
Last edited:

Soly

Member
I think I'd personally make the reset mat to rebuild the stats instead of subtracting existing mats, but that's just me.

The character name is wchar and also it needs to start with \tE or \tJ (or any others that are unused?)
 

PalasX

Member
Ah, i see what you mean about the wide character! I wondered why a char type would have an extra null byte between ever letter when saved out to SQL.

This version works as expected.
C:
      if (!strcmp(myCommand, "modcharname"))
      {
        if ( myCmdArgs == 0 )
          SendB0 ("Need to specify new name...", client);
        else
        {
          if ( strlen ( myArgs[0] ) > 10)
          {
            SendB0 ("Name can only be up to 10 characters...", client);
          }
          else
          {
            size_t arglen = strlen(myArgs[0]);
            size_t i = 0;
            size_t index = 0;
            for (; i < arglen; i++){
              index = 4 + (i * 2);
              sprintf( &client->character.name[index], "%c", myArgs[0][i] );
              client->character.name[index+1] = 0;
            }
            index = 4 + (arglen *2);
            memset (&client->character.name[index], '\0', 24 - (arglen*2));
            SendB0 ("Character name changes to: ", client);
            SendB0 (Unicode_to_ASCII ((uint16_t*) &client->character.name[4]), client);
            SendB0 ("\nPlease change blocks to reflect changes...\n", client);
          }
        }

Does this look sane to you?

Next i'm going to try to implement /characterbank, to give up to 32 characters per account. If you have any advice on where to start there, or when the server determins which slots to read, i'd appreciate it. I assume that you had to add a new SQL table entry in the account_data table to indicate which was the active set of 4 slots?
 

Soly

Member
Does this look sane to you?
I guess? I mean... if it works.

Next i'm going to try to implement /characterbank, to give up to 32 characters per account. If you have any advice on where to start there, or when the server determins which slots to read, i'd appreciate it. I assume that you had to add a new SQL table entry in the account_data table to indicate which was the active set of 4 slots?
Sadly I can't give you advice on that, that'd depend on how you want to implement it.
The way I'd do it, is probably not an option for you.
 

PalasX

Member
several ideas come to mind. letting the ship server connect to the sql server and run some sort of stored request to shift the character slots around seems fairly straightforward.
"hiding" a single byte in an unused portion of character data to store 1-8 (or 0 thru 7 plus 1) and then using that as a switch to offset the character slot requested (actual char slot = requested char slot * slot_byte).

broadly, how would you go about it? it might be an option for me afterall :)
 
Top