123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/platform.h"
- #include "core/dnet.h"
- #include "console/simBase.h"
- #include "sim/netConnection.h"
- #include "core/stream/bitStream.h"
- #include "console/consoleTypes.h"
- class NetStringEvent : public NetEvent
- {
- NetStringHandle mString;
- U32 mIndex;
- public:
- typedef NetEvent Parent;
- NetStringEvent(U32 index = 0, NetStringHandle string = NetStringHandle())
- {
- mIndex = index;
- mString = string;
- }
- virtual void pack(NetConnection* /*ps*/, BitStream *bstream)
- {
- bstream->writeInt(mIndex, ConnectionStringTable::EntryBitSize);
- bstream->writeString(mString.getString());
- }
- virtual void write(NetConnection* /*ps*/, BitStream *bstream)
- {
- bstream->writeInt(mIndex, ConnectionStringTable::EntryBitSize);
- bstream->writeString(mString.getString());
- }
- virtual void unpack(NetConnection* /*con*/, BitStream *bstream)
- {
- char buf[256];
- mIndex = bstream->readInt(ConnectionStringTable::EntryBitSize);
- bstream->readString(buf);
- mString = NetStringHandle(buf);
- }
- virtual void notifyDelivered(NetConnection *ps, bool madeit)
- {
- if(madeit)
- ps->confirmStringReceived(mString, mIndex);
- }
- virtual void process(NetConnection *connection)
- {
- #ifdef TORQUE_DEBUG_NET
- Con::printf("Mapping string: %s to index: %d", mString.getString(), mIndex);
- #endif
- connection->mapString(mIndex, mString);
- }
- #ifdef TORQUE_DEBUG_NET
- const char *getDebugName()
- {
- static char buffer[512];
- dSprintf(buffer, sizeof(buffer), "%s - \"", getClassName());
- expandEscape(buffer + dStrlen(buffer), mString.getString());
- dStrcat(buffer, "\"", 512);
- return buffer;
- }
- #endif
- DECLARE_CONOBJECT(NetStringEvent);
- };
- IMPLEMENT_CO_NETEVENT_V1(NetStringEvent);
- ConsoleDocClass( NetStringEvent,
- "@brief Internal event used for transmitting strings across the server.\n\n"
-
- "For internal use only, not intended for TorqueScript or game development\n\n"
- "@internal\n"
- );
- //--------------------------------------------------------------------
- ConnectionStringTable::ConnectionStringTable(NetConnection *parent)
- {
- mParent = parent;
- for(U32 i = 0; i < EntryCount; i++)
- {
- mEntryTable[i].nextHash = NULL;
- mEntryTable[i].nextLink = &mEntryTable[i+1];
- mEntryTable[i].prevLink = &mEntryTable[i-1];
- mEntryTable[i].index = i;
- mHashTable[i] = NULL;
- }
- mLRUHead.nextLink = &mEntryTable[0];
- mEntryTable[0].prevLink = &mLRUHead;
- mLRUTail.prevLink = &mEntryTable[EntryCount-1];
- mEntryTable[EntryCount-1].nextLink = &mLRUTail;
- }
- U32 ConnectionStringTable::getNetSendId(NetStringHandle &string)
- {
- // see if the entry is in the hash table right now
- U32 hashIndex = string.getIndex() % EntryCount;
- for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->nextHash)
- if(walk->string == string)
- return walk->index;
- AssertFatal(0, "Net send id is not in the table. Error!");
- return 0;
- }
- U32 ConnectionStringTable::checkString(NetStringHandle &string, bool *isOnOtherSide)
- {
- // see if the entry is in the hash table right now
- U32 hashIndex = string.getIndex() % EntryCount;
- for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->nextHash)
- {
- if(walk->string == string)
- {
- pushBack(walk);
- if(isOnOtherSide)
- *isOnOtherSide = walk->receiveConfirmed;
- return walk->index;
- }
- }
- // not in the hash table, means we have to add it
- Entry *newEntry;
- // pull the new entry from the LRU list.
- newEntry = mLRUHead.nextLink;
- pushBack(newEntry);
- // remove the string from the hash table
- Entry **hashWalk;
- for (hashWalk = &mHashTable[newEntry->string.getIndex() % EntryCount]; *hashWalk; hashWalk = &((*hashWalk)->nextHash))
- {
- if(*hashWalk == newEntry)
- {
- *hashWalk = newEntry->nextHash;
- break;
- }
- }
- newEntry->string = string;
- newEntry->receiveConfirmed = false;
- newEntry->nextHash = mHashTable[hashIndex];
- mHashTable[hashIndex] = newEntry;
- mParent->postNetEvent(new NetStringEvent(newEntry->index, string));
- if(isOnOtherSide)
- *isOnOtherSide = false;
- return newEntry->index;
- }
- void ConnectionStringTable::mapString(U32 netId, NetStringHandle &string)
- {
- // the netId is sent by the other side... throw it in our mapping table:
- mRemoteStringTable[netId] = string;
- }
- void ConnectionStringTable::readDemoStartBlock(BitStream *stream)
- {
- // ok, reading the demo start block
- for(U32 i = 0; i < EntryCount; i++)
- {
- if(stream->readFlag())
- {
- char buffer[256];
- stream->readString(buffer);
- mRemoteStringTable[i] = NetStringHandle(buffer);
- }
- }
- }
- void ConnectionStringTable::writeDemoStartBlock(ResizeBitStream *stream)
- {
- // ok, writing the demo start block
- for(U32 i = 0; i < EntryCount; i++)
- {
- if(stream->writeFlag(mRemoteStringTable[i].isValidString()))
- {
- stream->writeString(mRemoteStringTable[i].getString());
- stream->validate();
- }
- }
- }
|