void CLog::out(const CString format, ...) { va_list s_format_v; #ifndef NO_BOOST boost::recursive_mutex::scoped_lock lock(*m_write); #endif // Assemble and print the timestamp. char timestr[60]; time_t curtime = time(0); strftime(timestr, sizeof(timestr), "%I:%M %p", localtime(&curtime)); printf("[%s] ", timestr); // Log output to file. if (true == enabled && 0 != file) { // Save the timestamp to the file. strftime(timestr, sizeof(timestr), "%a %b %d %X %Y", localtime(&curtime)); fprintf(file, "[%s] ", timestr); // Write the message to the file. va_start(s_format_v, format); vfprintf(file, format.text(), s_format_v); va_end(s_format_v); fflush(file); } // Display message. va_start(s_format_v, format); vprintf(format.text(), s_format_v); va_end(s_format_v); }
int CLevel::addNewNpc(CString& pImage, CString& pCodeFile, float pX, float pY) { CStringList codeData; CString code; char* dataFile = getDataFile(pCodeFile.text()); if(!strlen(dataFile)) return 0; if(!codeData.load(dataFile)) return 0; for(int i = 0; i < codeData.count(); i++) code << codeData[i] << "\xa7"; // Create the new NPC. Do this before parsing the join commands. // The CNpc constructor will remove all comments. CString code2; CNpc* npc = new CNpc( pImage, code, pX, pY, this, false ); // Now filter out the join commands. CStringList npcData; npcData.load( npc->clientCode.text(), "\xa7" ); for ( int j = 0; j < npcData.count(); ++j ) code2 << processNpcLine( npcData[j] ) << "\xa7"; npc->clientCode = code2; // Now, add all the joined files to the code. if ( joinList.count() > 0 ) { CString* file = 0; while ( (file = (CString*)joinList[0]) != 0 ) { // Load the source file into memory. CString dataFile = getDataFile(file->text()); if(dataFile.length()) { // Append to the end of the script. CString retVal; retVal.load(dataFile.text()); retVal.replaceAll("\r\n", "\xa7"); retVal.replaceAll("\n", "\xa7"); npc->clientCode << retVal << "\xa7"; } delete (CString*)joinList[0]; joinList.remove(0); } } joinList.clear(); npcs.add(npc); for(int i = 0; i < players.count(); i++) { CPlayer* player = (CPlayer*)players[i]; player->sendPacket(CPacket() << (char)SNPCPROPS << (int)npc->id << npc->getPropertyList(0)); } return npc->id; }
void CLevel::loadNpcs(CPacket& levelData) { while(levelData.bytesLeft()) { CPacket line; line << levelData.readLine(); if(line.length() < 1 || line == "#") break; float x = line.readByte1(); float y = line.readByte1(); CString image = line.readString("#"); CString code = line.readChars(line.bytesLeft()); // Create the new NPC. Do this before parsing the join commands. // The CNpc constructor will remove all comments. CString code2; CNpc* jnpc = new CNpc( image, code, x, y, this, true ); // Now filter out the join commands. CStringList npcData; npcData.load( jnpc->clientCode.text(), "\xa7" ); for ( int j = 0; j < npcData.count(); ++j ) code2 << processNpcLine( npcData[j] ) << "\xa7"; jnpc->clientCode = code2; // Now, add all the joined files to the code. if ( joinList.count() > 0 ) { CString* file = 0; while ( (file = (CString*)joinList[0]) != 0 ) { // Load the source file into memory. CString dataFile = getDataFile(file->text()); if(dataFile.length()) { // Append to the end of the script. CString retVal; retVal.load(dataFile.text()); retVal.replaceAll("\r\n", "\xa7"); retVal.replaceAll("\n", "\xa7"); jnpc->clientCode << retVal << "\xa7"; } delete (CString*)joinList[0]; joinList.remove(0); } } joinList.clear(); npcs.add( jnpc ); } }
int CSocket::sendData(CString& data) { int intError = 0; int size = 0; // Make sure the socket is connected! if (properties.state == SOCKET_STATE_DISCONNECTED) return SOCKET_INVALID; do { // See if we can send data. // If we can't, return how many bytes we did send. fd_set set; struct timeval tm; tm.tv_sec = tm.tv_usec = 0; FD_ZERO(&set); FD_SET(properties.handle, &set); select(properties.handle + 1, 0, &set, 0, &tm); if (!FD_ISSET(properties.handle, &set)) return size; // Send our data, yay! int sent = 0; if ((sent = ::send(properties.handle, data.text(), data.length(), 0)) == SOCKET_ERROR) { intError = identifyError(); switch (intError) { case ENETDOWN: case ENETRESET: case ENOTCONN: case EHOSTUNREACH: case ECONNABORTED: case ECONNRESET: case ETIMEDOUT: // Destroy the bad socket and create a new one. disconnect(); return intError; break; } if (intError == EAGAIN || intError == EWOULDBLOCK || intError == EINPROGRESS) return size; disconnect(); return intError; } // Remove what we sent. // Increase size by how much we sent. if (sent >= data.length()) data.clear(); else if (sent > 0) data.removeI(0, sent); size += sent; // Repeat while data is still left. } while (data.length() > 0 && intError == 0); // Return how much data was ultimately sent. return size; }
void getSubFiles(char* pDir, CStringList& pOut, CString* search) { SceUID dir; if ((dir = sceIoDopen(pDir)) <= 0) return; SceIoDirent ent; SceIoStat statx; while (sceIoDread(dir, &ent) > 0) { CString fullName = CString() << pDir << ent.d_name; sceIoGetstat(fullName.text(), &statx); if (!(statx.st_mode & S_IFDIR)) { if (search != 0) { CString s( *search ); CString m( ent.d_name ); s.replaceAll( "%", "*" ); s << ".txt"; if (m.match( s.text()) == false) continue; } pOut.add( ent.d_name ); } } sceIoDclose(dir); }
void getSubFiles(char* pDir, CStringList& pOut, CString* search) { DIR *dir; struct stat statx; struct dirent *ent; if ((dir = opendir(pDir)) == NULL) return; while ((ent = readdir(dir)) != NULL) { CString fullName = CString() << pDir << ent->d_name; stat(fullName.text(), &statx); if (!(statx.st_mode & S_IFDIR)) { if ( search != 0 ) { CString s( *search ); CString m( ent->d_name ); s.replaceAll( "%", "*" ); s << ".txt"; if ( m.match( s.text() ) == false ) continue; } pOut.add( ent->d_name ); } } closedir(dir); }
void saveWeapons(char* pFile) { CStringList weaponData; for(int i = 0; i < weaponList.count(); i++) { CString code; char modTime[30]; int index; CWeapon* weapon = (CWeapon*)weaponList[i]; index = weaponData.add("NEWWEAPON "); sprintf(modTime, "%li", (long int)weapon->modTime); // Save name. weaponData[index] << weapon->name << ","; // If the NPC doesn't have an image, write a hyphen. if ( weapon->image.length() == 0 ) weaponData[index] << "-" << ","; else weaponData[index] << weapon->image << ","; // Write the modification time. weaponData[index] << modTime; code = weapon->code; char* line = strtok(code.text(), "\xa7"); while(line != NULL) { weaponData.add(line); line = strtok(NULL, "\xa7"); } weaponData.add("ENDWEAPON\r\n"); } weaponData.save(pFile); }
void CLevel::saveNpcs() { return; CStringList npcData; //printf("SAVING NPCS\n"); for(int i = 0; i < npcs.count(); i++) { CNpc* npc = (CNpc*)npcs[i]; if(npc == NULL) continue; npcData.add(CString() << "REPLACENPC " << toString(i)); CPacket props; for(int ii = 0; ii < npcpropcount; ii++) { if(ii != ACTIONSCRIPT) props << (char) ii << npc->getProperty(ii); } npcData.add(props); npcData.add("REPLACENPCEND\r\n"); } CString fName; fName << "npcprops" << fSep << fileName << ".code"; npcData.save(fName.text()); }
void CFileSystem::loadAllDirectories(const CString& directory, bool recursive) { CString dir = CString() << directory.remove(directory.findl(fSep)) << fSep; WIN32_FIND_DATAA filedata; HANDLE hFind = FindFirstFileA(directory.text(), &filedata); if (hFind != INVALID_HANDLE_VALUE) { do { if (filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (filedata.cFileName[0] != '.' && recursive) { // We need to add the directory to the directory list. CString newDir = CString() << dir << filedata.cFileName << fSep; newDir.removeI(0, server->getServerPath().length()); addDir(newDir, "*", true); } } else { // Grab the file name. CString file((char *)filedata.cFileName); fileList[file] = CString(dir) << filedata.cFileName; } } while (FindNextFileA(hFind, &filedata)); } FindClose(hFind); }
void getSubDirs() { // If foldersconfig.txt is turned off, use the old style. if ( noFoldersConfig ) { subDirs.clear(); getSubDirs_os( dataDir.text() ); if ( shareFolder.length() > 1 ) getSubDirs_os( shareFolder.text() ); } else { subDirs.clear(); subDirs.add(dataDir); for (int i = 0; i < folderConfig.count(); i++) { if (folderConfig[i][0] == '#') continue; CBuffer fmask, fname; // Get rid of all \t and replace with ' '. // Also, trim. folderConfig[i].replaceAll( "\t", " " ); // Read past the identifier. folderConfig[i].setRead(folderConfig[i].find(' ')); // Read the mask CBuffer temp = folderConfig[i].readString( "" ); temp.trim(); // If it starts with ./, use . instead of world/ as the search dir. if ( temp.find( "./" ) == 0 ) fmask = CBuffer() << programDir << temp; else fmask = CBuffer() << dataDir << temp; // Pull off the file mask and only save the directory. fname = CBuffer() << fmask.readChars(fmask.findl(fSep[0])) << fSep; if (subDirs.find(fname) == -1) subDirs.add(fname); } } }
bool isValidFile(CBuffer& file, int type) { for ( int i = 0; i < folderConfig.count(); ++i ) { folderConfig[i].setRead(0); CString ftype( folderConfig[i].readString( " " ) ); CString fmask = CBuffer() << dataDir << CBuffer(folderConfig[i].readString( "" )).trim().text(); folderConfig[i].setRead(0); switch ( type ) { case 11: // HEADGIF if ( ftype == "head" ) if ( file.match( fmask.text() ) ) return true; break; case 35: // BODYIMG if ( ftype == "body" ) if ( file.match( fmask.text() ) ) return true; break; case 8: // SWORDPOWER if ( ftype == "sword" ) if ( file.match( fmask.text() ) ) return true; break; case 9: // SHIELDPOWER if ( ftype == "shield" ) if ( file.match( fmask.text() ) ) return true; break; case 1: // level if ( ftype == "level" ) if ( file.match( fmask.text() ) ) return true; break; case -1: // Any if ( file.match( fmask.text() ) ) return true; break; default: case 0: // file if ( ftype == "file" ) if ( file.match( fmask.text() ) ) return true; break; } } return false; }
void CLog::out(const CString format, ...) { va_list s_format_v; va_start(s_format_v, format); boost::recursive_mutex::scoped_lock lock(*m_write); // Log output to file. if (true == enabled && 0 != file) { vfprintf(file, format.text(), s_format_v); fflush(file); } // Display message. vprintf(format.text(), s_format_v); va_end(s_format_v); }
void getSubDirs_os(char *pDir) { DIR *dir; struct stat statx; struct dirent *ent; if ((dir = opendir(pDir)) == NULL) return; subDirs.add(pDir); while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] != '.') { CString directory = CString() << pDir << ent->d_name << fSep; stat(directory.text(), &statx); if (statx.st_mode & S_IFDIR) getSubDirs_os(directory.text()); } } closedir(dir); }
void CFileSystem::loadAllDirectories(const CString& directory, bool recursive) { CString path = CString() << directory.remove(directory.findl(fSep)) << fSep; CString wildcard = directory.subString(directory.findl(fSep) + 1); DIR *dir; struct stat statx; struct dirent *ent; // Try to open the directory. if ((dir = opendir(path.text())) == 0) return; // Read everything in it now. while ((ent = readdir(dir)) != 0) { if (ent->d_name[0] != '.') { CString dircheck = CString() << path << ent->d_name; stat(dircheck.text(), &statx); if ((statx.st_mode & S_IFDIR)) { if (recursive) { // We need to add the directory to the directory list. CString newDir = CString() << path << ent->d_name << fSep; newDir.removeI(0, server->getServerPath().length()); addDir(newDir, "*", true); } continue; } } else continue; // Grab the file name. CString file(ent->d_name); if (file.match(wildcard)) fileList[file] = CString(path) << file; } closedir(dir); }
int CFileSystem::getFileSize(const CString& file) const { boost::recursive_mutex::scoped_lock lock(*m_preventChange); // Get the full path to the file. CString fileName = find(file); if (fileName.length() == 0) return 0; struct stat fileStat; if (stat(fileName.text(), &fileStat) != -1) return fileStat.st_size; return 0; }
void getSubDirs_os(char *pDir) { CString searchdir = CString() << pDir << "*"; WIN32_FIND_DATA filedata; HANDLE hFind = FindFirstFile(searchdir.text(), &filedata); subDirs.add(pDir); if(hFind!=NULL) { do { if(filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(filedata.cFileName[0] != '.') { CString directory = CString() << pDir << filedata.cFileName << fSep; getSubDirs_os(directory.text()); } } } while (FindNextFile(hFind, &filedata)); } FindClose(hFind); }
bool CLevel::loadGraal(CString& pFileName) { CPacket levelData; CString version; char* dataFile = getDataFile(pFileName.text()); if(!strlen(dataFile)) return false; if(!levelData.load(dataFile)) return false; fileName = pFileName; modTime = getFileModTime(dataFile); version = levelData.readChars(8); bool v0 = (version == "GR-V1.00"); bool v1 = (version == "GR-V1.01"); bool v2 = (version == "GR-V1.02"); bool v3 = (version == "GR-V1.03"); //printf("Loading map %s\n", pFileName.text()); //printf("Loading tiles..\n"); loadTiles(levelData, version); //printf("Loading links..\n"); loadLinks(levelData); //printf("Loading baddies..\n"); loadBaddies(levelData); if (v0 || v1 || v2 || v3) { //printf("Loading npcs..\n"); loadNpcs(levelData); } if (v1 || v2 || v3) { //printf("Loading chests..\n"); loadChests(levelData); } //printf("Loading signs..\n"); loadSigns(levelData); //Find our map id for(int i = 0; i < CMap::mapList.count(); i++) { CMap* m = (CMap*)CMap::mapList[i]; if((levelIndex = m->getLevelpos(pFileName)) >= 0) { map = m; break; } } return true; }
bool CLevel::loadZelda(CString& pFileName) { CPacket levelData; CString version; char* dataFile = getDataFile(pFileName.text()); if(!strlen(dataFile)) return false; if(!levelData.load(dataFile)) return false; fileName = pFileName; modTime = getFileModTime(dataFile); version = levelData.readChars(8); // Some clients will actually save .zelda levels as .graal. // If this is the case, parse it through the .graal loader. if (version.copy(0, 2) == "GR") return loadGraal(pFileName); bool v0 = (version == "unknown"); bool v1 = (version == "unknown"); bool v2 = (version == "unknown"); bool v3 = (version == "Z3-V1.03"); bool v4 = (version == "Z3-V1.04"); // If we encountered an unknown version, ask the user to send it in so we can add support for it. if (!v3 && !v4) { errorOut("errorlog.txt", CString() << "Level " << fileName << " is of version " << version << ". That version is unknown. Please send us the level so we may add support for it.", true); return false; } loadTiles(levelData, version); loadLinks(levelData); loadBaddies(levelData); loadSigns(levelData); //Find our map id for(int i = 0; i < CMap::mapList.count(); i++) { CMap* m = (CMap*)CMap::mapList[i]; if((levelIndex = m->getLevelpos(pFileName)) >= 0) { map = m; break; } } return true; }
time_t CFileSystem::getModTime(const CString& file) const { #ifndef NO_BOOST boost::recursive_mutex::scoped_lock lock(*m_preventChange); #endif // Get the full path to the file. CString fileName = find(file); if (fileName.length() == 0) return 0; struct stat fileStat; if (stat(fileName.text(), &fileStat) != -1) return (time_t)fileStat.st_mtime; return 0; }
int CSocket::init(const CString& host, const CString& port) { struct addrinfo hints; struct addrinfo* res; // Make sure a TCP socket is disconnected. if (properties.protocol == SOCKET_PROTOCOL_TCP && properties.state != SOCKET_STATE_DISCONNECTED) return SOCKET_ALREADY_CONNECTED; // Start creating the hints. memset((struct sockaddr_storage*)&properties.address, 0, sizeof(struct sockaddr_storage)); memset((void*)&hints, 0, sizeof(hints)); if (properties.protocol == SOCKET_PROTOCOL_TCP) hints.ai_socktype = SOCK_STREAM; if (properties.protocol == SOCKET_PROTOCOL_UDP) hints.ai_socktype = SOCK_DGRAM; hints.ai_family = AF_INET; // Create the host. int error; if (properties.type == SOCKET_TYPE_CLIENT && host.length() != 0) error = getaddrinfo(host.text(), port.text(), &hints, &res); else if (properties.type == SOCKET_TYPE_SERVER) { hints.ai_flags = AI_PASSIVE; // Local socket. error = getaddrinfo(0, port.text(), &hints, &res); } else return SOCKET_ERROR; // Check for errors. if (error) return SOCKET_HOST_UNKNOWN; else memcpy((void*)&properties.address, res->ai_addr, res->ai_addrlen); return 0; }
void CLog::append(const CString format, ...) { va_list s_format_v; va_start(s_format_v, format); #ifndef NO_BOOST boost::recursive_mutex::scoped_lock lock(*m_write); #endif // Log output to file. if (true == enabled && 0 != file) { // Write the message to the file. vfprintf(file, format.text(), s_format_v); fflush(file); va_end(s_format_v); va_start(s_format_v, format); } // Display message. vprintf(format.text(), s_format_v); va_end(s_format_v); }
bool CFileSystem::setModTime(const CString& file, time_t modTime) const { boost::recursive_mutex::scoped_lock lock(*m_preventChange); // Get the full path to the file. CString fileName = find(file); if (fileName.length() == 0) return false; // Set the times. struct utimbuf ut; ut.actime = modTime; ut.modtime = modTime; // Change the file. if (utime(fileName.text(), &ut) == 0) return true; return false; }
CPacket listFiles(char *pDir, char *pRights) { CPacket retVal; CStringList files; struct stat fileStat; getSubFiles(pDir, files); for (int i = 0; i < files.count(); i++) { CPacket dir; CString fullName; fullName << pDir << files[i]; stat(fullName.text(), &fileStat); dir << (char)files[i].length() << files[i] << (char)strlen(pRights) << pRights << (long long)fileStat.st_size << (long long)fileStat.st_mtime; retVal << " " << (char)dir.length() << dir; } return retVal; }
void CLevel::loadLinks(CPacket& levelData) { while(levelData.bytesLeft()) { CBuffer line = levelData.readLine(); if(line.length() <= 0 || line == "#") break; CString nextMap = line.readString(" "); if(!strlen(getDataFile(nextMap.text()))) continue; int x = atoi(line.readString(" ")); int y = atoi(line.readString(" ")); int width = atoi(line.readString(" ")); int height = atoi(line.readString(" ")); CString warpX = line.readString(" "); CString warpY = line.readString(" "); links.add(new CLink(nextMap, x, y, width, height, warpX, warpY)); } }
bool CLevel::loadGraal(CString& pFileName) { CPacket levelData; CString version; char* dataFile = getDataFile(pFileName.text()); if(!strlen(dataFile)) return false; if(!levelData.load(dataFile)) return false; fileName = pFileName; modTime = getFileModTime(dataFile); version = levelData.readChars(8); bool v0 = (version == "GR-V1.00"); bool v1 = (version == "GR-V1.01"); bool v2 = (version == "GR-V1.02"); bool v3 = (version == "GR-V1.03"); //printf("Loading map %s\n", pFileName.text()); //printf("Loading tiles..\n"); loadTiles(levelData, version); //printf("Loading links..\n"); loadLinks(levelData); //printf("Loading baddies..\n"); loadBaddies(levelData); if (v0 || v1 || v2 || v3) { //printf("Loading npcs..\n"); loadNpcs(levelData); } if (v1 || v2 || v3) { //printf("Loading chests..\n"); loadChests(levelData); } //printf("Loading signs..\n"); loadSigns(levelData); return true; }
bool CLevel::loadNW(CString& pFileName) { CStringList levelData; CString version; char* dataFile = getDataFile(pFileName.text()); if(!strlen(dataFile)) return false; if(!levelData.load(dataFile)) return false; if(levelData.count() < 1) return false; version = levelData[0]; modTime = getFileModTime(dataFile); fileName = pFileName; if(version == "GLEVNW01" || version == "GSERVL01") { for(int i = 1; i < levelData.count(); i ++) { CStringList words; words.load(levelData[i].text(), " "); if(words.count() <= 0) continue; if(words[0] == "BOARD") { if(words.count() <= 5) continue; int x = atoi(words[1].text()); int y = atoi(words[2].text()); int w = atoi(words[3].text()); CString& data = words[5]; if(x >= 0 && x <= 64 && y >= 0 && y <= 64 && w > 0 && x + w <= 64) { if(data.length() >= w*2) { for(int ii = x; ii < x + w; ii++) { char left = data.readChar(); char top = data.readChar(); short tile = base64.find(left) << 6; tile += base64.find(top); tiles[ii + y*64] = tile; } } } } else if(words[0] == "LINK") { if(words.count() <= 7) continue; if(strlen(getDataFile(words[1].text()))) { links.add(new CLink(words[1], atoi(words[2].text()), atoi(words[3].text()), atoi(words[4].text()), atoi(words[5].text()), words[6], words[7])); } } else if(words[0] == "CHEST") { if(words.count() <= 4) continue; for(int ii = 0; ii < itemcount; ii++) { if(words[3] == itemNames[ii]) { chests.add(new CChest(atoi(words[1].text()), atoi(words[2].text()), atoi(words[4].text()), ii)); break; } } } else if(words[0] == "NPC") { if(words.count() <= 3) continue; CString image, code, code2; float x, y; if(words[1] != "-") image = words[1]; x = (float)atof(words[2].text()); y = (float)atof(words[3].text()); for(i++; i < levelData.count() && levelData[i] != "NPCEND"; i++) code << levelData[i] << "\xa7"; // Create the new NPC. Do this before parsing the join commands. // The CNpc constructor will remove all comments. CNpc* jnpc = new CNpc( image, code, x, y, this, true ); // Now filter out the join commands. CStringList npcData; npcData.load( jnpc->clientCode.text(), "\xa7" ); for ( int j = 0; j < npcData.count(); ++j ) code2 << processNpcLine( npcData[j] ) << "\xa7"; jnpc->clientCode = code2; // Now, add all the joined files to the code. if ( joinList.count() > 0 ) { CString* file = 0; while ( (file = (CString*)joinList[0]) != 0 ) { // Load the source file into memory. CString dataFile = getDataFile(file->text()); if(dataFile.length()) { // Append to the end of the script. CString retVal; retVal.load(dataFile.text()); retVal.replaceAll("\r\n", "\xa7"); retVal.replaceAll("\n", "\xa7"); jnpc->clientCode << retVal << "\xa7"; } delete (CString*)joinList[0]; joinList.remove(0); } } joinList.clear(); npcs.add( jnpc ); } else if(words[0] == "BADDY") { if(words.count() <= 3) continue; int x = atoi(words[1].text()); int y = atoi(words[2].text()); int type = atoi(words[3].text()); CBaddy* baddy = new CBaddy(x, y, type); int baddyId = createBaddyId(baddy); baddy->id = baddyId; for(i++; i < levelData.count() && levelData[i] != "BADDYEND"; i++) baddy->verses.add(levelData[i].text()); if(baddies.count() < 50) baddies.add(baddy); else delete baddy; } else if(words[0] == "SIGN") { if(words.count() <= 2) continue; CString sign; int x = atoi(words[1].text()); int y = atoi(words[2].text()); sign.writeChar(x+32); sign.writeChar(y+32); for (i++; i < levelData.count() && levelData[i] != "SIGNEND"; i++) sign << getSignCode(CString() << levelData[i] << "\n"); signs.add(sign); } else if(words[0] == "REPLACENPC") { int npcId = atoi(words[1].text()); CNpc* npc = (CNpc*)npcs[npcId]; if(npc == NULL) continue; for(i++; i < levelData.count() && levelData[i] != "REPLACENPCEND"; i++) npc->setProps((CPacket&)levelData[i]); } } } else return false; return true; }
int CSocket::getData() { int size = 0; int intError = 0; //char buff[ 0x10000 ]; // 65536 bytes, 64KB char buff[ 0x2000 ]; // 8192 bytes, 8KB int bufflen = 0x2000; CString temp; // Make sure it is connected! if (properties.state == SOCKET_STATE_DISCONNECTED) return SOCKET_ERROR; do { // Make sure there is data to be read. // If size == bufflen, that means there may be more data. Just in case, // call select so blocking sockets don't block. if (size == 0 || size == bufflen) { fd_set set; struct timeval tm; tm.tv_sec = tm.tv_usec = 0; FD_ZERO(&set); FD_SET(properties.handle, &set); select(properties.handle + 1, &set, 0, 0, &tm); if (!FD_ISSET(properties.handle, &set)) return temp.length(); } // Allocate buff. memset((void*)buff, 0, bufflen); // Get our data if (properties.protocol == SOCKET_PROTOCOL_UDP) size = recvfrom(properties.handle, buff, bufflen, 0, 0, 0); else size = recv(properties.handle, buff, bufflen, 0); // Add to the buffer. if (size > 0) temp.write(buff, size); // Check for error! if (size == SOCKET_ERROR) { intError = identifyError(); switch (intError) { case ENETDOWN: case ENETRESET: case ENOTCONN: case EHOSTUNREACH: case ECONNABORTED: case ECONNRESET: case ETIMEDOUT: case ESHUTDOWN: // Destroy the bad socket and create a new one. disconnect(); break; default: break; } } } while (size > 0 && intError == 0); // If size is 0, the socket was disconnected. if (size == 0) disconnect(); // Add the data we just got to the buffer. if (temp.length() > 0) buffer.write(temp.text(), temp.length()); // Return the amount of data obtained. return temp.length(); }
bool TAccount::saveAccount() { // Don't save 'Load Only' or RC Accounts if (isLoadOnly) return false; CString newFile = "GRACC001\r\n"; newFile << "NAME " << accountName << "\r\n"; newFile << "NICK " << nickName << "\r\n"; newFile << "COMMUNITYNAME " << accountName /*communityName*/ << "\r\n"; newFile << "LEVEL " << levelName << "\r\n"; newFile << "X " << CString(x) << "\r\n"; newFile << "Y " << CString(y) << "\r\n"; newFile << "Z " << CString(z) << "\r\n"; newFile << "MAXHP " << CString(maxPower) << "\r\n"; newFile << "HP " << CString(power) << "\r\n"; newFile << "RUPEES " << CString(gralatc) << "\r\n"; newFile << "ANI " << gani << "\r\n"; newFile << "ARROWS " << CString(arrowc) << "\r\n"; newFile << "BOMBS " << CString(bombc) << "\r\n"; newFile << "GLOVEP " << CString(glovePower) << "\r\n"; newFile << "SHIELDP " << CString(shieldPower) << "\r\n"; newFile << "SWORDP " << CString(swordPower) << "\r\n"; newFile << "BOWP " << CString(bowPower) << "\r\n"; newFile << "BOW " << bowImage << "\r\n"; newFile << "HEAD " << headImg << "\r\n"; newFile << "BODY " << bodyImg << "\r\n"; newFile << "SWORD " << swordImg << "\r\n"; newFile << "SHIELD " << shieldImg << "\r\n"; newFile << "COLORS " << CString(colors[0]) << "," << CString(colors[1]) << "," << CString(colors[2]) << "," << CString(colors[3]) << "," << CString(colors[4]) << "\r\n"; newFile << "SPRITE " << CString(sprite) << "\r\n"; newFile << "STATUS " << CString(status) << "\r\n"; newFile << "MP " << CString(mp) << "\r\n"; newFile << "AP " << CString(ap) << "\r\n"; newFile << "APCOUNTER " << CString(apCounter) << "\r\n"; newFile << "ONSECS " << CString(onlineTime) << "\r\n"; newFile << "IP " << CString(accountIp) << "\r\n"; newFile << "LANGUAGE " << language << "\r\n"; newFile << "KILLS " << CString(kills) << "\r\n"; newFile << "DEATHS " << CString(deaths) << "\r\n"; newFile << "RATING " << CString(rating) << "\r\n"; newFile << "DEVIATION " << CString(deviation) << "\r\n"; newFile << "OLDDEVIATION " << CString(oldDeviation) << "\r\n"; newFile << "LASTSPARTIME " << CString((unsigned long)lastSparTime) << "\r\n"; // Attributes for (unsigned int i = 0; i < 30; i++) { if (attrList[i].length() > 0) newFile << "ATTR" << CString(i+1) << " " << attrList[i] << "\r\n"; } // Chests for (unsigned int i = 0; i < chestList.size(); i++) newFile << "CHEST " << chestList[i] << "\r\n"; // Weapons for (unsigned int i = 0; i < weaponList.size(); i++) newFile << "WEAPON " << weaponList[i] << "\r\n"; // Flags for (std::map<CString, CString>::const_iterator i = mFlagList.begin(); i != mFlagList.end(); ++i) { newFile << "FLAG " << i->first; if (!i->second.isEmpty()) newFile << "=" << i->second; newFile << "\r\n"; } // Account Settings newFile << "\r\n"; newFile << "BANNED " << CString((int)(isBanned == true ? 1 : 0)) << "\r\n"; newFile << "BANREASON " << banReason << "\r\n"; newFile << "BANLENGTH " << banLength << "\r\n"; newFile << "COMMENTS " << accountComments << "\r\n"; newFile << "EMAIL " << email << "\r\n"; newFile << "LOCALRIGHTS " << CString(adminRights) << "\r\n"; newFile << "IPRANGE " << adminIp << "\r\n"; // Folder Rights for (unsigned int i = 0; i < folderList.size(); i++) newFile << "FOLDERRIGHT " << folderList[i] << "\r\n"; newFile << "LASTFOLDER " << lastFolder << "\r\n"; // See if a plugin saves the account. if (server->getPluginManager().SaveAccount(accountName.text(), newFile.text())) return true; // Save the account now. CString accpath = CString() << server->getServerPath() << "accounts/" << accountName << ".txt"; CFileSystem::fixPathSeparators(&accpath); if (!newFile.save(accpath)) server->getRCLog().out("** Error saving account: %s\n", accountName.text()); return true; }
int main(int argc, char *argv[]) { #ifdef PSPSDK pspDebugScreenInit(); SetupCallbacks(); #else // Shut down the server if we get a kill signal. signal( SIGINT, (sighandler_t) shutdownServer ); signal( SIGTERM, (sighandler_t) shutdownServer ); #endif /* Setup Data-Directory */ dataDir = CBuffer(argv[0]).replaceAll("\\", "/"); dataDir = dataDir.copy(0, dataDir.findl('/') + 1); programDir = dataDir; dataDir << "world/"; /* Main Initiating */ adminNames.load( __admin, sizeof(__admin) / sizeof(const char*) ); colourNames.load( __colours, sizeof(__colours) / sizeof(const char*) ); clothCommands.load( __cloths, sizeof(__cloths) / sizeof(const char*) ); defaultFiles.load( __defaultfiles, sizeof(__defaultfiles) / sizeof(const char*) ); playerIds.add(0); playerIds.add(0); npcIds.add(0); srand((int)time(NULL)); /* Load Important Files */ updateFile("rchelp.txt"); updateFile("rcmessage.txt"); updateFile("rules.txt"); updateFile("serverflags.txt"); updateFile("servermessage.html"); updateFile("foldersconfig.txt"); /* Load Settings */ if (!loadSettings("serveroptions.txt")) { errorOut("errorlog.txt", "Unable to load server settings.."); return 1; } /* Load Weapons */ if (!loadWeapons("weapons.txt")) { errorOut("errorlog.txt", "Unable to load weapons from weapons.txt.."); return 1; } /* Initialize Sockets */ serverSock.setType( SOCKET_TYPE_SERVER ); serverSock.setProtocol( SOCKET_PROTOCOL_TCP ); serverSock.setOptions( SOCKET_OPTION_NONBLOCKING ); serverSock.setDescription( "serverSock" ); CString empty; if ( serverSock.init( empty, serverPort ) ) return 1; // Connect server socket. if ( serverSock.connect() ) { errorOut("errorlog.txt", CString() << "SOCK ERROR: Unable to listen on port: " << serverPort); return 1; } /* Server Finished Loading */ printf("GServer 2 by 39ster\nSpecial thanks to Marlon, Agret, Pac300, 39ster and others for porting the \noriginal 1.39 gserver to 2.1\nServer listening on port: %s\nServer version: Build %s\n\n", serverPort.text(), listServerFields[3].text()); errorOut("serverlog.txt", "Server started"); if ( listServerFields[5] == "localhost" ) errorOut("serverlog.txt", "[DEBUG_LOCALHOSTMODE] Localhost mode is activated.\nListserver communication & account authentication are disabled.", true); serverRunning = true; if ( !(listServerFields[5] == "localhost") ) if (!lsConnected) ListServer_Connect(); while (serverRunning) { long long second = time(NULL); while (second == time(NULL)) { acceptNewPlayers(serverSock); for (int i = 0; i < newPlayers.count(); i ++) { CPlayer* player = (CPlayer*)newPlayers[i]; player->main(); if (player->deleteMe) { delete player; i--; } } for(int i = 0; i < playerList.count(); i++) { CPlayer* player = (CPlayer*)playerList[i]; player->main(); if(player->deleteMe) { delete player; i--; } } // Was moved so it can process faster. - Joey ListServer_Main(); wait(10); } doTimer(); gameTime ++; NOLEVEL->reset(); // Every 30 seconds if (gameTime % 30 == 0) { ListServer_Send(CPacket() << (char)SLSPING << "\n"); } // Every 10 seconds if (gameTime % 10 == 0) { CPacket pPacket; CString file; for (int i = 0; i < playerList.count(); i++) { CPlayer *player = (CPlayer *)playerList[i]; file << player->accountName << "," << player->nickName << "," << player->levelName << "," << toString(player->x) << "," << toString(player->y) << "," << toString(player->ap) << "\n"; } file.save("logs/playerlist.txt"); serverFlags.save("serverflags.txt"); } //Every 5 seconds? int current = getNWTime(); if (nwTime != current) { nwTime = current; for (int i = 0; i < playerList.count(); i++) { CPacket out; out << (char)NEWWORLDTIME; out.writeByte4(current); ((CPlayer*)playerList[i])->sendPacket(out); } } } }
/* TAccount: Account Management */ bool TAccount::meetsConditions( CString fileName, CString conditions ) { const char* conditional[] = { ">=", "<=", "!=", "=", ">", "<" }; // Load and check if the file is valid. std::vector<CString> file; file = CString::loadToken(fileName, "\n", true); if (file.size() == 0 || (file.size() != 0 && file[0] != "GRACC001")) return false; // Load the conditions into a string list. std::vector<CString> cond; conditions.removeAllI("'"); conditions.replaceAllI("%", "*"); cond = conditions.tokenize(","); bool* conditionsMet = new bool[cond.size()]; memset((void*)conditionsMet, 0, sizeof(bool) * cond.size()); // Go through each line of the loaded file. for (std::vector<CString>::iterator i = file.begin(); i != file.end(); ++i) { int sep = (*i).find(' '); CString section = (*i).subString(0, sep); CString val = (*i).subString(sep + 1).removeAll("\r"); section.trimI(); val.trimI(); // Check each line against the conditions specified. for (unsigned int j = 0; j < cond.size(); ++j) { int cond_num = -1; // Read out the name and value. cond[j].setRead(0); // Find out what conditional we are using. for (int k = 0; k < 6; ++k) { if (cond[j].find(conditional[k]) != -1) { cond_num = k; k = 6; } } if (cond_num == -1) continue; CString cname = cond[j].readString(conditional[cond_num]); CString cvalue = cond[j].readString(""); cname.trimI(); cvalue.trimI(); cond[j].setRead(0); // Now, do a case-insensitive comparison of the section name. #ifdef WIN32 if (_stricmp(section.text(), cname.text()) == 0) #else if (strcasecmp(section.text(), cname.text()) == 0) #endif { switch (cond_num) { case 0: case 1: { // 0: >= // 1: <= // Check if it is a number. If so, do a number comparison. bool condmet = false; if (val.isNumber()) { double vNum[2] = { atof(val.text()), atof(cvalue.text()) }; if (((cond_num == 1) ? (vNum[0] <= vNum[1]) : (vNum[0] >= vNum[1]))) { conditionsMet[j] = true; condmet = true; } } else { // If not a number, do a string comparison. int ret = strcmp(val.text(), cvalue.text()); if (((cond_num == 1) ? (ret <= 0) : (ret >= 0))) { conditionsMet[j] = true; condmet = true; } } // No conditions met means we see if we can fail. if (condmet == false) { CString cnameUp = cname.toUpper(); if (!(cnameUp == "CHEST" || cnameUp == "WEAPON" || cnameUp == "FLAG" || cnameUp == "FOLDERRIGHT")) goto condAbort; } break; } case 4: case 5: { // 4: > // 5: < bool condmet = false; if (val.isNumber()) { double vNum[2] = { atof(val.text()), atof(cvalue.text()) }; if (((cond_num == 5) ? (vNum[0] < vNum[1]) : (vNum[0] > vNum[1]))) { conditionsMet[j] = true; condmet = true; } } else { int ret = strcmp(val.text(), cvalue.text()); if (((cond_num == 5) ? (ret < 0) : (ret > 0))) { conditionsMet[j] = true; condmet = true; } } if (condmet == false) { CString cnameUp = cname.toUpper(); if (!(cnameUp == "CHEST" || cnameUp == "WEAPON" || cnameUp == "FLAG" || cnameUp == "FOLDERRIGHT")) goto condAbort; } break; } case 2: { // 2: != // If we find a match, return false. if (val.isNumber()) { double vNum[2] = { atof(val.text()), atof(cvalue.text()) }; if (vNum[0] == vNum[1]) goto condAbort; conditionsMet[j] = true; } else { if (val.match(cvalue.text()) == true) goto condAbort; conditionsMet[j] = true; } break; } case 3: default: { // 0 - equals // If it returns false, don't include this account in the search. bool condmet = false; if (val.isNumber()) { double vNum[2] = { atof(val.text()), atof(cvalue.text()) }; if (vNum[0] == vNum[1]) { conditionsMet[j] = true; condmet = true; } } else { if (val.match(cvalue.text()) == true) { conditionsMet[j] = true; condmet = true; } } if (condmet == false) { CString cnameUp = cname.toUpper(); if (!(cnameUp == "CHEST" || cnameUp == "WEAPON" || cnameUp == "FLAG" || cnameUp == "FOLDERRIGHT")) goto condAbort; } break; } } } } } // Check if all the conditions were met. for (unsigned int i = 0; i < cond.size(); ++i) if (conditionsMet[i] == false) goto condAbort; // Clean up. delete [] conditionsMet; return true; condAbort: delete [] conditionsMet; return false; }