Merge branch 'main/gingo-test' into fixes

fixes
Nuno 3 years ago
commit 9923062417

1
.gitignore vendored

@ -165,6 +165,7 @@ build/*
install/* install/*
win-build/ win-build/
build_* build_*
install_*
nel/tools/build_gamedata/configuration/buildsite.py nel/tools/build_gamedata/configuration/buildsite.py
# Linux nel compile # Linux nel compile

@ -249,6 +249,8 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
OPTION(WITH_ASSIMP "Use assimp exporter" OFF) OPTION(WITH_ASSIMP "Use assimp exporter" OFF)
OPTION(WITH_LIBGSF "Use libgsf for max file library" OFF) OPTION(WITH_LIBGSF "Use libgsf for max file library" OFF)
OPTION(WITH_FFMPEG "Use ffmpeg for audio decoder" OFF)
### ###
# GUI toolkits # GUI toolkits
### ###

@ -1,59 +1,55 @@
jobs: jobs:
- job: ubuntu16 - job: ubuntu18
timeoutInMinutes: 120 timeoutInMinutes: 120
pool: pool:
vmImage: 'Ubuntu-16.04' vmImage: 'ubuntu-18.04'
steps: steps:
- script: | - script: |
sudo apt-get update sudo apt update
sudo apt-get install -y software-properties-common sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ubuntu-toolchain-r/test # sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update sudo apt update
sudo apt-get install cmake build-essential -y sudo apt install cmake build-essential -y
sudo apt-get install gcc-8 g++-8 -y sudo apt install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60
sudo apt-get install bison autoconf automake -y sudo apt install bison autoconf automake -y
sudo apt-get install libpng12-dev -y sudo apt install libpng-dev -y
sudo apt-get install libjpeg-dev -y sudo apt install libjpeg-dev -y
sudo apt-get install libgif-dev libfreetype6-dev -y sudo apt install libgif-dev libfreetype6-dev -y
sudo apt-get install freeglut3-dev -y sudo apt install freeglut3-dev -y
sudo apt-get install liblua5.1-dev libluabind-dev libcpptest-dev -y sudo apt install liblua5.2-dev libluabind-dev libcpptest-dev -y
sudo apt-get install libogg-dev libvorbis-dev libopenal-dev -y sudo apt install libogg-dev libvorbis-dev libopenal-dev -y
sudo apt-get install libavcodec-dev libavformat-dev libavdevice-dev libswscale-dev libpostproc-dev -y sudo apt install libavcodec-dev libavformat-dev libavdevice-dev libswscale-dev libpostproc-dev -y
sudo apt-get install libmysqlclient-dev -y sudo apt install libmysqlclient-dev -y
sudo apt-get install libxml2-dev -y sudo apt install libxml2-dev -y
sudo apt-get install libcurl4-openssl-dev libssl-dev -y sudo apt install libcurl4-openssl-dev libssl-dev -y
sudo apt-get install libsquish-dev -y sudo apt install libsquish-dev -y
sudo apt-get install liblzma-dev -y sudo apt install liblzma-dev -y
sudo apt-get install libgsf-1-dev -y sudo apt install libgsf-1-dev -y
sudo apt-get install qtbase5-dev qttools5-dev qttools5-dev-tools sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools
displayName: 'Dependencies' displayName: 'Dependencies'
- script: | - script: |
mkdir build mkdir build
cmake --version cmake --version
cd build cd build
cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON .. cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=OFF -DWITH_LUA52=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON ..
cat CMakeCache.txt cat CMakeCache.txt
displayName: 'CMake' displayName: 'CMake'
- script: | - script: |
cd build cd build
make -j`nproc` make -j`nproc`
displayName: 'Make' displayName: 'Make'
- job: ubuntu18 - job: ubuntu20
timeoutInMinutes: 120 timeoutInMinutes: 120
pool: pool:
vmImage: 'ubuntu-18.04' vmImage: 'ubuntu-20.04'
steps: steps:
- script: | - script: |
sudo apt update sudo apt update
sudo apt install -y software-properties-common sudo apt install -y software-properties-common
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update sudo apt update
sudo apt install cmake build-essential -y sudo apt install cmake build-essential -y
sudo apt install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60
sudo apt install bison autoconf automake -y sudo apt install bison autoconf automake -y
sudo apt install libpng-dev -y sudo apt install libpng-dev -y
sudo apt install libjpeg-dev -y sudo apt install libjpeg-dev -y

@ -20,7 +20,9 @@ ENDIF()
IF(WITH_SOUND) IF(WITH_SOUND)
FIND_PACKAGE(Ogg) FIND_PACKAGE(Ogg)
FIND_PACKAGE(Vorbis) FIND_PACKAGE(Vorbis)
FIND_PACKAGE(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE) IF(WITH_FFMPEG)
FIND_PACKAGE(FFmpeg REQUIRED COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE)
ENDIF()
IF(WITH_DRIVER_OPENAL) IF(WITH_DRIVER_OPENAL)
FIND_PACKAGE(OpenAL) FIND_PACKAGE(OpenAL)

@ -76,16 +76,16 @@ namespace NLGUI
void reindexChilds(); void reindexChilds();
// escape text tag or attribute value // escape text tag or attribute value
std::string htmlEscape(std::string val, bool isAttribute = false) const; std::string htmlEscape(const std::string &val) const;
// serialize element attributes as string // serialize element attributes as string
std::string serializeAttributes() const; std::string serializeAttributes(bool escape = true) const;
// serialize child elements as html string // serialize child elements as html string
std::string serializeChilds() const; std::string serializeChilds(bool escape = true) const;
// serialize itself and children as html string // serialize itself and children as html string
std::string serialize() const; std::string serialize(bool escape = true) const;
// debug // debug
std::string toString(bool tree = false, uint depth = 0) const; std::string toString(bool tree = false, uint depth = 0) const;

@ -174,10 +174,6 @@
# define NL_COMP_GCC # define NL_COMP_GCC
#endif #endif
#if defined(_HAS_CPP0X) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(NL_COMP_VC_VERSION) && NL_COMP_VC_VERSION >= 110)
# define NL_ISO_CPP0X_AVAILABLE
#endif
#if defined(NL_COMP_GCC) && (__cplusplus >= 201103L) #if defined(NL_COMP_GCC) && (__cplusplus >= 201103L)
# define NL_NO_EXCEPTION_SPECS # define NL_NO_EXCEPTION_SPECS
#endif #endif
@ -233,6 +229,10 @@
# endif # endif
#endif #endif
#if defined(_HAS_CPP0X) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(NL_COMP_VC_VERSION) && NL_COMP_VC_VERSION >= 110) || (defined(NL_COMP_GCC) && (GCC_VERSION >= 40400) && (__cplusplus >= 201103L))
# define NL_ISO_CPP0X_AVAILABLE
#endif
// Remove stupid Visual C++ warnings // Remove stupid Visual C++ warnings
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
# pragma warning (disable : 4503) // STL: Decorated name length exceeded, name was truncated # pragma warning (disable : 4503) // STL: Decorated name length exceeded, name was truncated

@ -34,7 +34,7 @@ class CCurlHttpClient
public: public:
/// Constructor /// Constructor
CCurlHttpClient() : _CurlStruct(NULL) {} CCurlHttpClient() : _CurlStruct(NULL), m_Verify(true) {}
/// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server. /// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server.
bool connect(const std::string &server); bool connect(const std::string &server);
@ -63,6 +63,8 @@ public:
/// Disconnect if connected (otherwise does nothing) /// Disconnect if connected (otherwise does nothing)
void disconnect(); void disconnect();
const char *lastError() { return &m_ErrorBuf[0]; }
protected: protected:
/// Helper /// Helper
@ -78,6 +80,10 @@ private:
std::vector<uint8> _ReceiveBuffer; std::vector<uint8> _ReceiveBuffer;
std::string _Auth; // must be kept here because curl only stores the char pointer std::string _Auth; // must be kept here because curl only stores the char pointer
std::vector<char> m_ErrorBuf;
bool m_Verify;
}; };
extern CCurlHttpClient CurlHttpClient; extern CCurlHttpClient CurlHttpClient;

@ -999,6 +999,9 @@ private:
bool createWindow(const GfxMode& mode); bool createWindow(const GfxMode& mode);
bool destroyWindow(); bool destroyWindow();
// Return monitor info and positon in multi monitor setup or false if monitor not found.
bool getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const;
enum EWindowStyle { EWSWindowed, EWSFullscreen }; enum EWindowStyle { EWSWindowed, EWSFullscreen };
void setWindowSize(uint32 width, uint32 height); void setWindowSize(uint32 width, uint32 height);

@ -650,8 +650,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
_win = EmptyWindow; _win = EmptyWindow;
_CurrentMode = mode;
_WindowVisible = false; _WindowVisible = false;
_Resizable = resizeable; _Resizable = resizeable;
_DestroyWindow = false; _DestroyWindow = false;
@ -1194,6 +1192,8 @@ bool CDriverGL::saveScreenMode()
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: if using mode switching, save current xrandr mode to _OldSizeID
res = true;
if (!res && _xrandr_version > 0) if (!res && _xrandr_version > 0)
{ {
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
@ -1254,6 +1254,8 @@ bool CDriverGL::restoreScreenMode()
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: if using mode switching, then restore mode from _OldSizeID
res = true;
if (!res && _xrandr_version > 0) if (!res && _xrandr_version > 0)
{ {
Window root = RootWindow(_dpy, screen); Window root = RootWindow(_dpy, screen);
@ -1348,7 +1350,8 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
&& mode.Width == previousMode.Width && mode.Width == previousMode.Width
&& mode.Height == previousMode.Height && mode.Height == previousMode.Height
&& mode.Depth == previousMode.Depth && mode.Depth == previousMode.Depth
&& mode.Frequency == previousMode.Frequency) && mode.Frequency == previousMode.Frequency
&& mode.DisplayDevice == previousMode.DisplayDevice)
return true; return true;
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
@ -1388,6 +1391,8 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
bool found = false; bool found = false;
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
// TODO: implement mode switching using xrandr crts
found = true;
if (!found && _xrandr_version > 0) if (!found && _xrandr_version > 0)
{ {
@ -1911,8 +1916,92 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
return true; return true;
} }
bool CDriverGL::getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const
{
bool found = false;
#if HAVE_XRANDR
int screen = DefaultScreen(_dpy);
// xrandr 1.5+
if (_xrandr_version >= 105)
{
int nmonitors = 0;
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
if (!monitor)
return false;
for(sint i = 0; i< nmonitors; ++i)
{
char* pname = XGetAtomName(_dpy, monitor[i].name);
found = (nlstricmp(pname, name) == 0);
XFree(pname);
if (found)
{
x = monitor[i].x;
y = monitor[i].y;
w = monitor[i].width;
h = monitor[i].height;
break;
}
}
XRRFreeMonitors(monitor);
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
for(uint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected && nlstricmp(name, output->name) == 0)
{
// physical monitor
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
found = true;
x = crtc->x;
y = crtc->y;
// TODO: test rotation
if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180)
{
w = crtc->width;
h = crtc->height;
}
else
{
w = crtc->height;
h = crtc->width;
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
if (found)
break;
}
XRRFreeScreenResources(resources);
}
#endif
return found;
}
// -------------------------------------------------- // --------------------------------------------------
bool CDriverGL::setMode(const GfxMode& mode) bool CDriverGL::setMode(const GfxMode& amode)
{ {
H_AUTO_OGL(CDriverGL_setMode); H_AUTO_OGL(CDriverGL_setMode);
@ -1920,6 +2009,10 @@ bool CDriverGL::setMode(const GfxMode& mode)
if (!_DestroyWindow) if (!_DestroyWindow)
return true; return true;
#if !(HAVE_XRANDR)
const GfxMode &mode = amode;
#endif
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
// save relative cursor // save relative cursor
POINT cursorPos; POINT cursorPos;
@ -1929,21 +2022,89 @@ bool CDriverGL::setMode(const GfxMode& mode)
BOOL cursorPosOk = isSystemCursorInClientArea() BOOL cursorPosOk = isSystemCursorInClientArea()
&& GetCursorPos(&cursorPos) && GetCursorPos(&cursorPos)
&& ScreenToClient(_win, &cursorPos); && ScreenToClient(_win, &cursorPos);
// FIXME: this probably needs to use _CurrentMode instead of mode
sint curX = (sint)cursorPos.x * (sint)mode.Width; sint curX = (sint)cursorPos.x * (sint)mode.Width;
sint curY = (sint)cursorPos.y * (sint)mode.Height; sint curY = (sint)cursorPos.y * (sint)mode.Height;
#endif #endif
#if HAVE_XRANDR
GfxMode mode = amode;
if (!mode.Windowed)
{
GfxMode current;
if (!getCurrentScreenMode(current))
nlinfo("3D: XrandR: Reading active monitor info failed");
sint newX = _WindowX;
sint newY = _WindowY;
// make sure resolution matches requested or currently active monitor's resolution
mode.Width = current.Width;
mode.Height = current.Height;
if (!mode.DisplayDevice.empty())
{
uint newW = current.Width;
uint newH = current.Height;
if (getMonitorByName(mode.DisplayDevice, newX, newY, newW, newH))
{
mode.Width = newW;
mode.Height = newH;
}
else
{
nlinfo("3D: XrandR: Reading requested monitor '%s' info failed, using '%s'", mode.DisplayDevice.c_str(), current.DisplayDevice.c_str());
mode.DisplayDevice = current.DisplayDevice;
}
}
// switching monitors.
// first move mouse pointer to target monitor and then move window.
// if window is visible, then also restore mouse relative position.
if (!mode.DisplayDevice.empty() && mode.DisplayDevice != current.DisplayDevice)
{
int screen = DefaultScreen(_dpy);
Window root = RootWindow(_dpy, screen);
uint mouseX = mode.Width / 2;
uint mouseY = mode.Height / 2;
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
if (xwa.map_state != IsUnmapped)
{
Window root_win;
Window child_win;
sint root_x, root_y, win_x, win_y;
uint mask;
Bool res = XQueryPointer(_dpy, _win, &root_win, &child_win, &root_x, &root_y, &win_x, &win_y, &mask);
if (res)
{
mouseX = (uint)((float)win_x * mode.Width / current.Width);
mouseY = (uint)((float)win_y * mode.Height / current.Height);
}
}
XWarpPointer(_dpy, None, root, None, None, None, None, newX + mouseX, newY + mouseY);
XMoveWindow(_dpy, _win, newX, newY);
_WindowX = newX;
_WindowY = newY;
}
}
#endif
if (!setScreenMode(mode)) if (!setScreenMode(mode))
return false; return false;
_CurrentMode.Depth = mode.Depth;
_CurrentMode.Frequency = mode.Frequency;
_CurrentMode.DisplayDevice = mode.DisplayDevice;
// when changing window style, it's possible system change window size too // when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen);
if (!mode.Windowed)
_CurrentMode.Depth = mode.Depth;
setWindowSize(mode.Width, mode.Height);
setWindowPos(_WindowX, _WindowY); setWindowPos(_WindowX, _WindowY);
setWindowSize(mode.Width, mode.Height);
switch (_CurrentMode.Depth) switch (_CurrentMode.Depth)
{ {
@ -2120,6 +2281,66 @@ bool CDriverGL::getModes(std::vector<GfxMode> &modes)
int screen = DefaultScreen(_dpy); int screen = DefaultScreen(_dpy);
#if defined(HAVE_XRANDR) #if defined(HAVE_XRANDR)
if (_xrandr_version >= 105)
{
int nmonitors = 0;
// virtual monitors
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
for(sint i = 0; i < nmonitors; ++i)
{
char * name = XGetAtomName(_dpy, monitor[i].name);
GfxMode mode;
mode.DisplayDevice = name;
mode.Width = monitor[i].width;
mode.Height = monitor[i].height;
mode.Frequency = 0;
modes.push_back(mode);
XFree(name);
}
XRRFreeMonitors(monitor);
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
std::map<int, int> resourceModeMap;
for(sint i = 0; i< resources->nmode; ++i)
resourceModeMap.insert(std::make_pair(resources->modes[i].id, i));
for(sint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected)
{
// physical monitor
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
std::map<int,int>::const_iterator it = resourceModeMap.find(crtc->mode);
if (it != resourceModeMap.end())
{
GfxMode mode;
mode.DisplayDevice = output->name;
mode.Width = resources->modes[it->second].width;
mode.Height = resources->modes[it->second].height;
mode.Frequency = 0;
modes.push_back(mode);
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
}
XRRFreeScreenResources(resources);
}
found = modes.size() > 0;
if (!found && _xrandr_version >= 100) if (!found && _xrandr_version >= 100)
{ {
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
@ -2255,6 +2476,120 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
int screen = DefaultScreen(_dpy); int screen = DefaultScreen(_dpy);
#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
int x = 0;
int y = 0;
Window child;
// get window position so we can compare monitors (or mouse position if window not visible yet)
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
if (xwa.map_state != IsUnmapped)
{
XTranslateCoordinates(_dpy, _win, xwa.root, xwa.x, xwa.y, &x, &y, &child);
}
else
{
sint rx, ry, wx, wy;
uint mask;
Bool res = XQueryPointer(_dpy, RootWindow(_dpy, screen), &child, &child, &rx, &ry, &wx, &wy, &mask);
if (res)
{
x = rx;
y = ry;
}
}
if (_xrandr_version >= 105)
{
int nmonitors = 0;
XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors);
if (monitor)
{
sint bestMatch = -1;
for(sint i = 0; i< nmonitors; ++i)
{
if ((x >= monitor[i].x && x < (monitor[i].x + monitor[i].width) &&
y >= monitor[i].y && y < (monitor[i].y + monitor[i].height)) ||
(monitor[i].primary && bestMatch == -1))
{
bestMatch = i;
}
}
// best match or primary monitor
if (bestMatch != -1)
{
found = true;
char* pname = XGetAtomName(_dpy, monitor[bestMatch].name);
mode.DisplayDevice = pname;
mode.Width = monitor[bestMatch].width;
mode.Height = monitor[bestMatch].height;
mode.Windowed = _CurrentMode.Windowed;
mode.OffScreen = false;
mode.Depth = (uint) DefaultDepth(_dpy, screen);
mode.Frequency = 0;
XFree(pname);
}
XRRFreeMonitors(monitor);
}
}
else
{
XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen));
if (!resources)
resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen));
for(uint i = 0; i < resources->noutput; ++i)
{
XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]);
if (!output)
continue;
if (output->crtc && output->connection == RR_Connected)
{
XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc);
if (crtc)
{
sint width, height;
bool match = false;
// TODO: test rotation
if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180)
{
width = crtc->width;
height = crtc->height;
}
else
{
width = crtc->height;
height = crtc->width;
}
if (x >= crtc->x && y >= crtc->y && x < (crtc->x + width) && y < (crtc->y + height))
{
found = true;
mode.DisplayDevice = output->name;
mode.Width = width;
mode.Height = height;
mode.Windowed = _CurrentMode.Windowed;
mode.OffScreen = false;
mode.Depth = (uint) DefaultDepth(_dpy, screen);
mode.Frequency = 0;
}
XRRFreeCrtcInfo(crtc);
}
}
XRRFreeOutputInfo(output);
if (found)
break;
}
XRRFreeScreenResources(resources);
}
if (!found && _xrandr_version > 0) if (!found && _xrandr_version > 0)
{ {
@ -2432,7 +2767,6 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y)
_DecorationWidth = -1; _DecorationWidth = -1;
_DecorationHeight = -1; _DecorationHeight = -1;
} }
XMoveWindow(_dpy, _win, x, y); XMoveWindow(_dpy, _win, x, y);
} }

@ -331,6 +331,7 @@ bool CDriverUser::getCurrentScreenMode(CMode &mode)
GfxMode gfxMode; GfxMode gfxMode;
bool res= _Driver->getCurrentScreenMode(gfxMode); bool res= _Driver->getCurrentScreenMode(gfxMode);
mode.Windowed= gfxMode.Windowed; mode.Windowed= gfxMode.Windowed;
mode.DisplayDevice= gfxMode.DisplayDevice;
mode.Width= gfxMode.Width; mode.Width= gfxMode.Width;
mode.Height= gfxMode.Height; mode.Height= gfxMode.Height;
mode.Depth= gfxMode.Depth; mode.Depth= gfxMode.Depth;

@ -6793,7 +6793,7 @@ namespace NLGUI
_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup; _TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
std::string content = strFindReplaceAll(elm.serializeChilds(), std::string("\r"), std::string("")); std::string content = strFindReplaceAll(elm.serializeChilds(false), std::string("\r"), std::string(""));
CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, content, _TextAreaMaxLength); CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, content, _TextAreaMaxLength);
if (textArea) if (textArea)
@ -6826,7 +6826,7 @@ namespace NLGUI
// if (!_ReadingHeadTag) return; // if (!_ReadingHeadTag) return;
// consume all child elements // consume all child elements
_TitleString = strFindReplaceAll(elm.serializeChilds(), std::string("\t"), std::string(" ")); _TitleString = strFindReplaceAll(elm.serializeChilds(false), std::string("\t"), std::string(" "));
_TitleString = strFindReplaceAll(_TitleString, std::string("\n"), std::string(" ")); _TitleString = strFindReplaceAll(_TitleString, std::string("\n"), std::string(" "));
setTitle(_TitleString); setTitle(_TitleString);
} }

@ -142,30 +142,33 @@ namespace NLGUI
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::htmlEscape(std::string val, bool isAttribute) const std::string CHtmlElement::htmlEscape(const std::string &val) const
{ {
static const std::string searchReplace[] = { if (val.find_first_of("\"'&<>\xA0") == std::string::npos)
"&", "&amp;", return val;
"<", "&lt;",
">", "&gt;", std::string ret;
"\xA0", "&nbsp;", // resize is quaranteed, make room for some free replacements
}; ret.reserve(val.size() + 24);
for(size_t pos = 0; pos != val.size(); pos++)
for(uint i = 0; i < (sizeof(searchReplace) / sizeof(searchReplace[0])); i+=2)
val = strFindReplaceAll(val, searchReplace[i], searchReplace[i+1]);
if (isAttribute)
{ {
static const std::string q = "\""; switch(val[pos])
static const std::string quot = "&quot;"; {
val = strFindReplaceAll(val, q, quot); case '"': ret.append("&quot;"); break;
case '\'': ret.append("&#39;"); break;
case '&': ret.append("&amp;"); break;
case '<': ret.append("&lt;"); break;
case '>': ret.append("&gt;"); break;
case '\xA0': ret.append("&nbsp;"); break;
default : ret.append(&val[pos],1); break;
}
} }
return val; return ret;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serializeAttributes() const std::string CHtmlElement::serializeAttributes(bool escape) const
{ {
std::string result; std::string result;
for(std::map<std::string, std::string>::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it) for(std::map<std::string, std::string>::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it)
@ -179,30 +182,30 @@ namespace NLGUI
{ {
result += " "; result += " ";
} }
result += htmlEscape(*it2, true); result += (escape ? htmlEscape(*it2) : *it2);
} }
result += "\""; result += "\"";
} }
else else
{ {
result += " " + it->first + "=\"" + htmlEscape(it->second, true) + "\""; result += " " + it->first + "=\"" + (escape ? htmlEscape(it->second) : it->second) + "\"";
} }
} }
return result; return result;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serializeChilds() const std::string CHtmlElement::serializeChilds(bool escape) const
{ {
std::string result; std::string result;
for(std::list<CHtmlElement>::const_iterator it = Children.begin(); it != Children.end(); ++it) for(std::list<CHtmlElement>::const_iterator it = Children.begin(); it != Children.end(); ++it)
result += it->serialize(); result += it->serialize(escape);
return result; return result;
} }
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::serialize() const std::string CHtmlElement::serialize(bool escape) const
{ {
if (Type == TEXT_NODE) if (Type == TEXT_NODE)
{ {
@ -211,12 +214,14 @@ namespace NLGUI
parent->ID == HTML_NOSCRIPT)) parent->ID == HTML_NOSCRIPT))
{ {
return Value; return Value;
} else { } else if (escape) {
return htmlEscape(Value); return htmlEscape(Value);
} else {
return Value;
} }
} }
std::string result = "<" + Value + serializeAttributes() + ">"; std::string result = "<" + Value + serializeAttributes(escape) + ">";
if (ID == HTML_AREA || ID == HTML_BASE || ID == HTML_BR || if (ID == HTML_AREA || ID == HTML_BASE || ID == HTML_BR ||
ID == HTML_COL || ID == HTML_EMBED || ID == HTML_HR || ID == HTML_COL || ID == HTML_EMBED || ID == HTML_HR ||
@ -231,7 +236,7 @@ namespace NLGUI
result += "\n"; result += "\n";
if (!Children.empty()) if (!Children.empty())
result += serializeChilds(); result += serializeChilds(escape);
result += "</" + Value + ">"; result += "</" + Value + ">";

@ -42,6 +42,12 @@
#define assert(x) #define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
#include <nel/misc/algo.h> #include <nel/misc/algo.h>
#include <nel/misc/path.h> #include <nel/misc/path.h>

@ -48,6 +48,12 @@
# define assert(x) # define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
// in luabind > 0.6, LUABIND_MAX_ARITY is set to 10 // in luabind > 0.6, LUABIND_MAX_ARITY is set to 10
#if LUABIND_MAX_ARITY == 10 #if LUABIND_MAX_ARITY == 10
@ -220,7 +226,9 @@ namespace NLGUI
void CLuaIHM::push(CLuaState &ls, const ucstring &value) void CLuaIHM::push(CLuaState &ls, const ucstring &value)
{ {
//H_AUTO(Lua_CLuaIHM_push) //H_AUTO(Lua_CLuaIHM_push)
#if LUABIND_VERSION > 600 #if defined(LUABIND_STACK_HPP_INCLUDED)
luabind::push(ls.getStatePointer(), value);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), value); luabind::detail::push(ls.getStatePointer(), value);
#else #else
luabind::object obj(ls.getStatePointer(), value); luabind::object obj(ls.getStatePointer(), value);
@ -1156,7 +1164,9 @@ namespace NLGUI
case CInterfaceExprValue::RGBA: case CInterfaceExprValue::RGBA:
{ {
CRGBA color = value.getRGBA(); CRGBA color = value.getRGBA();
#if LUABIND_VERSION > 600 #if defined(LUABIND_STACK_HPP_INCLUDED)
luabind::push(ls.getStatePointer(), color);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), color); luabind::detail::push(ls.getStatePointer(), color);
#else #else
luabind::object obj(ls.getStatePointer(), color); luabind::object obj(ls.getStatePointer(), color);
@ -1416,7 +1426,9 @@ namespace NLGUI
case CReflectedProperty::UCString: case CReflectedProperty::UCString:
{ {
ucstring str = (reflectedObject.*(property.GetMethod.GetUCString))(); ucstring str = (reflectedObject.*(property.GetMethod.GetUCString))();
#if LUABIND_VERSION > 600 #if defined(LUABIND_STACK_HPP_INCLUDED)
luabind::push(ls.getStatePointer(), str);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), str); luabind::detail::push(ls.getStatePointer(), str);
#else #else
luabind::object obj(ls.getStatePointer(), str); luabind::object obj(ls.getStatePointer(), str);
@ -1427,7 +1439,9 @@ namespace NLGUI
case CReflectedProperty::UCStringRef: case CReflectedProperty::UCStringRef:
{ {
ucstring str = (reflectedObject.*(property.GetMethod.GetUCStringRef))(); ucstring str = (reflectedObject.*(property.GetMethod.GetUCStringRef))();
#if LUABIND_VERSION > 600 #if defined(LUABIND_STACK_HPP_INCLUDED)
luabind::push(ls.getStatePointer(), str);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), str); luabind::detail::push(ls.getStatePointer(), str);
#else #else
luabind::object obj(ls.getStatePointer(), str); luabind::object obj(ls.getStatePointer(), str);
@ -1442,7 +1456,9 @@ namespace NLGUI
case CReflectedProperty::RGBA: case CReflectedProperty::RGBA:
{ {
CRGBA color = (reflectedObject.*(property.GetMethod.GetRGBA))(); CRGBA color = (reflectedObject.*(property.GetMethod.GetRGBA))();
#if LUABIND_VERSION > 600 #if defined(LUABIND_STACK_HPP_INCLUDED)
luabind::push(ls.getStatePointer(), color);
#elif (LUABIND_VERSION > 600)
luabind::detail::push(ls.getStatePointer(), color); luabind::detail::push(ls.getStatePointer(), color);
#else #else
luabind::object obj(ls.getStatePointer(), color); luabind::object obj(ls.getStatePointer(), color);

@ -75,8 +75,9 @@ static const std::string CAFilename = "cacert.pem"; // https://curl.haxx.se/docs
// *************************************************************************** // ***************************************************************************
bool CCurlHttpClient::verifyServer(bool verify) bool CCurlHttpClient::verifyServer(bool verify)
{ {
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, verify ? 2 : 0); m_Verify = verify;
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, verify ? 1 : 0); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, verify ? 1 : 0);
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, verify ? 2 : 0);
// specify custom CA certs // specify custom CA certs
CCurlCertificates::addCertificateFile(CAFilename); CCurlCertificates::addCertificateFile(CAFilename);
@ -97,8 +98,8 @@ bool CCurlHttpClient::sendRequest(const std::string& methodWB, const std::string
curl_easy_setopt(_Curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(_Curl, CURLOPT_URL, url.c_str());
if (url.length() > 8 && (url[4] == 's' || url[4] == 'S')) // 01234 https if (url.length() > 8 && (url[4] == 's' || url[4] == 'S')) // 01234 https
{ {
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, m_Verify ? 1L : 0);
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, 2L); curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYHOST, m_Verify ? 2L : 0);
} }
// Authentication // Authentication
@ -124,15 +125,17 @@ bool CCurlHttpClient::sendRequest(const std::string& methodWB, const std::string
curl_easy_setopt(_Curl, CURLOPT_WRITEFUNCTION, CCurlHttpClient::writeDataFromCurl); curl_easy_setopt(_Curl, CURLOPT_WRITEFUNCTION, CCurlHttpClient::writeDataFromCurl);
curl_easy_setopt(_Curl, CURLOPT_WRITEDATA, this); curl_easy_setopt(_Curl, CURLOPT_WRITEDATA, this);
char errorbuf [CURL_ERROR_SIZE+1]; if (!m_ErrorBuf.size())
curl_easy_setopt(_Curl, CURLOPT_ERRORBUFFER, errorbuf); m_ErrorBuf.resize(CURL_ERROR_SIZE + 1);
m_ErrorBuf[0] = '\0';
curl_easy_setopt(_Curl, CURLOPT_ERRORBUFFER, &m_ErrorBuf[0]);
// Send // Send
CURLcode res = curl_easy_perform(_Curl); CURLcode res = curl_easy_perform(_Curl);
if (res != 0) if (res != 0)
{ {
if (verbose) if (verbose)
nlwarning(errorbuf); nlwarning(&m_ErrorBuf[0]);
return false; return false;
} }

@ -629,7 +629,11 @@ void sqlInit ()
nlerror ("mysql_init() failed"); nlerror ("mysql_init() failed");
} }
#if LIBMYSQL_VERSION_ID < 80000
my_bool opt = true; my_bool opt = true;
#else
bool opt = true;
#endif
if (mysql_options (db, MYSQL_OPT_RECONNECT, &opt)) if (mysql_options (db, MYSQL_OPT_RECONNECT, &opt))
{ {
mysql_close(db); mysql_close(db);

@ -302,6 +302,7 @@ CClientConfig::CClientConfig()
SelectedSlot = 0; // Default is slot 0 SelectedSlot = 0; // Default is slot 0
Windowed = false; // Default is windowed mode. Windowed = false; // Default is windowed mode.
MonitorName = "";
Width = 0; // Default Width for the window (0 = current screen resolution). Width = 0; // Default Width for the window (0 = current screen resolution).
Height = 0; // Default Height for the window (0 = current screen resolution). Height = 0; // Default Height for the window (0 = current screen resolution).
Depth = 32; // Default Bit per Pixel. Depth = 32; // Default Bit per Pixel.
@ -847,6 +848,8 @@ void CClientConfig::setValues()
} }
else else
cfgWarning("Default value used for 'Fullscreen'"); cfgWarning("Default value used for 'Fullscreen'");
READ_STRING_FV(MonitorName);
// Width // Width
READ_INT_FV(Width) READ_INT_FV(Width)
// Height // Height
@ -1993,6 +1996,11 @@ void CClientConfig::serial(NLMISC::IStream &f)
f.serial(Light); f.serial(Light);
f.xmlPop(); f.xmlPop();
f.xmlPushBegin("MonitorName");
f.xmlPushEnd();
f.serial(MonitorName);
f.xmlPop();
f.xmlPushBegin("Windowed"); f.xmlPushBegin("Windowed");
f.xmlPushEnd(); f.xmlPushEnd();
f.serial(Windowed); f.serial(Windowed);

@ -137,6 +137,8 @@ struct CClientConfig
TDriver3D Driver3D; TDriver3D Driver3D;
/// Application start in a window or in fullscreen. /// Application start in a window or in fullscreen.
bool Windowed; bool Windowed;
/// Monitor to use for fullscreen
std::string MonitorName;
/// Width for the Application. /// Width for the Application.
uint16 Width; uint16 Width;
/// Height for the Application. /// Height for the Application.

@ -198,38 +198,9 @@ bool hasPrivilegeTESTER() { return (UserPrivileges.find(":TESTER:") != std::stri
// Restore the video mode (fullscreen for example) after the connection (done in a window) // Restore the video mode (fullscreen for example) after the connection (done in a window)
void connectionRestoreVideoMode () void connectionRestoreVideoMode ()
{ {
// Setup full screen if we have to
UDriver::CMode mode;
Driver->getCurrentScreenMode(mode);
if (mode.Windowed)
{
uint32 width, height;
Driver->getWindowSize(width, height);
mode.Width = width;
mode.Height = height;
}
// don't allow sizes smaller than 1024x768
if (ClientCfg.Width < 1024) ClientCfg.Width = 1024;
if (ClientCfg.Height < 768) ClientCfg.Height = 768;
if (StereoDisplay) if (StereoDisplay)
StereoDisplayAttached = StereoDisplay->attachToDisplay(); StereoDisplayAttached = StereoDisplay->attachToDisplay();
if (!StereoDisplayAttached && (
(ClientCfg.Windowed != mode.Windowed) ||
(ClientCfg.Width != mode.Width) ||
(ClientCfg.Height != mode.Height)))
{
mode.Windowed = ClientCfg.Windowed;
mode.Depth = uint8(ClientCfg.Depth);
mode.Width = ClientCfg.Width;
mode.Height = ClientCfg.Height;
mode.Frequency = ClientCfg.Frequency;
setVideoMode(mode);
}
// And setup hardware mouse if we have to // And setup hardware mouse if we have to
InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached);
SetMouseFreeLook (); SetMouseFreeLook ();
@ -1293,19 +1264,7 @@ TInterfaceState globalMenu()
// Restore video mode // Restore video mode
if (ClientCfg.SelectCharacter == -1) if (ClientCfg.SelectCharacter == -1)
{
if (ClientCfg.Windowed)
{
// if used changed window resolution in char select
// if we don't update ClientCfg, then UI from icfg is restored wrong
uint32 width, height;
Driver->getWindowSize(width, height);
ClientCfg.Width = width;
ClientCfg.Height = height;
}
connectionRestoreVideoMode (); connectionRestoreVideoMode ();
}
// Skip intro next time // Skip intro next time
ClientCfg.writeBool("SkipIntro", true); ClientCfg.writeBool("SkipIntro", true);

@ -1061,43 +1061,48 @@ void prelogInit()
return; return;
} }
// used to determine screen default resolution UDriver::CMode mode;
if (ClientCfg.Width < 800 || ClientCfg.Height < 600) // first run (no client.cfg)
if (ClientCfg.Width == 0 || ClientCfg.Height == 0)
{ {
UDriver::CMode mode; if (Driver->getCurrentScreenMode(mode))
CConfigFile::CVar *varPtr = NULL;
if (!ClientCfg.Windowed && Driver->getCurrentScreenMode(mode))
{ {
// fullscreen, using monitor resolution
mode.Windowed = false;
ClientCfg.MonitorName = mode.DisplayDevice;
ClientCfg.Windowed = mode.Windowed;
ClientCfg.Width = mode.Width; ClientCfg.Width = mode.Width;
ClientCfg.Height = mode.Height; ClientCfg.Height = mode.Height;
ClientCfg.Depth = mode.Depth; ClientCfg.Depth = mode.Depth;
ClientCfg.Frequency = mode.Frequency; ClientCfg.Frequency = mode.Frequency;
// update client.cfg with detected depth and frequency
varPtr = ClientCfg.ConfigFile.getVarPtr("Depth");
if(varPtr)
varPtr->forceAsInt(ClientCfg.Depth);
varPtr = ClientCfg.ConfigFile.getVarPtr("Frequency");
if(varPtr)
varPtr->forceAsInt(ClientCfg.Frequency);
} }
else else
{ {
// fallback
ClientCfg.Windowed = true;
ClientCfg.Width = 1024; ClientCfg.Width = 1024;
ClientCfg.Height = 768; ClientCfg.Height = 768;
} }
// update client.cfg with detected resolution // update client.cfg with detected resolution
varPtr = ClientCfg.ConfigFile.getVarPtr("Width"); ClientCfg.writeBool("FullScreen", !ClientCfg.Windowed, true);
if(varPtr) ClientCfg.writeString("MonitorName", ClientCfg.MonitorName, true);
varPtr->forceAsInt(ClientCfg.Width); ClientCfg.writeInt("Width", ClientCfg.Width, true);
ClientCfg.writeInt("Height", ClientCfg.Height, true);
varPtr = ClientCfg.ConfigFile.getVarPtr("Height"); ClientCfg.writeInt("Depth", ClientCfg.Depth, true);
if(varPtr) ClientCfg.writeInt("Frequency", ClientCfg.Frequency, true);
varPtr->forceAsInt(ClientCfg.Height);
ClientCfg.ConfigFile.save();
}
else
{
mode.DisplayDevice = ClientCfg.MonitorName;
mode.Windowed = ClientCfg.Windowed;
mode.Width = ClientCfg.Width;
mode.Height = ClientCfg.Height;
mode.Depth = ClientCfg.Depth;
mode.Frequency = ClientCfg.Frequency;
} }
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup"));
@ -1107,25 +1112,6 @@ void prelogInit()
// Check the driver is not is 16 bits // Check the driver is not is 16 bits
checkDriverDepth (); checkDriverDepth ();
UDriver::CMode mode;
if (Driver->getCurrentScreenMode(mode))
{
// use current mode if its smaller than 1024x768
// mode should be windowed already, but incase its not, use the mode as is
if (mode.Windowed && (mode.Width > 1024 && mode.Height > 768))
{
mode.Width = 1024;
mode.Height = 768;
}
}
else
{
mode.Width = 1024;
mode.Height = 768;
mode.Windowed = true;
}
// Disable Hardware Vertex Program. // Disable Hardware Vertex Program.
if(ClientCfg.DisableVtxProgram) if(ClientCfg.DisableVtxProgram)
Driver->disableHardwareVertexProgram(); Driver->disableHardwareVertexProgram();
@ -1260,10 +1246,11 @@ void prelogInit()
else else
{ {
// position is not saved in config so center the window // position is not saved in config so center the window
if (Driver->getCurrentScreenMode(mode)) UDriver::CMode tmp;
if (Driver->getCurrentScreenMode(tmp))
{ {
posX = (mode.Width - Driver->getWindowWidth())/2; posX = (tmp.Width - Driver->getWindowWidth())/2;
posY = (mode.Height - Driver->getWindowHeight())/2; posY = (tmp.Height - Driver->getWindowHeight())/2;
} }
} }
@ -1456,6 +1443,15 @@ void prelogInit()
} }
} }
void stopSoundMngr()
{
if (SoundMngr)
{
delete SoundMngr;
SoundMngr = NULL;
}
}
// *************************************************************************** // ***************************************************************************
void initBotObjectSelection() void initBotObjectSelection()
@ -1588,6 +1584,39 @@ void postlogInit()
// set the primitive context // set the primitive context
CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
{
H_AUTO(InitRZSound)
if (!SoundMngr)
{
// Init the sound manager
nmsg = "Initializing sound manager...";
ProgressBar.newMessage(ClientCfg.buildLoadingString(nmsg));
if (ClientCfg.SoundOn)
{
SoundMngr = new CSoundManager(&ProgressBar);
try
{
SoundMngr->init(&ProgressBar);
}
catch (const Exception &e)
{
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
delete SoundMngr;
SoundMngr = NULL;
}
if (SoundMngr)
{
// init the SoundMngr with backuped volume
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
}
}
}
}
{ {
H_AUTO(InitRZShIdI) H_AUTO(InitRZShIdI)

@ -3458,6 +3458,7 @@ class CHandlerGameConfigApply : public IActionHandler
{ {
// Get W, H // Get W, H
sint w = 1024, h = 768; sint w = 1024, h = 768;
string name;
{ {
CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO )); CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO ));
if( pCB != NULL ) if( pCB != NULL )
@ -3467,6 +3468,11 @@ class CHandlerGameConfigApply : public IActionHandler
fromString(tmp, w); fromString(tmp, w);
tmp = vidModeStr.substr(vidModeStr.find('x')+2,vidModeStr.size()); tmp = vidModeStr.substr(vidModeStr.find('x')+2,vidModeStr.size());
fromString(tmp, h); fromString(tmp, h);
// extract monitor "1024x768 (VGA-1)"
string::size_type pos = vidModeStr.find('(');
if (pos != std::string::npos)
name = vidModeStr.substr(pos + 1, vidModeStr.find(")") - pos - 1);
} }
} }
@ -3509,6 +3515,7 @@ class CHandlerGameConfigApply : public IActionHandler
ClientCfg.Width = w; ClientCfg.Width = w;
ClientCfg.Height = h; ClientCfg.Height = h;
ClientCfg.MonitorName = name;
// Write the modified client.cfg // Write the modified client.cfg
ClientCfg.writeBool("FullScreen", bFullscreen); ClientCfg.writeBool("FullScreen", bFullscreen);
@ -3517,6 +3524,7 @@ class CHandlerGameConfigApply : public IActionHandler
if (bFullscreen) if (bFullscreen)
{ {
ClientCfg.writeString("MonitorName", name, true);
ClientCfg.writeInt("Depth", screenMode.Depth); ClientCfg.writeInt("Depth", screenMode.Depth);
ClientCfg.writeInt("Frequency", freq); ClientCfg.writeInt("Frequency", freq);
} }

@ -1899,9 +1899,12 @@ bool CInterfaceManager::loadConfig (const string &filename)
// NB: we are typically InGame here (even though the _InGame flag is not yet set) // NB: we are typically InGame here (even though the _InGame flag is not yet set)
// Use the screen size of the config file. Don't update current UI, just _Modes // Use the screen size of the config file. Don't update current UI, just _Modes
// //
// ClientCfg has W/H set to screen size, but interface expects scaled size uint32 width, height;
sint32 scaledW = ClientCfg.Width / ClientCfg.InterfaceScale; // get non-scaled width/height
sint32 scaledH = ClientCfg.Height / ClientCfg.InterfaceScale; Driver->getWindowSize(width, height);
// convert to scaled width/height for ui
sint32 scaledW = width / ClientCfg.InterfaceScale;
sint32 scaledH = height / ClientCfg.InterfaceScale;
CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false); CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false);
updateDesktops(scaledW, scaledH); updateDesktops(scaledW, scaledH);
} }

@ -41,6 +41,12 @@
# define assert(x) # define assert(x)
#endif #endif
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
// in luabind > 0.6, LUABIND_MAX_ARITY is set to 10 // in luabind > 0.6, LUABIND_MAX_ARITY is set to 10
#if LUABIND_MAX_ARITY == 10 #if LUABIND_MAX_ARITY == 10

@ -2218,6 +2218,7 @@ class CAHLessLod : public IActionHandler
REGISTER_ACTION_HANDLER (CAHLessLod, "less_lod"); REGISTER_ACTION_HANDLER (CAHLessLod, "less_lod");
// *************************************************************************** // ***************************************************************************
// TODO: remove resolution change from login screen
class CAHUninitResLod : public IActionHandler class CAHUninitResLod : public IActionHandler
{ {
virtual void execute (CCtrlBase * /* pCaller */, const string &/* sParams */) virtual void execute (CCtrlBase * /* pCaller */, const string &/* sParams */)
@ -2842,7 +2843,7 @@ string checkLogin(const string &login, const string &password, const string &cli
{ {
// ask server for salt // ask server for salt
if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog())) if(!HttpClient.sendGet(url + "?cmd=ask&cp=2&login=" + login + "&lg=" + ClientCfg.LanguageCode, "", pPM->isVerboseLog()))
return "Can't send (error code 60)"; return std::string("Can't send (error code 60) ") + HttpClient.lastError();
if(pPM->isVerboseLog()) nlinfo("Sent request for password salt"); if(pPM->isVerboseLog()) nlinfo("Sent request for password salt");
@ -2916,13 +2917,13 @@ string checkLogin(const string &login, const string &password, const string &cli
std::string cryptedPassword = CCrypt::crypt(password, Salt); std::string cryptedPassword = CCrypt::crypt(password, Salt);
if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) if(!HttpClient.sendGet(url + "?cmd=login&login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters))
return "Can't send (error code 2)"; return std::string("Can't send (error code 2) ") + HttpClient.lastError();
} }
else else
{ {
// don't send login and password if empty // don't send login and password if empty
if(!HttpClient.sendGet(url + "?cmd=login&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters)) if(!HttpClient.sendGet(url + "?cmd=login&clientApplication=" + clientApp + "&cp=2" + "&lg=" + ClientCfg.LanguageCode + customParameters))
return "Can't send (error code 2)"; return std::string("Can't send (error code 2) ") + HttpClient.lastError();
} }
// the response should contains the result code and the cookie value // the response should contains the result code and the cookie value
@ -3032,7 +3033,7 @@ string checkLogin(const string &login, const string &password, const string &cli
std::string cryptedPassword = CCrypt::crypt(password, Salt); std::string cryptedPassword = CCrypt::crypt(password, Salt);
if(!HttpClient.sendGet(url + "?login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2")) if(!HttpClient.sendGet(url + "?login=" + login + "&password=" + cryptedPassword + "&clientApplication=" + clientApp + "&cp=2"))
return "Can't send (error code 2)"; return std::string("Can't send (error code 2) ") + HttpClient.lastError();
/* /*
if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp)) if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
return "Can't send (error code 2)"; return "Can't send (error code 2)";

@ -2605,7 +2605,7 @@ public:
} }
}; };
void stopSoundMngr();
// **************************************************************************** // ****************************************************************************
void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
@ -2618,6 +2618,12 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
// Destination File Name (in writable directory) // Destination File Name (in writable directory)
string DestinationName; string DestinationName;
if (NLMISC::startsWith(rFTP.FileName, "sound"))
{
// Stop sound playback
stopSoundMngr();
}
if (rFTP.ExtractPath.empty()) if (rFTP.ExtractPath.empty())
{ {
DestinationName = pPM->WritableClientDataPath + rFTP.FileName; DestinationName = pPM->WritableClientDataPath + rFTP.FileName;

@ -76,7 +76,7 @@ void updateFromClientCfg()
// set latest config display mode if not attached // set latest config display mode if not attached
if (!StereoDisplayAttached) if (!StereoDisplayAttached)
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
ClientCfg.Windowed, ClientCfg.Frequency)); ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName));
// force software cursor when attached // force software cursor when attached
InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached);
} }
@ -87,12 +87,13 @@ void updateFromClientCfg()
(ClientCfg.Width != LastClientCfg.Width) || (ClientCfg.Width != LastClientCfg.Width) ||
(ClientCfg.Height != LastClientCfg.Height) || (ClientCfg.Height != LastClientCfg.Height) ||
(ClientCfg.Depth != LastClientCfg.Depth) || (ClientCfg.Depth != LastClientCfg.Depth) ||
(ClientCfg.Frequency != LastClientCfg.Frequency)) (ClientCfg.Frequency != LastClientCfg.Frequency)||
(ClientCfg.MonitorName != LastClientCfg.MonitorName))
{ {
if (!StereoDisplayAttached) if (!StereoDisplayAttached)
{ {
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
ClientCfg.Windowed, ClientCfg.Frequency)); ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName));
} }
} }

@ -1408,6 +1408,7 @@ bool getRyzomModes(std::vector<NL3D::UDriver::CMode> &videoModes, std::vector<st
// **** Init Video Modes // **** Init Video Modes
Driver->getModes(videoModes); Driver->getModes(videoModes);
// TODO: for resolutions below 1024x768, could use automatic UI scaling like in login/outgame
// Remove modes under 1024x768 (outgame ui limitation) and get the unique strings // Remove modes under 1024x768 (outgame ui limitation) and get the unique strings
sint i, j; sint i, j;
for (i = 0; i < (sint)videoModes.size(); ++i) for (i = 0; i < (sint)videoModes.size(); ++i)
@ -1424,6 +1425,9 @@ bool getRyzomModes(std::vector<NL3D::UDriver::CMode> &videoModes, std::vector<st
// create string format with width and height // create string format with width and height
string res = toString(videoModes[i].Width)+" x "+toString(videoModes[i].Height); string res = toString(videoModes[i].Width)+" x "+toString(videoModes[i].Height);
if (!videoModes[i].DisplayDevice.empty())
res += toString(" (%s)", videoModes[i].DisplayDevice.c_str());
// check if video mode already found in list // check if video mode already found in list
for (j = 0; j < (sint)stringModeList.size(); ++j) for (j = 0; j < (sint)stringModeList.size(); ++j)
{ {

@ -1402,18 +1402,6 @@ void CUserEntity::moveToCheckStartDist(CLFECOMMON::TCLEntityId slot, double dist
// disable afk mode // disable afk mode
setAFK(false); setAFK(false);
// if sufficiently near, launch the action
CEntityCL *target = EntitiesMngr.entity(slot);
if(target)
{
CVectorD dir2targ = target->pos() - pos();
dir2targ.z = 0.0;
if((dir2targ==CVectorD::Null) || (dir2targ.norm() < dist))
{
moveToAction(target);
}
}
} }
}// moveToCheckStartDist // }// moveToCheckStartDist //

@ -37,6 +37,10 @@ void quitCrashReport()
{ {
} }
void stopSoundMngr()
{
}
/// domain server version for patch /// domain server version for patch
string R2ServerVersion; string R2ServerVersion;
/// name of the version (used to alias many version under the same name), /// name of the version (used to alias many version under the same name),

@ -30,6 +30,13 @@ extern "C"
#include <cassert> #include <cassert>
#undef assert #undef assert
#define assert nlassert #define assert nlassert
// Always use unique_ptr with ValyriaTear/luabind on Ubuntu 20,
// since the setting is not stored in build_information.hpp
#ifndef LUABIND_USE_CXX11
#define LUABIND_USE_CXX11
#endif
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
using namespace std; using namespace std;

Loading…
Cancel
Save