void C4Network2IRCChannel::OnUsers(const char *szUsers, const char *szPrefixes) { // Find actual prefixes szPrefixes = SSearch(szPrefixes, ")"); // Reconstructs the list if(!fReceivingUsers) ClearUsers(); while(szUsers && *szUsers) { // Get user name StdStrBuf PrefixedName = ircExtractPar(&szUsers); // Remove prefix(es) const char *szName = PrefixedName.getData(); if(szPrefixes) while(strchr(szPrefixes, *szName)) szName++; // Copy prefix StdStrBuf Prefix; Prefix.Copy(PrefixedName.getData(), szName - PrefixedName.getData()); // Add user AddUser(szName)->SetPrefix(Prefix.getData()); } // Set flag the user list won't get cleared again until OnUsersEnd is called fReceivingUsers = true; }
bool C4Network2Res::SetByFile(const char *strFilePath, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName, bool fSilent) { CStdLock FileLock(&FileCSec); // default resource name: relative path if (!szResName) szResName = Config.AtRelativePath(strFilePath); SCopy(strFilePath, szFile, sizeof(szFile)-1); // group? C4Group Grp; if (Reloc.Open(Grp, strFilePath)) return SetByGroup(&Grp, fTemp, eType, iResID, szResName, fSilent); // so it needs to be a file StdStrBuf szFullFile; if (!Reloc.LocateItem(szFile, szFullFile)) { if (!fSilent) LogF("SetByFile: file %s not found!", strFilePath); return false; } // calc checksum uint32_t iCRC32; if (!GetFileCRC(szFullFile.getData(), &iCRC32)) return false; #ifdef C4NET2RES_DEBUG_LOG // log LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, szResName, szFile, fTemp ? "temp" : "static"); #endif // set core Core.Set(eType, iResID, Config.AtRelativePath(szFullFile.getData()), iCRC32); // set own data fDirty = true; fTempFile = fTemp; fStandaloneFailed = false; fRemoved = false; iLastReqTime = time(NULL); fLoading = false; // ok return true; }
bool OpenLog() { // open sLogFileName = C4CFN_Log; int iLog = 2; #ifdef _WIN32 while (!(C4LogFile = _fsopen(Config.AtUserDataPath(sLogFileName.getData()), "wt", _SH_DENYWR))) #elif defined(HAVE_SYS_FILE_H) int fd = 0; while (!(fd = open(Config.AtUserDataPath(sLogFileName.getData()), O_WRONLY | O_CREAT, 0644)) || flock(fd, LOCK_EX|LOCK_NB)) #else while (!(C4LogFile = fopen(Config.AtUserDataPath(sLogFileName.getData()), "wb"))) #endif { // Already locked by another instance? #if !defined(_WIN32) && defined(HAVE_SYS_FILE_H) if (fd) close(fd); #else if (C4LogFile) fclose(C4LogFile); #endif // If the file does not yet exist, the directory is r/o // don't go on then, or we have an infinite loop if (access(Config.AtUserDataPath(sLogFileName.getData()), 0)) return false; // try different name sLogFileName.Format(C4CFN_LogEx, iLog++); } #if !defined(_WIN32) && defined(HAVE_SYS_FILE_H) ftruncate(fd, 0); C4LogFile = fdopen(fd, "wb"); #endif // save start time time(&C4LogStartTime); return true; }
void C4Console::UpdateNetMenu() { // Active & network hosting check if (!Active) return; if (!::Network.isHost() || !::Network.isEnabled()) return; // Clear old ClearNetMenu(); // Insert menu C4ConsoleGUI::AddNetMenu(); // Host StdStrBuf str; str.Format(LoadResStr("IDS_MNU_NETHOST"),Game.Clients.getLocalName(),Game.Clients.getLocalID()); AddNetMenuItemForPlayer(Game.Clients.getLocalID(), str.getData(), C4ConsoleGUI::CO_None); // Clients for (C4Network2Client *pClient=::Network.Clients.GetNextClient(nullptr); pClient; pClient=::Network.Clients.GetNextClient(pClient)) { if (pClient->isHost()) continue; str.Format(LoadResStr(pClient->isActivated() ? "IDS_MNU_NETCLIENT_DEACTIVATE" : "IDS_MNU_NETCLIENT_ACTIVATE"), pClient->getName(), pClient->getID()); AddNetMenuItemForPlayer(pClient->getID(), str.getData(), pClient->isActivated() ? C4ConsoleGUI::CO_Deactivate : C4ConsoleGUI::CO_Activate); str.Format(LoadResStr("IDS_NET_KICKCLIENTEX"), pClient->getName(), pClient->getID()); AddNetMenuItemForPlayer(pClient->getID(), str.getData(), C4ConsoleGUI::CO_Kick); } return; }
bool C4PlayerList::Save(C4Group &hGroup, bool fStoreTiny, const C4PlayerInfoList &rStoreList) { StdStrBuf sTempFilename; bool fSuccess = true; // Save to external player files and add to group for (C4Player *pPlr=First; pPlr; pPlr=pPlr->Next) { // save only those in the list, and only those with a filename C4PlayerInfo *pNfo = rStoreList.GetPlayerInfoByID(pPlr->ID); if (!pNfo) continue; if (!pNfo->GetFilename() || !*pNfo->GetFilename()) continue;; // save over original file? bool fStoreOnOriginal = (!fStoreTiny && pNfo->GetType() == C4PT_User); // Create temporary file sTempFilename.Copy(Config.AtTempPath(pNfo->GetFilename())); if (fStoreOnOriginal) if (!C4Group_CopyItem(pPlr->Filename, sTempFilename.getData())) return false; // Open group C4Group PlrGroup; if (!PlrGroup.Open(sTempFilename.getData(), !fStoreOnOriginal)) return false; // Save player if (!pPlr->Save(PlrGroup, true, fStoreOnOriginal)) return false; PlrGroup.Close(); // Add temp file to group if (!hGroup.Move(sTempFilename.getData(), pNfo->GetFilename())) return false; } return fSuccess; }
void C4Def::LoadMeshMaterials(C4Group &hGroup, C4DefGraphicsPtrBackup *gfx_backup) { // Load all mesh materials from this folder C4DefAdditionalResourcesLoader loader(hGroup); hGroup.ResetSearch(); char MaterialFilename[_MAX_PATH + 1]; *MaterialFilename = 0; for (const auto &mat : mesh_materials) { ::MeshMaterialManager.Remove(mat, &gfx_backup->GetUpdater()); } mesh_materials.clear(); while (hGroup.FindNextEntry(C4CFN_DefMaterials, MaterialFilename, NULL, !!*MaterialFilename)) { StdStrBuf material; if (hGroup.LoadEntryString(MaterialFilename, &material)) { try { StdStrBuf buf; buf.Copy(hGroup.GetName()); buf.Append("/"); buf.Append(MaterialFilename); auto new_materials = ::MeshMaterialManager.Parse(material.getData(), buf.getData(), loader); mesh_materials.insert(new_materials.begin(), new_materials.end()); } catch (const StdMeshMaterialError& ex) { DebugLogF("Failed to read material script: %s", ex.what()); } } } }
bool LogSilent(const char *szMessage, bool fConsole) { if (!Application.AssertMainThread()) return false; // security if (!szMessage) return false; // add timestamp time_t timenow; time(&timenow); StdStrBuf TimeMessage; TimeMessage.SetLength(11 + SLen(szMessage) + 1); strftime(TimeMessage.getMData(), 11 + 1, "[%H:%M:%S] ", localtime(&timenow)); // output until all data is written const char *pSrc = szMessage; do { // timestamp will always be that length char *pDest = TimeMessage.getMData() + 11; // copy rest of message, skip tags CMarkup Markup(false); while (*pSrc) { Markup.SkipTags(&pSrc); // break on crlf while (*pSrc == '\r') pSrc++; if (*pSrc == '\n') { pSrc++; break; } // copy otherwise if (*pSrc) *pDest++ = *pSrc++; } *pDest++ = '\n'; *pDest = '\0'; #ifdef HAVE_ICONV StdStrBuf Line = Languages.IconvSystem(TimeMessage.getData()); #else StdStrBuf &Line = TimeMessage; #endif // Save into log file if (C4LogFile) { fputs(Line.getData(), C4LogFile); fflush(C4LogFile); } // Write to console if (fConsole || Game.Verbose) { #if defined(_DEBUG) && defined(_WIN32) // debug: output to VC console OutputDebugString(Line.getData()); #endif fputs(Line.getData(), stdout); fflush(stdout); } } while (*pSrc); return true; }
size_t C4Network2IRCClient::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) { // Find line seperation const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize())); if(!pSep) return 0; // Check if it's actually correct seperation (rarely the case) int iSize = pSep - getBufPtr<char>(rInBuf) + 1, iLength = iSize - 1; if(iLength && *(pSep - 1) == '\r') iLength--; // Copy the line StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength); // Ignore prefix const char *pMsg = Buf.getData(); StdStrBuf Prefix; if(*pMsg == ':') { Prefix.CopyUntil(pMsg + 1, ' '); pMsg += Prefix.getLength() + 1; } // Strip whitespace while(*pMsg == ' ') pMsg++; // Ignore empty message if(!*pMsg) return iSize; // Get command StdStrBuf Cmd; Cmd.CopyUntil(pMsg, ' '); // Precess command const char *szParameters = SSearch(pMsg, " "); OnCommand(Prefix.getData(), Cmd.getData(), szParameters ? szParameters : ""); // Consume the line return iSize; }
bool C4Network2Res::SetByGroup(C4Group *pGrp, bool fTemp, C4Network2ResType eType, int32_t iResID, const char *szResName, bool fSilent) // by main thread { Clear(); CStdLock FileLock(&FileCSec); // default resource name: relative path StdStrBuf sResName; if (szResName) sResName = szResName; else { StdStrBuf sFullName = pGrp->GetFullName(); sResName.Copy(Config.AtRelativePath(sFullName.getData())); } SCopy(pGrp->GetFullName().getData(), szFile, sizeof(szFile)-1); // set core Core.Set(eType, iResID, sResName.getData(), pGrp->EntryCRC32()); #ifdef C4NET2RES_DEBUG_LOG // log LogSilentF("Network: Resource: complete %d:%s is file %s (%s)", iResID, sResName.getData(), szFile, fTemp ? "temp" : "static"); #endif // set data fDirty = true; fTempFile = fTemp; fStandaloneFailed = false; fRemoved = false; iLastReqTime = time(NULL); fLoading = false; // ok return true; }
void C4Network2ResDlg::ListItem::Update(const C4Network2Res *pByRes) { // update progress label iProgress = pByRes->getPresentPercent(); if (iProgress < 100) { StdStrBuf progress; progress.Format("%d%%", iProgress); if (pProgress) pProgress->SetText(progress.getData()); else { pProgress = new C4GUI::Label(progress.getData(), GetBounds().Wdt - IconLabelSpacing, 0, ARight); pProgress->SetToolTip(LoadResStr("IDS_NET_RESPROGRESS_DESC")); AddElement(pProgress); } } else if (pProgress) { delete pProgress; pProgress=NULL; } // update disk icon if (IsSavePossible()) { if (!pSaveBtn) { pSaveBtn = new C4GUI::CallbackButtonEx<C4Network2ResDlg::ListItem, C4GUI::IconButton>(C4GUI::Ico_Save, GetToprightCornerRect(16,16,2,1), 0, this, &ListItem::OnButtonSave); AddElement(pSaveBtn); } } else if (pSaveBtn) delete pSaveBtn; }
bool C4Language::Init() { // Clear (to allow clean re-init) Clear(); // Make sure Language.ocg is unpacked (TODO: This won't work properly if Language.ocg is in system data path) // Assume for now that Language.ocg is either at a writable location or unpacked already. // TODO: Use all Language.c4gs that we find, and merge them. // TODO: Use gettext instead? StdStrBuf langPath; C4Reloc::iterator iter; for(iter = Reloc.begin(); iter != Reloc.end(); ++iter) { langPath.Copy((*iter).strBuf + DirSep + C4CFN_Languages); if(ItemExists(langPath.getData())) { if(DirectoryExists(langPath.getData())) break; if(C4Group_UnpackDirectory(langPath.getData())) break; } } // Break if no language.ocg found if(iter != Reloc.end()) { // Look for available language packs in Language.ocg C4Group *pPack; char strPackFilename[_MAX_FNAME + 1], strEntry[_MAX_FNAME + 1]; if (PackDirectory.Open(langPath.getData())) { while (PackDirectory.FindNextEntry("*.ocg", strEntry)) { sprintf(strPackFilename, "%s" DirSep "%s", C4CFN_Languages, strEntry); pPack = new C4Group(); if (pPack->Open(strPackFilename)) { Packs.RegisterGroup(*pPack, true, C4GSCnt_Language, false); } else { delete pPack; } } } // Now create a pack group for each language pack (these pack groups are child groups // that browse along each pack to access requested data) for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++) PackGroups.RegisterGroup(*(new C4Group), true, C4GSPrio_Base, C4GSCnt_Language); } // Load language infos by scanning string tables (the engine doesn't really need this at the moment) InitInfos(); // Done return true; }
void C4Network2IRCClient::OnMessage(bool fNotice, const char *szSender, const char *szTarget, const char *szText) { // Find channel, if not private. C4Network2IRCChannel *pChan = NULL; if(!SEqualNoCase(szTarget, Nick.getData())) pChan = getChannel(szTarget); // CTCP tagged data? const char X_DELIM = '\001'; if(szText[0] == X_DELIM) { // Process messages (it's very rarely more than one, but the spec allows it) const char *pMsg = szText + 1; while(*pMsg) { // Find end const char *pEnd = strchr(pMsg, X_DELIM); if(!pEnd) pEnd = pMsg + SLen(pMsg); // Copy CTCP query/reply, get tag StdStrBuf CTCP; CTCP.Copy(pMsg, pEnd - pMsg); StdStrBuf Tag; Tag.CopyUntil(CTCP.getData(), ' '); const char *szData = SSearch(CTCP.getData(), " "); StdStrBuf Sender; Sender.CopyUntil(szSender, '!'); // Process if(SEqualNoCase(Tag.getData(), "ACTION")) PushMessage(MSG_Action, szSender, szTarget, szData ? szData : ""); if(SEqualNoCase(Tag.getData(), "FINGER") && !fNotice) { StdStrBuf Answer; if(Config.Registered()) { Answer = Config.GetRegistrationData("Cuid"); } else { Answer = LoadResStr("IDS_PRC_UNREGUSER"); } Send("NOTICE", FormatString("%s :%cFINGER %s%c", Sender.getData(), X_DELIM, Answer.getData(), X_DELIM).getData()); } if(SEqualNoCase(Tag.getData(), "VERSION") && !fNotice) Send("NOTICE", FormatString("%s :%cVERSION " C4ENGINECAPTION ":" C4VERSION ":" C4_OS "%c", Sender.getData(), X_DELIM, X_DELIM).getData()); if(SEqualNoCase(Tag.getData(), "PING") && !fNotice) Send("NOTICE", FormatString("%s :%cPING %s%c", Sender.getData(), X_DELIM, szData, X_DELIM).getData()); // Get next message pMsg = pEnd; if(*pMsg == X_DELIM) pMsg++; } } // Standard message (not CTCP tagged): Push else PushMessage(fNotice ? MSG_Notice : MSG_Message, szSender, szTarget, szText); }
bool C4Network2Res::SetByCore(const C4Network2ResCore &nCore, bool fSilent, const char *szAsFilename, int32_t iRecursion) // by main thread { StdStrBuf sFilename; // try open local file const char *szFilename = szAsFilename ? szAsFilename : GetC4Filename(nCore.getFileName()); if (SetByFile(szFilename, false, nCore.getType(), nCore.getID(), nCore.getFileName(), fSilent)) { // check contents checksum if (Core.getContentsCRC() == nCore.getContentsCRC()) { // set core fDirty = true; Core = nCore; // ok then return true; } } // get and search for filename without specified folder (e.g., Castle.ocs when the opened game is Easy.ocf\Castle.ocs) const char *szFilenameOnly = GetFilename(szFilename); const char *szFilenameC4 = GetC4Filename(szFilename); if (szFilenameOnly != szFilenameC4) { sFilename.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4)); sFilename.Append(szFilenameOnly); if (SetByCore(nCore, fSilent, szFilenameOnly, Config.Network.MaxResSearchRecursion)) return true; } // if it could still not be set, try within all folders of root (ignoring special folders), and try as file outside the folder // but do not recurse any deeper than set by config (default: One folder) if (iRecursion >= Config.Network.MaxResSearchRecursion) return false; StdStrBuf sSearchPath; const char *szSearchPath; if (!iRecursion) szSearchPath = Config.General.ExePath.getData(); else { sSearchPath.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4)); szSearchPath = sSearchPath.getData(); } StdStrBuf sNetPath; sNetPath.Copy(Config.Network.WorkPath); char *szNetPath = sNetPath.GrabPointer(); TruncateBackslash(szNetPath); sNetPath.Take(szNetPath); for (DirectoryIterator i(szSearchPath); *i; ++i) if (DirectoryExists(*i)) if (!*GetExtension(*i)) // directories without extension only if (!szNetPath || !*szNetPath || !ItemIdentical(*i, szNetPath)) // ignore network path { // search for complete name at subpath (e.g. MyFolder\Easy.ocf\Castle.ocs) sFilename.Format("%s%c%s", *i, DirectorySeparator, szFilenameC4); if (SetByCore(nCore, fSilent, sFilename.getData(), iRecursion + 1)) return true; } // file could not be found locally return false; }
bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg) { // name by file Name.Copy(GetFilenameOnly(szFilename)); #if defined(_WIN32) && !defined(HAVE_FREETYPE) // check whether group is directory or packed if (!hGrp.IsPacked()) { // it's open: use the file directly SCopy(hGrp.GetFullName().getData(), FileName, _MAX_PATH); AppendBackslash(FileName); SAppend(szFilename, FileName); if (!FileExists(FileName)) { *FileName=0; return false; } fIsTempFile = false; } else { // it's packed: extract to temp path SCopy(rCfg.AtTempPath(szFilename), FileName, _MAX_PATH); // make sure the filename is not in use, in case multiple instances of the engine are run if (FileExists(FileName)) { RemoveExtension(FileName); StdStrBuf sNewFilename; for (int i=0; i<1000; ++i) { sNewFilename.Format("%s%x", FileName, (int)rand()); if (*GetExtension(szFilename)) { sNewFilename.AppendChar('.'); sNewFilename.Append(GetExtension(szFilename)); } if (!FileExists(sNewFilename.getData())) break; } SCopy(sNewFilename.getData(), FileName, _MAX_PATH); } if (!hGrp.ExtractEntry(szFilename, FileName)) { *FileName=0; return false; } fIsTempFile = true; } // add the font resource //if (!AddFontResourceEx(FileName, FR_PRIVATE, NULL)) requires win2k if (!AddFontResource(FileName)) { if (fIsTempFile) EraseFile(FileName); *FileName='\0'; return false; } #else if (!hGrp.LoadEntry(szFilename, Data)) return false; #endif // success return true; }
void C4StartupMainDlg::OnNetJoin(const StdStrBuf &rsHostAddress) { // no IP given: No join if (!rsHostAddress || !*rsHostAddress.getData()) return; // set default startup parameters *Game.ScenarioFilename=0; SCopy("Objects.ocd", Game.DefinitionFilenames); Game.NetworkActive = true; Game.fLobby = true; Game.fObserve = false; SCopy(rsHostAddress.getData(), Game.DirectJoinAddress, sizeof(Game.DirectJoinAddress)-1); // start with this set! Application.OpenGame(); }
GLenum C4Shader::AddTexCoord(const char *szName) { // Make sure we have enough space assert(iTexCoords < C4Shader_MaxTexCoords); if(iTexCoords >= C4Shader_MaxTexCoords) return -1; // Add slices StdStrBuf Code = FormatString("gl_TexCoord[%d] = gl_MultiTexCoord%d;\n", iTexCoords, iTexCoords); AddVertexSlice(C4Shader_Vertex_TexCoordPos, Code.getData()); Code.Format("#define %s gl_TexCoord[%d]\n", szName, iTexCoords); AddFragmentSlice(-1, Code.getData()); return GL_TEXTURE0 + iTexCoords++; }
int C4Shader::ParsePosition(const char *szWhat, const char **ppPos) { const char *pPos = *ppPos; while (isspace(*pPos)) pPos++; // Expect a name const char *pStart = pPos; while (isalnum(*pPos)) pPos++; StdStrBuf Name; Name.Copy(pStart, pPos - pStart); // Lookup name int iPosition = -1; for (int i = 0; i < sizeof(C4SH_PosNames) / sizeof(*C4SH_PosNames); i++) { if (SEqual(Name.getData(), C4SH_PosNames[i].Name)) { iPosition = C4SH_PosNames[i].Position; break; } } if (iPosition == -1) { ShaderLogF(" gl: Unknown slice position in %s: %s", szWhat, Name.getData()); return -1; } // Add modifier while (isspace(*pPos)) pPos++; if (*pPos == '+') { int iMod, iModLen; if (!sscanf(pPos+1, "%d%n", &iMod, &iModLen)) { ShaderLogF(" gl: Invalid slice modifier in %s", szWhat); return -1; } iPosition += iMod; pPos += 1+iModLen; } if (*pPos == '-') { int iMod, iModLen; if (!sscanf(pPos+1, "%d%n", &iMod, &iModLen)) { ShaderLogF(" gl: Invalid slice modifier in %s", szWhat); return -1; } iPosition -= iMod; pPos += 1+iModLen; } // Everything okay! *ppPos = pPos; return iPosition; }
bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName) { #ifdef C4ENGINE // build file in memory StdStrBuf sTexMapFile; // add desc sTexMapFile.Append("# Automatically generated texture map" LineFeed); sTexMapFile.Append("# Contains material-texture-combinations added at runtime" LineFeed); // add overload-entries if (fOverloadMaterials) sTexMapFile.Append("# Import materials from global file as well" LineFeed "OverloadMaterials" LineFeed); if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well" LineFeed "OverloadTextures" LineFeed); sTexMapFile.Append(LineFeed); // add entries for (int32_t i = 0; i < C4M_MaxTexIndex; i++) if (!Entry[i].isNull()) { // compose line sTexMapFile.AppendFormat("%d=%s-%s" LineFeed, i, Entry[i].GetMaterialName(), Entry[i].GetTextureName()); } // create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers size_t iBufSize = sTexMapFile.getLength(); BYTE *pBuf = new BYTE[iBufSize]; memcpy(pBuf, sTexMapFile.getData(), iBufSize); // add to group bool fSuccess = !!hGroup.Add(szEntryName, pBuf, iBufSize, false, true); if (!fSuccess) delete [] pBuf; // done return fSuccess; #else return FALSE; #endif }
bool C4Application::SetGameFont(const char *szFontFace, int32_t iFontSize) { #ifndef USE_CONSOLE // safety if (!szFontFace || !*szFontFace || iFontSize<1 || SLen(szFontFace)>=static_cast<int>(sizeof Config.General.RXFontName)) return false; // first, check if the selected font can be created at all // check regular font only - there's no reason why the other fonts couldn't be created CStdFont TestFont; if (!::FontLoader.InitFont(&TestFont, szFontFace, C4FontLoader::C4FT_Main, iFontSize, &::GraphicsResource.Files)) return false; // OK; reinit all fonts StdStrBuf sOldFont; sOldFont.Copy(Config.General.RXFontName); int32_t iOldFontSize = Config.General.RXFontSize; SCopy(szFontFace, Config.General.RXFontName); Config.General.RXFontSize = iFontSize; if (!::GraphicsResource.InitFonts() || !C4Startup::Get()->Graphics.InitFonts()) { // failed :o // shouldn't happen. Better restore config. SCopy(sOldFont.getData(), Config.General.RXFontName); Config.General.RXFontSize = iOldFontSize; return false; } #endif // save changes return true; }
bool C4DownloadDlg::DownloadFile(const char *szDLType, C4GUI::Screen *pScreen, const char *szURL, const char *szSaveAsFilename, const char *szNotFoundMessage) { // log it LogF(LoadResStr("IDS_PRC_DOWNLOADINGFILE"), szURL); // show download dialog C4DownloadDlg *pDlg = new C4DownloadDlg(szDLType); if (!pDlg->ShowModal(pScreen, szURL, szSaveAsFilename)) { // show an appropriate error const char *szError = pDlg->GetError(); if (!szError || !*szError) szError = LoadResStr("IDS_PRC_UNKOWNERROR"); StdStrBuf sError; sError.Format(LoadResStr("IDS_PRC_DOWNLOADERROR"), GetFilename(szURL), szError); // it's a 404: display extended message if (SSearch(szError, "404") && szNotFoundMessage) { sError.Append("|"); sError.Append(szNotFoundMessage); } // display message pScreen->ShowMessageModal(sError.getData(), FormatString(LoadResStr("IDS_CTL_DL_TITLE"), szDLType).getData(), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error, NULL); delete pDlg; return false; } LogF(LoadResStr("IDS_PRC_DOWNLOADCOMPLETE"), szURL); delete pDlg; return true; }
bool ShaderLogF(const char *strMessage ...) { va_list args; va_start(args, strMessage); StdStrBuf Buf; Buf.FormatV(strMessage, args); return ShaderLog(Buf.getData()); }
static int RunFile(const char * filename, bool checkOnly) { C4Group File; if (!File.Open(GetWorkingDirectory())) { fprintf(stderr, "Open failed: %s\n", File.GetError()); return 1; } // get scripts StdStrBuf fn; File.ResetSearch(); if (!File.FindNextEntry(filename, &fn)) { fprintf(stderr, "FindNextEntry failed: %s\n", File.GetError()); return 1; } InitializeC4Script(); GameScript.Load(File, fn.getData(), nullptr, nullptr); if (!checkOnly) RunLoadedC4Script(); ClearC4Script(); return ScriptEngine.errCnt; }
void C4StartupMainDlg::OnNetJoin(const StdStrBuf &rsHostAddress) { #ifdef NETWORK // no IP given: No join if (!rsHostAddress || !*rsHostAddress.getData()) return; // set default startup parameters *Game.ScenarioFilename = 0; SCopy("Objects.c4d", Game.DefinitionFilenames); Game.NetworkActive = TRUE; Game.fLobby = TRUE; Game.fObserve = FALSE; SCopy(rsHostAddress.getData(), Game.DirectJoinAddress, sizeof(Game.DirectJoinAddress) - 1); // start with this set! C4Startup::Get()->Start(); #endif }
bool C4GameSave::SaveDesc(C4Group &hToGroup) { // Unfortunately, there's no way to prealloc the buffer in an appropriate size StdStrBuf sBuffer; // Header sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", 0 /*FIXME: a number for UTF-8 here*/); sBuffer.Append(LineFeed); // Scenario title sBuffer.AppendFormat("\\uc1\\pard\\ulnone\\b\\f0\\fs20 %s\\par",Game.ScenarioTitle.getData()); sBuffer.Append(LineFeed "\\b0\\fs16\\par" LineFeed); // OK; each specializations has its own desc format WriteDesc(sBuffer); // End of file sBuffer.Append(LineFeed "}" LineFeed); // Generate Filename StdStrBuf sFilename; char szLang[3]; SCopyUntil(Config.General.Language, szLang, ',', 2); sFilename.Format(C4CFN_ScenarioDesc,szLang); // Save to file return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true); }
void C4GameOverDlg::SetNetResult(const char *szResultString, C4RoundResults::NetResult eResultType, size_t iPendingStreamingData, bool fIsStreaming) { // add info about pending streaming data StdStrBuf sResult(szResultString); if (fIsStreaming) { sResult.AppendChar('|'); sResult.AppendFormat("[!]Transmitting record to league server... (%d kb remaining)", int(iPendingStreamingData/1024)); } // message linebreak into box StdStrBuf sBrokenResult; C4GUI::GetRes()->TextFont.BreakMessage(sResult.getData(), pNetResultLabel->GetBounds().Wdt, &sBrokenResult, true); pNetResultLabel->SetText(sBrokenResult.getData(), false); // all done? if (eResultType != C4RoundResults::NR_None && !fIsStreaming) { // a final result is determined and all streaming data has been transmitted fIsNetDone = true; } // network error? if (eResultType == C4RoundResults::NR_NetError) { // disconnected. Do not show winners/losers for (int32_t i=0; i<iPlrListCount; ++i) ppPlayerLists[i]->SetMode(C4PlayerInfoListBox::PILBM_EvaluationNoWinners); } }
StdStrBuf C4FileSelDlg::GetSelection(const char *szFixedSelection, bool fFilenameOnly) const { StdStrBuf sResult; if (!IsMultiSelection()) { // get single selected file for single selection dlg if (pSelection) sResult.Copy(fFilenameOnly ? GetFilename(pSelection->GetFilename()) : pSelection->GetFilename()); } else { // force fixed selection first if (szFixedSelection) sResult.Append(szFixedSelection); // get ';'-seperated list for multi selection dlg for (ListItem *pFileItem = static_cast<ListItem *>(pFileListBox->GetFirst()); pFileItem; pFileItem = static_cast<ListItem *>(pFileItem->GetNext())) if (pFileItem->IsChecked()) { const char *szAppendFilename = pFileItem->GetFilename(); if (fFilenameOnly) szAppendFilename = GetFilename(szAppendFilename); // prevent adding entries twice (especially those from the fixed // selection list) if (!SIsModule(sResult.getData(), szAppendFilename)) { if (sResult.getLength()) sResult.AppendChar(';'); sResult.Append(szAppendFilename); } } } return sResult; }
bool C4MaterialMap::LoadEnumeration(C4Group &hGroup) { // Load enumeration map (from savegame), succeed if not present StdStrBuf mapbuf; if (!hGroup.LoadEntryString(C4CFN_MatMap, &mapbuf)) return true; // Sort material array by enumeration map, fail if some missing const char *csearch; char cmatname[C4M_MaxName+1]; int32_t cmat=0; if (!(csearch = SSearch(mapbuf.getData(),"[Enumeration]"))) { return false; } csearch=SAdvanceSpace(csearch); while (IsIdentifier(*csearch)) { SCopyIdentifier(csearch,cmatname,C4M_MaxName); if (!SortEnumeration(cmat,cmatname)) { // Output error message! return false; } cmat++; csearch+=SLen(cmatname); csearch=SAdvanceSpace(csearch); } return true; }
bool C4PlayerInfoCore::Load(C4Group &hGroup) { // New version StdStrBuf Source; if (hGroup.LoadEntryString(C4CFN_PlayerInfoCore,&Source)) { // Compile StdStrBuf GrpName = hGroup.GetFullName(); GrpName.Append(DirSep C4CFN_PlayerInfoCore); if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Source, GrpName.getData())) return false; // Pref for AutoContextMenus is still undecided: default by player's control style if (OldPrefAutoContextMenu == -1) OldPrefAutoContextMenu = OldPrefControlStyle; // Determine true color from indexed pref color if (!PrefColorDw) PrefColorDw = GetPrefColorValue(PrefColor); // Validate colors PrefColorDw &= 0xffffff; PrefColor2Dw &= 0xffffff; // Validate name C4Markup::StripMarkup(PrefName); // Success return true; } // Old version no longer supported - sorry return false; }
void C4Console::PlayerJoin() { // Get player file name(s) StdCopyStrBuf c4pfile(""); if (!FileSelect(&c4pfile, "OpenClonk Player\0*.ocp\0\0", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER )) return; // Multiple players if (DirectoryExists(c4pfile.getData())) { const char *cptr = c4pfile.getData() + SLen(c4pfile.getData()) + 1; while (*cptr) { StdStrBuf f; f.Copy(c4pfile.getData()); f.AppendBackslash(); f.Append(cptr); cptr += SLen(cptr)+1; ::Players.JoinNew(f.getData()); } } // Single player else { ::Players.JoinNew(c4pfile.getData()); } }
bool C4TexMapEntry::Init() { // Find material iMaterialIndex = ::MaterialMap.Get(Material.getData()); if (!MatValid(iMaterialIndex)) { DebugLogF("Error initializing material %s-%s: Invalid material!", Material.getData(), Texture.getData()); return false; } pMaterial = &::MaterialMap.Map[iMaterialIndex]; // Find texture StdStrBuf FirstTexture; FirstTexture.CopyUntil(Texture.getData(), '-'); C4Texture * sfcTexture = ::TextureMap.GetTexture(FirstTexture.getData()); if (!sfcTexture) { DebugLogF("Error initializing material %s-%s: Invalid texture!", Material.getData(), FirstTexture.getData()); Clear(); return false; } // Get overlay properties int32_t iOverlayType=pMaterial->OverlayType; int32_t iZoom=0; if (iOverlayType & C4MatOv_Exact) iZoom=1; if (iOverlayType & C4MatOv_HugeZoom) iZoom=4; // Create pattern MatPattern.Set(sfcTexture->Surface32, iZoom); return true; }