-Fix bugrepot:7609 fix picklog enum (add cashshop type)
-Fix bugreport:7615 freeze after closse by Secure timer, also fix "Unable to restore stack! Double continuation!" case (when dead by mob talking to npc) -Upd secure timer, now stop timer when we already in close/end state. -Fix st_>mes_active case where var wasn't refresh but dialogue was ended -Add packet support for ZC_ITEM_PICKUP_ACK_V5 (0x990), (0x0897,0x093F,0x0886,0x035f) (Hercule/Shaktoh) -Cleanup too duplicate, too wide comment git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17303 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
b37ff67ef0
commit
eb013a6d5e
@ -1802,7 +1802,7 @@ packet_ver: 33
|
||||
packet_ver: 34
|
||||
0x01FD,15,repairitem,2
|
||||
0x086D,26,friendslistadd,2
|
||||
0x0897,5,hommenu,2:4
|
||||
0x0897,5,changedir,2:4
|
||||
0x0947,36,storagepassword,0
|
||||
0x086F,26,partyinvite2,2
|
||||
0x0888,19,wanttoconnection,2:6:10:14:18
|
||||
@ -1810,7 +1810,7 @@ packet_ver: 34
|
||||
0x089B,10,useskilltoid,2:4:6
|
||||
0x0881,5,walktoxy,2
|
||||
0x0363,6,ticksend,2
|
||||
0x093F,5,changedir,2:4
|
||||
0x093F,5,hommenu,2:4
|
||||
0x0933,6,takeitem,2
|
||||
0x0438,6,dropitem,2:4
|
||||
0x08AC,8,movetokafra,2:4
|
||||
@ -1827,13 +1827,14 @@ packet_ver: 34
|
||||
0x0998,8,equipitem,2:4
|
||||
//0x0281,-1,itemlistwindowselected,2:4:8
|
||||
0x0938,-1,reqopenbuyingstore,2:4:8:9:89
|
||||
//0x0817,2,reqclosebuyingstore,0
|
||||
//0x0360,6,reqclickbuyingstore,2
|
||||
0x0886,2,reqclosebuyingstore,0
|
||||
0x035f,6,reqclickbuyingstore,2
|
||||
0x0922,-1,reqtradebuyingstore,2:4:8:12
|
||||
0x094E,-1,searchstoreinfo,2:4:5:9:13:14:15
|
||||
//0x0835,2,searchstoreinfonextpage,0
|
||||
//0x0838,12,searchstoreinfolistitemclick,2:6:10
|
||||
0x0447,2
|
||||
0x990,31 //additem
|
||||
0x99b,8 //maptypeproperty2
|
||||
0x84b,19 //fallitem4
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// --------------------------------------------------------------
|
||||
// - Renewal Core Scripts -
|
||||
// --------------------------------------------------------------
|
||||
|
||||
npc: npc/re/tester.txt
|
||||
// -------------------------- Airport ---------------------------
|
||||
npc: npc/re/airports/izlude.txt
|
||||
|
||||
|
@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS `picklog` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`time` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`char_id` int(11) NOT NULL default '0',
|
||||
`type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U') NOT NULL default 'P',
|
||||
`type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$') NOT NULL default 'P',
|
||||
`nameid` int(11) NOT NULL default '0',
|
||||
`amount` int(11) NOT NULL default '1',
|
||||
`refine` tinyint(3) unsigned NOT NULL default '0',
|
||||
@ -139,4 +139,4 @@ CREATE TABLE IF NOT EXISTS `cashlog` (
|
||||
`map` varchar(11) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `type` (`type`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1;
|
||||
|
1
sql-files/upgrades/upgrade_svn17303_log.sql
Normal file
1
sql-files/upgrades/upgrade_svn17303_log.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `picklog` CHANGE `type` `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$') NOT NULL default 'P';
|
@ -1271,11 +1271,6 @@ static void clif_weather_check(struct map_session_data *sd)
|
||||
clif_specialeffect_single(&sd->bl, 163, fd);
|
||||
if (map[m].flag.leaves)
|
||||
clif_specialeffect_single(&sd->bl, 333, fd);
|
||||
/**
|
||||
* No longer available, keeping here just in case it's back someday. [Ind]
|
||||
**/
|
||||
//if (map[m].flag.rain)
|
||||
// clif_specialeffect_single(&sd->bl, 161, fd);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -1714,8 +1709,7 @@ void clif_fixpos(struct block_list *bl)
|
||||
WBUFW(buf,8) = bl->y;
|
||||
clif_send(buf, packet_len(0x88), bl, AREA);
|
||||
|
||||
if( disguised(bl) )
|
||||
{
|
||||
if( disguised(bl) ) {
|
||||
WBUFL(buf,2) = -bl->id;
|
||||
clif_send(buf, packet_len(0x88), bl, SELF);
|
||||
}
|
||||
@ -1882,8 +1876,7 @@ void clif_scriptclose(struct map_session_data *sd, int npcid)
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------*/
|
||||
void clif_sendfakenpc(struct map_session_data *sd, int npcid)
|
||||
{
|
||||
void clif_sendfakenpc(struct map_session_data *sd, int npcid) {
|
||||
unsigned char *buf;
|
||||
int fd = sd->fd;
|
||||
sd->state.using_fake_npc = 1;
|
||||
@ -2117,6 +2110,7 @@ static void clif_addcards(unsigned char* buf, struct item* item)
|
||||
/// 00a0 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B (ZC_ITEM_PICKUP_ACK)
|
||||
/// 029a <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L (ZC_ITEM_PICKUP_ACK2)
|
||||
/// 02d4 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK3)
|
||||
/// 0990 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W <unknow>.W (ZC_ITEM_PICKUP_ACK_V5)
|
||||
void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
|
||||
{
|
||||
int fd;
|
||||
@ -2124,8 +2118,10 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
|
||||
const int cmd = 0xa0;
|
||||
#elif PACKETVER < 20071002
|
||||
const int cmd = 0x29a;
|
||||
#else
|
||||
#elif PACKETVER < 20120925
|
||||
const int cmd = 0x2d4;
|
||||
#else
|
||||
const int cmd = 0x990;
|
||||
#endif
|
||||
nullpo_retv(sd);
|
||||
|
||||
@ -2181,6 +2177,9 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
|
||||
#endif
|
||||
#if PACKETVER >= 20071002
|
||||
WFIFOW(fd,27)=0; // unknown
|
||||
#endif
|
||||
#if PACKETVER >= 20120925
|
||||
WFIFOW(fd,29)=0; // unknown
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2240,8 +2239,7 @@ void clif_delitem(struct map_session_data *sd,int n,int amount, short reason)
|
||||
// Simplifies inventory/cart/storage packets by handling the packet section relevant to items. [Skotlex]
|
||||
// Equip is >= 0 for equippable items (holds the equip-point, is 0 for pet
|
||||
// armor/egg) -1 for stackable items, -2 for stackable items where arrows must send in the equip-point.
|
||||
void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *id, int equip)
|
||||
{
|
||||
void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *id, int equip) {
|
||||
if (id->view_id > 0)
|
||||
WBUFW(buf,n)=id->view_id;
|
||||
else
|
||||
@ -2264,8 +2262,7 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
|
||||
}
|
||||
void clif_favorite_item(struct map_session_data* sd, unsigned short index);
|
||||
//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
|
||||
void clif_inventorylist(struct map_session_data *sd)
|
||||
{
|
||||
void clif_inventorylist(struct map_session_data *sd) {
|
||||
int i,n,ne,arrow=-1;
|
||||
unsigned char *buf;
|
||||
unsigned char *bufe;
|
||||
@ -2340,8 +2337,7 @@ void clif_inventorylist(struct map_session_data *sd)
|
||||
if( arrow >= 0 )
|
||||
clif_arrowequip(sd,arrow);
|
||||
|
||||
if( ne )
|
||||
{
|
||||
if( ne ) {
|
||||
#if PACKETVER < 20071002
|
||||
WBUFW(bufe,0)=0xa4;
|
||||
#else
|
||||
@ -3111,8 +3107,7 @@ void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_ta
|
||||
/// <int>.B <need int>.B <dex>.B <need dex>.B <luk>.B <need luk>.B <atk>.W <atk2>.W
|
||||
/// <matk min>.W <matk max>.W <def>.W <def2>.W <mdef>.W <mdef2>.W <hit>.W
|
||||
/// <flee>.W <flee2>.W <crit>.W <aspd>.W <aspd2>.W
|
||||
void clif_initialstatus(struct map_session_data *sd)
|
||||
{
|
||||
void clif_initialstatus(struct map_session_data *sd) {
|
||||
int fd, mdef2;
|
||||
unsigned char *buf;
|
||||
|
||||
@ -16747,7 +16742,7 @@ static int packetdb_readdb(void)
|
||||
0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
//#0x0980
|
||||
0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,
|
||||
31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
@ -159,9 +159,9 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
|
||||
map_addnpc(nd->bl.m, nd);
|
||||
map_addblock(&nd->bl);
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
status_change_init(&nd->bl);
|
||||
unit_dataset(&nd->bl);
|
||||
clif_spawn(&nd->bl);
|
||||
status_change_init(&nd->bl);
|
||||
unit_dataset(&nd->bl);
|
||||
clif_spawn(&nd->bl);
|
||||
|
||||
}
|
||||
|
||||
@ -2491,7 +2491,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
|
||||
for(i = 0; i < MAX_MVP_DROP; i++) {
|
||||
while( 1 ) {
|
||||
int va = rand()%MAX_MVP_DROP;
|
||||
int va = rnd()%MAX_MVP_DROP;
|
||||
if( !mdrop_id[va] || !md->db->mvpitem[i].nameid ) {
|
||||
mdrop_id[va] = md->db->mvpitem[i].nameid;
|
||||
mdrop_p[va] = md->db->mvpitem[i].p;
|
||||
|
@ -246,6 +246,7 @@ struct npc_data* npc_name2id(const char* name)
|
||||
int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
|
||||
struct map_session_data* sd = NULL;
|
||||
unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
|
||||
int cur_tick = gettick(); //ensure we are on last tick
|
||||
if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) {
|
||||
if( sd ) sd->npc_idle_timer = INVALID_TIMER;
|
||||
return 0;//Not logged in anymore OR no longer attached to a npc
|
||||
@ -261,22 +262,13 @@ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat
|
||||
//case NPCT_WAIT: var starts with this value
|
||||
}
|
||||
|
||||
if( DIFF_TICK(tick,sd->npc_idle_tick) > (timeout*1000) ) {
|
||||
/**
|
||||
* If we still have the NPC script attached, tell it to stop.
|
||||
**/
|
||||
if( sd->st )
|
||||
sd->st->state = END;
|
||||
sd->state.menu_or_input = 0;
|
||||
sd->npc_menu = 0;
|
||||
|
||||
/**
|
||||
* This guy's been idle for longer than allowed, close him.
|
||||
**/
|
||||
clif_scriptclose(sd,sd->npc_id);
|
||||
sd->npc_idle_timer = INVALID_TIMER;
|
||||
} else //Create a new instance of ourselves to continue
|
||||
sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
|
||||
if( DIFF_TICK(cur_tick,sd->npc_idle_tick) > (timeout*1000) ) {
|
||||
pc_close_npc(sd,1);
|
||||
} else if(sd->st && (sd->st->state == END || sd->st->state == CLOSE)){
|
||||
sd->npc_idle_timer = INVALID_TIMER; //stop timer the script is already ending
|
||||
} else { //Create a new instance of ourselves to continue
|
||||
sd->npc_idle_timer = add_timer(cur_tick + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -1248,14 +1240,8 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
/**
|
||||
* Update the last NPC iteration
|
||||
**/
|
||||
sd->npc_idle_tick = gettick();
|
||||
sd->npc_idle_tick = gettick(); //Update the last NPC iteration
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1264,7 +1250,7 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
||||
if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0 )
|
||||
return 1;
|
||||
|
||||
if( closing && sd->st->state == CLOSE )
|
||||
if( closing && sd->st && sd->st->state == CLOSE )
|
||||
sd->st->state = END;
|
||||
|
||||
run_script_main(sd->st);
|
||||
@ -1290,7 +1276,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
|
||||
sd->npc_id=0;
|
||||
return 1;
|
||||
}
|
||||
if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
|
||||
if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
|
||||
return 1;
|
||||
if( nd->class_ < 0 && !sd->state.callshop )
|
||||
{// not called through a script and is not a visible NPC so an invalid call
|
||||
|
@ -175,9 +175,6 @@ extern struct npc_data* fake_nd;
|
||||
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
|
||||
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||
#endif
|
||||
|
55
src/map/pc.c
55
src/map/pc.c
@ -965,13 +965,9 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
|
||||
sd->invincible_timer = INVALID_TIMER;
|
||||
sd->npc_timer_id = INVALID_TIMER;
|
||||
sd->pvp_timer = INVALID_TIMER;
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
/**
|
||||
* Initialize to defaults/expected
|
||||
**/
|
||||
// Initialize to defaults/expected
|
||||
sd->npc_idle_timer = INVALID_TIMER;
|
||||
sd->npc_idle_tick = tick;
|
||||
sd->npc_idle_type = NPCT_INPUT;
|
||||
@ -6569,6 +6565,37 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
|
||||
sd->canlog_tick = gettick();
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to properly close npc for player and clear anything related
|
||||
* @flag == 1 : produce close button
|
||||
* @flag == 2 : directly close it
|
||||
*/
|
||||
void pc_close_npc(struct map_session_data *sd,int flag) {
|
||||
nullpo_retv(sd);
|
||||
|
||||
if (sd->npc_id) {
|
||||
if (sd->state.using_fake_npc) {
|
||||
clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
|
||||
sd->state.using_fake_npc = 0;
|
||||
}
|
||||
if (sd->st) {
|
||||
sd->st->state = (flag==1)?CLOSE:END;
|
||||
sd->st->mes_active = 0;
|
||||
}
|
||||
sd->state.menu_or_input = 0;
|
||||
sd->npc_menu = 0;
|
||||
sd->npc_idle_timer = INVALID_TIMER;
|
||||
clif_scriptclose(sd,sd->npc_id);
|
||||
if(flag==2 && sd->st) {
|
||||
if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
|
||||
script_free_state(sd->st);
|
||||
sd->st = NULL;
|
||||
sd->npc_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Invoked when a player has negative current hp
|
||||
*------------------------------------------*/
|
||||
@ -6620,21 +6647,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
duel_reject(sd->duel_invite, sd);
|
||||
}
|
||||
|
||||
// Clear anything NPC-related when you die and was interacting with one.
|
||||
if (sd->npc_id) {
|
||||
if (sd->state.using_fake_npc) {
|
||||
clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
|
||||
sd->state.using_fake_npc = 0;
|
||||
}
|
||||
if (sd->state.menu_or_input)
|
||||
sd->state.menu_or_input = 0;
|
||||
if (sd->npc_menu)
|
||||
sd->npc_menu = 0;
|
||||
|
||||
sd->npc_id = 0;
|
||||
if (sd->st && sd->st->state != END)
|
||||
sd->st->state = END;
|
||||
}
|
||||
pc_close_npc(sd,2); //close npc if we were using one
|
||||
|
||||
/* e.g. not killed thru pc_damage */
|
||||
if( pc_issit(sd) ) {
|
||||
|
@ -472,9 +472,6 @@ struct map_session_data {
|
||||
unsigned int bg_id;
|
||||
unsigned short user_font;
|
||||
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
/**
|
||||
* ID of the timer
|
||||
@ -720,6 +717,7 @@ int pc_setnewpc(struct map_session_data*,int,int,int,unsigned int,int,int);
|
||||
bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers);
|
||||
void pc_authfail(struct map_session_data *);
|
||||
int pc_reg_received(struct map_session_data *sd);
|
||||
void pc_close_npc(struct map_session_data *sd,int flag);
|
||||
|
||||
int pc_isequip(struct map_session_data *sd,int n);
|
||||
int pc_equippoint(struct map_session_data *sd,int n);
|
||||
|
@ -3606,9 +3606,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event)
|
||||
st->bk_st = NULL;
|
||||
st->bk_npcid = 0;
|
||||
} else if(dequeue_event) {
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
/**
|
||||
* We're done with this NPC session, so we cancel the timer (if existent) and move on
|
||||
@ -3652,9 +3650,6 @@ static void script_attach_state(struct script_state* st)
|
||||
sd->st = st;
|
||||
sd->npc_id = st->oid;
|
||||
sd->npc_item_flag = st->npc_item_flag; // load default.
|
||||
/**
|
||||
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
|
||||
**/
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
if( sd->npc_idle_timer == INVALID_TIMER )
|
||||
sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
|
||||
@ -6916,6 +6911,7 @@ BUILDIN_FUNC(delitem)
|
||||
|
||||
ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
|
||||
st->state = END;
|
||||
st->mes_active = 0;
|
||||
clif_scriptclose(sd, st->oid);
|
||||
return 1;
|
||||
}
|
||||
@ -6992,6 +6988,7 @@ BUILDIN_FUNC(delitem2)
|
||||
|
||||
ShowError("script:delitem2: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
|
||||
st->state = END;
|
||||
st->mes_active = 0;
|
||||
clif_scriptclose(sd, st->oid);
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user