aboutsummaryrefslogtreecommitdiff
path: root/src/game.cpp
Commit message (Collapse)AuthorAge
* Footsteps: Fix offset footstep and shallow water sound bugsparamat2017-02-12
| | | | | | | | | | | | | | | Fix footstep sounds coming from nodes to either side when walking on a 1 node wide row of nodebox slabs such as default:snow. Fix sand footsteps when swimming in 1 node deep water. Use a new function 'getFootstepNodePos()' instead of 'getStandingNodePos()' to avoid using a horizontally-offset 'sneak node' for sounds. Sound is selected from the node BS * 0.05 below the player's feet, so that 1/16th slabs will play the slab sound but 1/32nd slabs will not. If the player is not 'touching ground' the node detection position is changed to BS * 0.5 below to preserve footstep sounds when landing after a jump or fall.
* Re-add halo highlight (#5130)Dániel Juhász2017-01-30
| | | | Due to a rebase mistake halo highlighting was disabled. This commit re-adds that feature.
* Add console height setting (#5136)Ezhh2017-01-30
|
* Rename height to scale for openConsole() (#5139)Zeno-2017-01-29
| | | | | For Game::openConsole() and GUIChatConsole::openConsole() the parameter name 'height' is misleading because it's actually a percentage of the screen/window height.
* Add hardware node coloring. Includes:Dániel Juhász2017-01-23
| | | | | | - Increase ContentFeatures serialization version - Color property and palettes for nodes - paramtype2 = "color", "colored facedir" or "colored wallmounted"
* Environment & IGameDef code refactoring (#4985)Ner'zhul2017-01-09
| | | | | | | | | | | | | | | | | | | | | * Environment code refactoring * Cleanup includes & class declarations in client & server environment to improve build speed * ServerEnvironment::m_gamedef is now a pointer to Server instead of IGameDef, permitting to cleanup many casts. * Cleanup IGameDef * Move ITextureSource* IGameDef::getTextureSource() to Client only. * Also move ITextureSource *IGameDef::tsrc() helper * drop getShaderSource, getSceneManager, getSoundManager & getCamera abstract call * drop unused emerge() call * cleanup server unused functions (mentionned before) * Drop one unused parameter from ContentFeatures::updateTextures * move checkLocalPrivilege to Client * Remove some unnecessary casts * create_formspec_menu: remove IWritableTextureSource pointer, as client already knows it * Fix some comments * Change required IGameDef to Server/Client pointers * Previous change that game.cpp sometimes calls functions with Client + InventoryManager + IGameDef in same functions but it's the same objects * Remove duplicate Client pointer in GUIFormSpecMenu::GUIFormSpecMenu * drop ClientMap::sectorWasDrawn which is unused
* Improve getPointedThing() (#4346)Dániel Juhász2017-01-04
| | | | | | | | | | | | | | | | | | | * Improved getPointedThing() The new algorithm checks every node exactly once. Now the point and normal vector of the collision is also returned in the PointedThing (currently they are not used outside of the function). Now the CNodeDefManager keeps the union of all possible nodeboxes, so the raycast won't miss any nodes. Also if there are only small nodeboxes, getPointedThing() is exceptionally fast. Also adds unit test for VoxelLineIterator. * Cleanup, code move This commit moves getPointedThing() and Client::getSelectedActiveObject() to ClientEnvironment. The map nodes now can decide which neighbors they are connecting to (MapNode::getNeighbors()).
* Irrlicht 1.9 supportsfan52016-12-26
|
* Fix camera jumping on Android when panning past 0/360 markrubenwardy2016-12-12
|
* View range: Set maximum to 4000 nodesRogier2016-12-12
| | | | The network protocol does not support larger than 255 mapblocks.
* Fix computation of viewing range (in blocks) sent to server (#4882)Rogier-52016-12-11
| | | | | | | | Fixes #4878 Also remove an artificial viewing range reduction that (presumably) was added to compensate for miscomputed viewing ranges, and that doesn't seem to be needed any more (thanks to lhofhansl).
* Fog: Make fraction of visible distance at which fog starts configurableLars Hofhansl2016-12-07
| | | | | | Optimise the fetching of global settings 'camera_smoothing', 'cinematic' and 'cinematic_camera_smoothing'. Cache 'cam_smoothing'.
* Wieldhand: Allow overriding the handTeTpaAka2016-11-26
|
* Make supplying empty formspec strings close the formspec (#4737)orwell962016-11-23
| | | This will only happen if the formname matches or if formname is "".
* Fix superflous shader setting updates (#4800)ShadowNinja2016-11-23
| | | This improves rendering performance by ~40%
* Halo: Highlight selected faceRealBadAngel2016-11-12
| | | | | This is a slightly modified and cleaned up version of #3774 by RealBadAngel. By sofar: Remove color change (just make it lighter) and some minor cleanups.
* Cycle directly to nothing shown instead of showing the profiler graph againlhofhansl2016-11-04
| | | | Fix for previous commit.
* Add debug priv, and allow player to display the scene as wire-frame. (#4709)lhofhansl2016-11-04
|
* Rename testsounds/ directory to sounds/ (#1984)Hugo Locurcio2016-10-30
|
* Damage flash: Reduce maximum alpha. Avoid fade overloadparamat2016-10-21
| | | | | | | | | | | Flash alpha maximum is reduced from 180 to 127 to avoid player blindness in combat. Flash alpha minimum is unchanged. The 'damage_flash' value is now limited to max alpha, to avoid multiple hits creating a huge value that causes flash to stay at maximum alpha for a long period. Now alpha always starts to fade immediately after taking damage. Both problems can be seen in Minetest let's play videos. Simplify and optimise some code.
* Revert changes to toggleNoClip and toggleFreeMoveLars Hofhansl2016-10-17
|
* Don't use day light sky unless noclip and free_move are enabledLars Hofhansl2016-10-17
|
* Use range-based fog instead of z-plane based.Lars Hofhansl2016-10-13
|
* Don't use unordered maps for ProfilerGraph (fixes flickering)sfan52016-10-12
|
* Remove unused parameter of GUIVolumeChangeRui2016-10-09
|
* Player/LocalPlayer/RemotePlayer inheritance cleanup (part 1 on X)Loic Blot2016-10-08
| | | | | | | | | | | * LocalPlayer take ownership of maxHudId as it's the only caller * RemotePlayer take ownership of day night ratio as it's the only user * Pass getPlayerControl as const reference to prevent object copy on each call (perf improvement in ObjectRef::l_get_player_control call) * getPlayerSAO is now only RemotePlayer call * get/setHotbarItemCount is now RemotePlayer owned * Server: Use RemotePlayer instead of Player object on concerned call to properly fix the object type * PlayerSAO now uses RemotePlayer instead of Player because it's only server side * ObjectRef::getplayer also returns RemotePlayer as it's linked with PlayerSAO
* Replace various std::map with UNORDERED_MAP + various cleanupsLoic Blot2016-10-05
| | | | | | | | | | | | This is part 2 for 5f084cd98d7b3326b51320455364337539710efd Other improvements: * Use the defined ItemGroupList when used * make Client::checkPrivilege const * inline some trivial functions * Add ActiveObjectMap typedef * Add SettingsEntries typedef
* Client: disable pre v25 init sending by defaultest312016-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Disable the ability to connect to old servers by default to improve password security. If people still want to connect to old (0.4.12 and earlier) servers, they can flip the send_pre_v25_init setting. Add the ability to detect if we've tried to connect to a server which only supports the pre v25 init protocol, and show an apropriate error message. Most times the error will already be catched at the serverlist level, the detection mechanism only acts as last resort, because the "Connection timed out" error message that would be shown otherwise would be very confusing. Automatic "fixing" of this condition is not desired, as it would allow for downgrade attacks. As already 161 of the 167 servers on the serverlist support the new srp based auth protocol (> 96%), the breakage should be minimal. Follow up of commit af30183124d40a969040d7de4b3a487feec466e4 "Add option to not send pre v25 init packet" Also change the pessimistic assumption of masterlist server versions to optimistic, in order to avoid buggy behaviour (favourites not in the serverlist would be denied to connect to, etc).
* Add zoom, tweakable with zoom_fov, default key: Z (like optifine)Esteban I. Ruiz Moreno2016-08-10
|
* Use mathematical function to determine yaw directionsfan52016-07-05
|
* Remove top left minetest watermarkest312016-07-03
| | | | | | | | Move version information into the window caption. On popular player request. Fixes #4209.
* Initial Gamepad supportest312016-06-03
| | | | | | | Adds initial ingame gamepad support to minetest. Full Formspec support is not implemented yet and can be added by a later change.
* Input related generalisationsest312016-06-03
| | | | | * Move key types into own file * Use Generalized input methods in game.cpp
* Add colored text (not only colored chat).Ekdohibs2016-05-31
| | | | | Add documentation, move files to a proper place and avoid memory leaks. Make it work with most kind of texts, and allow backgrounds too.
* Colored chat working as expected for both freetype and non-freetype builds. ↵TriBlade92016-05-31
| | | | @nerzhul improvements * Add unit tests * Fix coding style * move guiChatConsole.hpp to client/
* Tell irrlicht if we handle a key or not.est312016-05-26
| | | | | | | | | We can remove the function in MtNativeActivity now as it serves precisely that purpose: to tell irrlicht that we handled the esc key. TODO for later: * Perhaps try to find a more performant container than KeyList
* Escape more strings: formspecs, item descriptions, infotexts...Ekdohibs2016-04-24
| | | | | | Also, change the escape character to the more standard \x1b Thus, it can be used in the future for translation or colored text, for example.
* Add option to disable entity selectionboxes. (#3992)TriBlade92016-04-14
| | | | Setting only loaded once, default value is to enable them.
* Fix connected nodes' selection boxes.Auke Kok2016-03-21
| | | | | | | This allows the player to more easily target and punch connected nodeboxes, especially if they have a fixed nodebox that is very small, like technic cabling, or xpanes. Tried it on fences and my xpane conversion, and happy with the result.
* Nodebox: Allow nodeboxes to "connect"Auke Kok2016-03-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We introduce a new nodebox type "connected", and allow these nodes to have optional nodeboxes that connect it to other connecting nodeboxes. This is all done at scenedraw time in the client. The client will inspect the surrounding nodes and if they are to be connected to, it will draw the appropriate connecting nodeboxes to make those connections. In the node_box definition, we have to specify separate nodeboxes for each valid connection. This allows us to make nodes that connect only horizontally (the common case) by providing optional nodeboxes for +x, -x, +z, -z directions. Or this allows us to make wires that can connect up and down, by providing nodeboxes that connect it up and down (+y, -y) as well. The optional nodeboxes can be arrays. They are named "connect_top, "connect_bottom", "connect_front", "connect_left", "connect_back" and "connect_right". Here, "front" means the south facing side of the node that has facedir = 0. Additionally, a "fixed" nodebox list present will always be drawn, so one can make a central post, for instance. This "fixed" nodebox can be omitted, or it can be an array of nodeboxes. Collision boxes are also updated in exactly the same fashion, which allows you to walk over the upper extremities of the individual node boxes, or stand really close to them. You can also walk up node noxes that are small in height, all as expected, and unlike the NDT_FENCELIKE nodes. I've posted a screenshot demonstrating the flexibility at http://i.imgur.com/zaJq8jo.png In the screenshot, all connecting nodes are of this new subtype. Transparent textures render incorrectly, Which I don't think is related to this text, as other nodeboxes also have issues with this. A protocol bump is performed in order to be able to send older clients a nodeblock that is usable for them. In order to avoid abuse of users we send older clients a "full-size" node, so that it's impossible for them to try and walk through a fence or wall that's created in this fashion. This was tested with a pre-bump client connected against a server running the new protocol. These nodes connect to other nodes, and you can select which ones those are by specifying node names (or group names) in the connects_to string array: connects_to = { "group:fence", "default:wood" } By default, nodes do not connect to anything, allowing you to create nodes that always have to be paired in order to connect. lua_api.txt is updated to reflect the extension to the node_box API. Example lua code needed to generate these nodes can be found here: https://gist.github.com/sofar/b381c8c192c8e53e6062
* Add Android chat formShadowNinja2016-03-02
|
* Unlock cursor when opening consoleShadowNinja2016-03-02
|
* Use the console instead of a dedicated window when pressing keymap_chat/cmdEsteban I. Ruiz Moreno2016-03-02
| | | | keymap_console opens a full window for chat history browsing.
* Fix getting pointed nodeRealBadAngel2016-02-22
| | | | | Fixes #3719 Closes #3753
* Camera: remove auto tune FPS, single view range settingRealBadAngel2016-02-21
|
* Move object nametags to cameraRealBadAngel2016-02-18
|
* Use proper variable types for uniform sampler layersRealBadAngel2016-02-14
|
* Cleanup selection mesh code, add shaders for halo and selection boxesRealBadAngel2016-02-08
|
* Show infotext with description for item entitiesRealBadAngel2016-01-18
|
* New 3D Mode: PageflipDalai Felinto2016-01-09
| | | | | | | | | | | | | | | | The pageflip mode requires a stereo quadbuffer, and a modern graphic card. Patch tested with NVidia 3D Vision. The mini-map is not drawn, but that's what is done for topbottom and sidebyside modes as well. Also most of the time the user would prefer the HUD to be off. That's for the user to decide though, and toggle it manually. Finally, the interocular distance (aka eye separation) is twice as much as the "3d_paralax_strength" settings. I find this a strange design decision. I didn't want to chance this though, since it's how the other 3d modes interpret this settings.
, &blockSize); oss << "Windows/" << HIWORD(fixedFileInfo->dwProductVersionMS) << '.' // Major << LOWORD(fixedFileInfo->dwProductVersionMS) << '.' // Minor << HIWORD(fixedFileInfo->dwProductVersionLS) << ' '; // Build #ifdef _WIN64 oss << "x86_64"; #else BOOL is64 = FALSE; if (IsWow64Process(GetCurrentProcess(), &is64) && is64) oss << "x86_64"; // 32-bit app on 64-bit OS else oss << "x86"; #endif delete[] lpVersionInfo; delete[] filePath; return oss.str(); #else struct utsname osinfo; uname(&osinfo); return std::string(osinfo.sysname) + "/" + osinfo.release + " " + osinfo.machine; #endif } bool getCurrentWorkingDir(char *buf, size_t len) { #ifdef _WIN32 DWORD ret = GetCurrentDirectory(len, buf); return (ret != 0) && (ret <= len); #else return getcwd(buf, len); #endif } bool getExecPathFromProcfs(char *buf, size_t buflen) { #ifndef _WIN32 buflen--; ssize_t len; if ((len = readlink("/proc/self/exe", buf, buflen)) == -1 && (len = readlink("/proc/curproc/file", buf, buflen)) == -1 && (len = readlink("/proc/curproc/exe", buf, buflen)) == -1) return false; buf[len] = '\0'; return true; #else return false; #endif } //// Windows #if defined(_WIN32) bool getCurrentExecPath(char *buf, size_t len) { DWORD written = GetModuleFileNameA(NULL, buf, len); if (written == 0 || written == len) return false; return true; } //// Linux #elif defined(__linux__) bool getCurrentExecPath(char *buf, size_t len) { if (!getExecPathFromProcfs(buf, len)) return false; return true; } //// Mac OS X, Darwin #elif defined(__APPLE__) bool getCurrentExecPath(char *buf, size_t len) { uint32_t lenb = (uint32_t)len; if (_NSGetExecutablePath(buf, &lenb) == -1) return false; return true; } //// FreeBSD, NetBSD, DragonFlyBSD #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) bool getCurrentExecPath(char *buf, size_t len) { // Try getting path from procfs first, since valgrind // doesn't work with the latter if (getExecPathFromProcfs(buf, len)) return true; int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; if (sysctl(mib, 4, buf, &len, NULL, 0) == -1) return false; return true; } #elif defined(__HAIKU__) bool getCurrentExecPath(char *buf, size_t len) { return find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, buf, len) == B_OK; } //// Solaris #elif defined(__sun) || defined(sun) bool getCurrentExecPath(char *buf, size_t len) { const char *exec = getexecname(); if (exec == NULL) return false; if (strlcpy(buf, exec, len) >= len) return false; return true; } // HP-UX #elif defined(__hpux) bool getCurrentExecPath(char *buf, size_t len) { struct pst_status psts; if (pstat_getproc(&psts, sizeof(psts), 0, getpid()) == -1) return false; if (pstat_getpathname(buf, len, &psts.pst_fid_text) == -1) return false; return true; } #else bool getCurrentExecPath(char *buf, size_t len) { return false; } #endif //// Non-Windows #if !defined(_WIN32) const char *getHomeOrFail() { const char *home = getenv("HOME"); // In rare cases the HOME environment variable may be unset FATAL_ERROR_IF(!home, "Required environment variable HOME is not set"); return home; } #endif //// Windows #if defined(_WIN32) bool setSystemPaths() { char buf[BUFSIZ]; // Find path of executable and set path_share relative to it FATAL_ERROR_IF(!getCurrentExecPath(buf, sizeof(buf)), "Failed to get current executable path"); pathRemoveFile(buf, '\\'); std::string exepath(buf); // Use ".\bin\.." path_share = exepath + "\\.."; if (detectMSVCBuildDir(exepath)) { // The msvc build dir schould normaly not be present if properly installed, // but its usefull for debugging. path_share += DIR_DELIM ".."; } // Use "C:\Users\<user>\AppData\Roaming\<PROJECT_NAME_C>" DWORD len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf)); FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA"); path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME_C; return true; } //// Linux #elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) bool setSystemPaths() { char buf[BUFSIZ]; if (!getCurrentExecPath(buf, sizeof(buf))) { #ifdef __ANDROID__ errorstream << "Unable to read bindir "<< std::endl; #else FATAL_ERROR("Unable to read bindir"); #endif return false; } pathRemoveFile(buf, '/'); std::string bindir(buf); // Find share directory from these. // It is identified by containing the subdirectory "builtin". std::list<std::string> trylist; std::string static_sharedir = STATIC_SHAREDIR; if (!static_sharedir.empty() && static_sharedir != ".") trylist.push_back(static_sharedir); trylist.push_back(bindir + DIR_DELIM ".." DIR_DELIM "share" DIR_DELIM + PROJECT_NAME); trylist.push_back(bindir + DIR_DELIM ".."); #ifdef __ANDROID__ trylist.push_back(path_user); #endif for (std::list<std::string>::const_iterator i = trylist.begin(); i != trylist.end(); ++i) { const std::string &trypath = *i; if (!fs::PathExists(trypath) || !fs::PathExists(trypath + DIR_DELIM + "builtin")) { warningstream << "system-wide share not found at \"" << trypath << "\""<< std::endl; continue; } // Warn if was not the first alternative if (i != trylist.begin()) { warningstream << "system-wide share found at \"" << trypath << "\"" << std::endl; } path_share = trypath; break; } #ifndef __ANDROID__ path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + PROJECT_NAME; #endif return true; } //// Mac OS X #elif defined(__APPLE__) bool setSystemPaths() { CFBundleRef main_bundle = CFBundleGetMainBundle(); CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(main_bundle); char path[PATH_MAX]; if (CFURLGetFileSystemRepresentation(resources_url, TRUE, (UInt8 *)path, PATH_MAX)) { path_share = std::string(path); } else { warningstream << "Could not determine bundle resource path" << std::endl; } CFRelease(resources_url); path_user = std::string(getHomeOrFail()) + "/Library/Application Support/" + PROJECT_NAME; return true; } #else bool setSystemPaths() { path_share = STATIC_SHAREDIR; path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + lowercase(PROJECT_NAME); return true; } #endif void migrateCachePath() { const std::string local_cache_path = path_user + DIR_DELIM + "cache"; // Delete tmp folder if it exists (it only ever contained // a temporary ogg file, which is no longer used). if (fs::PathExists(local_cache_path + DIR_DELIM + "tmp")) fs::RecursiveDelete(local_cache_path + DIR_DELIM + "tmp"); // Bail if migration impossible if (path_cache == local_cache_path || !fs::PathExists(local_cache_path) || fs::PathExists(path_cache)) { return; } if (!fs::Rename(local_cache_path, path_cache)) { errorstream << "Failed to migrate local cache path " "to system path!" << std::endl; } } void initializePaths() { #if RUN_IN_PLACE char buf[BUFSIZ]; infostream << "Using relative paths (RUN_IN_PLACE)" << std::endl; bool success = getCurrentExecPath(buf, sizeof(buf)) || getExecPathFromProcfs(buf, sizeof(buf)); if (success) { pathRemoveFile(buf, DIR_DELIM_CHAR); std::string execpath(buf); path_share = execpath + DIR_DELIM ".."; path_user = execpath + DIR_DELIM ".."; if (detectMSVCBuildDir(execpath)) { path_share += DIR_DELIM ".."; path_user += DIR_DELIM ".."; } } else { errorstream << "Failed to get paths by executable location, " "trying cwd" << std::endl; if (!getCurrentWorkingDir(buf, sizeof(buf))) FATAL_ERROR("Ran out of methods to get paths"); size_t cwdlen = strlen(buf); if (cwdlen >= 1 && buf[cwdlen - 1] == DIR_DELIM_CHAR) { cwdlen--; buf[cwdlen] = '\0'; } if (cwdlen >= 4 && !strcmp(buf + cwdlen - 4, DIR_DELIM "bin")) pathRemoveFile(buf, DIR_DELIM_CHAR); std::string execpath(buf); path_share = execpath; path_user = execpath; } path_cache = path_user + DIR_DELIM + "cache"; #else infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl; if (!setSystemPaths()) errorstream << "Failed to get one or more system-wide path" << std::endl; # ifdef _WIN32 path_cache = path_user + DIR_DELIM + "cache"; # else // Initialize path_cache // First try $XDG_CACHE_HOME/PROJECT_NAME const char *cache_dir = getenv("XDG_CACHE_HOME"); const char *home_dir = getenv("HOME"); if (cache_dir) { path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME; } else if (home_dir) { // Then try $HOME/.cache/PROJECT_NAME path_cache = std::string(home_dir) + DIR_DELIM + ".cache" + DIR_DELIM + PROJECT_NAME; } else { // If neither works, use $PATH_USER/cache path_cache = path_user + DIR_DELIM + "cache"; } // Migrate cache folder to new location if possible migrateCachePath(); # endif // _WIN32 #endif // RUN_IN_PLACE infostream << "Detected share path: " << path_share << std::endl; infostream << "Detected user path: " << path_user << std::endl; infostream << "Detected cache path: " << path_cache << std::endl; #if USE_GETTEXT bool found_localedir = false; # ifdef STATIC_LOCALEDIR /* STATIC_LOCALEDIR may be a generalized path such as /usr/share/locale that * doesn't necessarily contain our locale files, so check data path first. */ path_locale = getDataPath("locale"); if (fs::PathExists(path_locale)) { found_localedir = true; infostream << "Using in-place locale directory " << path_locale << " even though a static one was provided." << std::endl; } else if (STATIC_LOCALEDIR[0] && fs::PathExists(STATIC_LOCALEDIR)) { found_localedir = true; path_locale = STATIC_LOCALEDIR; infostream << "Using static locale directory " << STATIC_LOCALEDIR << std::endl; } # else path_locale = getDataPath("locale"); if (fs::PathExists(path_locale)) { found_localedir = true; } # endif if (!found_localedir) { warningstream << "Couldn't find a locale directory!" << std::endl; } #endif // USE_GETTEXT } //// //// OS-specific Secure Random //// #ifdef WIN32 bool secure_rand_fill_buf(void *buf, size_t len) { HCRYPTPROV wctx; if (!CryptAcquireContext(&wctx, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; CryptGenRandom(wctx, len, (BYTE *)buf); CryptReleaseContext(wctx, 0); return true; } #else bool secure_rand_fill_buf(void *buf, size_t len) { // N.B. This function checks *only* for /dev/urandom, because on most // common OSes it is non-blocking, whereas /dev/random is blocking, and it // is exceptionally uncommon for there to be a situation where /dev/random // exists but /dev/urandom does not. This guesswork is necessary since // random devices are not covered by any POSIX standard... FILE *fp = fopen("/dev/urandom", "rb"); if (!fp) return false; bool success = fread(buf, len, 1, fp) == 1; fclose(fp); return success; } #endif void attachOrCreateConsole() { #ifdef _WIN32 static bool consoleAllocated = false; const bool redirected = (_fileno(stdout) == -2 || _fileno(stdout) == -1); // If output is redirected to e.g a file if (!consoleAllocated && redirected && (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())) { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); consoleAllocated = true; } #endif } int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) { // https://msdn.microsoft.com/en-us/library/bt7tawza.aspx // Many of the MSVC / Windows printf-style functions do not support positional // arguments (eg. "%1$s"). We just forward the call to vsnprintf for sane // platforms, but defer to _vsprintf_p on MSVC / Windows. // https://github.com/FFmpeg/FFmpeg/blob/5ae9fa13f5ac640bec113120d540f70971aa635d/compat/msvcrt/snprintf.c#L46 // _vsprintf_p has to be shimmed with _vscprintf_p on -1 (for an example see // above FFmpeg link). va_list args; va_start(args, fmt); #ifndef _MSC_VER int c = vsnprintf(buf, buf_size, fmt, args); #else // _MSC_VER int c = _vsprintf_p(buf, buf_size, fmt, args); if (c == -1) c = _vscprintf_p(fmt, args); #endif // _MSC_VER va_end(args); return c; } static bool open_uri(const std::string &uri) { if (uri.find_first_of("\r\n") != std::string::npos) { errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl; return false; } #if defined(_WIN32) return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; #elif defined(__ANDROID__) openURIAndroid(uri); return true; #elif defined(__APPLE__) const char *argv[] = {"open", uri.c_str(), NULL}; return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, (*_NSGetEnviron())) == 0; #else const char *argv[] = {"xdg-open", uri.c_str(), NULL}; return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; #endif } bool open_url(const std::string &url) { if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") { errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl; return false; } return open_uri(url); } bool open_directory(const std::string &path) { if (!fs::IsDir(path)) { errorstream << "Unable to open directory as it does not exist: " << path << std::endl; return false; } return open_uri(path); } // Load performance counter frequency only once at startup #ifdef _WIN32 inline double get_perf_freq() { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; } double perf_freq = get_perf_freq(); #endif } //namespace porting