Jump to content

Lemongrass

Developer
  • Posts

    545
  • Joined

  • Last visited

  • Days Won

    15

Posts posted by Lemongrass

  1. I did it by using a SELECT INTO statement.

     

    For example:

    INSERT INTO `item_db_re` SELECT * FROM `item_db`;
    

     

    But notice that the column count and column types should be the same, which is not a problem for most tables.

  2. Schau mal nach ob dein Setup ein HKCU oder HKLM. Lag früher öfter daran. ;)

    Und nur so als Tipp fürs nächste Mal, wenn die Fragen ordentlich formuliert sind und das Problem genauer beschrieben, ist man vielleicht eher angeregt dir zu helfen.

     

    Bei einem Topic Titel wie "hmn ro fersten ist so klein.." wohl eher nicht.

  3. conf/char_athena.conf

     

    //===================================
    // Pincode system
    //===================================
    // NOTE: Requires client 2011-03-09aragexeRE or newer.
    // A window is opened before you can select your character and you will have to enter a pincode by using only your mouse.
    // Default: yes
    pincode_enabled: yes
    

     

    Set "pincode_enabled" to "no".

  4. Thats strange then because there are packets for deleting and a must change packet.

    The problem with sending state 7 directly when you come to char select is that you dont have to enter the pin if you dont click that button. I think I know a workarround for this.

    So is anyone against commiting this?

  5. Howdy guys,

     

    today I worked on something odd and nerving. The pincode system. I got help from Yommy for some of the packets and the decrypt function.

    But basically I want someone to review my code and additionally I would need some further information about the system.

     

    Required infos:

    • How often does a user on kRO have to change his PIN code?
    • The PIN code system checks for the KSSN on AEGIS, I would say we leave that out or do a birthday check instead. Which would mess up the client translation, because that one says "You cant use your KSSN".
    • How can a user delete his PIN?
    • When is the button for the pincode system displayed in char select? Send state 7 to find it there.
    • Has anybody got an UI translation for that system?
    • How often can a user enter his PIN code wrong and what happens then?

    Thanks in advance and have fun testing.

     

     

    Index: conf/char_athena.conf
    ===================================================================
    --- conf/char_athena.conf    (revision 17179)
    +++ conf/char_athena.conf    (working copy)
    @@ -159,4 +159,16 @@
     // What folder the DB files are in (item_db.txt, etc.)
     db_path: db
     
    +// Pincode system
    +// A window is opened before you can select your character and you will have to enter a pincode by using only your mouse
    +// 0: disabled
    +// 1: enabled
    +pincode_enabled: 0
    +
    +// How often does a user have to change his pincode?
    +// Default: 1209600 (2 weeks)
    +// 0: never
    +// X: every X seconds
    +pincode_changetime: 1209600
    +
     import: conf/import/char_conf.txt
    Index: sql-files/upgrades/upgrade_svn17179.sql
    ===================================================================
    --- sql-files/upgrades/upgrade_svn17179.sql    (revision 0)
    +++ sql-files/upgrades/upgrade_svn17179.sql    (working copy)
    @@ -0,0 +1,2 @@
    +ALTER TABLE `login` ADD COLUMN `pincode` varchar(4) NOT NULL DEFAULT '';
    +ALTER TABLE `login` ADD COLUMN `pincode_change` int(11) unsigned NOT NULL DEFAULT '0';
    \ No newline at end of file
    Index: src/char/char.c
    ===================================================================
    --- src/char/char.c    (revision 17179)
    +++ src/char/char.c    (working copy)
    @@ -131,6 +131,9 @@
         uint8 clienttype;
         char new_name[NAME_LENGTH];
         char birthdate[10+1];  // YYYY-MM-DD
    +    char pincode[4+1];
    +    uint16 pincode_seed;
    +    time_t pincode_change;
     };
     
     int max_connect_user = -1;
    @@ -141,6 +144,23 @@
     int start_armor = 2301;
     int guild_exp_rate = 100;
     
    +// Pincode system
    +#define PINCODE_OK 0
    +#define PINCODE_ASK 1
    +#define PINCODE_NOTSET 2
    +#define PINCODE_EXPIRED 3
    +#define    PINCODE_WRONG 8
    +
    +int pincode_enabled = PINCODE_OK; // PINCODE_OK = off, PINCODE_ASK = on
    +int pincode_changetime =  14 * 24 * 60 * 60; // every 14 days
    +
    +void pincode_check( int fd, struct char_session_data* sd );
    +void pincode_change( int fd, struct char_session_data* sd );
    +void pincode_setnew( int fd, struct char_session_data* sd );
    +void pincode_sendstate( int fd, struct char_session_data* sd, uint16 state );
    +void pincode_notifylogin( int account_id, char* pin );
    +void pincode_decrypt( unsigned long userSeed, char* pin );
    +
     //Custom limits for the fame lists. [Skotlex]
     int fame_list_size_chemist = MAX_FAME_LIST;
     int fame_list_size_smith = MAX_FAME_LIST;
    @@ -2147,7 +2167,7 @@
             break;
     
             case 0x2717: // account data
    -            if (RFIFOREST(fd) < 63)
    +            if (RFIFOREST(fd) < 68)
                     return 0;
     
                 // find the authenticated session with this account id
    @@ -2165,6 +2185,7 @@
                     } else if ( !sd->char_slots )/* no value aka 0 in sql */
                         sd->char_slots = MAX_CHARS;/* cap to maximum */
                     safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
    +                safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
                     ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
                     // continued from char_auth_ok...
                     if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
    @@ -2179,18 +2200,28 @@
                         // send characters to player
                         mmo_char_send006b(i, sd);
     #if PACKETVER >=  20110309
    -                    // PIN code system, disabled
    -                    WFIFOHEAD(i, 12);
    -                    WFIFOW(i, 0) = 0x08B9;
    -                    WFIFOW(i, 2) = 0;
    -                    WFIFOW(i, 4) = 0;
    -                    WFIFOL(i, 6) = sd->account_id;
    -                    WFIFOW(i, 10) = 0;
    -                    WFIFOSET(i, 12);
    +                    if( pincode_enabled ){
    +                        // PIN code system enabled
    +                        if( strlen( sd->pincode ) <= 0 ){
    +                            // No PIN code has been set yet
    +                            pincode_sendstate( i, sd, PINCODE_NOTSET );
    +                        }else{
    +                            if( !pincode_changetime && sd->pincode_change > time(NULL) ){
    +                                // Ask user for his PIN code
    +                                pincode_sendstate( i, sd, PINCODE_ASK );
    +                            }else{
    +                                // User hasnt changed his PIN code too long
    +                                pincode_sendstate( i, sd, PINCODE_EXPIRED );
    +                            }
    +                        }
    +                    }else{
    +                        // PIN code system, disabled
    +                        pincode_sendstate( i, sd, PINCODE_OK );
    +                    }
     #endif
                     }
                 }
    -            RFIFOSKIP(fd,63);
    +            RFIFOSKIP(fd,68);
             break;
     
             // login-server alive packet
    @@ -4188,6 +4219,50 @@
             }
             return 0; // avoid processing of followup packets here
     
    +        // checks the entered pin
    +        case 0x8b8:
    +            pincode_check( fd, sd );
    +        break;
    +
    +        // request for security window?
    +        case 0x8c5:
    +            if( RFIFOREST(fd) < 6 )
    +                return 0;
    +
    +            if( RFIFOL(fd,2) != sd->account_id )
    +                break;
    +
    +            // Obviously we should do something here. Open up pincode dialog?
    +            pincode_sendstate( fd, sd, 0 );
    +
    +            RFIFOSKIP(fd,6);
    +        break;
    +
    +        // pincode change request
    +        case 0x8be:
    +            if( RFIFOREST(fd) < 14 )
    +                return 0;
    +
    +            if( RFIFOL(fd,2) != sd->account_id )
    +                break;
    +
    +            pincode_change( fd, sd );
    +
    +            RFIFOSKIP(fd,14);
    +        break;
    +
    +        case 0x8ba:
    +            if( RFIFOREST(fd) < 10 )
    +                return 0;
    +
    +            if( RFIFOL(fd,2) != sd->account_id )
    +                break;
    +
    +            pincode_setnew( fd, sd );
    +
    +            RFIFOSKIP(fd,10);
    +        break;
    +
             // unknown packet received
             default:
                 ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
    @@ -4369,6 +4444,102 @@
     }
     
     //------------------------------------------------
    +//Pincode system
    +//------------------------------------------------
    +void pincode_check( int fd, struct char_session_data* sd ){
    +    char pin[5] = "\0\0\0\0";
    +    strncpy((char*)pin, (char*)RFIFOP(fd, 6), 4+1);
    +
    +    pincode_decrypt(sd->pincode_seed, pin );
    +
    +    if( strcmp( sd->pincode, pin ) == 0 ){
    +        pincode_sendstate( fd, sd, PINCODE_OK );
    +    }else{
    +        pincode_sendstate( fd, sd, PINCODE_WRONG );
    +    }
    +}
    +
    +void pincode_change( int fd, struct char_session_data* sd ){
    +    char oldpin[5] = "\0\0\0\0";
    +    char newpin[5] = "\0\0\0\0";
    +
    +    strncpy(oldpin, (char*)RFIFOP(fd,6), 4+1);
    +    pincode_decrypt(sd->pincode_seed,oldpin);
    +
    +    if( strcmp( sd->pincode, oldpin ) != 0 ){
    +        pincode_sendstate( fd, sd, PINCODE_WRONG );
    +        return;
    +    }
    +
    +    strncpy(newpin, (char*)RFIFOP(fd,10), 4+1);
    +    pincode_decrypt(sd->pincode_seed,newpin);
    +
    +    pincode_notifylogin( sd->account_id, newpin );
    +
    +    pincode_sendstate( fd, sd, PINCODE_OK );
    +}
    +
    +void pincode_setnew( int fd, struct char_session_data* sd ){
    +    char newpin[5] = "\0\0\0\0";
    +
    +    strncpy(newpin, (char*)RFIFOP(fd,6), 4+1);
    +    pincode_decrypt(sd->pincode_seed,newpin);
    +
    +    pincode_notifylogin( sd->account_id, newpin );
    +
    +    pincode_sendstate( fd, sd, PINCODE_OK );
    +}
    +
    +// 0 = disabled / pin is correct
    +// 1 = ask for pin - client sends 0x8b8
    +// 2 = create new pin - client sends 0x8ba
    +// 3 = pin must be changed - client 0x8be
    +// 4 = create new pin ?? - client sends 0x8ba
    +// 5 = client shows msgstr(1896)
    +// 6 = client shows msgstr(1897) Unable to use your KSSN number
    +// 7 = char select window shows a button - client sends 0x8c5
    +// 8 = pincode was incorrect
    +void pincode_sendstate( int fd, struct char_session_data* sd, uint16 state ){
    +    WFIFOHEAD(fd, 12);
    +    WFIFOW(fd, 0) = 0x8b9;
    +    WFIFOL(fd, 2) = sd->pincode_seed = rand() % 0xFFFF;
    +    WFIFOL(fd, 6) = sd->account_id;
    +    WFIFOW(fd,10) = state;
    +    WFIFOSET(fd,12);
    +}
    +
    +void pincode_notifylogin( int account_id, char* pin ){
    +    WFIFOHEAD(login_fd,15);
    +    WFIFOW(login_fd,0) = 0x2738;
    +    WFIFOL(login_fd,2) = account_id;
    +    strncpy( (char*)WFIFOP(login_fd,6), pin, 5 );
    +    WFIFOL(login_fd,11) = pincode_changetime;
    +    WFIFOSET(login_fd,15);
    +}
    +
    +void pincode_decrypt( unsigned long userSeed, char* pin ){
    +    int i, pos;
    +    char tab[10] = {0,1,2,3,4,5,6,7,8,9};
    +    unsigned long multiplier = 0x3498, baseSeed = 0x881234;
    +
    +    for( i = 1; i < 10; i++ ){
    +        userSeed = baseSeed + userSeed * multiplier;
    +        pos = userSeed % (i + 1);
    +        if( i != pos ){
    +            tab[i] ^= tab[pos];
    +            tab[pos] ^= tab[i];
    +            tab[i] ^= tab[pos];
    +        }
    +    }
    +    
    +    for( i = 0; i < 4; i++ ){
    +        pin[i] = tab[pin[i]- '0'];
    +    }
    +
    +    sprintf(pin, "%d%d%d%d", pin[0], pin[1], pin[2], pin[3]);
    +}
    +
    +//------------------------------------------------
     //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
     //replies/disconnect the player we tried to kick. [Skotlex]
     //------------------------------------------------
    @@ -4691,6 +4862,10 @@
                 }
             } else if (strcmpi(w1, "guild_exp_rate") == 0) {
                 guild_exp_rate = atoi(w2);
    +        } else if (strcmpi(w1, "pincode_enabled") == 0) {
    +            pincode_enabled = atoi(w2);
    +        } else if (strcmpi(w1, "pincode_changetime") == 0) {
    +            pincode_changetime = atoi(w2);
             } else if (strcmpi(w1, "import") == 0) {
                 char_config_read(w2);
             }
    Index: src/char/inter.c
    ===================================================================
    --- src/char/inter.c    (revision 17179)
    +++ src/char/inter.c    (working copy)
    @@ -387,7 +387,7 @@
         account_id = atoi(query);
     
         if (account_id < START_ACCOUNT_NUM) {    // is string
    -        if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `char` WHERE `name` LIKE '%s' LIMIT 10", query_esq)
    +        if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq)
                     || Sql_NumRows(sql_handle) == 0 ) {
                 if( Sql_NumRows(sql_handle) == 0 ) {
                     inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
    Index: src/login/account.h
    ===================================================================
    --- src/login/account.h    (revision 17179)
    +++ src/login/account.h    (working copy)
    @@ -50,6 +50,8 @@
         char lastlogin[24];     // date+time of last successful login
         char last_ip[16];       // save of last IP of connection
         char birthdate[10+1];   // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
    +    char pincode[4+1];        // pincode system
    +    time_t pincode_change;    // (timestamp): last time of pincode change
         int account_reg2_num;
         struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
     };
    Index: src/login/account_sql.c
    ===================================================================
    --- src/login/account_sql.c    (revision 17179)
    +++ src/login/account_sql.c    (working copy)
    @@ -522,7 +522,7 @@
     
         // retrieve login entry for the specified account
         if( SQL_ERROR == Sql_Query(sql_handle,
    -        "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots` FROM `%s` WHERE `account_id` = %d",
    +        "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change` FROM `%s` WHERE `account_id` = %d",
             db->account_db, account_id )
         ) {
             Sql_ShowDebug(sql_handle);
    @@ -549,6 +549,8 @@
         Sql_GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
         Sql_GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate));
         Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = atoi(data);
    +    Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
    +    Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data);
     
         Sql_FreeResult(sql_handle);
     
    @@ -597,7 +599,7 @@
         if( is_new )
         {// insert into account table
             if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
    -            "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    +            "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                 db->account_db)
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_INT,    (void*)&acc->account_id,      sizeof(acc->account_id))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING, (void*)acc->userid,           strlen(acc->userid))
    @@ -613,6 +615,8 @@
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip,         strlen(acc->last_ip))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate,       strlen(acc->birthdate))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_UCHAR,  (void*)&acc->char_slots,      sizeof(acc->char_slots))
    +        ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_STRING, (void*)&acc->pincode,           sizeof(acc->pincode))
    +        ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG,    (void*)&acc->pincode_change, sizeof(acc->pincode_change))
             ||  SQL_SUCCESS != SqlStmt_Execute(stmt)
             ) {
                 SqlStmt_ShowDebug(stmt);
    @@ -621,7 +625,7 @@
         }
         else
         {// update account table
    -        if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
    +        if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_STRING, (void*)acc->userid,           strlen(acc->userid))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING, (void*)acc->pass,             strlen(acc->pass))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  2, SQLDT_ENUM,   (void*)&acc->sex,             sizeof(acc->sex))
    @@ -635,6 +639,8 @@
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip,         strlen(acc->last_ip))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate,       strlen(acc->birthdate))
             ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_UCHAR,  (void*)&acc->char_slots,      sizeof(acc->char_slots))
    +        ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_STRING, (void*)&acc->pincode,           strlen(acc->pincode))
    +        ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_LONG,   (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
             ||  SQL_SUCCESS != SqlStmt_Execute(stmt)
             ) {
                 SqlStmt_ShowDebug(stmt);
    Index: src/login/login.c
    ===================================================================
    --- src/login/login.c    (revision 17179)
    +++ src/login/login.c    (working copy)
    @@ -562,6 +562,7 @@
                 uint8 char_slots = 0;
                 int group_id = 0;
                 char birthdate[10+1] = "";
    +            char pincode[4+1] = "";
     
                 int account_id = RFIFOL(fd,2);
                 RFIFOSKIP(fd,6);
    @@ -574,9 +575,11 @@
                     group_id = acc.group_id;
                     char_slots = acc.char_slots;
                     safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
    +                safestrncpy(pincode, acc.pincode, sizeof(pincode));
    +                acc.pincode_change = 0;
                 }
     
    -            WFIFOHEAD(fd,63);
    +            WFIFOHEAD(fd,68);
                 WFIFOW(fd,0) = 0x2717;
                 WFIFOL(fd,2) = account_id;
                 safestrncpy((char*)WFIFOP(fd,6), email, 40);
    @@ -584,7 +587,8 @@
                 WFIFOB(fd,50) = (unsigned char)group_id;
                 WFIFOB(fd,51) = char_slots;
                 safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
    -            WFIFOSET(fd,63);
    +            safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
    +            WFIFOSET(fd,68);
             }
             break;
     
    @@ -910,6 +914,27 @@
                 RFIFOSKIP(fd,2);
             break;
     
    +        case 0x2738: //Change PIN Code for a account
    +            if( RFIFOREST(fd) < 15 )
    +                return 0;
    +
    +        {
    +            struct mmo_account acc;
    +
    +            if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) )
    +            {
    +                strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 );
    +                acc.pincode_change = RFIFOL(fd,11);
    +                if( acc.pincode_change > 0 ){
    +                    acc.pincode_change += time( NULL );
    +                }
    +                accounts->save(accounts, &acc);
    +            }
    +
    +            RFIFOSKIP(fd,15);
    +        }
    +        break;
    +
             default:
                 ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
                 set_eof(fd);
    @@ -961,6 +986,8 @@
         safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin));
         safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip));
         safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
    +    safestrncpy(acc.pincode, "", sizeof(acc.pincode));
    +    acc.pincode_change = 0;
     
         acc.char_slots = 0;
    

    pincode_system.patch

    • Upvote 3
  6. Das Problem liegt eher darin, dass rAthena offiziell die Packete nicht unterstützt, die nicht von kRO kommen und somit bleibt dir eigentlich garnichts anderes übrig. Höchstens du kennst dich sehr sehr gut damit aus, aber dann würdest du schätze ich mal nicht so eine Frage stellen.

  7. Dazu würd ich dir empfehlen einfach mal das Script zum Endless Tower anzusehen.

     

    Prinzipiell funktioniert das ganze mit OnKill-Events in denen du mitzählen kannst wieviele Monster schon tod sind und wenn keine mehr übrig sind einfach einen zuerst versteckten Warp NPC wieder freischalten.

    • Upvote 1
  8. Also da es mich sehr gewundert hat, hab ich das ganze gerade durchprobiert und bei mir bleibt das Item ein Rentalitem.

     

    Hier meine Test NPCs:

     

    gonryun,159,117,4    script    Refiner    113,{
        successrefitem EQI_HAND_L;
        mes "refined";
        close;
    }
    
    gonryun,165,117,4    script    Renter    113,{
        rentitem 1701, 60 * 5;
    }
    
  9. Since you did not really specify your problem I tried to sort it out(without testing it on a server):

     

    You are referring to a NPC ID with "GvG::", but you did not declare this ID. So the mapserver can not find the NPC.

     

    Change the declaration line as follows:

     

     

    prontera,127,213,4    script    Guild_Emperium::GvG    722,{
    

     

    Here is a formated and somewhat corrected version. Try it out and if there still are problems, please describe them a little bit better.

     

    prontera,127,213,4    script    Guild_Emperium::GvG    722,{
        if( @breakgname$ != "" ) {
                flagemblem @breakgnameid;
        }
        switch( select( "Participate:Guild Master:Guild Breaker" ) ){
            case 1:
                if( agitcheck() == 1 ){
                    mes "War of Emperium is currently active.";
                    close;
                }
                
                if( getcharid(2) == 0 ){
                    mes "You should be in a guild;";
                    close;
                }
                
                if( @breakgname$ && getcharid(2) == @breakgnameid ){
                    close2;
                    warp "pvp_y_1-1", 155, 195;
                    end;
                }
                
                close2;
                warp "pvp_y_1-1", 279, 204;
                dispbottom "The emperium is located at the center of the map.";
                end;
            
            case 2:
                if( @breakgname$ == "" ){
                    mes "No record yet.";
                    close;
                }else{
                    mes "The Guild Master of ^ff0000" + @breakgname$ + "^000000 Guild is:";
                    mes "^ff0000" + GetGuildMaster( @breakgnameid )+"^000000";
                    close;
                }
            
            case 3:
                if( @breakgname$ == "" ){
                    mes "No record yet.";
                    close;
                }else{
                    mes "The breaker of ^ff0000" + @breakgname$ + "^000000 Guild is:";
                    mes "^ff0000" + @breakeremp$ + "^000000";
                    close;
                }
        }
        
    OnInit:
        monster "pvp_y_1-1", 155, 195, "Emperium", 1288, 1, "GvG::OnBreakEmp";
        end;
    
    OnBreakEmp:
        set @breakeremp$, "" + strcharinfo(0);
        set @breakgnameid, getcharid( 2 );
        set @breakgname$, getguildname( @breakgnameid );
        maprespawnguildid "pvp_y_1-1", @breakgnameid, 6;
        sleep2 1000;
        announce "The [ Guild Emperium ] has been destroyed by the [ " + @breakgname$ + " ] guild.", bc_all;
        if( !mobcount( "pvp_y_1-1", "GvG::OnBreakEmp" ) ){
            monster "pvp_y_1-1", 155, 195, "Emperium", 1288, 1, "GvG::OnBreakEmp";
        }
        end;
    
    OnGuildBreak:
        SetCastleData "pvp_y_1-1", 0, 0;
        sleep2 2000;
        Announce "Guild Emperium has been abandoned.", 0;
        end;
    }
    
    pvp_y_1-1    mapflag    nowarp
    pvp_y_1-1    mapflag    nomemo
    pvp_y_1-1    mapflag    nobranch
    pvp_y_1-1    mapflag    noteleport
    pvp_y_1-1    mapflag    nosave    SavePoint
    pvp_y_1-1    mapflag    gvg_castle
    
  10. I agree with Brian. I would add it to the wiki and put the reasonable descriptions inside the code above the function. Maybe even in a format so that the programming environment can parse and show the function/structure description(if we decide to do it that way, we should decide on a environment or find a tool like cmake for comments inside the source code, if that is even possible).

    • Upvote 1
  11. I got a PM that there already is an outdated C# programm for the AEGIS script files. I already started coding in Java though and maybe I will rely on the code of the current tool, I will have to have a look into it and ask the owner if he is okay with that or not.

    I will add it to the repo later on or maybe when we move to GIT. But as of the current state it is not worth releasing it, because of the code structure and the way it works. I want to get the basic parsing/code splitting done(which I would say is finished to 80-85%) and then change it so that the commands can be parsed from anywhere(especially from the DB files), which is not possible right now.

    • Upvote 3
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.