Пример #1
0
void log_with_timestamp(io::WriteFile& out, XString line)
{
    if (!line)
    {
        out.put('\n');
        return;
    }
    timestamp_milliseconds_buffer tmpstr;
    stamp_time(tmpstr);
    out.really_put(tmpstr.data(), tmpstr.size());
    out.really_put(": ", 2);
    out.put_line(line);
}
Пример #2
0
int main(int argc, char *argv[])
{
    // These are all the signals we are likely to get
    // The shell handles stop/cont
    signal(SIGTERM, stop_process);
    signal(SIGINT, stop_process);
    signal(SIGQUIT, stop_process);
    signal(SIGABRT, stop_process);

    workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver");

    ZString config = CONFIG;
    if (argc > 1)
        config = ZString(strings::really_construct_from_a_pointer, argv[1], nullptr);
    read_config(config);

    if (chdir(workdir.c_str()) < 0)
    {
        perror("Failed to change directory");
        exit(1);
    }

    PRINTF("Starting:\n");
    PRINTF("* workdir: %s\n",  workdir);
    PRINTF("* login_server: %s\n", login_server);
    PRINTF("* map_server: %s\n", map_server);
    PRINTF("* char_server: %s\n", char_server);
    {
        //make sure all possible file descriptors are free for use by the servers
        //if there are file descriptors higher than the max open from before the limit dropped, that's not our problem
        int fd = sysconf(_SC_OPEN_MAX);
        while (--fd > 2)
           if (close(fd) == 0)
               FPRINTF(stderr, "close fd %d\n", fd);
        fd = open("/dev/null", O_RDWR);
        if (fd < 0)
        {
            perror("open /dev/null");
            exit(1);
        }
        dup2(fd, 0);
        dup2(fd, 1);
        close(fd);
    }
    while (1)
    {
        // write stuff to stderr
        timestamp_seconds_buffer timestamp;
        stamp_time(timestamp);

        if (!pid_login)
        {
            pid_login = start_process(login_server);
            FPRINTF(stderr, "[%s] forked login server: %lu\n",
                    timestamp, static_cast<unsigned long>(pid_login));
        }
        if (!pid_char)
        {
            pid_char = start_process(char_server);
            FPRINTF(stderr, "[%s] forked char server: %lu\n",
                    timestamp, static_cast<unsigned long>(pid_char));
        }
        if (!pid_map)
        {
            pid_map = start_process(map_server);
            FPRINTF(stderr, "[%s] forked map server: %lu\n",
                    timestamp, static_cast<unsigned long>(pid_map));
        }
        pid_t dead = wait(NULL);
        if (dead == -1)
        {
            perror("Failed to wait for child");
            exit(1);
        }
        if (pid_login == dead)
            pid_login = 0;
        if (pid_char == dead)
            pid_char = 0;
        if (pid_map == dead)
            pid_map = 0;
    }
}
Пример #3
0
/*==========================================
 * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
 *------------------------------------------
 */
static
int chrif_accountban(Session *, const Packet_Fixed<0x2b14>& fixed)
{
    dumb_ptr<map_session_data> sd;

    AccountId acc = fixed.account_id;
    if (battle_config.etc_log)
        PRINTF("chrif_accountban %d.\n"_fmt, acc);
    sd = map_id2sd(account_to_block(acc));
    if (acc)
    {
        if (sd != nullptr)
        {
            sd->login_id1++;    // change identify, because if player come back in char within the 5 seconds, he can change its characters
            if (fixed.ban_not_status == 0)
            {                   // 0: change of statut, 1: ban
                switch (static_cast<time_t>(fixed.status_or_ban_until))
                {               // status or final date of a banishment
                    case 1:    // 0 = Unregistered ID
                        clif_displaymessage(sd->sess,
                                             "Your account has 'Unregistered'."_s);
                        break;
                    case 2:    // 1 = Incorrect Password
                        clif_displaymessage(sd->sess,
                                             "Your account has an 'Incorrect Password'..."_s);
                        break;
                    case 3:    // 2 = This ID is expired
                        clif_displaymessage(sd->sess,
                                             "Your account has expired."_s);
                        break;
                    case 4:    // 3 = Rejected from Server
                        clif_displaymessage(sd->sess,
                                             "Your account has been rejected from server."_s);
                        break;
                    case 5:    // 4 = You have been blocked by the GM Team
                        clif_displaymessage(sd->sess,
                                             "Your account has been blocked by the GM Team."_s);
                        break;
                    case 6:    // 5 = Your Game's EXE file is not the latest version
                        clif_displaymessage(sd->sess,
                                             "Your Game's EXE file is not the latest version."_s);
                        break;
                    case 7:    // 6 = Your are Prohibited to log in until %s
                        clif_displaymessage(sd->sess,
                                             "Your account has been prohibited to log in."_s);
                        break;
                    case 8:    // 7 = Server is jammed due to over populated
                        clif_displaymessage(sd->sess,
                                             "Server is jammed due to over populated."_s);
                        break;
                    case 9:    // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
                        clif_displaymessage(sd->sess,
                                             "Your account has not more authorised."_s);
                        break;
                    case 100:  // 99 = This ID has been totally erased
                        clif_displaymessage(sd->sess,
                                             "Your account has been totally erased."_s);
                        break;
                    default:
                        clif_displaymessage(sd->sess,
                                             "Your account has not more authorised."_s);
                        break;
                }
            }
            else if (fixed.ban_not_status == 1)
            {
                // 0: change of statut, 1: ban
                const TimeT timestamp = fixed.status_or_ban_until;    // status or final date of a banishment
                timestamp_seconds_buffer buffer;
                stamp_time(buffer, &timestamp);
                AString tmpstr = STRPRINTF("Your account has been banished until %s"_fmt, buffer);
                clif_displaymessage(sd->sess, tmpstr);
            }
            clif_setwaitclose(sd->sess); // forced to disconnect for the change
        }
    }
    else
    {
        if (sd != nullptr)
            PRINTF("chrif_accountban failed - player not online.\n"_fmt);
    }

    return 0;
}
Пример #4
0
void fread_news( NEWS * news, FILE * fp )
{
   const char *word;
   bool fMatch;

   for( ;; )
   {
      word = feof( fp ) ? "End" : fread_word( fp );
      fMatch = FALSE;

      switch ( UPPER( word[0] ) )
      {
         case '*':
            fread_to_eol( fp );
            break;

         case 'D':
            KEY( "Date", news->date, fread_string( fp ) );
            break;

         case 'E':
            if( !str_cmp( word, "END" ) )
            {
               if( !news->name )
                  news->name = STRALLOC( "Unknown" );

               if( !news->date )
               {
                  news->date = STRALLOC( stamp_time(  ) );
               }

               if( !news->title )
                  news->title = STRALLOC( "News Post" );

               if( news->type <= -1 )
                  news->type = 0;
               return;
            }
            break;

         case 'N':
            KEY( "Name", news->name, fread_string( fp ) );
            break;

         case 'P':
            if( !str_cmp( word, "POST" ) )
            {
               fMatch = TRUE;
               news->post = fread_string( fp );
               break;
            }
            break;

         case 'T':
            KEY( "Title", news->title, fread_string( fp ) );
            KEY( "Type", news->type, fread_number( fp ) );
            break;
      }

      if( !fMatch )
         bug( "fread_news(): no match: %s", word );
   }
}
Пример #5
0
/* olc editnews command */
void do_editnews( CHAR_DATA* ch, const char* argument)
{
   char arg[MAX_INPUT_LENGTH];

   if( IS_NPC( ch ) || !IS_IMMORTAL( ch ) )
   {
      send_to_char( "Huh?\r\n", ch );
      return;
   }

   set_char_color( AT_GREEN, ch );

   switch ( ch->substate )
   {
      default:
         break;

      case SUB_NEWS_POST:
      {
         NEWS *news = NULL;

         news = ( NEWS * ) ch->dest_buf;
         STRFREE( news->post );
         news->post = copy_buffer( ch );
         stop_editing( ch );
         ch->substate = ch->tempnum;
         renumber_news(  );
         save_news(  );
         return;
      }
         break;

      case SUB_NEWS_EDIT:
      {
         NEWS *news = NULL;

         news = ( NEWS * ) ch->dest_buf;
         STRFREE( news->post );
         news->post = copy_buffer( ch );
         stop_editing( ch );
         ch->substate = ch->tempnum;
         renumber_news(  );
         save_news(  );
         return;
      }
         break;
   }

   argument = one_argument( argument, arg );

   if( arg[0] == '\0' )
   {
      send_to_char( "Syntax: editnews addtype <name>\r\n"
                    "        editnews addnews <type> <subject>\r\n"
                    "        editnews removetype <number>\r\n"
                    "        editnews removenews <type> <number>\r\n"
                    "        editnews edittype <field> <value>\r\n"
                    "        editnews editnews <type> <number> <new subject [optional]>\r\n"
                    " Fields being one of the following:\r\n" " name header cmd_name level\r\n", ch );
      return;
   }

   if( !str_cmp( arg, "save" ) )
   {
      renumber_news(  );
      save_news(  );
      send_to_char( "News saved.\r\n", ch );
      return;
   }

   if( !str_cmp( arg, "addtype" ) )
   {
      NEWS_TYPE *type = NULL;

      if( argument[0] == '\0' )
      {
         send_to_char( "Syntax: editnews addtype <name>\r\n", ch );
         return;
      }

      if( top_news_type >= NEWS_MAX_TYPES )
      {
         send_to_char( "There are too many news types.\r\n", ch );
         return;
      }

      CREATE( type, NEWS_TYPE, 1 );
      type->name = STRALLOC( argument );
      type->cmd_name = STRALLOC( argument );
      type->vnum = top_news_type++;
      type->level = -1;

      news_command_table[type->vnum] = STRALLOC( type->cmd_name );

      LINK( type, first_news_type, last_news_type, next, prev );
      ch_printf( ch, "Newstype '%s' created.\r\n", argument );
      return;
   }

   if( !str_cmp( arg, "removetype" ) )
   {
      NEWS_TYPE *type = NULL;
      NEWS *news = NULL, *news_next;

      if( argument[0] == '\0' )
      {
         send_to_char( "Syntax: editnews removetype <name>\r\n", ch );
         return;
      }

      if( ( type = figure_type( argument ) ) == NULL )
      {
         send_to_char( "Invaild newstype.\r\n", ch );
         return;
      }

      UNLINK( type, first_news_type, last_news_type, next, prev );
      STRFREE( type->name );
      STRFREE( type->header );
      STRFREE( type->cmd_name );
      STRFREE( news_command_table[type->vnum] );
      STRFREE( news_command_table[type->level] );

      for( news = type->first_news; news; news = news_next )
      {
         news_next = news->next;

         UNLINK( news, type->first_news, type->last_news, next, prev );
         STRFREE( news->name );
         STRFREE( news->title );
         STRFREE( news->date );
         STRFREE( news->post );
         DISPOSE( news );
      }

      DISPOSE( type );
      --top_news_type;
      renumber_news(  );
      save_news(  );
      ch_printf( ch, "Newstype '%s' removed.\r\n", argument );
      return;
   }

   if( !str_cmp( arg, "edittype" ) )
   {
      char arg2[MAX_INPUT_LENGTH];
      char arg3[MAX_INPUT_LENGTH];
      NEWS_TYPE *type = NULL;

      argument = one_argument( argument, arg2 );
      argument = one_argument( argument, arg3 );
      if( arg2[0] == '\0' || arg3[0] == '\0' )
      {
         send_to_char( "Syntax: editnews edittype <type> <field> <value>\r\n", ch );
         send_to_char( "Fields being one of the following:\r\n" "name header cmd_name level\r\n", ch );
         return;
      }

      if( ( type = figure_type( arg2 ) ) == NULL )
      {
         send_to_char( "Invalid newstype.\r\n", ch );
         return;
      }

      if( !str_cmp( arg3, "cmd_name" ) )
      {
         type->cmd_name = STRALLOC( argument );
         news_command_table[type->vnum] = STRALLOC( type->cmd_name );
         send_to_char( "Cmd_name set.\r\n", ch );
         save_news(  );
         return;
      }
      else if( !str_cmp( arg3, "name" ) )
      {
         type->name = STRALLOC( argument );
         send_to_char( "Name set.\r\n", ch );
         save_news(  );
         return;
      }
      else if( !str_cmp( arg3, "level" ) )
      {
         if( argument[0] == '\0' )
         {
            ch_printf( ch, "%d\r\n", type->level );
            return;
         }
         else
            type->level = atoi( argument );
         send_to_char( "Level set.\r\n", ch );
         save_news(  );
         return;
      }
      else
      {
         send_to_char( "Syntax: editnews edittype <type> <field> <value>\r\n", ch );
         send_to_char( "Fields being one of the following:\r\n" "name header cmd_name level\r\n", ch );
         return;
      }
   }

   if( !str_cmp( arg, "addnews" ) )
   {
      char arg2[MAX_INPUT_LENGTH];
      NEWS_TYPE *type = NULL;
      NEWS *news = NULL;

      argument = one_argument( argument, arg2 );

      if( arg2[0] == '\0' || argument[0] == '\0' )
      {
         send_to_char( "Syntax: editnews addnews <type> <subject>\r\n", ch );
         return;
      }

      if( ( type = figure_type( arg2 ) ) == NULL )
      {
         send_to_char( "Invaild newstype. Use 'newstypes' to get a valid listing.\r\n", ch );
         return;
      }

      CREATE( news, NEWS, 1 );
      news->title = STRALLOC( argument );
      news->name = STRALLOC( ch->name );
      news->date = STRALLOC( stamp_time(  ) );
      news->post = STRALLOC( "" );

      /*
       * pop character into a writing buffer 
       */
      if( ch->substate == SUB_REPEATCMD )
         ch->tempnum = SUB_REPEATCMD;
      else
         ch->tempnum = SUB_NONE;

      ch->substate = SUB_NEWS_POST;
      ch->dest_buf = news;
      start_editing( ch, news->post );
      LINK( news, type->first_news, type->last_news, next, prev );
      return;
   }

   if( !str_cmp( arg, "editnews" ) )
   {
      char arg2[MAX_INPUT_LENGTH];
      char arg3[MAX_INPUT_LENGTH];
      NEWS *news = NULL;
      NEWS_TYPE *type = NULL;

      argument = one_argument( argument, arg2 );
      argument = one_argument( argument, arg3 );
      if( arg2[0] == '\0' )
      {
         send_to_char( "Syntax: editnews editnews <type> <number> <new subject [optional]>\r\n", ch );
         return;
      }

      /*
       * changed for new -newstype- indexing - 5/5/02 
       */
      if( ( type = figure_type( arg2 ) ) == NULL )
      {
         send_to_char( "Invalid newstype. Use 'newstypes' to get a valid listing.\r\n", ch );
         return;
      }

      if( ( news = grab_news( type, arg3 ) ) == NULL )
      {
         pager_printf_color( ch, "That's not a valid news number.\r\nUse '%s' to view the valid numbers.\r\n",
                             type->cmd_name );
         return;
      }

      /*
       * a changed title 
       */
      if( argument[0] != '\0' )
         news->title = STRALLOC( argument );

      /*
       * new date news was edited 
       */
      news->date = STRALLOC( stamp_time(  ) );
      /*
       * pop character into a writing buffer 
       */
      if( ch->substate == SUB_REPEATCMD )
         ch->tempnum = SUB_REPEATCMD;
      else
         ch->tempnum = SUB_NONE;

      ch->substate = SUB_NEWS_EDIT;
      ch->dest_buf = news;
      start_editing( ch, news->post );
      return;
   }

   if( !str_cmp( arg, "removenews" ) )
   {
      char arg2[MAX_INPUT_LENGTH];
      NEWS *news = NULL;
      NEWS_TYPE *type = NULL;

      argument = one_argument( argument, arg2 );
      if( argument[0] == '\0' || arg2[0] == '\0' )
      {
         send_to_char( "Syntax: editnews remove <number>\r\n", ch );
         return;
      }

      /*
       * changed for new -newstype- indexing - 5/5/02 
       */
      if( ( type = figure_type( arg2 ) ) == NULL )
      {
         send_to_char( "Invalid newstype. Use 'newstypes' to get a valid listing.\r\n", ch );
         return;
      }

      if( ( news = grab_news( type, argument ) ) == NULL )
      {
         send_to_char( "Type 'news' to gain a list of the news numbers.\r\n", ch );
         return;
      }

      UNLINK( news, type->first_news, type->last_news, next, prev );
      STRFREE( news->name );
      STRFREE( news->title );
      STRFREE( news->date );
      STRFREE( news->post );
      DISPOSE( news );
      renumber_news(  );
      save_news(  );
      send_to_char( "News item removed.\r\n", ch );
      return;
   }
}