bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source) { ResourceCache* cache = GetSubsystem<ResourceCache>(); unsigned dataSize = source.GetSize(); SharedArrayPtr<char> buffer(new char[dataSize]); source.Read((void*)buffer.Get(), dataSize); // Pre-parse for includes // Adapted from Angelscript's scriptbuilder add-on Vector<String> includeFiles; unsigned pos = 0; while(pos < dataSize) { int len; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_COMMENT || t == asTC_WHITESPACE) { pos += len; continue; } // Is this a preprocessor directive? if (buffer[pos] == '#') { int start = pos++; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_IDENTIFIER) { String token(&buffer[pos], len); if (token == "include") { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_WHITESPACE) { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); } if (t == asTC_VALUE && len > 2 && buffer[pos] == '"') { // Get the include file String includeFile(&buffer[pos+1], len - 2); pos += len; // If the file is not found as it is, add the path of current file but only if it is found there if (!cache->Exists(includeFile)) { String prefixedIncludeFile = GetPath(GetName()) + includeFile; if (cache->Exists(prefixedIncludeFile)) includeFile = prefixedIncludeFile; } String includeFileLower = includeFile.ToLower(); // If not included yet, store it for later processing if (!includeFiles_.Contains(includeFileLower)) { includeFiles_.Insert(includeFileLower); includeFiles.Push(includeFile); } // Overwrite the include directive with space characters to avoid compiler error memset(&buffer[start], ' ', pos - start); } } } } // Don't search includes within statement blocks or between tokens in statements else { int len; // Skip until ; or { whichever comes first while (pos < dataSize && buffer[pos] != ';' && buffer[pos] != '{') { engine->ParseToken(&buffer[pos], 0, &len); pos += len; } // Skip entire statement block if (pos < dataSize && buffer[pos] == '{') { ++pos; // Find the end of the statement block int level = 1; while (level > 0 && pos < dataSize) { asETokenClass t = engine->ParseToken(&buffer[pos], 0, &len); if (t == asTC_KEYWORD) { if (buffer[pos] == '{') ++level; else if(buffer[pos] == '}') --level; } pos += len; } } else ++pos; } } // Process includes first for (unsigned i = 0; i < includeFiles.Size(); ++i) { cache->StoreResourceDependency(this, includeFiles[i]); SharedPtr<File> file = cache->GetFile(includeFiles[i]); if (file) { if (!AddScriptSection(engine, *file)) return false; } else { LOGERROR("Could not process all the include directives in " + GetName() + ": missing " + includeFiles[i]); return false; } } // Then add this section if (scriptModule_->AddScriptSection(source.GetName().CString(), (const char*)buffer.Get(), dataSize) < 0) { LOGERROR("Failed to add script section " + source.GetName()); return false; } SetMemoryUse(GetMemoryUse() + dataSize); return true; }
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject* pParent, std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths, u32 nesting_depth) { ENSURE(pParent); XMBAttributeList attributes = Element.GetAttributes(); CStr type(attributes.GetNamedItem(pFile->GetAttributeID("type"))); if (type.empty()) type = "empty"; // Construct object from specified type // henceforth, we need to do a rollback before aborting. // i.e. releasing this object IGUIObject* object = ConstructObject(type); if (!object) { LOGERROR("GUI: Unrecognized object type \"%s\"", type.c_str()); return; } // Cache some IDs for element attribute names, to avoid string comparisons #define ELMT(x) int elmt_##x = pFile->GetElementID(#x) #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x) ELMT(object); ELMT(action); ELMT(repeat); ELMT(translatableAttribute); ELMT(translate); ELMT(attribute); ELMT(keep); ELMT(include); ATTR(style); ATTR(type); ATTR(name); ATTR(hotkey); ATTR(z); ATTR(on); ATTR(file); ATTR(directory); ATTR(id); ATTR(context); // // Read Style and set defaults // // If the setting "style" is set, try loading that setting. // // Always load default (if it's available) first! // CStr argStyle(attributes.GetNamedItem(attr_style)); if (m_Styles.count("default") == 1) object->LoadStyle(*this, "default"); if (!argStyle.empty()) { if (m_Styles.count(argStyle) == 0) LOGERROR("GUI: Trying to use style '%s' that doesn't exist.", argStyle.c_str()); else object->LoadStyle(*this, argStyle); } bool NameSet = false; bool ManuallySetZ = false; CStrW inclusionPath; CStr hotkeyTag; for (XMBAttribute attr : attributes) { // If value is "null", then it is equivalent as never being entered if (CStr(attr.Value) == "null") continue; // Ignore "type" and "style", we've already checked it if (attr.Name == attr_type || attr.Name == attr_style) continue; if (attr.Name == attr_name) { CStr name(attr.Value); for (const std::pair<CStr, CStr>& sub : NameSubst) name.Replace(sub.first, sub.second); object->SetName(name); NameSet = true; continue; } if (attr.Name == attr_hotkey) hotkeyTag = attr.Value; if (attr.Name == attr_z) ManuallySetZ = true; if (object->SetSetting(pFile->GetAttributeString(attr.Name), attr.Value.FromUTF8(), true) != PSRETURN_OK) LOGERROR("GUI: (object: %s) Can't set \"%s\" to \"%s\"", object->GetPresentableName(), pFile->GetAttributeString(attr.Name), attr.Value); } // Check if name isn't set, generate an internal name in that case. if (!NameSet) { object->SetName("__internal(" + CStr::FromInt(m_InternalNameNumber) + ")"); ++m_InternalNameNumber; } if (!hotkeyTag.empty()) m_HotkeyObjects[hotkeyTag].push_back(object); CStrW caption(Element.GetText().FromUTF8()); if (!caption.empty()) object->SetSetting("caption", caption, true); for (XMBElement child : Element.GetChildNodes()) { // Check what name the elements got int element_name = child.GetNodeName(); if (element_name == elmt_object) { // Call this function on the child Xeromyces_ReadObject(child, pFile, object, NameSubst, Paths, nesting_depth); } else if (element_name == elmt_action) { // Scripted <action> element // Check for a 'file' parameter CStrW filename(child.GetAttributes().GetNamedItem(attr_file).FromUTF8()); CStr code; // If there is a file, open it and use it as the code if (!filename.empty()) { Paths.insert(filename); CVFSFile scriptfile; if (scriptfile.Load(g_VFS, filename) != PSRETURN_OK) { LOGERROR("Error opening GUI script action file '%s'", utf8_from_wstring(filename)); throw PSERROR_GUI_JSOpenFailed(); } code = scriptfile.DecodeUTF8(); // assume it's UTF-8 } XMBElementList grandchildren = child.GetChildNodes(); if (!grandchildren.empty()) // The <action> element contains <keep> and <translate> tags. for (XMBElement grandchild : grandchildren) { if (grandchild.GetNodeName() == elmt_translate) code += g_L10n.Translate(grandchild.GetText()); else if (grandchild.GetNodeName() == elmt_keep) code += grandchild.GetText(); } else // It’s pure JavaScript code. // Read the inline code (concatenating to the file code, if both are specified) code += CStr(child.GetText()); CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on)); // We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI. object->SetGUI(this); object->RegisterScriptHandler(action.LowerCase(), code, this); } else if (element_name == elmt_repeat) { Xeromyces_ReadRepeat(child, pFile, object, NameSubst, Paths, nesting_depth); } else if (element_name == elmt_translatableAttribute) { // This is an element in the form “<translatableAttribute id="attributeName">attributeValue</translatableAttribute>”. CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name. if (attributeName.empty()) { LOGERROR("GUI: ‘translatableAttribute’ XML element with empty ‘id’ XML attribute found. (object: %s)", object->GetPresentableName().c_str()); continue; } CStr value(child.GetText()); if (value.empty()) continue; CStr context(child.GetAttributes().GetNamedItem(attr_context)); // Read the context if any. if (!context.empty()) { CStr translatedValue(g_L10n.TranslateWithContext(context, value)); object->SetSetting(attributeName, translatedValue.FromUTF8(), true); } else { CStr translatedValue(g_L10n.Translate(value)); object->SetSetting(attributeName, translatedValue.FromUTF8(), true); } } else if (element_name == elmt_attribute) { // This is an element in the form “<attribute id="attributeName"><keep>Don’t translate this part // </keep><translate>but translate this one.</translate></attribute>”. CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name. if (attributeName.empty()) { LOGERROR("GUI: ‘attribute’ XML element with empty ‘id’ XML attribute found. (object: %s)", object->GetPresentableName().c_str()); continue; } CStr translatedValue; for (XMBElement grandchild : child.GetChildNodes()) { if (grandchild.GetNodeName() == elmt_translate) translatedValue += g_L10n.Translate(grandchild.GetText()); else if (grandchild.GetNodeName() == elmt_keep) translatedValue += grandchild.GetText(); } object->SetSetting(attributeName, translatedValue.FromUTF8(), true); } else if (element_name == elmt_include) { CStrW filename(child.GetAttributes().GetNamedItem(attr_file).FromUTF8()); CStrW directory(child.GetAttributes().GetNamedItem(attr_directory).FromUTF8()); if (!filename.empty()) { if (!directory.empty()) LOGWARNING("GUI: Include element found with file name (%s) and directory name (%s). Only the file will be processed.", utf8_from_wstring(filename), utf8_from_wstring(directory)); Paths.insert(filename); CXeromyces XeroIncluded; if (XeroIncluded.Load(g_VFS, filename, "gui") != PSRETURN_OK) { LOGERROR("GUI: Error reading included XML: '%s'", utf8_from_wstring(filename)); continue; } XMBElement node = XeroIncluded.GetRoot(); if (node.GetNodeName() != XeroIncluded.GetElementID("object")) { LOGERROR("GUI: Error reading included XML: '%s', root element must have be of type 'object'.", utf8_from_wstring(filename)); continue; } if (nesting_depth+1 >= MAX_OBJECT_DEPTH) { LOGERROR("GUI: Too many nested GUI includes. Probably caused by a recursive include attribute. Abort rendering '%s'.", utf8_from_wstring(filename)); continue; } Xeromyces_ReadObject(node, &XeroIncluded, object, NameSubst, Paths, nesting_depth+1); } else if (!directory.empty()) { if (nesting_depth+1 >= MAX_OBJECT_DEPTH) { LOGERROR("GUI: Too many nested GUI includes. Probably caused by a recursive include attribute. Abort rendering '%s'.", utf8_from_wstring(directory)); continue; } VfsPaths pathnames; vfs::GetPathnames(g_VFS, directory, L"*.xml", pathnames); for (const VfsPath& path : pathnames) { // as opposed to loading scripts, don't care if it's loaded before // one might use the same parts of the GUI in different situations Paths.insert(path); CXeromyces XeroIncluded; if (XeroIncluded.Load(g_VFS, path, "gui") != PSRETURN_OK) { LOGERROR("GUI: Error reading included XML: '%s'", path.string8()); continue; } XMBElement node = XeroIncluded.GetRoot(); if (node.GetNodeName() != XeroIncluded.GetElementID("object")) { LOGERROR("GUI: Error reading included XML: '%s', root element must have be of type 'object'.", path.string8()); continue; } Xeromyces_ReadObject(node, &XeroIncluded, object, NameSubst, Paths, nesting_depth+1); } } else LOGERROR("GUI: 'include' XML element must have valid 'file' or 'directory' attribute found. (object %s)", object->GetPresentableName().c_str()); } else { // Try making the object read the tag. if (!object->HandleAdditionalChildren(child, pFile)) LOGERROR("GUI: (object: %s) Reading unknown children for its type", object->GetPresentableName().c_str()); } } if (!ManuallySetZ) { // Set it automatically to 10 plus its parents bool absolute; GUI<bool>::GetSetting(object, "absolute", absolute); if (absolute) // If the object is absolute, we'll have to get the parent's Z buffered, // and add to that! GUI<float>::SetSetting(object, "z", pParent->GetBufferedZ() + 10.f, true); else // If the object is relative, then we'll just store Z as "10" GUI<float>::SetSetting(object, "z", 10.f, true); } try { if (pParent == m_BaseObject) AddObject(object); else pParent->AddChild(object); } catch (PSERROR_GUI& e) { LOGERROR("GUI error: %s", e.what()); } }
bool AnimationSet2D::LoadAnimation(const XMLElement& animationElem) { SharedPtr<Animation2D> animation(new Animation2D(this)); String name = animationElem.GetAttribute("name"); animation->SetName(name); float length = animationElem.GetFloat("length") * 0.001f; animation->SetLength(length); bool looped = true; if (animationElem.HasAttribute("looping")) looped = animationElem.GetBool("looping"); animation->SetLooped(looped); // Load timelines for (XMLElement timelineElem = animationElem.GetChild("timeline"); timelineElem; timelineElem = timelineElem.GetNext("timeline")) { Timeline2D timeline; timeline.name_ = timelineElem.GetAttribute("name"); if (timelineElem.GetAttribute("object_type") == "bone") timeline.type_ = OT_BONE; else timeline.type_ = OT_SPRITE; for (XMLElement keyElem = timelineElem.GetChild("key"); keyElem; keyElem = keyElem.GetNext("key")) { TimelineKey2D key; key.time_ = keyElem.GetFloat("time") * 0.001f; key.spin_ = 1; if (keyElem.HasAttribute("spin")) key.spin_ = keyElem.GetInt("spin"); XMLElement childElem = keyElem.GetChild(); Vector2 position; position.x_ = childElem.GetFloat("x"); position.y_ = childElem.GetFloat("y"); float angle = childElem.GetFloat("angle"); Vector2 scale(Vector2::ONE); if (childElem.HasAttribute("scale_x")) scale.x_ = childElem.GetFloat("scale_x"); if (childElem.HasAttribute("scale_y")) scale.y_ = childElem.GetFloat("scale_y"); key.transform_ = Transform2D(position, angle, scale); if (timeline.type_ == OT_SPRITE) { int folder = childElem.GetUInt("folder"); int file = childElem.GetUInt("file"); key.sprite_ = GetSprite(folder, file); if (!key.sprite_) { LOGERROR("Could not find sprite"); return false; } if (childElem.HasAttribute("pivot_x")) key.hotSpot_.x_ = childElem.GetFloat("pivot_x"); else key.hotSpot_.x_ = key.sprite_->GetHotSpot().x_; if (childElem.HasAttribute("pivot_y")) key.hotSpot_.y_ = childElem.GetFloat("pivot_y"); else key.hotSpot_.y_ = key.sprite_->GetHotSpot().y_; if (childElem.HasAttribute("a")) key.alpha_ = childElem.GetFloat("a"); } timeline.timelineKeys_.Push(key); } // Add end key for looped animation if (looped && timeline.timelineKeys_.Back().time_ != length) { TimelineKey2D key = timeline.timelineKeys_.Front(); key.time_ = length; timeline.timelineKeys_.Push(key); } animation->AddTimeline(timeline); } // Load main line XMLElement mainlineElem = animationElem.GetChild("mainline"); for (XMLElement keyElem = mainlineElem.GetChild("key"); keyElem; keyElem = keyElem.GetNext("key")) { MainlineKey2D mainlineKey; int id = keyElem.GetInt("id"); mainlineKey.time_ = keyElem.GetFloat("time") * 0.001f; for (XMLElement refElem = keyElem.GetChild(); refElem; refElem = refElem.GetNext()) { Reference2D ref; int refId = refElem.GetInt("id"); if (refElem.GetName() == "bone_ref") ref.type_ = OT_BONE; else ref.type_ = OT_SPRITE; ref.timeline_ = refElem.GetInt("timeline"); if (refElem.HasAttribute("parent")) { int parent = refElem.GetInt("parent"); int parentTimeline = mainlineKey.references_[parent].timeline_; animation->SetTimelineParent(ref.timeline_, parentTimeline); } if (refElem.GetName() == "object_ref") ref.zIndex_ = refElem.GetInt("z_index"); mainlineKey.references_.Push(ref); } animation->AddMainlineKey(mainlineKey); } animations_.Push(animation); return true; }
int main(int argc, char **argv) { #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) InitLeakFinder(); #endif // Magic code to produce dump-files on Windows if the server crashes: #if defined(_WIN32) && !defined(_WIN64) && defined(_MSC_VER) // 32-bit Windows app compiled in MSVC HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); if (g_WriteMiniDump != nullptr) { _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId()); SetUnhandledExceptionFilter(LastChanceExceptionFilter); } #endif // 32-bit Windows app compiled in MSVC // End of dump-file magic #if defined(_DEBUG) && defined(_MSC_VER) _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output) // Only useful when the leak is in the same sequence all the time // _CrtSetBreakAlloc(85950); #endif // _DEBUG && _MSC_VER #ifndef _DEBUG std::signal(SIGSEGV, NonCtrlHandler); std::signal(SIGTERM, NonCtrlHandler); std::signal(SIGINT, NonCtrlHandler); std::signal(SIGABRT, NonCtrlHandler); #ifdef SIGABRT_COMPAT std::signal(SIGABRT_COMPAT, NonCtrlHandler); #endif // SIGABRT_COMPAT #endif auto argsRepo = parseArguments(argc, argv); // Attempt to run as a service if (cRoot::m_RunAsService) { #if defined(_WIN32) // Windows service. SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)serviceMain }, { nullptr, nullptr } }; if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) { LOGERROR("Attempted, but failed, service startup."); return GetLastError(); } #else // UNIX daemon. pid_t pid = fork(); // fork() returns a negative value on error. if (pid < 0) { LOGERROR("Could not fork process."); return EXIT_FAILURE; } // Check if we are the parent or child process. Parent stops here. if (pid > 0) { return EXIT_SUCCESS; } // Child process now goes quiet, running in the background. close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); universalMain(std::move(argsRepo)); #endif } else { // Not running as a service, do normal startup universalMain(std::move(argsRepo)); } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) DeinitLeakFinder(); #endif return EXIT_SUCCESS; }
void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite& parent) { SGUIImage* Image = new SGUIImage; Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); // TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor) for (XMBAttribute attr : Element.GetAttributes()) { CStr attr_name(pFile->GetAttributeString(attr.Name)); CStrW attr_value(attr.Value.FromUTF8()); if (attr_name == "texture") { Image->m_TextureName = VfsPath("art/textures/ui") / attr_value; } else if (attr_name == "size") { CClientArea ca; if (!GUI<CClientArea>::ParseString(attr_value, ca)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_Size = ca; } else if (attr_name == "texture_size") { CClientArea ca; if (!GUI<CClientArea>::ParseString(attr_value, ca)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_TextureSize = ca; } else if (attr_name == "real_texture_placement") { CRect rect; if (!GUI<CRect>::ParseString(attr_value, rect)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_TexturePlacementInFile = rect; } else if (attr_name == "cell_size") { CSize size; if (!GUI<CSize>::ParseString(attr_value, size)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_CellSize = size; } else if (attr_name == "fixed_h_aspect_ratio") { float val; if (!GUI<float>::ParseString(attr_value, val)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_FixedHAspectRatio = val; } else if (attr_name == "round_coordinates") { bool b; if (!GUI<bool>::ParseString(attr_value, b)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_RoundCoordinates = b; } else if (attr_name == "wrap_mode") { if (attr_value == L"repeat") Image->m_WrapMode = GL_REPEAT; else if (attr_value == L"mirrored_repeat") Image->m_WrapMode = GL_MIRRORED_REPEAT; else if (attr_value == L"clamp_to_edge") Image->m_WrapMode = GL_CLAMP_TO_EDGE; else LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); } else if (attr_name == "z_level") { float z_level; if (!GUI<float>::ParseString(attr_value, z_level)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_DeltaZ = z_level/100.f; } else if (attr_name == "backcolor") { CColor color; if (!GUI<CColor>::ParseString(attr_value, color)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_BackColor = color; } else if (attr_name == "bordercolor") { CColor color; if (!GUI<CColor>::ParseString(attr_value, color)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_BorderColor = color; } else if (attr_name == "border") { bool b; if (!GUI<bool>::ParseString(attr_value, b)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); else Image->m_Border = b; } else debug_warn(L"Invalid data - DTD shouldn't allow this"); } // Look for effects for (XMBElement child : Element.GetChildNodes()) { CStr ElementName(pFile->GetElementString(child.GetNodeName())); if (ElementName == "effect") { if (Image->m_Effects) LOGERROR("GUI <image> must not have more than one <effect>"); else { Image->m_Effects = new SGUIImageEffects; Xeromyces_ReadEffects(child, pFile, *Image->m_Effects); } } else debug_warn(L"Invalid data - DTD shouldn't allow this"); } parent.AddImage(Image); }
void CSoundManager::al_ReportError(ALenum err, const char* caller, int line) { LOGERROR("OpenAL error: %s; called from %s (line %d)\n", alGetString(err), caller, line); }
int KHttp::getHttpFile(const KData& kServer, const KData& kHttpFile, const KData& kSaveFile, int nStartPos) { LOGD("Entry getHttpFile"); m_dtHttpServer = kServer; m_dtHttpFile = kHttpFile; m_bChunked = false; m_iWriteLen = nStartPos; m_iLength = 0; m_clientSock.close(); m_kCnnect.close(); _respHeadMap.clear(); m_iNotifyPos = 0; m_iNotifyGap = 0; m_iContentLength = 0; m_iStatusCode = 0; bool bGet = (_paramMap.size() == 0); KFile kFile; KData kHttpRequest; KData kDataPost; if (bGet) { kHttpRequest = "GET "; } else { kHttpRequest = "POST "; map<KData, KData>::iterator iter; for (iter = _paramMap.begin(); iter != _paramMap.end(); iter++) { if (iter != _paramMap.begin()) kDataPost += "&"; kDataPost += iter->first; kDataPost += "="; kDataPost += iter->second; } } kHttpRequest += kHttpFile; kHttpRequest += " HTTP/1.1"; kHttpRequest += CRLF; kHttpRequest += "Host: "; kHttpRequest += kServer; kHttpRequest += CRLF; kHttpRequest += "Accept: */*"; kHttpRequest += CRLF; if (!m_dtUserAgent.isEmpty()) { kHttpRequest += "User-Agent: "; kHttpRequest += m_dtUserAgent; kHttpRequest += CRLF; } if (nStartPos > 0) { kHttpRequest += "RANGE: bytes="; kHttpRequest += nStartPos; kHttpRequest += "-"; kHttpRequest += CRLF; } kHttpRequest += "Pragma: no-cache"; kHttpRequest += CRLF; kHttpRequest += "Cache-Control: no-cache"; kHttpRequest += CRLF; kHttpRequest += "Connection: close"; kHttpRequest += CRLF; if (!bGet) { kHttpRequest += "Content-Type: application/x-www-form-urlencoded"; kHttpRequest += CRLF; kHttpRequest += "Content-Length: "; kHttpRequest += KData((int) kDataPost.length()); kHttpRequest += CRLF; } kHttpRequest += CRLF; char szBuffer[MTU] = {0}; if (m_dtHttpProxy.isEmpty()) { LOGD("Connect to Server: %s", kServer.getData() ); m_clientSock.setServer(kServer, 80); } else { LOGD("Connect to Server: %s", m_dtHttpProxy.getData() ); m_clientSock.setServer(m_dtHttpProxy, 80); } m_clientSock.initSocket(); if (!m_clientSock.connect()) { LOGERROR("m_clientSock.connect() failed"); return -1; } m_kCnnect = m_clientSock.getConn(); m_kCnnect.setTimeout(m_timeout); if (m_kCnnect.writeData(kHttpRequest) != (int) kHttpRequest.length()) { LOGERROR(" m_conn.writeData(httpRequest) != (int)httpRequest.length() failed"); return -1; } m_iWritedBytes += kHttpRequest.length(); if (!bGet) { if (m_kCnnect.writeData(kDataPost) != (int) kDataPost.length()) { LOGERROR("m_conn.writeData(dtPost) != (int)dtPost.length() failed"); return -1; } m_iWritedBytes += kDataPost.length(); } int iRead = 0; m_iStatusCode = 0; bool bRun = true; memset(szBuffer, 0, MTU); if ((iRead = m_kCnnect.readLine(szBuffer, MTU)) <= 0) { LOGERROR( "Read command line err: %d", iRead ); m_iReadedBytes += iRead; return 0; } KData dtKData; KData dtLine(szBuffer, iRead); if (dtLine.match(SP, &dtKData, true) == NOT_FOUND) { LOGERROR("Read command line mactch space err" ); return 0; } if (dtKData != "HTTP/1.1" && dtKData != "HTTP/1.0") { LOGERROR( "GET HTTP HEAD ERR" ); return 0; } if (dtLine.match(SP, &dtKData, true) == NOT_FOUND) { LOGERROR("Read command line mactch space 2 err" ); return 0; } m_iStatusCode = (int)dtKData; LOGD("Ready to while ( (iRead = m_conn.readLine(buff,MTU)) > 0 )"); while ((iRead = m_kCnnect.readLine(szBuffer, MTU)) > 0) { m_iReadedBytes += iRead; KData dtLine(szBuffer, iRead); KData dtBefVal; if (FOUND == dtLine.match(":", &dtBefVal, true)) { dtBefVal.removeSpaces(); dtLine.removeSpaces(); if (isEqualNoCase(dtBefVal, "Content-Length")) { m_iLength = (int) dtLine + nStartPos; if (m_iNotifyPercent > 0 && m_iNotifyPercent <= 100) { m_iNotifyPos = m_iNotifyGap = m_iLength / (100 / m_iNotifyPercent); } } else if (isEqualNoCase(dtBefVal, "Transfer-Encoding")) { if (isEqualNoCase(dtLine, "chunked")) { m_bChunked = true; } } _respHeadMap[dtBefVal] = dtLine; } } if (iRead < 0) { LOGERROR("read err" ); return -1; } if (m_iStatusCode != 200 && m_iStatusCode != 206) { if (m_iStatusCode == 302) { KData dtRedirectUrl = getRespFieldValue("Location"); LOGD("Ready to return getHttpFile( dtRedirectUrl, savefile, startpos );"); return getHttpFile(dtRedirectUrl, kSaveFile, nStartPos); } LOGERROR(" m_iStatusCode!=200 && m_iStatusCode!=206"); return 0; } FILE* pkFile = 0; string strFile = kSaveFile.getData(); if (nStartPos <= 0) { pkFile = fopen(strFile.c_str(),"wb+"); } else { pkFile = fopen(strFile.c_str(), "wb+"); fclose(pkFile); pkFile = fopen(strFile.c_str(),"r+b"); if (0 == pkFile) { return -1; } fseek(pkFile, nStartPos, SEEK_SET); } if (m_bChunked) { LOGD("m_bChunked is true!"); unsigned char* pBuff = new unsigned char[MTU]; int iBuffLen = MTU; while ((iRead = m_kCnnect.readLine(szBuffer, MTU)) > 0) { m_iReadedBytes += iRead; if (iRead > 8) { return -1; } int nLength = KData(szBuffer, iRead).HexToInt(); if (nLength <= 0) { delete [] pBuff; return m_iWriteLen; } if (nLength > iBuffLen) { delete[] pBuff; iBuffLen = nLength; pBuff = new unsigned char[iBuffLen]; } int iReaded = 0; memset(pBuff, 0, nLength); m_kCnnect.readData(pBuff, nLength, iReaded); m_iReadedBytes += iReaded; kFile.write(pBuff, iReaded); m_iWriteLen += iReaded; if (m_iLength > 0) { if (m_iWriteLen >= m_iLength) { if (m_iNotifyGap > 0) { m_pNotifyCallback(m_pNotifyParam, 100, m_iWriteLen, m_iLength); } break; } if (m_iNotifyGap > 0 && m_iWriteLen > m_iNotifyPos) { int nPercent = int((m_iWriteLen / (float) m_iLength) * 100); m_iNotifyPos += m_iNotifyGap; m_pNotifyCallback(m_pNotifyParam, nPercent, m_iWriteLen, m_iLength); } } if (iReaded != nLength) { delete[] pBuff; return m_iWriteLen; } if (m_kCnnect.readLine(szBuffer, MTU) != 0) { return m_iWriteLen; } } delete[] pBuff; return m_iWriteLen; } else { string strFile = kSaveFile.getData(); while ((iRead = m_kCnnect.readn(szBuffer, MTU)) > 0 && bRun) { m_iReadedBytes += iRead; unsigned int uiWriteSize = fwrite((unsigned char*) szBuffer,1,iRead,pkFile); //kFile.write((unsigned char*) szBuffer, iRead); m_iWriteLen += iRead; if (m_iLength > 0) { if (m_iWriteLen >= m_iLength) { if (m_iNotifyGap > 0) { m_pNotifyCallback(m_pNotifyParam, 100, m_iWriteLen, m_iLength); } break; } if (m_iNotifyGap > 0 && m_iWriteLen > m_iNotifyPos) { int nPercent = int((m_iWriteLen / (float) m_iLength) * 100); m_iNotifyPos += m_iNotifyGap; m_pNotifyCallback(m_pNotifyParam, nPercent, m_iWriteLen, m_iLength); } } while (m_bPause) { vsleep(1000); } } //fclose(pkFile); } fclose(pkFile); m_kCnnect.close(); kFile.closeFile(); LOGD("return m_iWriteLen;"); return m_iWriteLen; }
bool FileWatcher::StartWatching(const String& pathName, bool watchSubDirs) { if (!fileSystem_) { LOGERROR("No FileSystem, can not start watching"); return false; } // Stop any previous watching StopWatching(); #if defined(ENABLE_FILEWATCHER) #if defined(WIN32) String nativePath = GetNativePath(RemoveTrailingSlash(pathName)); dirHandle_ = (void*)CreateFileW( WString(nativePath).CString(), FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (dirHandle_ != INVALID_HANDLE_VALUE) { path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; Start(); LOGDEBUG("Started watching path " + pathName); return true; } else { LOGERROR("Failed to start watching path " + pathName); return false; } #elif defined(__linux__) int flags = IN_CREATE|IN_DELETE|IN_MODIFY|IN_MOVED_FROM|IN_MOVED_TO; int handle = inotify_add_watch(watchHandle_, pathName.CString(), flags); if (handle < 0) { LOGERROR("Failed to start watching path " + pathName); return false; } else { // Store the root path here when reconstructed with inotify later dirHandle_[handle] = ""; path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; if (watchSubDirs_) { Vector<String> subDirs; fileSystem_->ScanDir(subDirs, pathName, "*", SCAN_DIRS, true); for (unsigned i = 0; i < subDirs.Size(); ++i) { String subDirFullPath = AddTrailingSlash(path_ + subDirs[i]); // Don't watch ./ or ../ sub-directories if (!subDirFullPath.EndsWith("./")) { handle = inotify_add_watch(watchHandle_, subDirFullPath.CString(), flags); if (handle < 0) LOGERROR("Failed to start watching subdirectory path " + subDirFullPath); else { // Store sub-directory to reconstruct later from inotify dirHandle_[handle] = AddTrailingSlash(subDirs[i]); } } } } Start(); LOGDEBUG("Started watching path " + pathName); return true; } #elif defined(__APPLE__) && !defined(IOS) if (!supported_) { LOGERROR("Individual file watching not supported by this OS version, can not start watching path " + pathName); return false; } watcher_ = CreateFileWatcher(pathName.CString(), watchSubDirs); if (watcher_) { path_ = AddTrailingSlash(pathName); watchSubDirs_ = watchSubDirs; Start(); LOGDEBUG("Started watching path " + pathName); return true; } else { LOGERROR("Failed to start watching path " + pathName); return false; } #else LOGERROR("FileWatcher not implemented, can not start watching path " + pathName); return false; #endif #else LOGDEBUG("FileWatcher feature not enabled"); return false; #endif }
bool cServer::InitServer(cIniFile & a_SettingsIni) { m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!").c_str(); m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100); m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false); m_PlayerCount = 0; m_PlayerCountDiff = 0; m_FaviconData = Base64Encode(cFile::ReadWholeFile(FILE_IO_PREFIX + AString("favicon.png"))); // Will return empty string if file nonexistant; client doesn't mind if (m_bIsConnected) { LOGERROR("ERROR: Trying to initialize server while server is already running!"); return false; } LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS); LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS); if (cSocket::WSAStartup() != 0) // Only does anything on Windows, but whatever { LOGERROR("WSAStartup() != 0"); return false; } bool HasAnyPorts = false; AString Ports = a_SettingsIni.GetValueSet("Server", "Port", "25565"); m_ListenThreadIPv4.SetReuseAddr(true); if (m_ListenThreadIPv4.Initialize(Ports)) { HasAnyPorts = true; } Ports = a_SettingsIni.GetValueSet("Server", "PortsIPv6", "25565"); m_ListenThreadIPv6.SetReuseAddr(true); if (m_ListenThreadIPv6.Initialize(Ports)) { HasAnyPorts = true; } if (!HasAnyPorts) { LOGERROR("Couldn't open any ports. Aborting the server"); return false; } m_RCONServer.Initialize(a_SettingsIni); m_bIsConnected = true; m_ServerID = "-"; m_ShouldAuthenticate = a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true); if (m_ShouldAuthenticate) { MTRand mtrand1; unsigned int r1 = (mtrand1.randInt() % 1147483647) + 1000000000; unsigned int r2 = (mtrand1.randInt() % 1147483647) + 1000000000; std::ostringstream sid; sid << std::hex << r1; sid << std::hex << r2; m_ServerID = sid.str(); m_ServerID.resize(16, '0'); } m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) { m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance); } if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE) { m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE; LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance); } m_NotifyWriteThread.Start(this); PrepareKeys(); return true; }
void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) { // style object we're adding SGUIScrollBarStyle scrollbar; CStr name; // // Read Attributes // // Now we can iterate all attributes and store XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name = pFile->GetAttributeString(attr.Name); CStr attr_value (attr.Value); if (attr_value == "null") continue; if (attr_name == "name") name = attr_value; else if (attr_name == "show_edge_buttons") { bool b; if (!GUI<bool>::ParseString(attr_value.FromUTF8(), b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_UseEdgeButtons = b; } if (attr_name == "width") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_Width = f; } else if (attr_name == "minimum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_MinimumBarSize = f; } else if (attr_name == "maximum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_MaximumBarSize = f; } else if (attr_name == "sprite_button_top") scrollbar.m_SpriteButtonTop = attr_value; else if (attr_name == "sprite_button_top_pressed") scrollbar.m_SpriteButtonTopPressed = attr_value; else if (attr_name == "sprite_button_top_disabled") scrollbar.m_SpriteButtonTopDisabled = attr_value; else if (attr_name == "sprite_button_top_over") scrollbar.m_SpriteButtonTopOver = attr_value; else if (attr_name == "sprite_button_bottom") scrollbar.m_SpriteButtonBottom = attr_value; else if (attr_name == "sprite_button_bottom_pressed") scrollbar.m_SpriteButtonBottomPressed = attr_value; else if (attr_name == "sprite_button_bottom_disabled") scrollbar.m_SpriteButtonBottomDisabled = attr_value; else if (attr_name == "sprite_button_bottom_over") scrollbar.m_SpriteButtonBottomOver = attr_value; else if (attr_name == "sprite_back_vertical") scrollbar.m_SpriteBackVertical = attr_value; else if (attr_name == "sprite_bar_vertical") scrollbar.m_SpriteBarVertical = attr_value; else if (attr_name == "sprite_bar_vertical_over") scrollbar.m_SpriteBarVerticalOver = attr_value; else if (attr_name == "sprite_bar_vertical_pressed") scrollbar.m_SpriteBarVerticalPressed = attr_value; } // // Add to CGUI // m_ScrollBarStyles[name] = scrollbar; }
bool Sound::LoadWav(Deserializer& source) { WavHeader header; // Try to open memset(&header, 0, sizeof header); source.Read(&header.riffText_, 4); header.totalLength_ = source.ReadUInt(); source.Read(&header.waveText_, 4); if (memcmp("RIFF", header.riffText_, 4) || memcmp("WAVE", header.waveText_, 4)) { LOGERROR("Could not read WAV data from " + source.GetName()); return false; } // Search for the FORMAT chunk for (;;) { source.Read(&header.formatText_, 4); header.formatLength_ = source.ReadUInt(); if (!memcmp("fmt ", &header.formatText_, 4)) break; source.Seek(source.GetPosition() + header.formatLength_); if (!header.formatLength_ || source.GetPosition() >= source.GetSize()) { LOGERROR("Could not read WAV data from " + source.GetName()); return false; } } // Read the FORMAT chunk header.format_ = source.ReadUShort(); header.channels_ = source.ReadUShort(); header.frequency_ = source.ReadUInt(); header.avgBytes_ = source.ReadUInt(); header.blockAlign_ = source.ReadUShort(); header.bits_ = source.ReadUShort(); // Skip data if the format chunk was bigger than what we use source.Seek(source.GetPosition() + header.formatLength_ - 16); // Check for correct format if (header.format_ != 1) { LOGERROR("Could not read WAV data from " + source.GetName()); return false; } // Search for the DATA chunk for (;;) { source.Read(&header.dataText_, 4); header.dataLength_ = source.ReadUInt(); if (!memcmp("data", &header.dataText_, 4)) break; source.Seek(source.GetPosition() + header.dataLength_); if (!header.dataLength_ || source.GetPosition() >= source.GetSize()) { LOGERROR("Could not read WAV data from " + source.GetName()); return false; } } // Allocate sound and load audio data unsigned length = header.dataLength_; SetSize(length); SetFormat(header.frequency_, header.bits_ == 16, header.channels_ == 2); source.Read(data_.Get(), length); // Convert 8-bit audio to signed if (!sixteenBit_) { for (unsigned i = 0; i < length; ++i) data_[i] -= 128; } return true; }
void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) { // Sprite object we're adding CGUISprite* Sprite = new CGUISprite; // and what will be its reference name CStr name; // // Read Attributes // // Get name, we know it exists because of DTD requirements name = Element.GetAttributes().GetNamedItem( pFile->GetAttributeID("name") ); if (m_Sprites.find(name) != m_Sprites.end()) LOGWARNING(L"GUI sprite name '%hs' used more than once; first definition will be discarded", name.c_str()); // // Read Children (the images) // SGUIImageEffects* effects = NULL; // Iterate children XMBElementList children = Element.GetChildNodes(); for (int i=0; i<children.Count; ++i) { // Get node XMBElement child = children.Item(i); CStr ElementName (pFile->GetElementString(child.GetNodeName())); if (ElementName == "image") { Xeromyces_ReadImage(child, pFile, *Sprite); } else if (ElementName == "effect") { if (effects) { LOGERROR(L"GUI <sprite> must not have more than one <effect>"); } else { effects = new SGUIImageEffects; Xeromyces_ReadEffects(child, pFile, *effects); } } else { debug_warn(L"Invalid data - DTD shouldn't allow this"); } } // Apply the effects to every image (unless the image overrides it with // different effects) if (effects) for (std::vector<SGUIImage*>::iterator it = Sprite->m_Images.begin(); it != Sprite->m_Images.end(); ++it) if (! (*it)->m_Effects) (*it)->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later delete effects; // // Add Sprite // m_Sprites[name] = Sprite; }
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths) { ENSURE(pParent); int i; // Our object we are going to create IGUIObject *object = NULL; XMBAttributeList attributes = Element.GetAttributes(); // Well first of all we need to determine the type CStr type (attributes.GetNamedItem(pFile->GetAttributeID("type"))); if (type.empty()) type = "empty"; // Construct object from specified type // henceforth, we need to do a rollback before aborting. // i.e. releasing this object object = ConstructObject(type); if (!object) { // Report error that object was unsuccessfully loaded LOGERROR(L"GUI: Unrecognized object type \"%hs\"", type.c_str()); return; } // Cache some IDs for element attribute names, to avoid string comparisons #define ELMT(x) int elmt_##x = pFile->GetElementID(#x) #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x) ELMT(object); ELMT(action); ELMT(repeat); ATTR(style); ATTR(type); ATTR(name); ATTR(hotkey); ATTR(z); ATTR(on); ATTR(file); // // Read Style and set defaults // // If the setting "style" is set, try loading that setting. // // Always load default (if it's available) first! // CStr argStyle (attributes.GetNamedItem(attr_style)); if (m_Styles.count("default") == 1) object->LoadStyle(*this, "default"); if (! argStyle.empty()) { // additional check if (m_Styles.count(argStyle) == 0) { LOGERROR(L"GUI: Trying to use style '%hs' that doesn't exist.", argStyle.c_str()); } else object->LoadStyle(*this, argStyle); } // // Read Attributes // bool NameSet = false; bool ManuallySetZ = false; // if z has been manually set, this turn true CStr hotkeyTag; // Now we can iterate all attributes and store for (i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); // If value is "null", then it is equivalent as never being entered if (CStr(attr.Value) == "null") continue; // Ignore "type" and "style", we've already checked it if (attr.Name == attr_type || attr.Name == attr_style) continue; // Also the name needs some special attention if (attr.Name == attr_name) { CStr name (attr.Value); // Apply the requested substitutions for (size_t j = 0; j < NameSubst.size(); ++j) name.Replace(NameSubst[j].first, NameSubst[j].second); object->SetName(name); NameSet = true; continue; } // Wire up the hotkey tag, if it has one if (attr.Name == attr_hotkey) hotkeyTag = attr.Value; if (attr.Name == attr_z) ManuallySetZ = true; // Try setting the value if (object->SetSetting(pFile->GetAttributeString(attr.Name), attr.Value.FromUTF8(), true) != PSRETURN_OK) { LOGERROR(L"GUI: (object: %hs) Can't set \"%hs\" to \"%ls\"", object->GetPresentableName().c_str(), pFile->GetAttributeString(attr.Name).c_str(), attr.Value.FromUTF8().c_str()); // This is not a fatal error } } // Check if name isn't set, generate an internal name in that case. if (!NameSet) { object->SetName("__internal(" + CStr::FromInt(m_InternalNameNumber) + ")"); ++m_InternalNameNumber; } // Attempt to register the hotkey tag, if one was provided if (! hotkeyTag.empty()) m_HotkeyObjects[hotkeyTag].push_back(object); CStrW caption (Element.GetText().FromUTF8()); if (! caption.empty()) { // Set the setting caption to this object->SetSetting("caption", caption, true); // There is no harm if the object didn't have a "caption" } // // Read Children // // Iterate children XMBElementList children = Element.GetChildNodes(); for (i=0; i<children.Count; ++i) { // Get node XMBElement child = children.Item(i); // Check what name the elements got int element_name = child.GetNodeName(); if (element_name == elmt_object) { // Call this function on the child Xeromyces_ReadObject(child, pFile, object, NameSubst, Paths); } else if (element_name == elmt_action) { // Scripted <action> element // Check for a 'file' parameter CStrW filename (child.GetAttributes().GetNamedItem(attr_file).FromUTF8()); CStr code; // If there is a file, open it and use it as the code if (! filename.empty()) { Paths.insert(filename); CVFSFile scriptfile; if (scriptfile.Load(g_VFS, filename) != PSRETURN_OK) { LOGERROR(L"Error opening GUI script action file '%ls'", filename.c_str()); throw PSERROR_GUI_JSOpenFailed(); } code = scriptfile.DecodeUTF8(); // assume it's UTF-8 } // Read the inline code (concatenating to the file code, if both are specified) code += CStr(child.GetText()); CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on)); // We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI. object->SetGUI(this); object->RegisterScriptHandler(action.LowerCase(), code, this); } else if (element_name == elmt_repeat) { Xeromyces_ReadRepeat(child, pFile, object, Paths); } else { // Try making the object read the tag. if (!object->HandleAdditionalChildren(child, pFile)) { LOGERROR(L"GUI: (object: %hs) Reading unknown children for its type", object->GetPresentableName().c_str()); } } } // // Check if Z wasn't manually set // if (!ManuallySetZ) { // Set it automatically to 10 plus its parents bool absolute; GUI<bool>::GetSetting(object, "absolute", absolute); // If the object is absolute, we'll have to get the parent's Z buffered, // and add to that! if (absolute) { GUI<float>::SetSetting(object, "z", pParent->GetBufferedZ() + 10.f, true); } else // If the object is relative, then we'll just store Z as "10" { GUI<float>::SetSetting(object, "z", 10.f, true); } } // // Input Child // try { if (pParent == m_BaseObject) AddObject(object); else pParent->AddChild(object); } catch (PSERROR_GUI& e) { LOGERROR(L"GUI error: %hs", e.what()); } }
int TskCarveExtractScalpel::processFile(int unallocImgId) { TskImgDB *imgDB = NULL; try { imgDB = &TskServices::Instance().getImgDB(); // Get the input folder path. The file to carve resides in a subdirectory of the carve prep output folder. The name of the subdirectory is the unallocated image file id. std::string carvePrepOutputPath = GetSystemProperty("CARVE_DIR"); if (!Poco::File(carvePrepOutputPath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::processFile : specified carve prep output folder '" << carvePrepOutputPath << "' does not exist"; throw TskException(msg.str()); } std::stringstream inputFolderPathBuilder; inputFolderPathBuilder << carvePrepOutputPath << Poco::Path::separator() << unallocImgId; // Get the input file name and construct the input file path. All of the files to carve have the same name. std::string carvePrepOutputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME"); std::stringstream unallocImgFilePathBuilder; unallocImgFilePathBuilder << inputFolderPathBuilder.str() << Poco::Path::separator() << carvePrepOutputFileName; Poco::File unallocImgFile(unallocImgFilePathBuilder.str()); if (!unallocImgFile.exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::processFile : did not find unalloc img file number " << unallocImgId << " at '" << unallocImgFilePathBuilder.str() << "'"; throw TskException(msg.str()); } if (unallocImgFile.getSize() > static_cast<Poco::File::FileSize>(0)) { // Attempt to carve the file, storing the carved files in a subdirectory of the input folder and the Scalpel console output in the input folder. // The console output is placed in the input folder rather than the output folder because Scalpel will only write to an empty directory. std::stringstream outputFolderPath; outputFolderPath << inputFolderPathBuilder.str() << Poco::Path::separator() << CARVED_FILES_FOLDER; std::stringstream stdOutFilePath; stdOutFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_OUT_DUMP_FILE_NAME; std::stringstream stdErrFilePath; stdErrFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_ERR_DUMP_FILE_NAME; carveFile(unallocImgFilePathBuilder.str(), outputFolderPath.str(), stdOutFilePath.str(), stdErrFilePath.str()); // Scalpel lists any files it carves out in a results file. Use the file list to add the files to the image DB and copy them to file storage. std::stringstream resultsFilePath; resultsFilePath << outputFolderPath.str() << Poco::Path::separator() << SCALPEL_RESULTS_FILE_NAME; processCarvedFiles(outputFolderPath.str(), parseCarvingResultsFile(unallocImgId, resultsFilePath.str())); // Update the unused sector info in the image database so it is known which of the unallocated sectors just carved did not go into a carved file. std::vector<TskUnusedSectorsRecord> unusedSectorsList; imgDB->addUnusedSectors(unallocImgId, unusedSectorsList); } else { // There is nothing to do if the file to be carved is of length zero. imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED); } return 0; } catch (TskException &ex) { LOGERROR(TskUtilities::toUTF16(ex.message())); if (imgDB) { imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR); } return 1; } }
//! //! //! //! @param[in] inst a pointer to the instance structure //! @param[in] in a transparent pointer (unused) //! //! @return //! //! @pre //! //! @note //! int instNetParamsSet(ccInstance * inst, void *in) { int rc = 0; int ret = 0; char userToken[64] = { 0 }; char *cleanGroupName = NULL; if (!inst) { return (1); } else if ((strcmp(inst->state, "Pending") && strcmp(inst->state, "Extant"))) { return (0); } LOGDEBUG("instanceId=%s publicIp=%s privateIp=%s privateMac=%s vlan=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.privateMac, inst->ccnet.vlan); if (inst->ccnet.vlan >= 0) { // activate network vnetconfig->networks[inst->ccnet.vlan].active = 1; // set up groupName and userName if (inst->groupNames[0][0] != '\0' && inst->accountId[0] != '\0') { // logic to strip the username from the supplied network name snprintf(userToken, 63, "%s-", inst->accountId); cleanGroupName = strstr(inst->groupNames[0], userToken); if (cleanGroupName) { cleanGroupName = cleanGroupName + strlen(userToken); } else { cleanGroupName = inst->groupNames[0]; } // if ( (vnetconfig->users[inst->ccnet.vlan].netName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].netName, inst->groupNames[0])) || (vnetconfig->users[inst->ccnet.vlan].userName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].userName, inst->accountId)) ) { if ((vnetconfig->users[inst->ccnet.vlan].netName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].netName, cleanGroupName)) || (vnetconfig->users[inst->ccnet.vlan].userName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].userName, inst->accountId))) { // this means that there is a pre-existing network with the passed in vlan tag, but with a different netName or userName LOGERROR("input instance vlan<->user<->netname mapping is incompatible with internal state. Internal - userName=%s netName=%s " "vlan=%d. Instance - userName=%s netName=%s vlan=%d\n", vnetconfig->users[inst->ccnet.vlan].userName, vnetconfig->users[inst->ccnet.vlan].netName, inst->ccnet.vlan, inst->accountId, cleanGroupName, inst->ccnet.vlan); ret = 1; } else { // snprintf(vnetconfig->users[inst->ccnet.vlan].netName, 32, "%s", inst->groupNames[0]); snprintf(vnetconfig->users[inst->ccnet.vlan].netName, 64, "%s", cleanGroupName); snprintf(vnetconfig->users[inst->ccnet.vlan].userName, 48, "%s", inst->accountId); } } } if (!ret) { // so far so good rc = vnetGenerateNetworkParams(vnetconfig, inst->instanceId, inst->ccnet.vlan, inst->ccnet.networkIndex, inst->ccnet.privateMac, inst->ccnet.publicIp, inst->ccnet.privateIp); if (rc) { print_ccInstance("failed to (re)generate network parameters: ", inst); ret = 1; } } if (ret) { LOGDEBUG("sync of network cache with instance data FAILED (instanceId=%s, publicIp=%s, privateIp=%s, vlan=%d, networkIndex=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.vlan, inst->ccnet.networkIndex); } else { LOGDEBUG("sync of network cache with instance data SUCCESS (instanceId=%s, publicIp=%s, privateIp=%s, vlan=%d, networkIndex=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.vlan, inst->ccnet.networkIndex); } return (0); }
// Similar to WriteScreenshot, but generates an image of size 640*tiles x 480*tiles. void WriteBigScreenshot(const VfsPath& extension, int tiles) { // If the game hasn't started yet then use WriteScreenshot to generate the image. if(g_Game == NULL){ WriteScreenshot(L".bmp"); return; } // get next available numbered filename // note: %04d -> always 4 digits, so sorting by filename works correctly. const VfsPath basenameFormat(L"screenshots/screenshot%04d"); const VfsPath filenameFormat = basenameFormat.ChangeExtension(extension); VfsPath filename; vfs::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); // Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and // hope the screen is actually large enough for that. const int tile_w = 640, tile_h = 480; ENSURE(g_xres >= tile_w && g_yres >= tile_h); const int img_w = tile_w*tiles, img_h = tile_h*tiles; const int bpp = 24; GLenum fmt = GL_RGB; int flags = TEX_BOTTOM_UP; // we want writing BMP to be as fast as possible, // so read data from OpenGL in BMP format to obviate conversion. if(extension == L".bmp") { #if !CONFIG2_GLES // GLES doesn't support BGR fmt = GL_BGR; flags |= TEX_BGR; #endif } const size_t img_size = img_w * img_h * bpp/8; const size_t tile_size = tile_w * tile_h * bpp/8; const size_t hdr_size = tex_hdr_size(filename); void* tile_data = malloc(tile_size); if(!tile_data) { WARN_IF_ERR(ERR::NO_MEM); return; } shared_ptr<u8> img_buf; AllocateAligned(img_buf, hdr_size+img_size, maxSectorSize); Tex t; GLvoid* img = img_buf.get() + hdr_size; if(t.wrap(img_w, img_h, bpp, flags, img_buf, hdr_size) < 0) { free(tile_data); return; } ogl_WarnIfError(); // Resize various things so that the sizes and aspect ratios are correct { g_Renderer.Resize(tile_w, tile_h); SViewPort vp = { 0, 0, tile_w, tile_h }; g_Game->GetView()->GetCamera()->SetViewPort(vp); g_Game->GetView()->SetCameraProjection(); } #if !CONFIG2_GLES // Temporarily move everything onto the front buffer, so the user can // see the exciting progress as it renders (and can tell when it's finished). // (It doesn't just use SwapBuffers, because it doesn't know whether to // call the SDL version or the Atlas version.) GLint oldReadBuffer, oldDrawBuffer; glGetIntegerv(GL_READ_BUFFER, &oldReadBuffer); glGetIntegerv(GL_DRAW_BUFFER, &oldDrawBuffer); glDrawBuffer(GL_FRONT); glReadBuffer(GL_FRONT); #endif // Hide the cursor CStrW oldCursor = g_CursorName; g_CursorName = L""; // Render each tile for (int tile_y = 0; tile_y < tiles; ++tile_y) { for (int tile_x = 0; tile_x < tiles; ++tile_x) { // Adjust the camera to render the appropriate region g_Game->GetView()->GetCamera()->SetProjectionTile(tiles, tile_x, tile_y); RenderLogger(false); RenderGui(false); Render(); RenderGui(true); RenderLogger(true); // Copy the tile pixels into the main image glReadPixels(0, 0, tile_w, tile_h, fmt, GL_UNSIGNED_BYTE, tile_data); for (int y = 0; y < tile_h; ++y) { void* dest = (char*)img + ((tile_y*tile_h + y) * img_w + (tile_x*tile_w)) * bpp/8; void* src = (char*)tile_data + y * tile_w * bpp/8; memcpy(dest, src, tile_w * bpp/8); } } } // Restore the old cursor g_CursorName = oldCursor; #if !CONFIG2_GLES // Restore the buffer settings glDrawBuffer(oldDrawBuffer); glReadBuffer(oldReadBuffer); #endif // Restore the viewport settings { g_Renderer.Resize(g_xres, g_yres); SViewPort vp = { 0, 0, g_xres, g_yres }; g_Game->GetView()->GetCamera()->SetViewPort(vp); g_Game->GetView()->SetCameraProjection(); g_Game->GetView()->GetCamera()->SetProjectionTile(1, 0, 0); } if (tex_write(&t, filename) == INFO::OK) { OsPath realPath; g_VFS->GetRealPath(filename, realPath); LOGMESSAGERENDER(L"Screenshot written to '%ls'", realPath.string().c_str()); } else LOGERROR(L"Error writing screenshot to '%ls'", filename.string().c_str()); free(tile_data); }
bool SpriteSheet2D::Load(Deserializer& source) { spriteMapping_.Clear(); SharedPtr<XMLFile> xmlFile(new XMLFile(context_)); if(!xmlFile->Load(source)) { LOGERROR("Could not load sprite sheet"); return false; } SetMemoryUse(source.GetSize()); XMLElement rootElem = xmlFile->GetRoot(); if (!rootElem) { LOGERROR("Invalid sprite sheet"); return false; } if (rootElem.GetName() == "spritesheet") { ResourceCache* cache = GetSubsystem<ResourceCache>(); texture_ = cache->GetResource<Texture2D>(rootElem.GetAttribute("texture")); if (!texture_) { LOGERROR("Cound not load texture"); return false; } XMLElement spriteElem = rootElem.GetChild("sprite"); while (spriteElem) { String name = spriteElem.GetAttribute("name"); IntRect rectangle = spriteElem.GetIntRect("rectangle"); Vector2 hotSpot(0.5f, 0.5f); if (spriteElem.HasAttribute("hotspot")) hotSpot = spriteElem.GetVector2("hotspot"); DefineSprite(name, rectangle, hotSpot); spriteElem = spriteElem.GetNext("sprite"); } } // Sparrow Starling texture atlas else if (rootElem.GetName() == "TextureAtlas") { ResourceCache* cache = GetSubsystem<ResourceCache>(); texture_ = cache->GetResource<Texture2D>(rootElem.GetAttribute("imagePath")); if (!texture_) { LOGERROR("Cound not load texture"); return false; } XMLElement subTextureElem = rootElem.GetChild("SubTexture"); while (subTextureElem) { String name = subTextureElem.GetAttribute("name"); int x = subTextureElem.GetInt("x"); int y = subTextureElem.GetInt("y"); int width = subTextureElem.GetInt("width"); int height = subTextureElem.GetInt("height"); IntRect rectangle(x, y, x + width, y + height); Vector2 hotSpot(0.5f, 0.5f); if (subTextureElem.HasAttribute("frameWidth") && subTextureElem.HasAttribute("frameHeight")) { int frameX = subTextureElem.GetInt("frameX"); int frameY = subTextureElem.GetInt("frameY"); int frameWidth = subTextureElem.GetInt("frameWidth"); int frameHeight = subTextureElem.GetInt("frameHeight"); hotSpot.x_ = ((float)frameX + frameWidth / 2) / width; hotSpot.y_ = 1.0f - ((float)frameY + frameHeight / 2) / height; } DefineSprite(name, rectangle, hotSpot); subTextureElem = subTextureElem.GetNext("SubTexture"); } } else { LOGERROR("Invalid sprite sheet file"); return false; } return true; }
void PrintPath(HDesign& design, HCriticalPath path, int pathNumber) { //columns numbers int sigDirections = design.cfg.ValueOf("Timing.SignalDirectionsUsed", 2); int ColAAT = 0; int ColRAT = ColAAT + 1; int ColGate = ColRAT + 1; int ColRC = ColGate + 1; int ColPhase = sigDirections == 2 ? ColRC + 1 : -1; int ColCap = ColRC + sigDirections; int ColFanout = ColCap + 1; int ColArcName = ColFanout + 1; int ColCellName = ColArcName + 1; int ColSep1 = ColCellName + 1; int ColNetName = ColSep1 + 1; int NCols = ColNetName + 1; //create header TableFormatter tf(NCols); //columns tf.SetColumnAlign(ColArcName, TableFormatter::Align_Left); tf.SetColumnAlign(ColCellName, TableFormatter::Align_Left); tf.SetColumnAlign(ColSep1, TableFormatter::Align_Fill); tf.SetColumnAlign(ColNetName, TableFormatter::Align_Left); //first header row tf.NewHeaderRow(); tf.SetCell(ColGate, "Delay[ps]", 2, TableFormatter::Align_Left); tf.SetCell(ColCap, "Cap", TableFormatter::Align_Left); tf.SetCell(ColFanout, "Fan-", TableFormatter::Align_Left); //second header row tf.NewHeaderRow(); tf.SetCell(ColAAT, "AAT", TableFormatter::Align_Left); tf.SetCell(ColRAT, "RAT", TableFormatter::Align_Left); tf.SetCell(ColGate, "Gate", TableFormatter::Align_Left); tf.SetCell(ColRC, "RC", TableFormatter::Align_Left); tf.SetCell(ColCap, "(fF)", TableFormatter::Align_Left); tf.SetCell(ColFanout, "out", TableFormatter::Align_Left); tf.SetCell(ColArcName, "Info", TableFormatter::Align_Left, 1000); //separator tf.NewBorderRow(); tf.SetCell(ColAAT, "-", TableFormatter::Align_Fill); tf.SetCell(ColRAT, "-", TableFormatter::Align_Fill); tf.SetCell(ColGate, "-", TableFormatter::Align_Fill); tf.SetCell(ColRC, "-", TableFormatter::Align_Fill); tf.SetCell(ColCap, "-", TableFormatter::Align_Fill); tf.SetCell(ColFanout, "-", TableFormatter::Align_Fill); tf.SetCell(ColPhase, "-", TableFormatter::Align_Fill); tf.SetCell(ColArcName, "-", TableFormatter::Align_Fill); //print arc (cell + net pairs) HCriticalPath::PointsEnumeratorW cpoint = (path,design).GetEnumeratorW(); HCriticalPathPointWrapper previousSink = design.CriticalPathPoints.NullW(); while (cpoint.MoveNext()) { HCriticalPathPointWrapper driver = cpoint; if (!cpoint.MoveNext()) break;//wtf? HPinWrapper driverPin = design[(driver.TimingPoint(),design).Pin()]; HSteinerPointWrapper stPointDriver = design[design.SteinerPoints[driverPin]]; HSteinerPointWrapper stPointSink = design[design.SteinerPoints[(cpoint.TimingPoint(),design).Pin()]]; HNetWrapper net = design[driverPin.Net()]; tf.NewRow(); tf.SetCell(ColFanout, net.SinksCount()); tf.SetCell(ColSep1, '-'); tf.SetCell(ColNetName, net.Name()); tf.SetCell(ColCellName, driverPin.IsPrimaryInput() ? driverPin.Name() : (driverPin.Cell(),design).Name()); if (driver.SignalDirection() == SignalDirection_Rise) { tf.SetCell(ColAAT, PikoSec(design[cpoint.TimingPoint()].RiseArrivalTime())); tf.SetCell(ColRAT, PikoSec(design[cpoint.TimingPoint()].RiseRequiredTime())); tf.SetCell(ColPhase, 'R'); tf.SetCell(ColRC, PikoSec(stPointSink.RisePathDelay())); tf.SetCell(ColCap, Round(1000.0 * stPointDriver.RiseObservedC())); } else if (driver.SignalDirection() == SignalDirection_Fall) { tf.SetCell(ColAAT, PikoSec(design[cpoint.TimingPoint()].FallArrivalTime())); tf.SetCell(ColRAT, PikoSec(design[cpoint.TimingPoint()].FallRequiredTime())); tf.SetCell(ColPhase, 'F'); tf.SetCell(ColRC, PikoSec(stPointSink.FallPathDelay())); tf.SetCell(ColCap, Round(1000.0 * stPointDriver.FallObservedC())); } else if (driver.SignalDirection() == SignalDirection_None) { tf.SetCell(ColAAT, PikoSec(design[cpoint.TimingPoint()].ArrivalTime())); tf.SetCell(ColRAT, PikoSec(design[cpoint.TimingPoint()].RequiredTime())); tf.SetCell(ColRC, PikoSec(stPointSink.PathDelay())); tf.SetCell(ColCap, Round(1000.0 * stPointDriver.ObservedC())); } else { LOGERROR("Unsupported signal direction."); } double arcTime; bool inversed; HTimingArcType arc = design.TimingArcTypes.Null(); if(design[path].ExtractionType() == PathExtractionType_Arrival || ::IsNull(previousSink)) arc = FindArrivalArc(design, driver.TimingPoint(), driver.SignalDirection(), arcTime, inversed); else if(design[path].ExtractionType() == PathExtractionType_Required) arc = FindRequiredArc(design, previousSink.TimingPoint(), previousSink.SignalDirection(), arcTime, inversed); tf.SetCell(ColGate, PikoSec(arcTime)); tf.SetCell(ColArcName, FormatArcName(design, driverPin, arc)); previousSink = cpoint; } //check for setup arc HPin finalPin = design.Get<HTimingPoint::Pin, HPin>(previousSink.TimingPoint()); for (HPinType::ArcsEnumeratorW arc = design.Get<HPinType::ArcTypesEnumerator, HPinType::ArcsEnumeratorW>( design.Get<HPin::Type, HPinType>(finalPin)); arc.MoveNext(); ) { if (arc.TimingType() == TimingType_SetupRising || arc.TimingType() == TimingType_SetupFalling) { tf.NewRow(); if (previousSink.SignalDirection() == SignalDirection_Fall) tf.SetCell(ColGate, PikoSec(arc.TIntrinsicFall())); else if (previousSink.SignalDirection() == SignalDirection_Rise || previousSink.SignalDirection() == SignalDirection_None) tf.SetCell(ColGate, PikoSec(arc.TIntrinsicRise())); else { LOGERROR("Unsupported signal direction."); } tf.SetCell(ColArcName, FormatArcName(design, finalPin, arc)); tf.SetCell(ColCellName, design[design[finalPin].Cell()].Name()); break; } } //separator tf.NewRow(); tf.SetCell(ColAAT, "-", TableFormatter::Align_Fill); tf.SetCell(ColRAT, "-", TableFormatter::Align_Fill); tf.SetCell(ColGate, "-", TableFormatter::Align_Fill); tf.SetCell(ColArcName, "-", TableFormatter::Align_Fill); //slack tf.NewRow(); tf.SetCell(ColAAT, PikoSec(design[path].Criticality())); tf.SetCell(ColArcName, "(slack)", 10); //printing Logger::Global.WriteIgnoringHTML("================================================================================"); WRITELINE(""); HPinWrapper firstPin = design[design[design[design[path].StartPoint()].TimingPoint()].Pin()]; HPinWrapper lastPin = design[design[design[design[path].EndPoint()].TimingPoint()].Pin()]; HCellWrapper firstCell = design[firstPin.Cell()]; HCellWrapper lastCell = design[lastPin.Cell()]; tf.Caption = Aux::Format("Path #%d %10s %s %s %8s %s %s", pathNumber, "From ", firstPin.IsPrimary() ? "PIN" : firstCell.Name().c_str(), firstPin.Name().c_str(), "To ", lastPin.IsPrimary() ? "PIN" : lastCell.Name().c_str(), lastPin.Name().c_str()); WRITELINE(""); tf.Print(); WRITELINE(""); WRITELINE(""); }
/** * Module execution function. Saves interesting files recorded on the * blackboard to a user-specified output directory. * * @returns TskModule::OK on success if all files saved, TskModule::FAIL if one or more files were not saved */ TSK_MODULE_EXPORT TskModule::Status report() { TskModule::Status status = TskModule::OK; const std::string MSG_PREFIX = "SaveInterestingFilesModule::report : "; try { if (outputFolderPath.empty()) { // Initialization failed. The reason why was already logged in initialize(). return TskModule::FAIL; } // Get the interesting file set hits from the blackboard and sort them by set name. FileSets fileSets; FileSetHits fileSetHits; std::vector<TskBlackboardArtifact> fileSetHitArtifacts = TskServices::Instance().getBlackboard().getArtifacts(TSK_INTERESTING_FILE_HIT); for (std::vector<TskBlackboardArtifact>::iterator fileHit = fileSetHitArtifacts.begin(); fileHit != fileSetHitArtifacts.end(); ++fileHit) { // Find the set name attrbute of the artifact. bool setNameFound = false; std::vector<TskBlackboardAttribute> attrs = (*fileHit).getAttributes(); for (std::vector<TskBlackboardAttribute>::iterator attr = attrs.begin(); attr != attrs.end(); ++attr) { if ((*attr).getAttributeTypeID() == TSK_SET_NAME) { setNameFound = true; // Save the set name and description, using a map to ensure that these values are saved once per file set. fileSets.insert(make_pair((*attr).getValueString(), (*attr).getContext())); // Drop the artifact into a multimap to allow for retrieval of all of the file hits for a file set as an // iterator range. fileSetHits.insert(make_pair((*attr).getValueString(), (*fileHit))); } } if (!setNameFound) { // Log the error and try the next artifact. std::stringstream msg; msg << MSG_PREFIX << "failed to find TSK_SET_NAME attribute for TSK_INTERESTING_FILE_HIT artifact with id '" << (*fileHit).getArtifactID() << "', skipping artifact"; LOGERROR(msg.str()); } } // Save the interesting files to the output directory, file set by file set. for (map<std::string, std::string>::const_iterator fileSet = fileSets.begin(); fileSet != fileSets.end(); ++fileSet) { // Get the file hits for the file set as an iterator range. FileSetHitsRange fileSetHitsRange = fileSetHits.equal_range((*fileSet).first); // Save the files corresponding to the file hit artifacts. saveFiles((*fileSet).first, (*fileSet).second, fileSetHitsRange); } } catch (TskException &ex) { status = TskModule::FAIL; std::stringstream msg; msg << MSG_PREFIX << "TskException: " << ex.message(); LOGERROR(msg.str()); } catch (Poco::Exception &ex) { status = TskModule::FAIL; std::stringstream msg; msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText(); LOGERROR(msg.str()); } catch (std::exception &ex) { status = TskModule::FAIL; std::stringstream msg; msg << MSG_PREFIX << "std::exception: " << ex.what(); LOGERROR(msg.str()); } catch (...) { status = TskModule::FAIL; LOGERROR(MSG_PREFIX + "unrecognized exception"); } return status; }
bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data) { PROFILE(SetTextureData); if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } // If compressed, align the update region on a block if (IsCompressed()) { x &= ~3; y &= ~3; width += 3; width &= 0xfffffffc; height += 3; height &= 0xfffffffc; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); unsigned rowStart = GetRowDataSize(x); unsigned subResource = D3D11CalcSubresource(level, face, levels_); if (usage_ == TEXTURE_DYNAMIC) { if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } D3D11_MAPPED_SUBRESOURCE mappedData; mappedData.pData = 0; graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0, &mappedData); if (mappedData.pData) { for (int row = 0; row < height; ++row) memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize); graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource); } else { LOGERROR("Failed to map texture for update"); return false; } } else {
int main(int argc, char *argv[]) { char *device, *username, *password; int width, height, fps, timeout, port; LOGINFO("camlite version:%s\n\n", CAMLITE_VERSION); if (argc != 9) { LOGINFO("usage: camlite DEVICE WIDTH HEIGHT FPS TIMEOUT PORT USERNAME PASSWORD\n\n"); return 0; } device = argv[1]; width = atoi(argv[2]); height = atoi(argv[3]); fps = atoi(argv[4]); timeout = atoi(argv[5]); port = atoi(argv[6]); username = argv[7]; password = argv[8]; LOGINFO("device:%s\n", device); LOGINFO("width:%d\n", width); LOGINFO("height:%d\n", height); LOGINFO("fps:%d\n", fps); LOGINFO("timeout:%d\n", timeout); LOGINFO("port:%d\n", port); LOGINFO("username:%s\n", username); LOGINFO("password:%s\n", password); LOGINFO("\n"); signal(SIGPIPE, SIG_IGN); if(signal(SIGINT, signal_handler) == SIG_ERR) { LOGERROR("could not register signal handler\n"); exit(EXIT_FAILURE); } g_base = pevent_base_create(); if (g_base == NULL) { LOGERROR("pevent_base_create error\n"); exit(EXIT_FAILURE); } if (camhttp_start(g_base, port, username, password) == -1) { LOGERROR("http start error\n"); exit(EXIT_FAILURE); } video_manager_init(g_base, (v4l2_read_callback)camhttp_on_video_read, timeout); video_manager_add(device, width, height, fps); while (pevent_base_loop(g_base, -1) != -1); pevent_base_cleanup(g_base); LOGINFO("event loop cleanup\n"); return 0; }
const FontFace* Font::GetFaceTTF(int pointSize) { // Create & initialize FreeType library if it does not exist yet FreeTypeLibrary* freeType = GetSubsystem<FreeTypeLibrary>(); if (!freeType) context_->RegisterSubsystem(freeType = new FreeTypeLibrary(context_)); FT_Face face; FT_Error error; FT_Library library = freeType->GetLibrary(); if (pointSize <= 0) { LOGERROR("Zero or negative point size"); return 0; } if (!fontDataSize_) { LOGERROR("Font not loaded"); return 0; } error = FT_New_Memory_Face(library, &fontData_[0], fontDataSize_, 0, &face); if (error) { LOGERROR("Could not create font face"); return 0; } error = FT_Set_Char_Size(face, 0, pointSize * 64, FONT_DPI, FONT_DPI); if (error) { FT_Done_Face(face); LOGERROR("Could not set font point size " + String(pointSize)); return 0; } SharedPtr<FontFace> newFace(new FontFace()); FT_GlyphSlot slot = face->glyph; unsigned numGlyphs = 0; // Build glyph mapping FT_UInt glyphIndex; FT_ULong charCode = FT_Get_First_Char(face, &glyphIndex); while (glyphIndex != 0) { numGlyphs = Max((int)glyphIndex + 1, (int)numGlyphs); newFace->glyphMapping_[charCode] = glyphIndex; charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); } LOGDEBUG("Font face has " + String(numGlyphs) + " glyphs"); // Load each of the glyphs to see the sizes & store other information int maxHeight = 0; FT_Pos ascender = face->size->metrics.ascender; newFace->glyphs_.Reserve(numGlyphs); for (unsigned i = 0; i < numGlyphs; ++i) { FontGlyph newGlyph; error = FT_Load_Glyph(face, i, FT_LOAD_DEFAULT); if (!error) { // Note: position within texture will be filled later newGlyph.width_ = (short)((slot->metrics.width) >> 6); newGlyph.height_ = (short)((slot->metrics.height) >> 6); newGlyph.offsetX_ = (short)((slot->metrics.horiBearingX) >> 6); newGlyph.offsetY_ = (short)((ascender - slot->metrics.horiBearingY) >> 6); newGlyph.advanceX_ = (short)((slot->metrics.horiAdvance) >> 6); maxHeight = Max(maxHeight, newGlyph.height_); } else {
bool Resource::Save(Serializer& dest) const { LOGERROR("Save not supported for " + GetTypeName()); return false; }
static void HandleError(const CStrW& message, const VfsPath& pathname, Status err) { if (err == ERR::AGAIN) return; // open failed because sound is disabled (don't log this) LOGERROR(L"%ls: pathname=%ls, error=%ls", message.c_str(), pathname.string().c_str(), ErrorString(err)); }
void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) { SGUIScrollBarStyle scrollbar; CStr name; // Setup some defaults. scrollbar.m_MinimumBarSize = 0.f; // Using 1.0e10 as a substitute for infinity scrollbar.m_MaximumBarSize = 1.0e10; scrollbar.m_UseEdgeButtons = false; for (XMBAttribute attr : Element.GetAttributes()) { CStr attr_name = pFile->GetAttributeString(attr.Name); CStr attr_value(attr.Value); if (attr_value == "null") continue; if (attr_name == "name") name = attr_value; else if (attr_name == "show_edge_buttons") { bool b; if (!GUI<bool>::ParseString(attr_value.FromUTF8(), b)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); else scrollbar.m_UseEdgeButtons = b; } else if (attr_name == "width") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); else scrollbar.m_Width = f; } else if (attr_name == "minimum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); else scrollbar.m_MinimumBarSize = f; } else if (attr_name == "maximum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); else scrollbar.m_MaximumBarSize = f; } else if (attr_name == "sprite_button_top") scrollbar.m_SpriteButtonTop = attr_value; else if (attr_name == "sprite_button_top_pressed") scrollbar.m_SpriteButtonTopPressed = attr_value; else if (attr_name == "sprite_button_top_disabled") scrollbar.m_SpriteButtonTopDisabled = attr_value; else if (attr_name == "sprite_button_top_over") scrollbar.m_SpriteButtonTopOver = attr_value; else if (attr_name == "sprite_button_bottom") scrollbar.m_SpriteButtonBottom = attr_value; else if (attr_name == "sprite_button_bottom_pressed") scrollbar.m_SpriteButtonBottomPressed = attr_value; else if (attr_name == "sprite_button_bottom_disabled") scrollbar.m_SpriteButtonBottomDisabled = attr_value; else if (attr_name == "sprite_button_bottom_over") scrollbar.m_SpriteButtonBottomOver = attr_value; else if (attr_name == "sprite_back_vertical") scrollbar.m_SpriteBackVertical = attr_value; else if (attr_name == "sprite_bar_vertical") scrollbar.m_SpriteBarVertical = attr_value; else if (attr_name == "sprite_bar_vertical_over") scrollbar.m_SpriteBarVerticalOver = attr_value; else if (attr_name == "sprite_bar_vertical_pressed") scrollbar.m_SpriteBarVerticalPressed = attr_value; } m_ScrollBarStyles[name] = scrollbar; }
bool CSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML) { // LOGERROR(L"loading new sound group '%ls'", pathnameXML.string().c_str()); CXeromyces XeroFile; if (XeroFile.Load(g_VFS, pathnameXML) != PSRETURN_OK) { HandleError(L"error loading file", pathnameXML, ERR::FAIL); return false; } // Define elements used in XML file #define EL(x) int el_##x = XeroFile.GetElementID(#x) #define AT(x) int at_##x = XeroFile.GetAttributeID(#x) EL(soundgroup); EL(gain); EL(looping); EL(omnipresent); EL(distanceless); EL(pitch); EL(priority); EL(randorder); EL(randgain); EL(randpitch); EL(conegain); EL(coneinner); EL(coneouter); EL(sound); EL(gainupper); EL(gainlower); EL(pitchupper); EL(pitchlower); EL(path); EL(threshold); EL(decay); #undef AT #undef EL XMBElement root = XeroFile.GetRoot(); if (root.GetNodeName() != el_soundgroup) { LOGERROR(L"Invalid SoundGroup format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str()); return false; } XERO_ITER_EL(root, child) { int child_name = child.GetNodeName(); if(child_name == el_gain) { SetGain(child.GetText().ToFloat()); } else if(child_name == el_looping) { if(child.GetText().ToInt() == 1) SetFlag(eLoop); } else if(child_name == el_omnipresent) { if(child.GetText().ToInt() == 1) SetFlag(eOmnipresent); } else if(child_name == el_distanceless) { if(child.GetText().ToInt() == 1) SetFlag(eDistanceless); } else if(child_name == el_pitch) { this->m_Pitch = child.GetText().ToFloat(); } else if(child_name == el_priority) { this->m_Priority = child.GetText().ToFloat(); } else if(child_name == el_randorder) { if(child.GetText().ToInt() == 1) SetFlag(eRandOrder); } else if(child_name == el_randgain) { if(child.GetText().ToInt() == 1) SetFlag(eRandGain); } else if(child_name == el_gainupper) { this->m_GainUpper = child.GetText().ToFloat(); } else if(child_name == el_gainlower) { this->m_GainLower = child.GetText().ToFloat(); } else if(child_name == el_randpitch) { if(child.GetText().ToInt() == 1) SetFlag(eRandPitch); } else if(child_name == el_pitchupper) { this->m_PitchUpper = child.GetText().ToFloat(); } else if(child_name == el_pitchlower) { this->m_PitchLower = child.GetText().ToFloat(); } else if(child_name == el_conegain) { this->m_ConeOuterGain = child.GetText().ToFloat(); } else if(child_name == el_coneinner) { this->m_ConeInnerAngle = child.GetText().ToFloat(); } else if(child_name == el_coneouter) { this->m_ConeOuterAngle = child.GetText().ToFloat(); } else if(child_name == el_sound) { this->filenames.push_back(child.GetText().FromUTF8()); } else if(child_name == el_path) { m_filepath = child.GetText().FromUTF8(); } else if(child_name == el_threshold) { m_IntensityThreshold = child.GetText().ToFloat(); } else if(child_name == el_decay) { m_Decay = child.GetText().ToFloat(); } }
bool AnimationSet2D::LoadFolders(const XMLElement& rootElem) { ResourceCache* cache = GetSubsystem<ResourceCache>(); bool async = GetAsyncLoadState() == ASYNC_LOADING; String parentPath = GetParentPath(GetName()); String spriteSheetFilePath = parentPath + GetFileName(GetName()) + ".xml"; SpriteSheet2D* spriteSheet = 0; bool hasSpriteSheet = false; // When async loading, request the sprite sheet for background loading but do not actually get it if (!async) spriteSheet = cache->GetResource<SpriteSheet2D>(spriteSheetFilePath, false); else { hasSpriteSheet = cache->Exists(spriteSheetFilePath); if (hasSpriteSheet) cache->BackgroundLoadResource<SpriteSheet2D>(spriteSheetFilePath, false, this); } for (XMLElement folderElem = rootElem.GetChild("folder"); folderElem; folderElem = folderElem.GetNext("folder")) { unsigned folderId = folderElem.GetUInt("id"); for (XMLElement fileElem = folderElem.GetChild("file"); fileElem; fileElem = fileElem.GetNext("file")) { unsigned fileId = fileElem.GetUInt("id"); String fileName = fileElem.GetAttribute("name"); // When async loading, request the sprites for background loading but do not actually get them if (!async) { SharedPtr<Sprite2D> sprite; if (spriteSheet) sprite = spriteSheet->GetSprite(GetFileName(fileName)); else sprite = (cache->GetResource<Sprite2D>(parentPath + fileName)); if (!sprite) { LOGERROR("Could not load sprite " + fileName); return false; } Vector2 hotSpot(0.0f, 1.0f); if (fileElem.HasAttribute("pivot_x")) hotSpot.x_ = fileElem.GetFloat("pivot_x"); if (fileElem.HasAttribute("pivot_y")) hotSpot.y_ = fileElem.GetFloat("pivot_y"); // If sprite is trimmed, recalculate hot spot const IntVector2& offset = sprite->GetOffset(); if (offset != IntVector2::ZERO) { int width = fileElem.GetInt("width"); int height = fileElem.GetInt("height"); float pivotX = width * hotSpot.x_; float pivotY = height * (1.0f - hotSpot.y_); const IntRect& rectangle = sprite->GetRectangle(); hotSpot.x_ = (offset.x_ + pivotX) / rectangle.Width(); hotSpot.y_ = 1.0f - (offset.y_ + pivotY) / rectangle.Height(); } sprite->SetHotSpot(hotSpot); sprites_[(folderId << 16) + fileId] = sprite; } else if (!hasSpriteSheet) cache->BackgroundLoadResource<Sprite2D>(parentPath + fileName, true, this); } } return true; }
//! //! //! //! @param[in] inst a pointer to the instance structure //! @param[in] in a transparent pointer (unused) //! //! @return //! //! @pre The inst pointer must not be NULL. //! //! @note //! int instIpSync(ccInstance * inst, void *in) { int ret = 0; if (!inst) { return (1); } else if ((strcmp(inst->state, "Pending") && strcmp(inst->state, "Extant"))) { return (0); } LOGDEBUG("instanceId=%s CCpublicIp=%s CCprivateIp=%s CCprivateMac=%s CCvlan=%d CCnetworkIndex=%d NCpublicIp=%s NCprivateIp=%s NCprivateMac=%s " "NCvlan=%d NCnetworkIndex=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.privateMac, inst->ccnet.vlan, inst->ccnet.networkIndex, inst->ncnet.publicIp, inst->ncnet.privateIp, inst->ncnet.privateMac, inst->ncnet.vlan, inst->ncnet.networkIndex); if (inst->ccnet.vlan == 0 && inst->ccnet.networkIndex == 0 && inst->ccnet.publicIp[0] == '\0' && inst->ccnet.privateIp[0] == '\0' && inst->ccnet.privateMac[0] == '\0') { // ccnet is completely empty, make a copy of ncnet LOGDEBUG("ccnet is empty, copying ncnet\n"); memcpy(&(inst->ccnet), &(inst->ncnet), sizeof(netConfig)); return (1); } // IP cases // 1.) local CC cache has no IP info for VM, NC VM has no IP info // - do nothing // 2.) local CC cache has no IP info, NC VM has IP info // - ingress NC info, kick_network // 3.) local CC cache has IP info, NC VM has no IP info // - send ncAssignAddress // 4.) local CC cache has IP info, NC VM has different IP info // - ingress NC info, kick_network // 5.) local CC cache has IP info, NC VM has same IP info // - do nothing if ((inst->ccnet.publicIp[0] == '\0' || !strcmp(inst->ccnet.publicIp, "0.0.0.0")) && (inst->ncnet.publicIp[0] != '\0' && strcmp(inst->ncnet.publicIp, "0.0.0.0"))) { // case 2 LOGDEBUG("CC publicIp is empty, NC publicIp is set\n"); snprintf(inst->ccnet.publicIp, 24, "%s", inst->ncnet.publicIp); ret++; } else if (((inst->ccnet.publicIp[0] != '\0' && strcmp(inst->ccnet.publicIp, "0.0.0.0")) && (inst->ncnet.publicIp[0] != '\0' && strcmp(inst->ncnet.publicIp, "0.0.0.0"))) && strcmp(inst->ccnet.publicIp, inst->ncnet.publicIp)) { // case 4 LOGDEBUG("CC publicIp and NC publicIp differ\n"); snprintf(inst->ccnet.publicIp, 24, "%s", inst->ncnet.publicIp); ret++; } // VLAN cases if (inst->ccnet.vlan != inst->ncnet.vlan) { // problem LOGERROR("CC and NC vlans differ instanceId=%s CCvlan=%d NCvlan=%d\n", inst->instanceId, inst->ccnet.vlan, inst->ncnet.vlan); } inst->ccnet.vlan = inst->ncnet.vlan; if (inst->ccnet.vlan >= 0) { if (!vnetconfig->networks[inst->ccnet.vlan].active) { LOGWARN("detected instance from NC that is running in a currently inactive network; will attempt to re-activate network '%d'\n", inst->ccnet.vlan); ret++; } } // networkIndex cases if (inst->ccnet.networkIndex != inst->ncnet.networkIndex) { // problem LOGERROR("CC and NC networkIndicies differ instanceId=%s CCnetworkIndex=%d NCnetworkIndex=%d\n", inst->instanceId, inst->ccnet.networkIndex, inst->ncnet.networkIndex); } inst->ccnet.networkIndex = inst->ncnet.networkIndex; // mac addr cases if (strcmp(inst->ccnet.privateMac, inst->ncnet.privateMac)) { // problem; LOGERROR("CC and NC mac addrs differ instanceId=%s CCmac=%s NCmac=%s\n", inst->instanceId, inst->ccnet.privateMac, inst->ncnet.privateMac); } snprintf(inst->ccnet.privateMac, 24, "%s", inst->ncnet.privateMac); // privateIp cases if (strcmp(inst->ccnet.privateIp, inst->ncnet.privateIp)) { // sync em snprintf(inst->ccnet.privateIp, 24, "%s", inst->ncnet.privateIp); } return (ret); }
bool Initialise(bool callConstructor) { if (!LoadScripts(m_AIName)) return false; OsPath path = L"simulation/ai/" + m_AIName + L"/data.json"; CScriptValRooted metadata = m_Worker.LoadMetadata(path); if (metadata.uninitialised()) { LOGERROR(L"Failed to create AI player: can't find %ls", path.string().c_str()); return false; } // Get the constructor name from the metadata std::string constructor; if (!m_ScriptInterface.GetProperty(metadata.get(), "constructor", constructor)) { LOGERROR(L"Failed to create AI player: %ls: missing 'constructor'", path.string().c_str()); return false; } // Get the constructor function from the loaded scripts CScriptVal ctor; if (!m_ScriptInterface.GetProperty(m_ScriptInterface.GetGlobalObject(), constructor.c_str(), ctor) || ctor.undefined()) { LOGERROR(L"Failed to create AI player: %ls: can't find constructor '%hs'", path.string().c_str(), constructor.c_str()); return false; } m_ScriptInterface.GetProperty(metadata.get(), "useShared", m_UseSharedComponent); CScriptVal obj; if (callConstructor) { // Set up the data to pass as the constructor argument CScriptVal settings; m_ScriptInterface.Eval(L"({})", settings); m_ScriptInterface.SetProperty(settings.get(), "player", m_Player, false); m_ScriptInterface.SetProperty(settings.get(), "difficulty", m_Difficulty, false); ENSURE(m_Worker.m_HasLoadedEntityTemplates); m_ScriptInterface.SetProperty(settings.get(), "templates", m_Worker.m_EntityTemplates, false); obj = m_ScriptInterface.CallConstructor(ctor.get(), settings.get()); } else { // For deserialization, we want to create the object with the correct prototype // but don't want to actually run the constructor again // XXX: actually we don't currently use this path for deserialization - maybe delete it? obj = m_ScriptInterface.NewObjectFromConstructor(ctor.get()); } if (obj.undefined()) { LOGERROR(L"Failed to create AI player: %ls: error calling constructor '%hs'", path.string().c_str(), constructor.c_str()); return false; } m_Obj = CScriptValRooted(m_ScriptInterface.GetContext(), obj); return true; }
bool Animation2D::Load(Deserializer& source) { frameEndTimes_.Clear(); frameSprites_.Clear(); SharedPtr<XMLFile> xmlFile(new XMLFile(context_)); if(!xmlFile->Load(source)) { LOGERROR("Could not load animation"); return false; } SetMemoryUse(source.GetSize()); XMLElement rootElem = xmlFile->GetRoot("animation"); if (!rootElem) { LOGERROR("Invalid animation"); return false; } ResourceCache* cache = GetSubsystem<ResourceCache>(); XMLElement keyFrameElem = rootElem.GetChild("frame"); if (!keyFrameElem) { LOGERROR("Could not found key frame"); return false; } float endTime = 0.0f; while (keyFrameElem) { endTime += keyFrameElem.GetFloat("duration"); frameEndTimes_.Push(endTime); SharedPtr<Sprite2D> sprite; Vector<String> names = keyFrameElem.GetAttribute("sprite").Split('@'); if (names.Size() == 1) sprite = cache->GetResource<Sprite2D>(names[0]); else if (names.Size() == 2) { SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(names[0]); if (!spriteSheet) { LOGERROR("Could not get sprite speet"); return false; } sprite = spriteSheet->GetSprite(names[1]); } if (!sprite) { LOGERROR("Could not get sprite"); return false; } frameSprites_.Push(sprite); keyFrameElem = keyFrameElem.GetNext("frame"); } return true; }