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/group_table.h"
#include "nel/gui/html_element.h"
#include "nel/gui/html_parser.h"
#include "nel/gui/css_style.h"
// forward declaration
@ -115,6 +116,9 @@ namespace NLGUI
// Browse error
void browseError (const char *msg);
// Error message with html content
void browseErrorHtml(const std::string &html);
bool isBrowsing();
// Update coords
@ -375,7 +379,9 @@ namespace NLGUI
// true if renderer is waiting for css files to finish downloading (link rel=stylesheet)
bool _WaitingForStylesheet;
// 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
bool _IgnoreBaseUrlTag;
@ -854,6 +860,7 @@ namespace NLGUI
CCurlWWWData *data;
std::string url;
std::string dest;
std::string tmpdest;
std::string luaScript;
std::string md5sum;
TDataType type;
@ -889,7 +896,7 @@ namespace NLGUI
std::string localBnpName(const std::string &url);
// 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)
void releaseDownloads();

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

@ -31,14 +31,23 @@ namespace NLGUI
class CHtmlParser
{
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;
// parse html string into DOM, extract <style> tags into styleString, <link stylesheet> urls into links
void getDOM(std::string htmlString, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
// parse html string into DOM, extract <style> and <link stylesheet> urls
void getDOM(std::string htmlString, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
private:
// iterate over libxml html tree, build DOM, and join all <style> tags together
void parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
// iterate over libxml html tree, build DOM
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
void parseStyle(xmlNode *a_node, std::string &styleString) const;

@ -524,18 +524,19 @@ namespace NLGUI
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
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)
{
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;
}
@ -543,7 +544,7 @@ namespace NLGUI
if (!curl)
{
fclose(fp);
CFile::deleteFile(tmpdest);
CFile::deleteFile(download.tmpdest);
nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
return false;
@ -607,54 +608,57 @@ namespace NLGUI
void CGroupHTML::finishCurlDownload(const CDataDownload &download)
{
std::string tmpfile = download.dest + ".tmp";
if (download.type == ImgType)
{
// there is race condition if two browser instances are downloading same file
// second instance deletes first tmpfile and creates new file for itself.
if (CFile::getFileSize(tmpfile) > 0)
if (CFile::fileExists(download.tmpdest) && CFile::getFileSize(download.tmpdest) > 0)
{
try
{
// verify that image is not corrupted
uint32 w, h;
CBitmap::loadSize(tmpfile, w, h);
CBitmap::loadSize(download.tmpdest, w, h);
if (w != 0 && h != 0)
{
// if not tmpfile, then img is already in cache
if (CFile::fileExists(tmpfile))
{
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);
}
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, 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);
}
CFile::moveFile(download.dest, download.tmpdest);
}
}
catch(const NLMISC::Exception &e)
{
// 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 (CFile::fileExists(tmpfile))
if (CFile::fileExists(download.tmpdest))
{
if (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
CFile::moveFile(download.dest, tmpfile);
CFile::moveFile(download.dest, download.tmpdest);
}
cssDownloadFinished(download.url, download.dest);
@ -680,20 +684,20 @@ namespace NLGUI
{
bool verified = false;
// 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 (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
CFile::moveFile(download.dest, tmpfile);
CFile::moveFile(download.dest, download.tmpdest);
}
else
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(download.tmpdest);
}
}
else if (CFile::fileExists(download.dest))
@ -745,7 +749,7 @@ namespace NLGUI
if (type != OverImage)
{
std::string temp = dest;
if (!CFile::fileExists(temp))
if (!CFile::fileExists(temp) || CFile::getFileSize(temp) == 0)
{
temp = placeholder;
}
@ -857,21 +861,16 @@ namespace NLGUI
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)
{
std::string url = getAbsoluteUrl(links[i]);
std::string local = localImageName(url);
_StylesheetQueue.push_back(links[i]);
std::string url = getAbsoluteUrl(links[i].Url);
_StylesheetQueue.back().Url = url;
// insert only if url not already downloading
std::vector<std::string>::const_iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
if (it == _StylesheetQueue.end())
{
_StylesheetQueue.push_back(url);
// push to the front of the queue
Curls.push_front(CDataDownload(url, local, StylesheetType, NULL, "", ""));
}
// push to the front of the queue
Curls.push_front(CDataDownload(url, localImageName(url), StylesheetType, NULL, "", ""));
}
pumpCurlQueue();
}
@ -971,9 +970,9 @@ namespace NLGUI
{
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->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
addHtmlGroup (newParagraph, beginSpace);
@ -2642,6 +2652,17 @@ namespace NLGUI
invalidateCoords();
}
void CGroupHTML::browseErrorHtml(const std::string &html)
{
releaseDownloads();
removeContent();
renderHtmlString(html);
updateRefreshButton();
invalidateCoords();
}
// ***************************************************************************
bool CGroupHTML::isBrowsing()
@ -3964,11 +3985,22 @@ namespace NLGUI
{
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;
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 += "\nURL '" + _CurlWWW->Url + "'";
browseError(err.c_str());
err += "<hr>(" + uri.scheme + "://" + uri.host + ") <a href=\"" + url + "\">reload</a>";
err += "</body></html>";
browseErrorHtml(err);
return;
}
@ -4080,10 +4112,9 @@ namespace NLGUI
obj.LastModified = data.data->getLastModified();
CHttpCache::getInstance()->store(data.dest, obj);
std::string tmpfile = data.dest + ".tmp";
if (code == 304 && CFile::fileExists(tmpfile))
if (code == 304 && CFile::fileExists(data.tmpdest))
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(data.tmpdest);
}
}
else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
@ -4111,10 +4142,9 @@ namespace NLGUI
LOG_DL("Redirect '%s'", location.c_str());
// no finished callback called, so cleanup old temp
std::string tmpfile = data.dest + ".tmp";
if (CFile::fileExists(tmpfile))
if (CFile::fileExists(data.tmpdest))
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(data.tmpdest);
}
return;
}
@ -4187,19 +4217,28 @@ namespace NLGUI
// ***************************************************************************
void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
{
// remove file from download queue
std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
if (it != _StylesheetQueue.end())
for(std::vector<CHtmlParser::StyleLink>::iterator it = _StylesheetQueue.begin();
it != _StylesheetQueue.end(); ++it)
{
_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))
{
return;
_StylesheetQueue.erase(it);
break;
}
}
parseStylesheetFile(local);
}
void CGroupHTML::renderDocument()
@ -4217,6 +4256,16 @@ namespace NLGUI
beginBuild();
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();
while(it != _HtmlDOM.Children.end())
{
@ -4826,9 +4875,6 @@ namespace NLGUI
// ***************************************************************************
bool CGroupHTML::parseHtml(const std::string &htmlString)
{
std::vector<std::string> links;
std::string styleString;
CHtmlElement *parsedDOM;
if (_CurrentHTMLElement == NULL)
{
@ -4841,16 +4887,28 @@ namespace NLGUI
parsedDOM = _CurrentHTMLElement;
}
std::vector<CHtmlParser::StyleLink> links;
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>
@ -4861,7 +4919,7 @@ namespace NLGUI
{
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) {
std::list<CHtmlElement>::iterator it2 = it->Children.begin();
while(it2 != it->Children.end())
@ -5358,6 +5416,11 @@ namespace NLGUI
cellParams.Align = CGroupCell::Center;
else if (align == "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
if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
table->setModulateGlobalColor(true);
else if (_Style.checkStyle("-ryzom-modulate-bgcolor", "false"))
table->setModulateGlobalColor(false);
table->setMarginLeft(getIndent());
addHtmlGroup (table, 0);

@ -64,6 +64,7 @@ namespace NLGUI
_Indent = 0;
_FirstViewIndentView = false;
_TextId = 0;
_TextAlign = AlignLeft;
}
// ----------------------------------------------------------------------------
@ -713,6 +714,10 @@ namespace NLGUI
CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element);
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->setX(0);
viewText->updateTextContext();
@ -730,6 +735,12 @@ namespace NLGUI
// Does we balance the last line height ?
if (viewText)
{
if (_TextAlign == AlignCenter && elmCount == 1)
{
sint pad = width - viewText->getWReal();
viewText->setX(pad/2);
}
changeLine = viewText->getNumLine() > 1;
if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n')
{

@ -57,7 +57,7 @@ namespace NLGUI
// ***************************************************************************
// 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 element_number;
@ -66,7 +66,15 @@ namespace NLGUI
{
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
if (node->type == XML_ELEMENT_NODE)
@ -145,7 +153,9 @@ namespace NLGUI
if (useStyle)
{
parseStyle(node->children, styleString);
std::string style;
parseStyle(node->children, style);
styles.push_back(style);
}
// style tag is kept in dom
}
@ -163,13 +173,24 @@ namespace NLGUI
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
}
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
// 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);
if (!parser)
@ -428,8 +449,7 @@ namespace NLGUI
xmlNode *root = xmlDocGetRootElement(parser->myDoc);
if (root)
{
styleString.clear();
parseNode(root, dom, styleString, links);
parseNode(root, dom, styles, links);
}
else
{

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

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

@ -180,6 +180,7 @@ int main(int argc, char **argv)
Args.setVersion(getDisplayVersion());
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.addAdditionalArg("login", "Login 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"
return !( isMandatory() ||
isRoot() ||
(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) ||
//(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) ||
Level==0 );
}

@ -49,12 +49,12 @@
#include "login_progress_post_thread.h"
#include "interface_v3/action_handler_base.h"
#include "item_group_manager.h"
#include "nel/misc/cmd_args.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace NLMISC;
using namespace NLNET;
using namespace NL3D;
@ -210,6 +210,7 @@ extern bool IsInRingSession;
extern void selectTipsOfTheDay (uint tips);
#define BAR_STEP_TP 2
extern NLMISC::CCmdArgs Args;
CLoginStateMachine::TEvent CLoginStateMachine::waitEvent()
{
@ -462,12 +463,14 @@ void CLoginStateMachine::run()
case st_check_patch:
/// check the data to check if patch needed
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 !
_CurrentState = st_display_eula;
break;
}
initPatchCheck();
SM_BEGIN_EVENT_TABLE
if (isBGDownloadEnabled())
@ -1517,4 +1520,3 @@ void CFarTP::farTPmainLoop()
if(welcomeWindow)
initWelcomeWindow();
}

@ -424,30 +424,37 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
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 endOfOriginal = msg.find(ucstring("}@{"));
// Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde !
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);
para->addChild(vt);
string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga";
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());
ctrlButton->setTexture(texture);
ctrlButton->setTextureOver(texture);
ctrlButton->setTexturePushed(texture);
if (!originalFirst)
if (!inverse)
{
ctrlButton->setDefaultContextHelp(original);
pos = endOfOriginal+3;
pos = endOfOriginal+4;
}
else
{
@ -456,7 +463,11 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
textSize = endOfOriginal;
}
ctrlButton->setId("tr");
para->addChild(ctrlButton);
if (hideFlag) {
delete ctrlButton;
} else {
para->addChild(ctrlButton);
}
}
// 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"));
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 (gl) gl->addChild(child);
@ -568,6 +586,18 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
ucstring newmsg = msg;
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;
if (gl != NULL)
{

@ -1107,6 +1107,7 @@ void CDBCtrlSheet::clearIconBuffs()
{
_EnchantIcons.clear();
_BuffIcons.clear();
_BoostIcons.clear();
}
// ***************************************************************************
@ -1139,8 +1140,15 @@ void CDBCtrlSheet::infoReceived()
if (brick)
{
if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
if (brick->BrickFamily == BRICK_FAMILIES::BSGMCB) // Boost of Allegories, use it as boost icon
{
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));
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;
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
if (_DispQuality != -1)
{
@ -3910,6 +3925,7 @@ void CDBCtrlSheet::resetAllTexIDs()
_ItemInfoChanged = true;
_EnchantIcons.clear();
_BuffIcons.clear();
_BoostIcons.clear();
}

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

@ -875,16 +875,20 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
// 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 textSize = ucsText.size();
string::size_type startTr = ucsText.find(ucstring("{:"));
string::size_type endOfOriginal = ucsText.find(ucstring("}@{"));
if (endOfOriginal != string::npos)
{
if (!originalFirst)
if (startTr != string::npos && endOfOriginal != string::npos) {
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;
}

@ -96,6 +96,7 @@
#include "../continent_manager.h"
#include "../zone_util.h"
#include "../motion/user_controls.h"
#include "../events_listener.h"
#include "group_html_cs.h"
#include "group_map.h"
#include "bonus_malus.h"
@ -153,6 +154,7 @@ using namespace R2;
extern NLMISC::CLog g_log;
extern CContinentManager ContinentMngr;
extern CClientChatManager ChatMngr;
extern CEventsListener EventsListener; // Inputs Manager
// ***************************************************************************
class CHandlerLUA : public IActionHandler
@ -443,6 +445,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame);
ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString);
ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements);
ls.registerFunc("getTimestampHuman", getTimestampHuman);
ls.registerFunc("formatUI", formatUI);
ls.registerFunc("formatDB", formatDB);
ls.registerFunc("dumpUI", dumpUI);
@ -469,6 +472,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getMouseDown", getMouseDown),
ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown),
ls.registerFunc("getMouseRightDown", getMouseRightDown),
ls.registerFunc("isShiftDown", isShiftDown),
ls.registerFunc("isCtrlDown", isCtrlDown),
ls.registerFunc("getShapeIdAt", getShapeIdAt),
ls.registerFunc("getPlayerFront", getPlayerFront);
ls.registerFunc("getPlayerDirection", getPlayerDirection);
@ -1271,7 +1276,7 @@ int CLuaIHMRyzom::getMouseDown(CLuaState &ls)
sint32 x, y;
bool down;
CTool::getMouseDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(leftButton));
ls.push(x);
ls.push(y);
@ -1283,8 +1288,7 @@ int CLuaIHMRyzom::getMouseMiddleDown(CLuaState &ls)
sint32 x, y;
bool down;
CTool::getMouseMiddleDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(middleButton));
ls.push(x);
ls.push(y);
@ -1297,13 +1301,30 @@ int CLuaIHMRyzom::getMouseRightDown(CLuaState &ls)
bool down;
CTool::getMouseRightDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(rightButton));
ls.push(x);
ls.push(y);
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)
{
@ -2120,6 +2141,31 @@ int CLuaIHMRyzom::updateAllLocalisedElements(CLuaState &ls)
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)
{
@ -3867,7 +3913,9 @@ void CLuaIHMRyzom::updateTooltipCoords()
CWidgetManager::getInstance()->updateTooltipCoords();
}
// ***************************************************************************
// WARNING PROBABLY DON'T WORKS
bool CLuaIHMRyzom::isCtrlKeyDown()
{
//H_AUTO(Lua_CLuaIHM_isCtrlKeyDown)
@ -3880,6 +3928,7 @@ bool CLuaIHMRyzom::isCtrlKeyDown()
return ctrlDown;
}
// ***************************************************************************
std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text)
{

@ -48,6 +48,9 @@ private:
static int launchContextMenuInGame(CLuaState &ls); // params : menu name
static int parseInterfaceFromString(CLuaState &ls); // params : intreface script
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 i18n(CLuaState &ls); // retrieve an unicode string from CI18N
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/character_summary.h"
#include "game_share/sphrase_com.h"
#include "game_share/outpost.h"
#include "game_share/msg_client_server.h"
#include "game_share/ryzom_database_banks.h"
#include "game_share/msg_encyclopedia.h"
@ -3205,9 +3206,11 @@ void impulseUserBars(NLMISC::CBitMemStream &impulse)
void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
{
// read message
uint8 type;
bool outpostInFire;
bool playerGuildInConflict;
bool playerGuildIsAttacker;
impulse.serial(type);
impulse.serial(outpostInFire);
impulse.serial(playerGuildInConflict);
impulse.serial(playerGuildIsAttacker);
@ -3219,7 +3222,7 @@ void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
impulse.serial( declTimer );
// start
OutpostManager.startPvpJoinProposal(outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
OutpostManager.startPvpJoinProposal((OUTPOSTENUMS::TPVPType)type, outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
ownerGuildNameId, attackerGuildNameId, declTimer);
}

@ -680,6 +680,7 @@ bool CNetworkConnection::connect(string &result)
_LatestLoginTime = ryzomGetLocalTime ();
_LatestSyncTime = _LatestLoginTime;
_LatestProbeTime = _LatestLoginTime;
m_LoginAttempts = 0;
nlinfo("CNET[%p]: Client connected to shard, attempting login", this);
return true;
@ -1091,6 +1092,17 @@ bool CNetworkConnection::stateLogin()
{
sendSystemLogin();
_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;
@ -2308,6 +2320,7 @@ bool CNetworkConnection::stateProbe()
else
{
nlwarning("CNET[%p]: received normal in state Probe", this);
_LatestProbeTime = _UpdateTime;
}
}
}

@ -822,6 +822,7 @@ private:
void sendSystemLogin();
bool stateLogin();
NLMISC::TTime _LatestLoginTime;
int m_LoginAttempts;
//
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)
{
// reset counter that force player to be neutral (eg: 10 seconds)
@ -64,10 +64,22 @@ void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildI
CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random"));
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"));
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"));
if (pGC)

@ -40,7 +40,7 @@ public:
COutpostManager();
/// 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);
/// 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(BCOKARR02)
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
NL_STRING_CONVERSION_TABLE_ENTRY(BCOA)
@ -558,6 +571,7 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMCB)
NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA)

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

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

@ -32,6 +32,8 @@ namespace OUTPOSTENUMS
NL_STRING_CONVERSION_TABLE_ENTRY(PVP)
NL_STRING_CONVERSION_TABLE_ENTRY(RVR)
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_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
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
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

@ -37,7 +37,7 @@ struct SPropVisualA
uint64 JacketColor : 3; // max: 8 current: 8
uint64 TrouserModel : 8; // max: 256 current: 104
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 ArmModel : 8; // max: 256 current: 94
uint64 ArmColor : 3; // max: 8 current: 8

Loading…
Cancel
Save