Merge branch 'atys' into feature/bonusmalus-timers

feature/bonusmalus-timers
Nuno 4 years ago
commit 06cd8ae46b

@ -27,6 +27,7 @@
#include "nel/gui/ctrl_button.h" #include "nel/gui/ctrl_button.h"
#include "nel/gui/group_table.h" #include "nel/gui/group_table.h"
#include "nel/gui/html_element.h" #include "nel/gui/html_element.h"
#include "nel/gui/html_parser.h"
#include "nel/gui/css_style.h" #include "nel/gui/css_style.h"
// forward declaration // forward declaration
@ -115,6 +116,9 @@ namespace NLGUI
// Browse error // Browse error
void browseError (const char *msg); void browseError (const char *msg);
// Error message with html content
void browseErrorHtml(const std::string &html);
bool isBrowsing(); bool isBrowsing();
// Update coords // Update coords
@ -375,7 +379,9 @@ namespace NLGUI
// true if renderer is waiting for css files to finish downloading (link rel=stylesheet) // true if renderer is waiting for css files to finish downloading (link rel=stylesheet)
bool _WaitingForStylesheet; bool _WaitingForStylesheet;
// list of css file urls that are queued up for download // list of css file urls that are queued up for download
std::vector<std::string> _StylesheetQueue; std::vector<CHtmlParser::StyleLink> _StylesheetQueue;
// <style> and downloaded <link rel=stylesheet> elements
std::vector<std::string> _HtmlStyles;
// Valid base href was found // Valid base href was found
bool _IgnoreBaseUrlTag; bool _IgnoreBaseUrlTag;
@ -854,6 +860,7 @@ namespace NLGUI
CCurlWWWData *data; CCurlWWWData *data;
std::string url; std::string url;
std::string dest; std::string dest;
std::string tmpdest;
std::string luaScript; std::string luaScript;
std::string md5sum; std::string md5sum;
TDataType type; TDataType type;
@ -889,7 +896,7 @@ namespace NLGUI
std::string localBnpName(const std::string &url); std::string localBnpName(const std::string &url);
// add css file from <link href=".." rel="stylesheet"> to download queue // add css file from <link href=".." rel="stylesheet"> to download queue
void addStylesheetDownload(std::vector<std::string> links); void addStylesheetDownload(std::vector<CHtmlParser::StyleLink> links);
// stop all curl downalods (html and data) // stop all curl downalods (html and data)
void releaseDownloads(); void releaseDownloads();

@ -54,6 +54,8 @@ namespace NLGUI
Right Right
}; };
enum TTextAlign { AlignLeft = 0, AlignCenter, AlignRight, AlignJustify };
///constructor ///constructor
CGroupParagraph(const TCtorParam &param); CGroupParagraph(const TCtorParam &param);
@ -97,6 +99,8 @@ namespace NLGUI
// the same, but with id taken from the database // the same, but with id taken from the database
void addTextChildID (const std::string &dbPath, bool multiLine = true); void addTextChildID (const std::string &dbPath, bool multiLine = true);
void setTextAlign(const TTextAlign align) { _TextAlign = align; }
protected: protected:
void delChild (CViewBase* child); void delChild (CViewBase* child);
@ -270,6 +274,9 @@ namespace NLGUI
// (the element drawn are stored in _views, _contrlos or _childrengroups of cinterfacegroup // (the element drawn are stored in _views, _contrlos or _childrengroups of cinterfacegroup
std::vector<CElementInfo> _Elements; std::vector<CElementInfo> _Elements;
// Horizontal align for elements
TTextAlign _TextAlign;
// Last parent width // Last parent width
sint32 _LastW; sint32 _LastW;

@ -31,14 +31,23 @@ namespace NLGUI
class CHtmlParser class CHtmlParser
{ {
public: public:
// <link rel=stylesheet>
struct StyleLink
{
uint Index;
std::string Url;
StyleLink(uint i, const std::string &url) : Index(i), Url(url)
{ }
};
bool parseHtml(std::string htmlString) const; bool parseHtml(std::string htmlString) const;
// parse html string into DOM, extract <style> tags into styleString, <link stylesheet> urls into links // parse html string into DOM, extract <style> and <link stylesheet> urls
void getDOM(std::string htmlString, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const; void getDOM(std::string htmlString, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
private: private:
// iterate over libxml html tree, build DOM, and join all <style> tags together // iterate over libxml html tree, build DOM
void parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const; void parseNode(xmlNode *a_node, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
// read <style> tag and add its content to styleString // read <style> tag and add its content to styleString
void parseStyle(xmlNode *a_node, std::string &styleString) const; void parseStyle(xmlNode *a_node, std::string &styleString) const;

@ -524,18 +524,19 @@ namespace NLGUI
return false; return false;
} }
string tmpdest = download.dest + ".tmp"; // use browser Id so that two browsers would not use same temp file
download.tmpdest = localImageName(_Id + download.dest) + ".tmp";
// erase the tmp file if exists // erase the tmp file if exists
if (CFile::fileExists(tmpdest)) if (CFile::fileExists(download.tmpdest))
{ {
CFile::deleteFile(tmpdest); CFile::deleteFile(download.tmpdest);
} }
FILE *fp = nlfopen (tmpdest, "wb"); FILE *fp = nlfopen (download.tmpdest, "wb");
if (fp == NULL) if (fp == NULL)
{ {
nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno)); nlwarning("Can't open file '%s' for writing: code=%d '%s'", download.tmpdest.c_str (), errno, strerror(errno));
return false; return false;
} }
@ -543,7 +544,7 @@ namespace NLGUI
if (!curl) if (!curl)
{ {
fclose(fp); fclose(fp);
CFile::deleteFile(tmpdest); CFile::deleteFile(download.tmpdest);
nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str()); nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
return false; return false;
@ -607,54 +608,57 @@ namespace NLGUI
void CGroupHTML::finishCurlDownload(const CDataDownload &download) void CGroupHTML::finishCurlDownload(const CDataDownload &download)
{ {
std::string tmpfile = download.dest + ".tmp";
if (download.type == ImgType) if (download.type == ImgType)
{ {
// there is race condition if two browser instances are downloading same file if (CFile::fileExists(download.tmpdest) && CFile::getFileSize(download.tmpdest) > 0)
// second instance deletes first tmpfile and creates new file for itself.
if (CFile::getFileSize(tmpfile) > 0)
{ {
try try
{ {
// verify that image is not corrupted // verify that image is not corrupted
uint32 w, h; uint32 w, h;
CBitmap::loadSize(tmpfile, w, h); CBitmap::loadSize(download.tmpdest, w, h);
if (w != 0 && h != 0) if (w != 0 && h != 0)
{ {
// if not tmpfile, then img is already in cache if (CFile::fileExists(download.dest))
if (CFile::fileExists(tmpfile)) CFile::deleteFile(download.dest);
{
if (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
// to reload image on page, the easiest seems to be changing texture
// to temp file temporarily. that forces driver to reload texture from disk
// ITexture::touch() seem not to do this.
// cache was updated, first set texture as temp file
for(uint i = 0; i < download.imgs.size(); i++)
{
setImage(download.imgs[i].Image, tmpfile, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style);
}
CFile::moveFile(download.dest, tmpfile);
}
// to reload image on page, the easiest seems to be changing texture
// to temp file temporarily. that forces driver to reload texture from disk
// ITexture::touch() seem not to do this.
// cache was updated, first set texture as temp file
for(uint i = 0; i < download.imgs.size(); i++) for(uint i = 0; i < download.imgs.size(); i++)
{ {
setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type); setImage(download.imgs[i].Image, download.tmpdest, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style); setImageSize(download.imgs[i].Image, download.imgs[i].Style);
} }
CFile::moveFile(download.dest, download.tmpdest);
} }
} }
catch(const NLMISC::Exception &e) catch(const NLMISC::Exception &e)
{ {
// exception message has .tmp file name, so keep it for further analysis // exception message has .tmp file name, so keep it for further analysis
nlwarning("Invalid image (%s): %s", download.url.c_str(), e.what()); nlwarning("Invalid image (%s) from url (%s): %s", download.tmpdest.c_str(), download.url.c_str(), e.what());
}
}
if (CFile::fileExists(download.dest) && CFile::getFileSize(download.dest) > 0)
{
try
{
// verify that image is not corrupted
uint32 w, h;
CBitmap::loadSize(download.dest, w, h);
if (w != 0 && h != 0)
for(uint i = 0; i < download.imgs.size(); i++)
{
setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style);
}
}
catch(const NLMISC::Exception &e)
{
nlwarning("Invalid image (%s) from url (%s): %s", download.dest.c_str(), download.url.c_str(), e.what());
} }
} }
@ -663,13 +667,13 @@ namespace NLGUI
if (download.type == StylesheetType) if (download.type == StylesheetType)
{ {
if (CFile::fileExists(tmpfile)) if (CFile::fileExists(download.tmpdest))
{ {
if (CFile::fileExists(download.dest)) if (CFile::fileExists(download.dest))
{ {
CFile::deleteFile(download.dest); CFile::deleteFile(download.dest);
} }
CFile::moveFile(download.dest, tmpfile); CFile::moveFile(download.dest, download.tmpdest);
} }
cssDownloadFinished(download.url, download.dest); cssDownloadFinished(download.url, download.dest);
@ -680,20 +684,20 @@ namespace NLGUI
{ {
bool verified = false; bool verified = false;
// no tmpfile if file was already in cache // no tmpfile if file was already in cache
if (CFile::fileExists(tmpfile)) if (CFile::fileExists(download.tmpdest))
{ {
verified = download.md5sum.empty() || (download.md5sum != getMD5(tmpfile).toString()); verified = download.md5sum.empty() || (download.md5sum != getMD5(download.tmpdest).toString());
if (verified) if (verified)
{ {
if (CFile::fileExists(download.dest)) if (CFile::fileExists(download.dest))
{ {
CFile::deleteFile(download.dest); CFile::deleteFile(download.dest);
} }
CFile::moveFile(download.dest, tmpfile); CFile::moveFile(download.dest, download.tmpdest);
} }
else else
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(download.tmpdest);
} }
} }
else if (CFile::fileExists(download.dest)) else if (CFile::fileExists(download.dest))
@ -745,7 +749,7 @@ namespace NLGUI
if (type != OverImage) if (type != OverImage)
{ {
std::string temp = dest; std::string temp = dest;
if (!CFile::fileExists(temp)) if (!CFile::fileExists(temp) || CFile::getFileSize(temp) == 0)
{ {
temp = placeholder; temp = placeholder;
} }
@ -857,21 +861,16 @@ namespace NLGUI
CFile::createDirectory( pathName ); CFile::createDirectory( pathName );
} }
void CGroupHTML::addStylesheetDownload(std::vector<std::string> links) void CGroupHTML::addStylesheetDownload(const std::vector<CHtmlParser::StyleLink> links)
{ {
for(uint i = 0; i < links.size(); ++i) for(uint i = 0; i < links.size(); ++i)
{ {
std::string url = getAbsoluteUrl(links[i]); _StylesheetQueue.push_back(links[i]);
std::string local = localImageName(url); std::string url = getAbsoluteUrl(links[i].Url);
_StylesheetQueue.back().Url = url;
// insert only if url not already downloading // push to the front of the queue
std::vector<std::string>::const_iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url); Curls.push_front(CDataDownload(url, localImageName(url), StylesheetType, NULL, "", ""));
if (it == _StylesheetQueue.end())
{
_StylesheetQueue.push_back(url);
// push to the front of the queue
Curls.push_front(CDataDownload(url, local, StylesheetType, NULL, "", ""));
}
} }
pumpCurlQueue(); pumpCurlQueue();
} }
@ -971,9 +970,9 @@ namespace NLGUI
{ {
fclose(it->fp); fclose(it->fp);
if (CFile::fileExists(it->dest + ".tmp")) if (CFile::fileExists(it->tmpdest))
{ {
CFile::deleteFile(it->dest + ".tmp"); CFile::deleteFile(it->tmpdest);
} }
} }
} }
@ -2549,6 +2548,17 @@ namespace NLGUI
newParagraph->setResizeFromChildH(true); newParagraph->setResizeFromChildH(true);
newParagraph->setMarginLeft(getIndent()); newParagraph->setMarginLeft(getIndent());
if (!_Style.Current.TextAlign.empty())
{
if (_Style.Current.TextAlign == "left")
newParagraph->setTextAlign(CGroupParagraph::AlignLeft);
else if (_Style.Current.TextAlign == "center")
newParagraph->setTextAlign(CGroupParagraph::AlignCenter);
else if (_Style.Current.TextAlign == "right")
newParagraph->setTextAlign(CGroupParagraph::AlignRight);
else if (_Style.Current.TextAlign == "justify")
newParagraph->setTextAlign(CGroupParagraph::AlignJustify);
}
// Add to the group // Add to the group
addHtmlGroup (newParagraph, beginSpace); addHtmlGroup (newParagraph, beginSpace);
@ -2642,6 +2652,17 @@ namespace NLGUI
invalidateCoords(); invalidateCoords();
} }
void CGroupHTML::browseErrorHtml(const std::string &html)
{
releaseDownloads();
removeContent();
renderHtmlString(html);
updateRefreshButton();
invalidateCoords();
}
// *************************************************************************** // ***************************************************************************
bool CGroupHTML::isBrowsing() bool CGroupHTML::isBrowsing()
@ -3964,11 +3985,22 @@ namespace NLGUI
{ {
if (!success) if (!success)
{ {
CUrlParser uri(_CurlWWW->Url);
// potentially unwanted chars
std::string url = _CurlWWW->Url;
url = strFindReplaceAll(url, string("<"), string("%3C"));
url = strFindReplaceAll(url, string(">"), string("%3E"));
url = strFindReplaceAll(url, string("\""), string("%22"));
url = strFindReplaceAll(url, string("'"), string("%27"));
std::string err; std::string err;
err = "Connection failed with cURL error: "; err = "<html><head><title>cURL error</title></head><body>";
err += "<h1>Connection failed with cURL error</h1>";
err += error; err += error;
err += "\nURL '" + _CurlWWW->Url + "'"; err += "<hr>(" + uri.scheme + "://" + uri.host + ") <a href=\"" + url + "\">reload</a>";
browseError(err.c_str()); err += "</body></html>";
browseErrorHtml(err);
return; return;
} }
@ -4080,10 +4112,9 @@ namespace NLGUI
obj.LastModified = data.data->getLastModified(); obj.LastModified = data.data->getLastModified();
CHttpCache::getInstance()->store(data.dest, obj); CHttpCache::getInstance()->store(data.dest, obj);
std::string tmpfile = data.dest + ".tmp"; if (code == 304 && CFile::fileExists(data.tmpdest))
if (code == 304 && CFile::fileExists(tmpfile))
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(data.tmpdest);
} }
} }
else if ((code >= 301 && code <= 303) || code == 307 || code == 308) else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
@ -4111,10 +4142,9 @@ namespace NLGUI
LOG_DL("Redirect '%s'", location.c_str()); LOG_DL("Redirect '%s'", location.c_str());
// no finished callback called, so cleanup old temp // no finished callback called, so cleanup old temp
std::string tmpfile = data.dest + ".tmp"; if (CFile::fileExists(data.tmpdest))
if (CFile::fileExists(tmpfile))
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(data.tmpdest);
} }
return; return;
} }
@ -4187,19 +4217,28 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local) void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
{ {
// remove file from download queue for(std::vector<CHtmlParser::StyleLink>::iterator it = _StylesheetQueue.begin();
std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url); it != _StylesheetQueue.end(); ++it)
if (it != _StylesheetQueue.end())
{ {
_StylesheetQueue.erase(it); if (it->Url == url)
} {
// read downloaded file into HtmlStyles
if (CFile::fileExists(local) && it->Index < _HtmlStyles.size())
{
CIFile in;
if (in.open(local))
{
if (!in.readAll(_HtmlStyles[it->Index]))
{
nlwarning("Failed to read downloaded css file(%s), url(%s)", local.c_str(), url.c_str());
}
}
}
if (!CFile::fileExists(local)) _StylesheetQueue.erase(it);
{ break;
return; }
} }
parseStylesheetFile(local);
} }
void CGroupHTML::renderDocument() void CGroupHTML::renderDocument()
@ -4217,6 +4256,16 @@ namespace NLGUI
beginBuild(); beginBuild();
removeContent(); removeContent();
// process all <style> and <link rel=stylesheet> elements
for(uint i = 0; i < _HtmlStyles.size(); ++i)
{
if (!_HtmlStyles[i].empty())
{
_Style.parseStylesheet(_HtmlStyles[i]);
}
}
_HtmlStyles.clear();
std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin(); std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin();
while(it != _HtmlDOM.Children.end()) while(it != _HtmlDOM.Children.end())
{ {
@ -4826,9 +4875,6 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
bool CGroupHTML::parseHtml(const std::string &htmlString) bool CGroupHTML::parseHtml(const std::string &htmlString)
{ {
std::vector<std::string> links;
std::string styleString;
CHtmlElement *parsedDOM; CHtmlElement *parsedDOM;
if (_CurrentHTMLElement == NULL) if (_CurrentHTMLElement == NULL)
{ {
@ -4841,16 +4887,28 @@ namespace NLGUI
parsedDOM = _CurrentHTMLElement; parsedDOM = _CurrentHTMLElement;
} }
std::vector<CHtmlParser::StyleLink> links;
CHtmlParser parser; CHtmlParser parser;
parser.getDOM(htmlString, *parsedDOM, styleString, links); parser.getDOM(htmlString, *parsedDOM, _HtmlStyles, links);
if (!styleString.empty()) // <link> elements inserted from lua::parseHtml are ignored
if (_CurrentHTMLElement == NULL && !links.empty())
{ {
_Style.parseStylesheet(styleString); addStylesheetDownload(links);
} }
if (!links.empty()) else if (_CurrentHTMLElement != NULL)
{ {
addStylesheetDownload(links); // Called from active element (lua)
// <style> order is not preserved as document is already being rendered
for(uint i = 0; i < _HtmlStyles.size(); ++i)
{
if (!_HtmlStyles[i].empty())
{
_Style.parseStylesheet(_HtmlStyles[i]);
}
}
_HtmlStyles.clear();
} }
// this should rarely fail as first element should be <html> // this should rarely fail as first element should be <html>
@ -4861,7 +4919,7 @@ namespace NLGUI
{ {
if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == "html") if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == "html")
{ {
// more newly parsed childs from <body> into siblings // move newly parsed childs from <body> into siblings
if (_CurrentHTMLElement) { if (_CurrentHTMLElement) {
std::list<CHtmlElement>::iterator it2 = it->Children.begin(); std::list<CHtmlElement>::iterator it2 = it->Children.begin();
while(it2 != it->Children.end()) while(it2 != it->Children.end())
@ -5358,6 +5416,11 @@ namespace NLGUI
cellParams.Align = CGroupCell::Center; cellParams.Align = CGroupCell::Center;
else if (align == "right") else if (align == "right")
cellParams.Align = CGroupCell::Right; cellParams.Align = CGroupCell::Right;
else if (align != "justify")
align.clear();
// copy td align (can be empty) attribute back into css
_Style.Current.TextAlign = align;
} }
{ {
@ -6783,6 +6846,9 @@ namespace NLGUI
// setting ModulateGlobalColor must be after addImageDownload // setting ModulateGlobalColor must be after addImageDownload
if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true")) if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
table->setModulateGlobalColor(true); table->setModulateGlobalColor(true);
else if (_Style.checkStyle("-ryzom-modulate-bgcolor", "false"))
table->setModulateGlobalColor(false);
table->setMarginLeft(getIndent()); table->setMarginLeft(getIndent());
addHtmlGroup (table, 0); addHtmlGroup (table, 0);

@ -64,6 +64,7 @@ namespace NLGUI
_Indent = 0; _Indent = 0;
_FirstViewIndentView = false; _FirstViewIndentView = false;
_TextId = 0; _TextId = 0;
_TextAlign = AlignLeft;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -713,6 +714,10 @@ namespace NLGUI
CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element); CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element);
if (viewText) if (viewText)
{ {
// FIXME: this does not work with multiple view text on same line
if (_TextAlign == AlignCenter && elmCount == 1)
viewText->setTextMode(CViewText::Centered);
viewText->setFirstLineX(x + ((i==0)?_FirstViewIndentView:0)); viewText->setFirstLineX(x + ((i==0)?_FirstViewIndentView:0));
viewText->setX(0); viewText->setX(0);
viewText->updateTextContext(); viewText->updateTextContext();
@ -730,6 +735,12 @@ namespace NLGUI
// Does we balance the last line height ? // Does we balance the last line height ?
if (viewText) if (viewText)
{ {
if (_TextAlign == AlignCenter && elmCount == 1)
{
sint pad = width - viewText->getWReal();
viewText->setX(pad/2);
}
changeLine = viewText->getNumLine() > 1; changeLine = viewText->getNumLine() > 1;
if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n') if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n')
{ {

@ -57,7 +57,7 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
// recursive function to walk html document // recursive function to walk html document
void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const
{ {
uint childIndex = 0; uint childIndex = 0;
uint element_number; uint element_number;
@ -66,7 +66,15 @@ namespace NLGUI
{ {
if (node->type == XML_TEXT_NODE) if (node->type == XML_TEXT_NODE)
{ {
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content))); // linebreak right after pre,textare open tag should be removed
if (parent.Children.empty() && (*node->content == '\n') && (parent.ID == HTML_PRE || parent.ID == HTML_TEXTAREA))
{
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content) + 1));
}
else
{
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content)));
}
} }
else else
if (node->type == XML_ELEMENT_NODE) if (node->type == XML_ELEMENT_NODE)
@ -145,7 +153,9 @@ namespace NLGUI
if (useStyle) if (useStyle)
{ {
parseStyle(node->children, styleString); std::string style;
parseStyle(node->children, style);
styles.push_back(style);
} }
// style tag is kept in dom // style tag is kept in dom
} }
@ -163,13 +173,24 @@ namespace NLGUI
if (useStyle) if (useStyle)
{ {
links.push_back(elm.getAttribute("href")); styles.push_back("");
links.push_back(StyleLink(styles.size()-1, elm.getAttribute("href")));
} }
// link tag is kept in dom // link tag is kept in dom
} }
else if (node->children) else if (node->children)
{ {
parseNode(node->children, elm, styleString, links); parseNode(node->children, elm, styles, links);
if (!elm.Children.empty() && elm.ID == HTML_PRE && elm.Children.back().Type == CHtmlElement::TEXT_NODE)
{
std::string::size_type size = elm.Children.back().Value.size();
// strip last '\n' from non-empty line
if (size > 1 && elm.Children.back().Value[size-1] == '\n')
{
elm.Children.back().Value = elm.Children.back().Value.substr(0, size - 1);
}
}
// must cleanup nested tags that libxml2 does not fix // must cleanup nested tags that libxml2 does not fix
// dt without end tag: <dl><dt><dt></dl> // dt without end tag: <dl><dt><dt></dl>
@ -406,7 +427,7 @@ namespace NLGUI
} }
// *************************************************************************** // ***************************************************************************
void CHtmlParser::getDOM(std::string htmlString, CHtmlElement &dom, std::string &styleString, std::vector<std::string> &links) const void CHtmlParser::getDOM(std::string htmlString, CHtmlElement &dom, std::vector<std::string> &styles, std::vector<StyleLink> &links) const
{ {
htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8); htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8);
if (!parser) if (!parser)
@ -428,8 +449,7 @@ namespace NLGUI
xmlNode *root = xmlDocGetRootElement(parser->myDoc); xmlNode *root = xmlDocGetRootElement(parser->myDoc);
if (root) if (root)
{ {
styleString.clear(); parseNode(root, dom, styles, links);
parseNode(root, dom, styleString, links);
} }
else else
{ {

@ -3570,7 +3570,7 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
} }
while(!eof); while(!eof);
} }
else if(fileType == JPG_HEADER) else if(memcmp(&fileType, &JPG_HEADER, 2) == 0)
{ {
uint8 blockMarker1 = 0; uint8 blockMarker1 = 0;
uint8 blockMarker2 = 0; uint8 blockMarker2 = 0;

@ -179,7 +179,6 @@
#else #else
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/sysctl.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
# include <cerrno> # include <cerrno>

@ -180,6 +180,7 @@ int main(int argc, char **argv)
Args.setVersion(getDisplayVersion()); Args.setVersion(getDisplayVersion());
Args.setDescription("Ryzom client"); Args.setDescription("Ryzom client");
Args.addArg("n", "nopatch", "value", "Use this to not use patch system");
Args.addArg("p", "profile", "id", "Use this profile to determine what directory to use by default"); Args.addArg("p", "profile", "id", "Use this profile to determine what directory to use by default");
Args.addAdditionalArg("login", "Login to use", true, false); Args.addAdditionalArg("login", "Login to use", true, false);
Args.addAdditionalArg("password", "Password to use", true, false); Args.addAdditionalArg("password", "Password to use", true, false);

@ -549,6 +549,6 @@ bool CSBrickSheet::mustDisplayLevel() const
// NB: Yoyo Hack. special interface with indexInFamily==63 means "want to display the level" // NB: Yoyo Hack. special interface with indexInFamily==63 means "want to display the level"
return !( isMandatory() || return !( isMandatory() ||
isRoot() || isRoot() ||
(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) || //(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) ||
Level==0 ); Level==0 );
} }

@ -49,12 +49,12 @@
#include "login_progress_post_thread.h" #include "login_progress_post_thread.h"
#include "interface_v3/action_handler_base.h" #include "interface_v3/action_handler_base.h"
#include "item_group_manager.h" #include "item_group_manager.h"
#include "nel/misc/cmd_args.h"
#ifdef DEBUG_NEW #ifdef DEBUG_NEW
#define new DEBUG_NEW #define new DEBUG_NEW
#endif #endif
using namespace NLMISC; using namespace NLMISC;
using namespace NLNET; using namespace NLNET;
using namespace NL3D; using namespace NL3D;
@ -210,6 +210,7 @@ extern bool IsInRingSession;
extern void selectTipsOfTheDay (uint tips); extern void selectTipsOfTheDay (uint tips);
#define BAR_STEP_TP 2 #define BAR_STEP_TP 2
extern NLMISC::CCmdArgs Args;
CLoginStateMachine::TEvent CLoginStateMachine::waitEvent() CLoginStateMachine::TEvent CLoginStateMachine::waitEvent()
{ {
@ -462,12 +463,14 @@ void CLoginStateMachine::run()
case st_check_patch: case st_check_patch:
/// check the data to check if patch needed /// check the data to check if patch needed
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login"));
if (!ClientCfg.PatchWanted)
if (!ClientCfg.PatchWanted || (Args.haveArg("n") && Args.getLongArg("nopatch").front() == "1"))
{ {
// client don't want to be patched ! // client don't want to be patched !
_CurrentState = st_display_eula; _CurrentState = st_display_eula;
break; break;
} }
initPatchCheck(); initPatchCheck();
SM_BEGIN_EVENT_TABLE SM_BEGIN_EVENT_TABLE
if (isBGDownloadEnabled()) if (isBGDownloadEnabled())
@ -1517,4 +1520,3 @@ void CFarTP::farTPmainLoop()
if(welcomeWindow) if(welcomeWindow)
initWelcomeWindow(); initWelcomeWindow();
} }

@ -424,30 +424,37 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
ucstring::size_type pos = 0; ucstring::size_type pos = 0;
// Manage Translations
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TRANSLATION_ONLY_AS_TOOLTIP_CB", false);
bool originalFirst = node->getValueBool();
string::size_type startTr = msg.find(ucstring("{:")); string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{")); string::size_type endOfOriginal = msg.find(ucstring("}@{"));
// Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde ! // Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde !
if (startTr != string::npos && endOfOriginal != string::npos) if (startTr != string::npos && endOfOriginal != string::npos)
{ {
string lang = toUpper(msg.substr(startTr+2, 2)).toString();
bool inverse = false;
bool hideFlag = false;
CCDBNodeLeaf *nodeInverse = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":INVERSE_DISPLAY", false);
if (nodeInverse)
inverse = nodeInverse->getValueBool();
CCDBNodeLeaf *nodeHideFlag = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":HIDE_FLAG", false);
if (nodeHideFlag)
hideFlag = nodeHideFlag->getValueBool();
CViewBase *vt = createMsgTextSimple(msg.substr(0, startTr), col, justified, NULL); CViewBase *vt = createMsgTextSimple(msg.substr(0, startTr), col, justified, NULL);
para->addChild(vt); para->addChild(vt);
string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga"; string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga";
ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5); ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5);
ucstring translation = msg.substr(endOfOriginal+3); ucstring translation = msg.substr(endOfOriginal+4);
CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam()); CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam());
ctrlButton->setTexture(texture); ctrlButton->setTexture(texture);
ctrlButton->setTextureOver(texture); ctrlButton->setTextureOver(texture);
ctrlButton->setTexturePushed(texture); ctrlButton->setTexturePushed(texture);
if (!originalFirst) if (!inverse)
{ {
ctrlButton->setDefaultContextHelp(original); ctrlButton->setDefaultContextHelp(original);
pos = endOfOriginal+3; pos = endOfOriginal+4;
} }
else else
{ {
@ -456,7 +463,11 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
textSize = endOfOriginal; textSize = endOfOriginal;
} }
ctrlButton->setId("tr"); ctrlButton->setId("tr");
para->addChild(ctrlButton); if (hideFlag) {
delete ctrlButton;
} else {
para->addChild(ctrlButton);
}
} }
// quickly check if text has links or not // quickly check if text has links or not

@ -216,7 +216,25 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr
gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list")); gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list"));
CViewBase *child = ctm.createMsgText(msg, col);
bool noTranslation = false;
CCDBNodeLeaf *nodeNoTranslation = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + toUpper(CChatGroup::groupTypeToString(gt)) + ":DISABLE", false);
if (nodeNoTranslation)
noTranslation = nodeNoTranslation->getValueBool();
ucstring msgNoTranslate = msg;
if (noTranslation) {
string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{"));
if (startTr != string::npos && endOfOriginal != string::npos) {
msgNoTranslate = msg.substr(0, startTr) + msg.substr(startTr+5, endOfOriginal-startTr-5);
}
}
CViewBase *child = ctm.createMsgText(msgNoTranslate, col);
if (child) if (child)
{ {
if (gl) gl->addChild(child); if (gl) gl->addChild(child);
@ -568,6 +586,18 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
ucstring newmsg = msg; ucstring newmsg = msg;
ucstring prefix; ucstring prefix;
CCDBNodeLeaf *nodeNoTranslation = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + toUpper(CChatGroup::groupTypeToString(gt)) + ":DISABLE", false);
bool noTranslation = nodeNoTranslation->getValueBool();
if (noTranslation) {
string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{"));
if (startTr != string::npos && endOfOriginal != string::npos) {
newmsg = newmsg.substr(0, startTr) + newmsg.substr(startTr+5, endOfOriginal-startTr-5);
}
}
CViewBase *child = NULL; CViewBase *child = NULL;
if (gl != NULL) if (gl != NULL)
{ {

@ -1107,6 +1107,7 @@ void CDBCtrlSheet::clearIconBuffs()
{ {
_EnchantIcons.clear(); _EnchantIcons.clear();
_BuffIcons.clear(); _BuffIcons.clear();
_BoostIcons.clear();
} }
// *************************************************************************** // ***************************************************************************
@ -1139,8 +1140,15 @@ void CDBCtrlSheet::infoReceived()
if (brick) if (brick)
{ {
if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter()) if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
if (brick->BrickFamily == BRICK_FAMILIES::BSGMCB) // Boost of Allegories, use it as boost icon
{ {
if (!haveRoot) if (!haveRoot)
_BoostIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
rVR.getTextureSizeFromId(_BoostIcons.back().TextureId, _BoostIcons.back().IconW, _BoostIcons.back().IconH);
}
else if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
{
if (!haveRoot && !brick->getIconBack().empty())
{ {
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor)); _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH); rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
@ -2550,10 +2558,17 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
} }
yIcon -= hIcon; yIcon -= hIcon;
rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color)); rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
rVR.drawRotFlipBitmap(_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color)); rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
if ((i - 1) < _BoostIcons.size()) {
rVR.drawRotFlipBitmap(_RenderLayer + 2, xIcon+wIcon-_BoostIcons[i-1].IconW, yIcon, _BoostIcons[i-1].IconW, _BoostIcons[i-1].IconH, 0, false, _BoostIcons[i-1].TextureId, fastMulRGB(curSheetColor, _BoostIcons[i-1].Color));
}
} }
} }
// Draw Quality. -1 for lookandfeel. Draw it with global color // Draw Quality. -1 for lookandfeel. Draw it with global color
if (_DispQuality != -1) if (_DispQuality != -1)
{ {
@ -3910,6 +3925,7 @@ void CDBCtrlSheet::resetAllTexIDs()
_ItemInfoChanged = true; _ItemInfoChanged = true;
_EnchantIcons.clear(); _EnchantIcons.clear();
_BuffIcons.clear(); _BuffIcons.clear();
_BoostIcons.clear();
} }

@ -701,6 +701,7 @@ protected:
}; };
std::vector<SBuffIcon> _BuffIcons; std::vector<SBuffIcon> _BuffIcons;
std::vector<SBuffIcon> _EnchantIcons; std::vector<SBuffIcon> _EnchantIcons;
std::vector<SBuffIcon> _BoostIcons;
// Level Brick or Quality // Level Brick or Quality
union union

@ -875,16 +875,20 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
// Clean bubble from translation system // Clean bubble from translation system
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TRANSLATION_ONLY_AS_TOOLTIP_CB", false);
bool originalFirst = node->getValueBool();
ucstring::size_type pos = 0; ucstring::size_type pos = 0;
ucstring::size_type textSize = ucsText.size(); ucstring::size_type textSize = ucsText.size();
string::size_type startTr = ucsText.find(ucstring("{:")); string::size_type startTr = ucsText.find(ucstring("{:"));
string::size_type endOfOriginal = ucsText.find(ucstring("}@{")); string::size_type endOfOriginal = ucsText.find(ucstring("}@{"));
if (endOfOriginal != string::npos)
{ if (startTr != string::npos && endOfOriginal != string::npos) {
if (!originalFirst) bool inverse = false;
string lang = toUpper(ucsText.substr(startTr+2, 2)).toString();
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":INVERSE_DISPLAY", false);
if (node)
inverse = node->getValueBool();
if (!inverse)
{ {
pos = endOfOriginal+4; pos = endOfOriginal+4;
} }

@ -96,6 +96,7 @@
#include "../continent_manager.h" #include "../continent_manager.h"
#include "../zone_util.h" #include "../zone_util.h"
#include "../motion/user_controls.h" #include "../motion/user_controls.h"
#include "../events_listener.h"
#include "group_html_cs.h" #include "group_html_cs.h"
#include "group_map.h" #include "group_map.h"
#include "bonus_malus.h" #include "bonus_malus.h"
@ -153,6 +154,7 @@ using namespace R2;
extern NLMISC::CLog g_log; extern NLMISC::CLog g_log;
extern CContinentManager ContinentMngr; extern CContinentManager ContinentMngr;
extern CClientChatManager ChatMngr; extern CClientChatManager ChatMngr;
extern CEventsListener EventsListener; // Inputs Manager
// *************************************************************************** // ***************************************************************************
class CHandlerLUA : public IActionHandler class CHandlerLUA : public IActionHandler
@ -443,6 +445,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame); ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame);
ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString); ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString);
ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements); ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements);
ls.registerFunc("getTimestampHuman", getTimestampHuman);
ls.registerFunc("formatUI", formatUI); ls.registerFunc("formatUI", formatUI);
ls.registerFunc("formatDB", formatDB); ls.registerFunc("formatDB", formatDB);
ls.registerFunc("dumpUI", dumpUI); ls.registerFunc("dumpUI", dumpUI);
@ -469,6 +472,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getMouseDown", getMouseDown), ls.registerFunc("getMouseDown", getMouseDown),
ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown), ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown),
ls.registerFunc("getMouseRightDown", getMouseRightDown), ls.registerFunc("getMouseRightDown", getMouseRightDown),
ls.registerFunc("isShiftDown", isShiftDown),
ls.registerFunc("isCtrlDown", isCtrlDown),
ls.registerFunc("getShapeIdAt", getShapeIdAt), ls.registerFunc("getShapeIdAt", getShapeIdAt),
ls.registerFunc("getPlayerFront", getPlayerFront); ls.registerFunc("getPlayerFront", getPlayerFront);
ls.registerFunc("getPlayerDirection", getPlayerDirection); ls.registerFunc("getPlayerDirection", getPlayerDirection);
@ -1271,7 +1276,7 @@ int CLuaIHMRyzom::getMouseDown(CLuaState &ls)
sint32 x, y; sint32 x, y;
bool down; bool down;
CTool::getMouseDown(down, x, y); CTool::getMouseDown(down, x, y);
ls.push(down); ls.push(EventsListener.isMouseButtonPushed(leftButton));
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
@ -1283,8 +1288,7 @@ int CLuaIHMRyzom::getMouseMiddleDown(CLuaState &ls)
sint32 x, y; sint32 x, y;
bool down; bool down;
CTool::getMouseMiddleDown(down, x, y); CTool::getMouseMiddleDown(down, x, y);
ls.push(EventsListener.isMouseButtonPushed(middleButton));
ls.push(down);
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
@ -1297,13 +1301,30 @@ int CLuaIHMRyzom::getMouseRightDown(CLuaState &ls)
bool down; bool down;
CTool::getMouseRightDown(down, x, y); CTool::getMouseRightDown(down, x, y);
ls.push(down); ls.push(EventsListener.isMouseButtonPushed(rightButton));
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
return 3; return 3;
} }
int CLuaIHMRyzom::isShiftDown(CLuaState &ls)
{
ls.push(Driver->AsyncListener.isKeyDown(KeySHIFT) ||
Driver->AsyncListener.isKeyDown(KeyLSHIFT) ||
Driver->AsyncListener.isKeyDown(KeyRSHIFT));
return 1;
}
int CLuaIHMRyzom::isCtrlDown(CLuaState &ls)
{
ls.push(Driver->AsyncListener.isKeyDown(KeyCONTROL) ||
Driver->AsyncListener.isKeyDown(KeyLCONTROL) ||
Driver->AsyncListener.isKeyDown(KeyRCONTROL));
return 1;
}
int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls) int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls)
{ {
@ -2120,6 +2141,31 @@ int CLuaIHMRyzom::updateAllLocalisedElements(CLuaState &ls)
return 0; return 0;
} }
// ***************************************************************************
int CLuaIHMRyzom::getTimestampHuman(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_getIslandId)
const char *funcName = "getTimestampHuman";
CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::check(ls, ls.isString(1), "getTimestampHuman() requires a string in param 1");
static char cstime[25];
time_t date;
time (&date);
struct tm *tms = localtime(&date);
string param = ls.toString(1);
if (tms)
strftime(cstime, 25, param.c_str(), tms);
else
strcpy(cstime, "");
ls.push(string(cstime));
return 1;
}
// *************************************************************************** // ***************************************************************************
int CLuaIHMRyzom::getCompleteIslands(CLuaState &ls) int CLuaIHMRyzom::getCompleteIslands(CLuaState &ls)
{ {
@ -3867,7 +3913,9 @@ void CLuaIHMRyzom::updateTooltipCoords()
CWidgetManager::getInstance()->updateTooltipCoords(); CWidgetManager::getInstance()->updateTooltipCoords();
} }
// *************************************************************************** // ***************************************************************************
// WARNING PROBABLY DON'T WORKS
bool CLuaIHMRyzom::isCtrlKeyDown() bool CLuaIHMRyzom::isCtrlKeyDown()
{ {
//H_AUTO(Lua_CLuaIHM_isCtrlKeyDown) //H_AUTO(Lua_CLuaIHM_isCtrlKeyDown)
@ -3880,6 +3928,7 @@ bool CLuaIHMRyzom::isCtrlKeyDown()
return ctrlDown; return ctrlDown;
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text) std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text)
{ {

@ -48,6 +48,9 @@ private:
static int launchContextMenuInGame(CLuaState &ls); // params : menu name static int launchContextMenuInGame(CLuaState &ls); // params : menu name
static int parseInterfaceFromString(CLuaState &ls); // params : intreface script static int parseInterfaceFromString(CLuaState &ls); // params : intreface script
static int updateAllLocalisedElements(CLuaState &ls); static int updateAllLocalisedElements(CLuaState &ls);
static int isShiftDown(CLuaState &ls);
static int isCtrlDown(CLuaState &ls);
static int getTimestampHuman(CLuaState &ls);
static int breakPoint(CLuaState &ls); static int breakPoint(CLuaState &ls);
static int i18n(CLuaState &ls); // retrieve an unicode string from CI18N static int i18n(CLuaState &ls); // retrieve an unicode string from CI18N
static int setTextFormatTaged(CLuaState &ls); // set a text that may contains Tag Format infos static int setTextFormatTaged(CLuaState &ls); // set a text that may contains Tag Format infos

@ -33,6 +33,7 @@
#include "game_share/chat_group.h" #include "game_share/chat_group.h"
#include "game_share/character_summary.h" #include "game_share/character_summary.h"
#include "game_share/sphrase_com.h" #include "game_share/sphrase_com.h"
#include "game_share/outpost.h"
#include "game_share/msg_client_server.h" #include "game_share/msg_client_server.h"
#include "game_share/ryzom_database_banks.h" #include "game_share/ryzom_database_banks.h"
#include "game_share/msg_encyclopedia.h" #include "game_share/msg_encyclopedia.h"
@ -3205,9 +3206,11 @@ void impulseUserBars(NLMISC::CBitMemStream &impulse)
void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse) void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
{ {
// read message // read message
uint8 type;
bool outpostInFire; bool outpostInFire;
bool playerGuildInConflict; bool playerGuildInConflict;
bool playerGuildIsAttacker; bool playerGuildIsAttacker;
impulse.serial(type);
impulse.serial(outpostInFire); impulse.serial(outpostInFire);
impulse.serial(playerGuildInConflict); impulse.serial(playerGuildInConflict);
impulse.serial(playerGuildIsAttacker); impulse.serial(playerGuildIsAttacker);
@ -3219,7 +3222,7 @@ void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
impulse.serial( declTimer ); impulse.serial( declTimer );
// start // start
OutpostManager.startPvpJoinProposal(outpostInFire, playerGuildInConflict, playerGuildIsAttacker, OutpostManager.startPvpJoinProposal((OUTPOSTENUMS::TPVPType)type, outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
ownerGuildNameId, attackerGuildNameId, declTimer); ownerGuildNameId, attackerGuildNameId, declTimer);
} }

@ -680,6 +680,7 @@ bool CNetworkConnection::connect(string &result)
_LatestLoginTime = ryzomGetLocalTime (); _LatestLoginTime = ryzomGetLocalTime ();
_LatestSyncTime = _LatestLoginTime; _LatestSyncTime = _LatestLoginTime;
_LatestProbeTime = _LatestLoginTime; _LatestProbeTime = _LatestLoginTime;
m_LoginAttempts = 0;
nlinfo("CNET[%p]: Client connected to shard, attempting login", this); nlinfo("CNET[%p]: Client connected to shard, attempting login", this);
return true; return true;
@ -1091,6 +1092,17 @@ bool CNetworkConnection::stateLogin()
{ {
sendSystemLogin(); sendSystemLogin();
_LatestLoginTime = _UpdateTime; _LatestLoginTime = _UpdateTime;
if (m_LoginAttempts > 24)
{
m_LoginAttempts = 0;
disconnect(); // will send disconnection message
nlwarning("CNET[%p]: Too many LOGIN attempts, connection problem", this);
return false; // exit now from loop, don't expect a new state
}
else
{
++m_LoginAttempts;
}
} }
return false; return false;
@ -2308,6 +2320,7 @@ bool CNetworkConnection::stateProbe()
else else
{ {
nlwarning("CNET[%p]: received normal in state Probe", this); nlwarning("CNET[%p]: received normal in state Probe", this);
_LatestProbeTime = _UpdateTime;
} }
} }
} }

@ -822,6 +822,7 @@ private:
void sendSystemLogin(); void sendSystemLogin();
bool stateLogin(); bool stateLogin();
NLMISC::TTime _LatestLoginTime; NLMISC::TTime _LatestLoginTime;
int m_LoginAttempts;
// //
void receiveSystemSync(NLMISC::CBitMemStream &msgin); void receiveSystemSync(NLMISC::CBitMemStream &msgin);

@ -40,7 +40,7 @@ COutpostManager::COutpostManager()
// *************************************************************************** // ***************************************************************************
void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker, void COutpostManager::startPvpJoinProposal(OUTPOSTENUMS::TPVPType type, bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker,
uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer) uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer)
{ {
// reset counter that force player to be neutral (eg: 10 seconds) // reset counter that force player to be neutral (eg: 10 seconds)
@ -58,16 +58,28 @@ void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildI
node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_DEFENDER"); node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_DEFENDER");
if(node) node->setValue32(ownerGuildNameId); if(node) node->setValue32(ownerGuildNameId);
node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_TICK_END"); node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_TICK_END");
if(node) node->setValue32(_EndTickForPvpJoinProposal); if(node) node->setValue32(_EndTickForPvpJoinProposal);
// open Popup // open Popup
CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random")); CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random"));
if (ctrl) if (ctrl)
ctrl->setActive(outpostInFire); ctrl->setActive(type != OUTPOSTENUMS::GVE && outpostInFire);
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral")); ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral"));
if (ctrl) if (ctrl)
ctrl->setActive(!outpostInFire); ctrl->setActive(type == OUTPOSTENUMS::GVE || !outpostInFire);
// GvE: only attacker guild can have the option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:attack"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(playerGuildIsAttacker);
// GvE : No defend option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:defend"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(false);
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal")); CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal"));
if (pGC) if (pGC)

@ -40,7 +40,7 @@ public:
COutpostManager(); COutpostManager();
/// Called when the server ask to join for PVP in a Outpost Zone /// Called when the server ask to join for PVP in a Outpost Zone
void startPvpJoinProposal(bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker, void startPvpJoinProposal(OUTPOSTENUMS::TPVPType type, bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker,
uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer); uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer);
/// Called when the client answer to the join for PVP in a Outpost Zone /// Called when the client answer to the join for PVP in a Outpost Zone

@ -264,6 +264,19 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARM02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARR02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKART02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKART02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARM01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARR01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMART01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMART02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENM01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENR01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENT01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENT02)
// Faber options // Faber options
NL_STRING_CONVERSION_TABLE_ENTRY(BCOA) NL_STRING_CONVERSION_TABLE_ENTRY(BCOA)
@ -558,6 +571,7 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC) NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD) NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC) NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMCB)
NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA) NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA)

@ -297,7 +297,20 @@ namespace BRICK_FAMILIES
BCOKARM02, BCOKARM02,
BCOKARR02, BCOKARR02,
BCOKART02, BCOKART02,
EndFaberMandatory = BCOKART02, BCOMARM01,
BCOMARR01,
BCOMART01,
BCOMARM02,
BCOMARR02,
BCOMART02,
BCOGENM01,
BCOGENR01,
BCOGENT01,
BCOGENM02,
BCOGENR02,
BCOGENT02,
EndFaberMandatory = BCOGENT02,
// OPTION FABER // OPTION FABER
BeginFaberOption, BeginFaberOption,
@ -675,7 +688,8 @@ namespace BRICK_FAMILIES
BSCMD, // heal Focus BSCMD, // heal Focus
EndPowerParameter = BSCMD, EndPowerParameter = BSCMD,
BSGMC, // jewels s2e0 BSGMC, // allegories
BSGMCB, // boost allegories
BeginMagicPowerCredit, BeginMagicPowerCredit,
BSXCA = BeginMagicPowerCredit, // recast time BSXCA = BeginMagicPowerCredit, // recast time

@ -633,7 +633,7 @@ sint32 CStaticFames::getStaticFameIndexed(uint factionIndex1, uint factionIndex2
if (factionIndex1 >= _FameTableSize || factionIndex2 >= _FameTableSize) if (factionIndex1 >= _FameTableSize || factionIndex2 >= _FameTableSize)
{ {
nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0"); //nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0");
return 0; return 0;
} }

@ -32,6 +32,8 @@ namespace OUTPOSTENUMS
NL_STRING_CONVERSION_TABLE_ENTRY(PVP) NL_STRING_CONVERSION_TABLE_ENTRY(PVP)
NL_STRING_CONVERSION_TABLE_ENTRY(RVR) NL_STRING_CONVERSION_TABLE_ENTRY(RVR)
NL_STRING_CONVERSION_TABLE_ENTRY(Full) NL_STRING_CONVERSION_TABLE_ENTRY(Full)
NL_STRING_CONVERSION_TABLE_ENTRY(GVE)
NL_STRING_CONVERSION_TABLE_ENTRY(GVG)
NL_STRING_CONVERSION_TABLE_ENTRY(UnknownPVPType) NL_STRING_CONVERSION_TABLE_ENTRY(UnknownPVPType)
NL_END_STRING_CONVERSION_TABLE(TPVPType, StaticCOutpostTPVPTypeConversion, UnknownPVPType) NL_END_STRING_CONVERSION_TABLE(TPVPType, StaticCOutpostTPVPTypeConversion, UnknownPVPType)

@ -50,7 +50,9 @@ namespace OUTPOSTENUMS
PVE, // can only be attacked if the outpost is held by a tribe and if the attacking guild comes from the same continent as the outpost PVE, // can only be attacked if the outpost is held by a tribe and if the attacking guild comes from the same continent as the outpost
PVP, // can only be attacked if the attacking guild comes from the same continent as the outpost PVP, // can only be attacked if the attacking guild comes from the same continent as the outpost
RVR, // can only be attacked if the attacking guild comes from another continent as the outpost RVR, // can only be attacked if the attacking guild comes from another continent as the outpost
Full // same as RVR but cant be set by the high council Full, // same as RVR but cant be set by the high council
GVE, // Only one guild vs tribes
GVG, // Only one guild vs another guild
}; };
enum TPVPSide enum TPVPSide

@ -37,7 +37,7 @@ struct SPropVisualA
uint64 JacketColor : 3; // max: 8 current: 8 uint64 JacketColor : 3; // max: 8 current: 8
uint64 TrouserModel : 8; // max: 256 current: 104 uint64 TrouserModel : 8; // max: 256 current: 104
uint64 TrouserColor : 3; // max: 8 current: 8 uint64 TrouserColor : 3; // max: 8 current: 8
uint64 WeaponRightHand : 10; // max: 1024 current: 457 uint64 WeaponRightHand : 10; // max: 1024 current: 625
uint64 WeaponLeftHand : 8; // max: 256 current: 63 uint64 WeaponLeftHand : 8; // max: 256 current: 63
uint64 ArmModel : 8; // max: 256 current: 94 uint64 ArmModel : 8; // max: 256 current: 94
uint64 ArmColor : 3; // max: 8 current: 8 uint64 ArmColor : 3; // max: 8 current: 8

Loading…
Cancel
Save