diff --git a/common/EQStream.cpp b/common/EQStream.cpp index 2d17ffc1f..2194cdb1a 100644 --- a/common/EQStream.cpp +++ b/common/EQStream.cpp @@ -23,6 +23,7 @@ #include "Mutex.h" #include "op_codes.h" #include "CRC16.h" +#include "platform.h" #include #include @@ -30,13 +31,6 @@ #include #include -#if defined(ZONE) || defined(WORLD) - #define RETRANSMITS -#endif -#ifdef RETRANSMITS - #include "rulesys.h" -#endif - #ifdef _WINDOWS #include #else @@ -75,17 +69,20 @@ void EQStream::init() { BytesWritten=0; SequencedBase = 0; NextSequencedSend = 0; -#ifdef RETRANSMITS - retransmittimer = Timer::GetCurrentTime(); - retransmittimeout = 500 * RuleR(EQStream, RetransmitTimeoutMult); //use 500ms as base before we have connection stats -#endif + + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + retransmittimer = Timer::GetCurrentTime(); + retransmittimeout = 500 * RETRANSMIT_TIMEOUT_MULT; + } + OpMgr = nullptr; -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "init Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + _log(NET__ERROR, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + } + + if(NextSequencedSend > SequencedQueue.size()) { + _log(NET__ERROR, _L "init Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + } } EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) @@ -118,7 +115,7 @@ EQProtocolPacket *EQStream::MakeProtocolPacket(const unsigned char *buf, uint32 void EQStream::ProcessPacket(EQProtocolPacket *p) { -uint32 processed=0,subpacket_length=0; + uint32 processed=0, subpacket_length=0; if (p == nullptr) return; // Raw Application packet @@ -304,9 +301,10 @@ uint32 processed=0,subpacket_length=0; #ifndef COLLECTOR uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); AckPackets(seq); -#ifdef RETRANSMITS - retransmittimer = Timer::GetCurrentTime(); -#endif + + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + retransmittimer = Timer::GetCurrentTime(); + } #endif } break; @@ -409,19 +407,24 @@ uint32 processed=0,subpacket_length=0; uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); MOutboundQueue.lock(); -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + _log(NET__ERROR, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + } + + if(NextSequencedSend > SequencedQueue.size()) { + _log(NET__ERROR, _L "Pre-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + } //if the packet they got out of order is between our last acked packet and the last sent packet, then its valid. if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) { _log(NET__NET_TRACE, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, seq, SequencedBase, SequencedBase+NextSequencedSend); -#ifdef RETRANSMITS - if (!RuleB(EQStream, RetransmitAckedPackets)) { -#endif + + bool retransmit_acked_packets = false; + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + retransmit_acked_packets = RETRANSMIT_ACKED_PACKETS; + } + + if(!retransmit_acked_packets) { uint16 sqsize = SequencedQueue.size(); uint16 index = seq - SequencedBase; _log(NET__NET_TRACE, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); @@ -431,22 +434,24 @@ if(NextSequencedSend > SequencedQueue.size()) { sitr += index; (*sitr)->acked = true; } -#ifdef RETRANSMITS } - if (RuleR(EQStream, RetransmitTimeoutMult)) { // only choose new behavior if multiplier is set + + if(RETRANSMIT_TIMEOUT_MULT) { retransmittimer = Timer::GetCurrentTime(); } -#endif + NextSequencedSend = 0; } else { _log(NET__NET_TRACE, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); } -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Post-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} + + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + _log(NET__ERROR, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + } + + if(NextSequencedSend > SequencedQueue.size()) { + _log(NET__ERROR, _L "Post-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + } MOutboundQueue.unlock(); #endif } @@ -468,19 +473,21 @@ if(NextSequencedSend > SequencedQueue.size()) { Stats->packets_sent=x; NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse,p->pBuffer,p->size)); AdjustRates(ntohl(Stats->average_delta)); -#ifdef RETRANSMITS - if (RuleR(EQStream, RetransmitTimeoutMult) && ntohl(Stats->average_delta)) { - //recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value - if((ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) > (ntohl(Stats->average_delta) * 2)) { - retransmittimeout = (ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) * RuleR(EQStream, RetransmitTimeoutMult); - } else { - retransmittimeout = ntohl(Stats->average_delta) * 2 * RuleR(EQStream, RetransmitTimeoutMult); + + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + if(RETRANSMIT_TIMEOUT_MULT && ntohl(Stats->average_delta)) { + //recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value + if((ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) > (ntohl(Stats->average_delta) * 2)) { + retransmittimeout = (ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) + * RETRANSMIT_TIMEOUT_MULT; + } else { + retransmittimeout = ntohl(Stats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT; + } + if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX) + retransmittimeout = RETRANSMIT_TIMEOUT_MAX; + _log(NET__NET_TRACE, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); } - if(retransmittimeout > RuleI(EQStream, RetransmitTimeoutMax)) - retransmittimeout = RuleI(EQStream, RetransmitTimeoutMax); - _log(NET__NET_TRACE, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); } -#endif #endif } break; @@ -527,16 +534,6 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode); - //make sure this packet is compatible with this stream -/* if(StreamType == UnknownStream || StreamType == ChatOrMailStream) { - _log(NET__DEBUG, _L "Stream type undetermined (%s), packet ignored" __L, StreamTypeString(StreamType)); - return; - } - if(pack->GetPacketType() != StreamType) { - _log(NET__ERROR, _L "Trying to queue a packet of type %s into a stream of type %s, dropping it." __L, StreamTypeString(pack->GetPacketType()), StreamTypeString(StreamType)); - return; - }*/ - _log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size); if (!ack_req) { @@ -549,8 +546,8 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) { -uint32 chunksize,used; -uint32 length; + uint32 chunksize,used; + uint32 length; // Convert the EQApplicationPacket to 1 or more EQProtocolPackets if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2) @@ -648,9 +645,9 @@ uint16 Seq=htons(seq); void EQStream::Write(int eq_fd) { -std::queue ReadyToSend; -bool SeqEmpty=false,NonSeqEmpty=false; -std::deque::iterator sitr; + std::queue ReadyToSend; + bool SeqEmpty=false, NonSeqEmpty=false; + std::deque::iterator sitr; // Check our rate to make sure we can send more MRate.lock(); @@ -673,14 +670,16 @@ std::deque::iterator sitr; // Place to hold the base packet t combine into EQProtocolPacket *p=nullptr; -#ifdef RETRANSMITS - // if we have a timeout defined and we have not received an ack recently enough, retransmit from beginning of queue - if (RuleR(EQStream, RetransmitTimeoutMult) && !SequencedQueue.empty() && NextSequencedSend && (GetState()==ESTABLISHED) && ((retransmittimer+retransmittimeout) < Timer::GetCurrentTime())) { - _log(NET__NET_TRACE, _L "Timeout since last ack received, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, SequencedBase, SequencedBase+NextSequencedSend); - NextSequencedSend = 0; - retransmittimer = Timer::GetCurrentTime(); // don't want to endlessly retransmit the first packet + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + // if we have a timeout defined and we have not received an ack recently enough, retransmit from beginning of queue + if (RETRANSMIT_TIMEOUT_MULT && !SequencedQueue.empty() && NextSequencedSend && + (GetState()==ESTABLISHED) && ((retransmittimer+retransmittimeout) < Timer::GetCurrentTime())) { + _log(NET__NET_TRACE, _L "Timeout since last ack received, starting retransmit at the start of our unacked " + "buffer (seq %d, was %d)." __L, SequencedBase, SequencedBase+NextSequencedSend); + NextSequencedSend = 0; + retransmittimer = Timer::GetCurrentTime(); // don't want to endlessly retransmit the first packet + } } -#endif // Find the next sequenced packet to send from the "queue" sitr = SequencedQueue.begin(); @@ -723,65 +722,87 @@ std::deque::iterator sitr; } if (sitr!=SequencedQueue.end()) { -//_log(NET__NET_COMBINE, _L "Send Seq with %d seq packets starting at seq %d, next send %d, and %d non-seq packets." __L, -// SequencedQueue.size(), SequencedBase, NextSequencedSend, NonSequencedQueue.size()); -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-Send Seq NSS=%d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, NextSequencedSend, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-Send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} - uint16 seq_send = SequencedBase + NextSequencedSend; //just for logging... -if(SequencedQueue.empty()) { -_log(NET__ERROR, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); -SeqEmpty=true; -continue; -} -/*if(CompareSequence(NextOutSeq, seq_send) == SeqFuture) { -_log(NET__ERROR, _L "Tried to write a packet beyond the end of the queue! (%d is past next out %d)" __L, seq_send, NextOutSeq); -sitr=SequencedQueue.end(); -continue; -}*/ -#ifdef RETRANSMITS - if (!RuleB(EQStream, RetransmitAckedPackets) && (*sitr)->acked) { - _log(NET__NET_TRACE, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); - sitr++; - NextSequencedSend++; - } else if (!p) { -#else - if (!p) { -#endif - // If we don't have a packet to try to combine into, use this one as the base - // Copy it first as it will still live until it is acked - p=(*sitr)->Copy(); - _log(NET__NET_COMBINE, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); - sitr++; - NextSequencedSend++; - } else if (!p->combine(*sitr)) { - // Trying to combine this packet with the base didn't work (too big maybe) - // So just send the base packet (we'll try this packet again later) - _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); - ReadyToSend.push(p); - BytesWritten+=p->size; - p=nullptr; + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + _log(NET__ERROR, _L "Pre-Send Seq NSS=%d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, NextSequencedSend, SequencedBase, SequencedQueue.size(), NextOutSeq); + } - if (BytesWritten > threshold) { - // Sent enough this round, lets stop to be fair - _log(NET__RATES, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); - break; + if(NextSequencedSend > SequencedQueue.size()) { + _log(NET__ERROR, _L "Pre-Send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + } + uint16 seq_send = SequencedBase + NextSequencedSend; //just for logging... + + if(SequencedQueue.empty()) { + _log(NET__ERROR, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); + SeqEmpty=true; + continue; + } + + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + if (!RETRANSMIT_ACKED_PACKETS && (*sitr)->acked) { + _log(NET__NET_TRACE, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); + sitr++; + NextSequencedSend++; + } else if (!p) { + // If we don't have a packet to try to combine into, use this one as the base + // Copy it first as it will still live until it is acked + p=(*sitr)->Copy(); + _log(NET__NET_COMBINE, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + sitr++; + NextSequencedSend++; + } else if (!p->combine(*sitr)) { + // Trying to combine this packet with the base didn't work (too big maybe) + // So just send the base packet (we'll try this packet again later) + _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + ReadyToSend.push(p); + BytesWritten+=p->size; + p=nullptr; + + if (BytesWritten > threshold) { + // Sent enough this round, lets stop to be fair + _log(NET__RATES, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + break; + } + } else { + // Combine worked + _log(NET__NET_COMBINE, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + sitr++; + NextSequencedSend++; } } else { - // Combine worked - _log(NET__NET_COMBINE, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); - sitr++; - NextSequencedSend++; + if (!p) { + // If we don't have a packet to try to combine into, use this one as the base + // Copy it first as it will still live until it is acked + p=(*sitr)->Copy(); + _log(NET__NET_COMBINE, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + sitr++; + NextSequencedSend++; + } else if (!p->combine(*sitr)) { + // Trying to combine this packet with the base didn't work (too big maybe) + // So just send the base packet (we'll try this packet again later) + _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + ReadyToSend.push(p); + BytesWritten+=p->size; + p=nullptr; + + if (BytesWritten > threshold) { + // Sent enough this round, lets stop to be fair + _log(NET__RATES, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + break; + } + } else { + // Combine worked + _log(NET__NET_COMBINE, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + sitr++; + NextSequencedSend++; + } + } + + if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { + _log(NET__ERROR, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + } + if(NextSequencedSend > SequencedQueue.size()) { + _log(NET__ERROR, _L "Post send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } -if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); -} -if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Post send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); -} } else { // No more sequenced packets SeqEmpty=true; @@ -1379,20 +1400,27 @@ void EQStream::Decay() void EQStream::AdjustRates(uint32 average_delta) { -#ifdef RETRANSMITS - if (average_delta && (average_delta <= RuleI(EQStream, AverageDeltaMax))) { -#else - if (average_delta) { -#endif - MRate.lock(); - RateThreshold=RATEBASE/average_delta; - DecayRate=DECAYBASE/average_delta; - _log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta); - MRate.unlock(); -#ifdef RETRANSMITS + if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { + if (average_delta && (average_delta <= AVERAGE_DELTA_MAX)) { + MRate.lock(); + RateThreshold=RATEBASE/average_delta; + DecayRate=DECAYBASE/average_delta; + _log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + RateThreshold, DecayRate, average_delta); + MRate.unlock(); + } else { + _log(NET__RATES, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, + average_delta, AVERAGE_DELTA_MAX); + } } else { - _log(NET__RATES, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, average_delta, RuleI(EQStream, AverageDeltaMax)); -#endif + if (average_delta) { + MRate.lock(); + RateThreshold=RATEBASE/average_delta; + DecayRate=DECAYBASE/average_delta; + _log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + RateThreshold, DecayRate, average_delta); + MRate.unlock(); + } } } diff --git a/common/EQStream.h b/common/EQStream.h index 2f10eb5a6..244ed1924 100644 --- a/common/EQStream.h +++ b/common/EQStream.h @@ -24,6 +24,11 @@ #define RATEBASE 1048576 // 1 MB #define DECAYBASE 78642 // RATEBASE/10 +#define RETRANSMIT_TIMEOUT_MULT 3.0 +#define RETRANSMIT_TIMEOUT_MAX 5000 +#define AVERAGE_DELTA_MAX 2500 +#define RETRANSMIT_ACKED_PACKETS true + #pragma pack(1) struct SessionRequest { uint32 UnknownA; diff --git a/common/ruletypes.h b/common/ruletypes.h index 7cb8cd717..628fe3961 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -499,13 +499,6 @@ RULE_CATEGORY( Console ) RULE_INT ( Console, SessionTimeOut, 600000 ) // Amount of time in ms for the console session to time out RULE_CATEGORY_END() -RULE_CATEGORY( EQStream ) -RULE_INT ( EQStream, RetransmitTimeoutMax, 5000 ) // maximum retransmit timeout before retransmitting unacked packets -RULE_INT ( EQStream, AverageDeltaMax, 2500 ) // maximum average rtt where we will still recalculate transmit rates -RULE_REAL ( EQStream, RetransmitTimeoutMult, 3.0 ) // multiplier applied to rtt stats to generate a retransmit timeout value -RULE_BOOL ( EQStream, RetransmitAckedPackets, true ) // should we restransmit packets that were already acked? -RULE_CATEGORY_END() - RULE_CATEGORY( QueryServ ) RULE_BOOL( QueryServ, PlayerChatLogging, false) // Logs Player Chat RULE_BOOL( QueryServ, PlayerLogTrades, false) // Logs Player Trades diff --git a/zone/client.cpp b/zone/client.cpp index b5ed493c2..9abe26072 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7114,13 +7114,13 @@ const char* Client::GetClassPlural(Client* client) { void Client::SendWebLink(const char *website) { - if(website != 0) + size_t len = strlen(website) + 1; + if(website != 0 && len > 1) { - std::string str = website; - EQApplicationPacket* outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + str.length() + 1); + EQApplicationPacket* outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len); Weblink_Struct *wl = (Weblink_Struct*)outapp->pBuffer; - memcpy(wl->weblink, str.c_str(), str.length() + 1); - wl->weblink[str.length() + 1] = '\0'; + memcpy(wl->weblink, website, len); + wl->weblink[len] = '\0'; FastQueuePacket(&outapp); } diff --git a/zone/client.h b/zone/client.h index c5c5f6e84..cb74a31c9 100644 --- a/zone/client.h +++ b/zone/client.h @@ -687,7 +687,6 @@ public: inline uint8 GetBecomeNPCLevel() const { return npclevel; } inline void SetBecomeNPC(bool flag) { npcflag = flag; } inline void SetBecomeNPCLevel(uint8 level) { npclevel = level; } - bool LootToStack(uint32 itemid); void SetFeigned(bool in_feigned); /// this cures timing issues cuz dead animation isn't done but server side feigning is? inline bool GetFeigned() const { return(feigned); } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index ac4e21823..9a828d1a2 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1914,50 +1914,6 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const return 0; } -bool Client::LootToStack(uint32 itemid) { //Loots stackable items to existing stacks - Wiz - // @merth: Need to do loot code with new inventory struct - /* - const Item_Struct* item; - int i; - for (i=22; i<=29; i++) { - item = GetItemAt(i); - if (item) { - if (m_pp.invitemproperties[i].charges < 20 && item->ID == itemid) - { - m_pp.invitemproperties[i].charges += 1; - EQApplicationPacket* outapp = new EQApplicationPacket(OP_PlaceItem, sizeof(Item_Struct)); - memcpy(outapp->pBuffer, item, outapp->size); - Item_Struct* outitem = (Item_Struct*) outapp->pBuffer; - outitem->equipSlot = i; - outitem->charges = m_pp.invitemproperties[i].charges; - QueuePacket(outapp); - safe_delete(outapp); - return true; - } - } - } - for (i=0; i<=pp_containerinv_size; i++) { - if (m_pp.containerinv[i] != 0xFFFF) { - item = database.GetItem(m_pp.containerinv[i]); - if (m_pp.bagitemproperties[i].charges < 20 && item->ID == itemid) - { - m_pp.bagitemproperties[i].charges += 1; - - EQApplicationPacket* outapp = new EQApplicationPacket(OP_PlaceItem, sizeof(Item_Struct)); - memcpy(outapp->pBuffer, item, outapp->size); - Item_Struct* outitem = (Item_Struct*) outapp->pBuffer; - outitem->equipSlot = 250+i; - outitem->charges = m_pp.bagitemproperties[i].charges; - QueuePacket(outapp); - safe_delete(outapp); - return true; - } - } - } - */ - return false; -} - // Send an item packet (including all subitems of the item) void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type) { diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index d4bb7c5eb..58df9699d 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -6,10 +6,25 @@ #include "masterentity.h" #include "lua_client.h" +#include "../common/item.h" + +struct InventoryWhere { }; luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()); } +luabind::scope lua_register_inventory_where() { + return luabind::class_("InventoryWhere") + .enum_("constants") + [ + luabind::value("Personal", static_cast(invWherePersonal)), + luabind::value("Bank", static_cast(invWhereBank)), + luabind::value("SharedBank", static_cast(invWhereSharedBank)), + luabind::value("Trading", static_cast(invWhereTrading)), + luabind::value("Cursor", static_cast(invWhereCursor)) + ]; +} + #endif diff --git a/zone/lua_client.h b/zone/lua_client.h index 59ded70d5..2ba3670b6 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -11,6 +11,7 @@ namespace luabind { } luabind::scope lua_register_client(); +luabind::scope lua_register_inventory_where(); class Lua_Client : public Lua_Mob { @@ -39,206 +40,189 @@ public: void Kick(); void Disconnect(); bool IsLD(); - WorldKick - GetAnon - Duck - Stand - SetGM - SetPVP - GetPVP - GetGM - SetBaseClass - SetBaseRace - SetBaseGender - GetBaseFace - GetLanguageSkill - GetLastName - GetLDoNPointsTheme - GetBaseSTR - GetBaseSTA - GetBaseCHA - GetBaseDEX - GetBaseINT - GetBaseAGI - GetBaseWIS - GetWeight - GetEXP - GetAAExp - GetTotalSecondsPlayed - UpdateLDoNPoints - SetDeity - AddEXP - SetEXP - SetBindPoint - GetBindX - GetBindY - GetBindZ - GetBindHeading - GetBindZoneID - MovePC - MovePCInstance - ChangeLastName - GetFactionLevel - SetFactionLevel - SetFactionLevel2 - GetRawItemAC - AccountID - AccountName - Admin - CharacterID - UpdateAdmin - UpdateWho - GuildRank - GuildID - GetFace - TakeMoneyFromPP - AddMoneyToPP - TGB - GetSkillPoints - SetSkillPoints - IncreaseSkill - IncreaseLanguageSkill - GetSkill - GetRawSkill - HasSkill - CanHaveSkill - SetSkill - AddSkill - CheckSpecializeIncrease - CheckIncreaseSkill - SetLanguageSkill - MaxSkill - GMKill - IsMedding - GetDuelTarget - IsDueling - SetDuelTarget - SetDueling - ResetAA - MemSpell - UnmemSpell - UnmemSpellAll - ScribeSpell - UnscribeSpell - UnscribeSpellAll - UntrainDisc - UntrainDiscAll - IsSitting - IsBecomeNPC - GetBecomeNPCLevel - SetBecomeNPC - SetBecomeNPCLevel - LootToStack - SetFeigned - GetFeigned - AutoSplitEnabled - SetHorseId - GetHorseId - NukeItem - SetTint - SetMaterial - Undye - GetItemIDAt - GetAugmentIDAt - DeleteItemInInventory - SummonItem - SetStats - IncStats - DropItem - BreakInvis - GetGroup - LeaveGroup - GetRaid - IsGrouped - IsRaidGrouped - Hungry - Thirsty - GetInstrumentMod - DecreaseByID - SlotConvert2 - Escape - RemoveNoRent - GoFish - ForageItem - CalcPriceMod - ResetTrade - UseDiscipline - GetCharacterFactionLevel - SetZoneFlag - ClearZoneFlag - HasZoneFlag - SendZoneFlagInfo - LoadZoneFlags - SetAATitle - GetClientVersion - GetClientVersionBit - SetTitleSuffix - SetAAPoints - GetAAPoints - GetSpentAA - AddAAPoints - RefundAA - GetModCharacterFactionLevel - GetLDoNWins - GetLDoNLosses - GetLDoNWinsTheme - GetLDoNLossesTheme - GetItemAt - GetAugmentAt - GetStartZone - SetStartZone - KeyRingAdd - KeyRingCheck - AddPVPPoints - AddCrystals - GetPVPPoints - GetRadiantCrystals - GetEbonCrystals - ReadBook - UpdateGroupAAs - GetGroupPoints - GetRaidPoints - LearnRecipe - GetEndurance - GetMaxEndurance - GetEnduranceRatio - SetEndurance - SendOPTranslocateConfirm - NPCSpawn - GetIP - AddLevelBasedExp - IncrementAA - GetAALevel - MarkCompassLoc - ClearCompassMark - GetFreeSpellBookSlot - GetSpellBookSlotBySpellID - UpdateTaskActivity - AssignTask - FailTask - IsTaskCompleted - IsTaskActive - IsTaskActivityActive - GetCorpseCount - GetCorpseID - GetCorpseItemAt - AssignToInstance - Freeze - UnFreeze - GetAggroCount - GetCarriedMoney - GetAllMoney - GetItemInInventory - SetCustomItemData - GetCustomItemData - OpenLFGuildWindow - SignalClient - AddAlternateCurrencyValue - SendWebLink - GetInstanceID - HasSpellScribed - SetAccountFlag - GetAccountFlag + void WorldKick(); + bool GetAnon(); + void Duck(); + void Stand(); + void SetGM(bool v); + void SetPVP(bool v); + bool GetPVP(); + bool GetGM(); + void SetBaseClass(int v); + void SetBaseRace(int v); + void SetBaseGender(int v); + int GetBaseFace(); + int GetLanguageSkill(); + int GetLastName(); + int GetLDoNPointsTheme(); + int GetBaseSTR(); + int GetBaseSTA(); + int GetBaseCHA(); + int GetBaseDEX(); + int GetBaseINT(); + int GetBaseAGI(); + int GetBaseWIS(); + int GetWeight(); + uint32 GetEXP(); + uint32 GetAAExp(); + uint32 GetTotalSecondsPlayed(); + void UpdateLDoNPoints(int points, uint32 theme); + void SetDeity(int v); + void AddEXP(uint32 add_exp, int conlevel = 255, bool resexp = false); + void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp = false); + SetBindPoint(int to_zone = -1, float new_x = 0.0f, float new_y = 0.0f, float new_z = 0.0f); + float GetBindX(int index = 0); + float GetBindY(int index = 0); + float GetBindZ(int index = 0); + float GetBindHeading(int index = 0); + uint32 GetBindZoneID(int index = 0); + void MovePC(int zone, float x, float y, float z, float heading); + void MovePCInstance(int zone, int instance, float x, float y, float z, float heading); + void ChangeLastName(const char *in); + int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class, uint32 deity, uint32 faction, Lua_NPC npc); + void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity); + void SetFactionLevel2(uint32 char_id, int faction_id, int char_class, int char_race, int char_deity, int value, int temp); + int GetRawItemAC(); + uint32 AccountID(); + const char *AccountName(); + bool Admin(); + uint32 CharacterID(); + int GuildRank(); + uint32 GuildID(); + int GetFace(); + bool TakeMoneyFromPP(uint64 copper, bool update_client = false); + void AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool update_client = false); + bool TGB(); + int GetSkillPoints(); + void SetSkillPoints(int skill); + void IncreaseSkill(int skill_id, int value); + void IncreaseLanguageSkill(int skill_id, int value); + int GetRawSkill(int skill_id); + bool HasSkill(int skill_id); + bool CanHaveSkill(int skill_id); + void SetSkill(int skill_id, int value); + void AddSkill(int skill_id, int value); + void CheckSpecializeIncrease(int spell_id); + void CheckIncreaseSkill(int skill_id, Lua_Mob target, int chance_mod = 0); + void SetLanguageSkill(int language, int value); + int MaxSkill(int spell_id); + bool IsMedding(); + Lua_Client GetDuelTarget(); + bool IsDueling(); + void SetDuelTarget(Lua_Client c); + void SetDueling(bool v); + void ResetAA(); + void MemSpell(int spell_id, int slot, bool update_client = true); + void UnmemSpell(int slot, bool update_client = true); + void UnmemSpellAll(bool update_client = true); + void ScribeSpell(int spell_id, int slot, bool update_client = true); + void UnscribeSpell(int slot, bool update_client = true); + void UnscribeSpellAll(bool update_client = true); + void UntrainDisc(int slot, bool update_client = true); + void UntrainDiscAll(bool update_client = true); + bool IsSitting(); + void SetFeigned(bool v); + bool GetFeigned(); + bool AutoSplitEnabled(); + void SetHorseId(int id); + int GetHorseId(); + void NukeItem(uint32 item_num, int where_to_check); + void SetTint(int slot_id, uint32 color); + void SetMaterial(int slot_id, uint32 item_id); + void Undye(int slot_id); + int GetItemIDAt(int slot_id); + int GetAugmentIDAt(int slot_id, int aug_slot); + void DeleteItemInInventory(int slot_id, int quantity, bool update_client = true); + void SummonItem(uint32 item_id, int charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, + uint32 aug5 = 0, bool attuned = false, int to_slot = 30); + void SetStats(int type, int value); + void IncStats(int type, int value); + int DropItem(int slot_id); + void BreakInvis(); + void LeaveGroup(); + bool IsGrouped(); + bool IsRaidGrouped(); + bool Hungry(); + bool Thirsty(); + int GetInstrumentMod(int spell_id); + bool DecreaseByID(uint32 type, int amt); + void Escape(); + void GoFish(); + void ForageItem(bool guarantee = false); + float CalcPriceMod(Lua_Mob other, bool reverse); + void ResetTrade(); + bool UseDiscipline(int spell_id, int target_id); + int GetCharacterFactionLevel(int faction_id); + void SetZoneFlag(int zone_id); + void ClearZoneFlag(int zone_id); + bool HasZoneFlag(int zone_id); + void SendZoneFlagInfo(Lua_Client to); + void SetAATitle(const char *title); + int GetClientVersion(); + uint32 GetClientVersionBit(); + void SetTitleSuffix(const char *text); + void SetAAPoints(int points); + int GetAAPoints(); + int GetSpentAA(); + void AddAAPoints(int points); + void RefundAA(); + int GetModCharacterFactionLevel(int faction); + int GetLDoNWins(); + int GetLDoNLosses(); + int GetLDoNWinsTheme(int theme); + int GetLDoNLossesTheme(int theme); + Lua_ItemInst GetItemAt(int slot); + int GetStartZone(); + void SetStartZone(int zone_id, float x = 0.0f, float y = 0.0f, float z = 0.0f); + void KeyRingAdd(uint32 item); + bool KeyRingCheck(uint32 item); + void AddPVPPoints(uint32 points); + void AddCrystals(uint32 radiant, uint32 ebon); + uint32 GetPVPPoints(); + uint32 GetRadiantCrystals(); + uint32 GetEbonCrystals(); + void ReadBook(const char *text, int type); + void UpdateGroupAAs(int points, uint32 type); + uint32 GetGroupPoints(); + uint32 GetRaidPoints(); + void LearnRecipe(uint32 recipe); + int GetEndurance(); + int GetMaxEndurance(); + int GetEndurancePercent(); + void SetEndurance(int endur); + void SendOPTranslocateConfirm(Lua_Mob caster, int spell_id); + const char *GetIP(); + void AddLevelBasedExp(int exp_pct, int max_level = 0); + void IncrementAA(int aa); + MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count = 1); + int GetFreeSpellBookSlot(int start = 0); + int GetSpellBookSlotBySpellID(int spell_id); + void UpdateTaskActivity(int task, int activity, int count); + void AssignTask(int task, int npc_id); + void FailTask(int task); + bool IsTaskCompleted(int task); + bool IsTaskActive(int task); + bool IsTaskActivityActive(int task, int activty); + int GetCorpseCount(); + int GetCorpseID(int corpse); + int GetCorpseItemAt(int corpse, int slot); + void AssignToInstance(int instance_id); + void Freeze(); + void UnFreeze(); + int GetAggroCount(); + uint64 GetCarriedMoney(); + uint64 GetAllMoney(); + void OpenLFGuildWindow(); + void Signal(uint32 id); + void AddAlternateCurrencyValue(uint32 currency, int amount); + void SendWebLink(const char *site); + bool HasSpellScribed(int spell_id); + void SetAccountFlag(std::string flag, std::string val); + std::string value GetAccountFlag(std::string flag); + + //unsup features + Lua_Group GetGroup(); + Lua_Raid GetRaid(); */ }; diff --git a/zone/lua_entity.h b/zone/lua_entity.h index 56ee29306..984d5245f 100644 --- a/zone/lua_entity.h +++ b/zone/lua_entity.h @@ -12,20 +12,6 @@ struct Lua_HateList; class Lua_Item; class Lua_ItemInst; -//TODO: Remove the error checking by a flag since this adds significant overhead to each c call -#define Lua_Safe_Call_Void() if(!d_) { return; } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Bool() if(!d_) { return false; } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Int() if(!d_) { return 0; } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Real() if(!d_) { return 0.0; } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_String() if(!d_) { return ""; } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Entity() if(!d_) { return Lua_Entity(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Mob() if(!d_) { return Lua_Mob(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_NPC() if(!d_) { return Lua_NPC(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Client() if(!d_) { return Lua_Client(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_HateList() if(!d_) { return Lua_HateList(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_Item() if(!d_) { return Lua_Item(); } NativeType *self = reinterpret_cast(d_) -#define Lua_Safe_Call_ItemInst() if(!d_) { return Lua_ItemInst(); } NativeType *self = reinterpret_cast(d_) - namespace luabind { struct scope; } diff --git a/zone/lua_general.h b/zone/lua_general.h index c06b87cc2..408ec63f5 100644 --- a/zone/lua_general.h +++ b/zone/lua_general.h @@ -4,6 +4,10 @@ luabind::scope lua_register_general(); luabind::scope lua_register_events(); +luabind::scope lua_register_faction(); +luabind::scope lua_register_slot(); +luabind::scope lua_register_material(); +luabind::scope lua_register_client_version(); #endif #endif \ No newline at end of file diff --git a/zone/lua_item.cpp b/zone/lua_item.cpp index 307de231e..bb5b0856d 100644 --- a/zone/lua_item.cpp +++ b/zone/lua_item.cpp @@ -5,7 +5,6 @@ #include #include "masterentity.h" -#include "lua_entity.h" #include "lua_item.h" Lua_Item::Lua_Item(uint32 item_id) { diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index b3cfc08e6..c6d3271cd 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -7,7 +7,6 @@ #include "masterentity.h" #include "lua_iteminst.h" #include "lua_item.h" -#include "lua_entity.h" bool Lua_ItemInst::IsType(int item_class) { Lua_Safe_Call_Bool(); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 11d66bbea..76329689c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1682,6 +1682,11 @@ int Lua_Mob::GetFlurryChance() { return self->GetFlurryChance(); } +int Lua_Mob::GetSkill(int skill) { + Lua_Safe_Call_Int(); + return self->GetSkill(static_cast(skill)); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -1977,7 +1982,8 @@ luabind::scope lua_register_mob() { .def("SetDisableMelee", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDisableMelee) .def("IsMeleeDisabled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMeleeDisabled) .def("SetFlurryChance", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlurryChance) - .def("GetFlurryChance", (int(Lua_Mob::*)(void))&Lua_Mob::GetFlurryChance); + .def("GetFlurryChance", (int(Lua_Mob::*)(void))&Lua_Mob::GetFlurryChance) + .def("GetSkill", (int(Lua_Mob::*)(int))&Lua_Mob::GetSkill); } #endif diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 5f4390eeb..65ebc767f 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -336,6 +336,7 @@ public: bool IsMeleeDisabled(); void SetFlurryChance(int value); int GetFlurryChance(); + int GetSkill(int skill_id); }; #endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 9193ca4fb..fa2901833 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -806,6 +806,7 @@ void LuaParser::MapFunctions(lua_State *L) { lua_register_mob(), lua_register_npc(), lua_register_client(), + lua_register_inventory_where(), lua_register_iteminst(), lua_register_item(), lua_register_spell(), @@ -946,56 +947,8 @@ void LuaParser::ExportQGlobals(NPC *n, Client *c) { return; } - QGlobalCache *npc_c = nullptr; - QGlobalCache *char_c = nullptr; - QGlobalCache *zone_c = nullptr; - uint32 npc_id = 0; - uint32 char_id = 0; - uint32 zone_id = 0; - - if(n) { - npc_id = n->GetNPCTypeID(); - npc_c = n->GetQGlobals(); - } - - if(c) { - char_id = c->CharacterID(); - char_c = c->GetQGlobals(); - } - - if(zone) { - zone_id = zone->GetZoneID(); - zone_c = zone->GetQGlobals(); - } - - if(!npc_c && n) { - npc_c = n->CreateQGlobals(); - npc_c->LoadByNPCID(npc_id); - } - - if(!char_c && c) { - char_c = c->CreateQGlobals(); - char_c->LoadByCharID(char_id); - } - - if(!zone_c && zone) { - zone_c = zone->CreateQGlobals(); - zone_c->LoadByZoneID(zone_id); - zone_c->LoadByGlobalContext(); - } - std::list global_map; - if(npc_c) { - QGlobalCache::Combine(global_map, npc_c->GetBucket(), npc_id, char_id, zone_id); - } - - if(char_c) { - QGlobalCache::Combine(global_map, char_c->GetBucket(), npc_id, char_id, zone_id); - } - - if(zone_c) { - QGlobalCache::Combine(global_map, zone_c->GetBucket(), npc_id, char_id, zone_id); - } + QGlobalCache::GetQGlobals(global_map, n, c, zone); auto iter = global_map.begin(); while(iter != global_map.end()) { diff --git a/zone/lua_ptr.h b/zone/lua_ptr.h index 0a6df3d95..f7382457f 100644 --- a/zone/lua_ptr.h +++ b/zone/lua_ptr.h @@ -2,6 +2,20 @@ #define EQEMU_LUA_PTR_H #ifdef LUA_EQEMU +//TODO: Remove the error checking by a flag since this adds significant overhead to each c call +#define Lua_Safe_Call_Void() if(!d_) { return; } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Bool() if(!d_) { return false; } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Int() if(!d_) { return 0; } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Real() if(!d_) { return 0.0; } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_String() if(!d_) { return ""; } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Entity() if(!d_) { return Lua_Entity(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Mob() if(!d_) { return Lua_Mob(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_NPC() if(!d_) { return Lua_NPC(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Client() if(!d_) { return Lua_Client(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_HateList() if(!d_) { return Lua_HateList(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_Item() if(!d_) { return Lua_Item(); } NativeType *self = reinterpret_cast(d_) +#define Lua_Safe_Call_ItemInst() if(!d_) { return Lua_ItemInst(); } NativeType *self = reinterpret_cast(d_) + template class Lua_Ptr { diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index d1c6f19f8..09201f1d6 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -2713,33 +2713,6 @@ XS(XS_Client_SetBecomeNPCLevel) XSRETURN_EMPTY; } -XS(XS_Client_LootToStack); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Client_LootToStack) -{ - dXSARGS; - if (items != 2) - Perl_croak(aTHX_ "Usage: Client::LootToStack(THIS, itemid)"); - { - Client * THIS; - bool RETVAL; - uint32 itemid = (uint32)SvUV(ST(1)); - - if (sv_derived_from(ST(0), "Client")) { - IV tmp = SvIV((SV*)SvRV(ST(0))); - THIS = INT2PTR(Client *,tmp); - } - else - Perl_croak(aTHX_ "THIS is not of type Client"); - if(THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - RETVAL = THIS->LootToStack(itemid); - ST(0) = boolSV(RETVAL); - sv_2mortal(ST(0)); - } - XSRETURN(1); -} - XS(XS_Client_SetFeigned); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_SetFeigned) { @@ -5854,7 +5827,6 @@ XS(boot_Client) newXSproto(strcpy(buf, "GetBecomeNPCLevel"), XS_Client_GetBecomeNPCLevel, file, "$"); newXSproto(strcpy(buf, "SetBecomeNPC"), XS_Client_SetBecomeNPC, file, "$$"); newXSproto(strcpy(buf, "SetBecomeNPCLevel"), XS_Client_SetBecomeNPCLevel, file, "$$"); - newXSproto(strcpy(buf, "LootToStack"), XS_Client_LootToStack, file, "$$"); newXSproto(strcpy(buf, "SetFeigned"), XS_Client_SetFeigned, file, "$$"); newXSproto(strcpy(buf, "GetFeigned"), XS_Client_GetFeigned, file, "$"); newXSproto(strcpy(buf, "AutoSplitEnabled"), XS_Client_AutoSplitEnabled, file, "$");