From e12d189d51cf44bb148016bd4a6c1f4f7794b3a9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 20 Apr 2014 21:41:57 +0200 Subject: [PATCH 001/344] Refactored input event handling a bit. --HG-- branch : gui-editor --- code/nel/include/nel/gui/widget_manager.h | 8 +- code/nel/src/gui/widget_manager.cpp | 692 +++++++++++----------- 2 files changed, 364 insertions(+), 336 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 5fd75ac8a..6d4f47164 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -332,7 +332,13 @@ namespace NLGUI void drawViews( NL3D::UCamera camera ); bool handleEvent( const CEventDescriptor &evnt ); - + + bool handleSystemEvent( const CEventDescriptor &evnt ); + + bool handleKeyboardEvent( const CEventDescriptor &evnt ); + + bool handleMouseEvent( const CEventDescriptor &evnt ); + bool handleMouseMoveEvent( const CEventDescriptor &eventDesc ); // Relative move of pointer diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 16357d373..2c3f1159e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2096,456 +2096,478 @@ namespace NLGUI if( activeAnims[i]->isDisableButtons() ) return false; + bool handled = false; + + CViewPointer *_Pointer = static_cast< CViewPointer* >( getPointer() ); + if( evnt.getType() == CEventDescriptor::system ) { - const CEventDescriptorSystem &systemEvent = reinterpret_cast< const CEventDescriptorSystem& >( evnt ); - if( systemEvent.getEventTypeExtended() == CEventDescriptorSystem::setfocus ) + handleSystemEvent( evnt ); + } + else + if (evnt.getType() == CEventDescriptor::key) + { + handled = handleKeyboardEvent( evnt ); + } + else if (evnt.getType() == CEventDescriptor::mouse ) + { + handled = handleMouseEvent( evnt ); + } + + CDBManager::getInstance()->flushObserverCalls(); + + return handled; + } + + bool CWidgetManager::handleSystemEvent( const CEventDescriptor &evnt ) + { + const CEventDescriptorSystem &systemEvent = reinterpret_cast< const CEventDescriptorSystem& >( evnt ); + if( systemEvent.getEventTypeExtended() == CEventDescriptorSystem::setfocus ) + { + if( getCapturePointerLeft() != NULL ) { - if( getCapturePointerLeft() != NULL ) - { - getCapturePointerLeft()->handleEvent( evnt ); - setCapturePointerLeft( NULL ); - } + getCapturePointerLeft()->handleEvent( evnt ); + setCapturePointerLeft( NULL ); + } - if( getCapturePointerRight() != NULL ) - { - getCapturePointerRight()->handleEvent( evnt ); - setCapturePointerRight( NULL ); - } + if( getCapturePointerRight() != NULL ) + { + getCapturePointerRight()->handleEvent( evnt ); + setCapturePointerRight( NULL ); + } - if( _CapturedView != NULL ) - { - _CapturedView->handleEvent( evnt ); - _CapturedView = NULL; - } + if( _CapturedView != NULL ) + { + _CapturedView->handleEvent( evnt ); + _CapturedView = NULL; } } - bool handled = false; + return true; + } - CViewPointer *_Pointer = static_cast< CViewPointer* >( getPointer() ); + bool CWidgetManager::handleKeyboardEvent( const CEventDescriptor &evnt ) + { + bool handled = false; + + CEventDescriptorKey &eventDesc = (CEventDescriptorKey&)evnt; - if (evnt.getType() == CEventDescriptor::key) - { - CEventDescriptorKey &eventDesc = (CEventDescriptorKey&)evnt; - //_LastEventKeyDesc = eventDesc; + //_LastEventKeyDesc = eventDesc; - // Any Key event disable the ContextHelp - disableContextHelp(); + // Any Key event disable the ContextHelp + disableContextHelp(); - // Hide menu if the key is pushed - // if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift()) - // Hide menu (or popup menu) is ESCAPE pressed - if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + // Hide menu if the key is pushed +// if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift()) + // Hide menu (or popup menu) is ESCAPE pressed + if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + { + if( hasModal() ) { - if( hasModal() ) - { - SModalWndInfo mwi = getModal(); - if (mwi.ModalExitKeyPushed) - disableModalWindow(); - } + SModalWndInfo mwi = getModal(); + if (mwi.ModalExitKeyPushed) + disableModalWindow(); } + } - // Manage "quit window" If the Key is ESCAPE, no captureKeyboard - if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + // Manage "quit window" If the Key is ESCAPE, no captureKeyboard + if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + { + // Get the last escapable active top window. NB: this is ergonomically better. + CInterfaceGroup *win= getLastEscapableTopWindow(); + if( win ) { - // Get the last escapable active top window. NB: this is ergonomically better. - CInterfaceGroup *win= getLastEscapableTopWindow(); - if( win ) + // If the window is a modal, must pop it. + if( dynamic_cast(win) ) { - // If the window is a modal, must pop it. - if( dynamic_cast(win) ) - { - if(!win->getAHOnEscape().empty()) - CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); - popModalWindow(); - handled= true; - } - // else just disable it. - // Special case: leave the escape Key to the CaptureKeyboard . - else if( !getCaptureKeyboard() ) - { - if(!win->getAHOnEscape().empty()) - CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); - win->setActive(false); - handled= true; - } + if(!win->getAHOnEscape().empty()) + CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); + popModalWindow(); + handled= true; + } + // else just disable it. + // Special case: leave the escape Key to the CaptureKeyboard . + else if( !getCaptureKeyboard() ) + { + if(!win->getAHOnEscape().empty()) + CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); + win->setActive(false); + handled= true; } } + } - // Manage complex "Enter" - if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN) + // Manage complex "Enter" + if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN) + { + // If the top window has Enter AH + CInterfaceGroup *tw= getTopWindow(); + if(tw && !tw->getAHOnEnter().empty()) { - // If the top window has Enter AH - CInterfaceGroup *tw= getTopWindow(); - if(tw && !tw->getAHOnEnter().empty()) + // if the captured keyboard is in this Modal window, then must handle him in priority + if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw) { - // if the captured keyboard is in this Modal window, then must handle him in priority - if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw) - { - bool result = getCaptureKeyboard()->handleEvent(evnt); - CDBManager::getInstance()->flushObserverCalls(); - return result; - } - else - { - // The window or modal control the OnEnter. Execute, and don't go to the chat. - CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams()); - handled= true; - } + bool result = getCaptureKeyboard()->handleEvent(evnt); + CDBManager::getInstance()->flushObserverCalls(); + return result; + } + else + { + // The window or modal control the OnEnter. Execute, and don't go to the chat. + CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams()); + handled= true; } + } - // else the 'return' key bring back to the last edit box (if possible) - CCtrlBase *oldCapture = getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard(); - if ( getCaptureKeyboard() == NULL && oldCapture && !handled) + // else the 'return' key bring back to the last edit box (if possible) + CCtrlBase *oldCapture = getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard(); + if ( getCaptureKeyboard() == NULL && oldCapture && !handled) + { + /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided + through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible + for the default capture (main chat) or the old captured window to not want to recover + (temporary Read Only chat for instance) + */ + if(!dynamic_cast(oldCapture) || + dynamic_cast(oldCapture)->getRecoverFocusOnEnter()) { - /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided - through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible - for the default capture (main chat) or the old captured window to not want to recover - (temporary Read Only chat for instance) - */ - if(!dynamic_cast(oldCapture) || - dynamic_cast(oldCapture)->getRecoverFocusOnEnter()) + setCaptureKeyboard( oldCapture ); + notifyElementCaptured(getCaptureKeyboard() ); + // make sure all parent windows are active + CCtrlBase *cb = getCaptureKeyboard(); + CGroupContainer *lastContainer = NULL; + for(;;) { - setCaptureKeyboard( oldCapture ); - notifyElementCaptured(getCaptureKeyboard() ); - // make sure all parent windows are active - CCtrlBase *cb = getCaptureKeyboard(); - CGroupContainer *lastContainer = NULL; - for(;;) + CGroupContainer *gc = dynamic_cast(cb); + if (gc) lastContainer = gc; + cb->forceOpen(); + if (cb->getParent()) { - CGroupContainer *gc = dynamic_cast(cb); - if (gc) lastContainer = gc; - cb->forceOpen(); - if (cb->getParent()) - { - cb = cb->getParent(); - } - else - { - cb->invalidateCoords(); - break; - } + cb = cb->getParent(); } - if (lastContainer) + else { - setTopWindow(lastContainer); - lastContainer->enableBlink(1); + cb->invalidateCoords(); + break; } - handled= true; } + if (lastContainer) + { + setTopWindow(lastContainer); + lastContainer->enableBlink(1); + } + handled= true; } } + } - // General case: handle it in the Captured keyboard - if ( getCaptureKeyboard() != NULL && !handled) - { - bool result = getCaptureKeyboard()->handleEvent(evnt); - CDBManager::getInstance()->flushObserverCalls(); - return result; - } - - lastKeyEvent = eventDesc; + // General case: handle it in the Captured keyboard + if ( getCaptureKeyboard() != NULL && !handled) + { + bool result = getCaptureKeyboard()->handleEvent(evnt); + CDBManager::getInstance()->flushObserverCalls(); + return result; } - //////////////////////////////////////////////// Keyboard handling ends here //////////////////////////////////// + lastKeyEvent = eventDesc; - else if (evnt.getType() == CEventDescriptor::mouse ) - { - CEventDescriptorMouse &eventDesc = (CEventDescriptorMouse&)evnt; + return handled; + } - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) ); - else - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) ); - else - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) ); - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) ); + bool CWidgetManager::handleMouseEvent( const CEventDescriptor &evnt ) + { + bool handled = false; - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove ) - handleMouseMoveEvent( eventDesc ); + CEventDescriptorMouse &eventDesc = (CEventDescriptorMouse&)evnt; - eventDesc.setX( _Pointer->getX() ); - eventDesc.setY( _Pointer->getY() ); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) ); + else + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) ); + else + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) ); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) ); - if( isMouseHandlingEnabled() ) - { - // First thing to do : Capture handling - if ( getCapturePointerLeft() != NULL) - handled|= getCapturePointerLeft()->handleEvent(evnt); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove ) + handleMouseMoveEvent( eventDesc ); - if ( getCapturePointerRight() != NULL && - getCapturePointerLeft() != getCapturePointerRight() ) - handled|= getCapturePointerRight()->handleEvent(evnt); + eventDesc.setX( _Pointer->getX() ); + eventDesc.setY( _Pointer->getY() ); - if( _CapturedView != NULL ) - _CapturedView->handleEvent( evnt ); + if( isMouseHandlingEnabled() ) + { + // First thing to do : Capture handling + if ( getCapturePointerLeft() != NULL) + handled|= getCapturePointerLeft()->handleEvent(evnt); - CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); - setCurrentWindowUnder( ptr ); + if ( getCapturePointerRight() != NULL && + getCapturePointerLeft() != getCapturePointerRight() ) + handled|= getCapturePointerRight()->handleEvent(evnt); - // Any Mouse event but move disable the ContextHelp - if(eventDesc.getEventTypeExtended() != CEventDescriptorMouse::mousemove) - { - disableContextHelp(); - } + if( _CapturedView != NULL ) + _CapturedView->handleEvent( evnt ); - // get the group under the mouse - CInterfaceGroup *pNewCurrentWnd = getCurrentWindowUnder(); - setMouseOverWindow( pNewCurrentWnd != NULL ); + CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); + setCurrentWindowUnder( ptr ); + // Any Mouse event but move disable the ContextHelp + if(eventDesc.getEventTypeExtended() != CEventDescriptorMouse::mousemove) + { + disableContextHelp(); + } - NLMISC::CRefPtr clickedOutModalWindow; + // get the group under the mouse + CInterfaceGroup *pNewCurrentWnd = getCurrentWindowUnder(); + setMouseOverWindow( pNewCurrentWnd != NULL ); - // modal special features - if ( hasModal() ) + + NLMISC::CRefPtr clickedOutModalWindow; + + // modal special features + if ( hasModal() ) + { + CWidgetManager::SModalWndInfo mwi = getModal(); + if(mwi.ModalWindow) { - CWidgetManager::SModalWndInfo mwi = getModal(); - if(mwi.ModalWindow) + // If we are not in "click out" mode so we dont handle controls other than those of the modal + if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut) { - // If we are not in "click out" mode so we dont handle controls other than those of the modal - if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut) - { - pNewCurrentWnd = NULL; - } - else + pNewCurrentWnd = NULL; + } + else + { + // If there is a handler on click out launch it + if (pNewCurrentWnd != mwi.ModalWindow) + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || + (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + if (!mwi.ModalHandlerClickOut.empty()) + CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams); + + // If the current window is not the modal and if must quit on click out + if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut) { - // If there is a handler on click out launch it - if (pNewCurrentWnd != mwi.ModalWindow) - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || - (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) - if (!mwi.ModalHandlerClickOut.empty()) - CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams); - - // If the current window is not the modal and if must quit on click out - if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut) - { - // NB: don't force handle==true because to quit a modal does not avoid other actions + // NB: don't force handle==true because to quit a modal does not avoid other actions - // quit if click outside - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || - (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + // quit if click outside + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || + (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + { + clickedOutModalWindow = dynamic_cast((CInterfaceGroup*)mwi.ModalWindow); + // disable the modal + popModalWindow(); + if ( hasModal() ) { - clickedOutModalWindow = dynamic_cast((CInterfaceGroup*)mwi.ModalWindow); - // disable the modal - popModalWindow(); - if ( hasModal() ) - { - // don't handle event unless it is a previous modal window - if( !isPreviousModal( pNewCurrentWnd ) ) - pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows - } - movePointer (0,0); // Reget controls under pointer + // don't handle event unless it is a previous modal window + if( !isPreviousModal( pNewCurrentWnd ) ) + pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows } + movePointer (0,0); // Reget controls under pointer } } } } + } - // Manage LeftClick. - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) + // Manage LeftClick. + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) + { + if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) { - if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) + CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); + if (pGC != NULL) { - CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); - if (pGC != NULL) - { - if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); - } - else - { - setTopWindow(pNewCurrentWnd); - } + if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); + } + else + { + setTopWindow(pNewCurrentWnd); } + } - bool captured = false; + bool captured = false; - // must not capture a new element if a sheet is currentlty being dragged. - // This may happen when alt-tab has been used => the sheet is dragged but the left button is up - if (!CCtrlDraggable::getDraggedSheet()) + // must not capture a new element if a sheet is currentlty being dragged. + // This may happen when alt-tab has been used => the sheet is dragged but the left button is up + if (!CCtrlDraggable::getDraggedSheet()) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; - } + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; } } + } - if( CInterfaceElement::getEditorMode() && !captured ) + if( CInterfaceElement::getEditorMode() && !captured ) + { + for( sint32 i = _ViewsUnderPointer.size()-1; i >= 0; i-- ) { - for( sint32 i = _ViewsUnderPointer.size()-1; i >= 0; i-- ) + CViewBase *v = _ViewsUnderPointer[i]; + if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) ) { - CViewBase *v = _ViewsUnderPointer[i]; - if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) ) - { - _CapturedView = v; - captured = true; - break; - } + _CapturedView = v; + captured = true; + break; } } - - notifyElementCaptured( getCapturePointerLeft() ); - if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) - { - CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams); - } } - //if found - if ( captured ) - { - // consider clicking on a control implies handling of the event. - handled= true; - // handle the capture - if( getCapturePointerLeft() != NULL ) - getCapturePointerLeft()->handleEvent(evnt); - else - _CapturedView->handleEvent( evnt ); + notifyElementCaptured( getCapturePointerLeft() ); + if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) + { + CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams); } } + //if found + if ( captured ) + { + // consider clicking on a control implies handling of the event. + handled= true; + + // handle the capture + if( getCapturePointerLeft() != NULL ) + getCapturePointerLeft()->handleEvent(evnt); + else + _CapturedView->handleEvent( evnt ); + } + } - // Manage RightClick - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown) + // Manage RightClick + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown) + { + if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) { - if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) + CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); + if (pGC != NULL) { - CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); - if (pGC != NULL) - { - if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); - } - else - { - setTopWindow(pNewCurrentWnd); - } + if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); + } + else + { + setTopWindow(pNewCurrentWnd); } + } - // Take the top most control. + // Take the top most control. + { + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerRight( ctrl ); - } + nMaxDepth = d; + setCapturePointerRight( ctrl ); } } - notifyElementCaptured( getCapturePointerRight() ); - if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) - { - CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams); - } } - //if found - if ( getCapturePointerRight() != NULL) + notifyElementCaptured( getCapturePointerRight() ); + if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) { - // handle the capture - handled |= getCapturePointerRight()->handleEvent(evnt); + CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams); } } + //if found + if ( getCapturePointerRight() != NULL) + { + // handle the capture + handled |= getCapturePointerRight()->handleEvent(evnt); + } + } - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) - { - if (!handled) - if (pNewCurrentWnd != NULL) - pNewCurrentWnd->handleEvent(evnt); - if ( getCapturePointerRight() != NULL) - { - setCapturePointerRight(NULL); - handled= true; - } + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) + { + if (!handled) + if (pNewCurrentWnd != NULL) + pNewCurrentWnd->handleEvent(evnt); + if ( getCapturePointerRight() != NULL) + { + setCapturePointerRight(NULL); + handled= true; } + } - // window handling. if not handled by a control - if (!handled) + // window handling. if not handled by a control + if (!handled) + { + if (((pNewCurrentWnd != NULL) && !hasModal()) || + ((hasModal() && getModal().ModalWindow == pNewCurrentWnd))) { - if (((pNewCurrentWnd != NULL) && !hasModal()) || - ((hasModal() && getModal().ModalWindow == pNewCurrentWnd))) + CEventDescriptorMouse ev2 = eventDesc; + sint32 x= eventDesc.getX(), y = eventDesc.getY(); + if (pNewCurrentWnd) { - CEventDescriptorMouse ev2 = eventDesc; - sint32 x= eventDesc.getX(), y = eventDesc.getY(); - if (pNewCurrentWnd) - { - pNewCurrentWnd->absoluteToRelative (x, y); - ev2.setX (x); ev2.setY (y); - handled|= pNewCurrentWnd->handleEvent (ev2); - } - - // After handle event of a left click, may set window Top if movable (infos etc...) - //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() ) - // setTopWindow(pNewCurrentWnd); + pNewCurrentWnd->absoluteToRelative (x, y); + ev2.setX (x); ev2.setY (y); + handled|= pNewCurrentWnd->handleEvent (ev2); } + + // After handle event of a left click, may set window Top if movable (infos etc...) + //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() ) + // setTopWindow(pNewCurrentWnd); } + } - // Put here to let a chance to the window to handle if the capture dont - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + // Put here to let a chance to the window to handle if the capture dont + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + { + if ( getCapturePointerLeft() != NULL) { - if ( getCapturePointerLeft() != NULL) - { - setCapturePointerLeft(NULL); - handled = true; - } + setCapturePointerLeft(NULL); + handled = true; } + } - // If the current window is the modal, may Modal quit. Do it after standard event handle - if(hasModal() && pNewCurrentWnd == getModal().ModalWindow) + // If the current window is the modal, may Modal quit. Do it after standard event handle + if(hasModal() && pNewCurrentWnd == getModal().ModalWindow) + { + // NB: don't force handle==true because to quit a modal does not avoid other actions + CWidgetManager::SModalWndInfo mwi = getModal(); + // and if must quit on click right + if(mwi.ModalExitClickR) { - // NB: don't force handle==true because to quit a modal does not avoid other actions - CWidgetManager::SModalWndInfo mwi = getModal(); - // and if must quit on click right - if(mwi.ModalExitClickR) - { - // quit if click right - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) - // disable the modal - disableModalWindow(); - } - - // and if must quit on click left - if(mwi.ModalExitClickL) - { - // quit if click right - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) - // disable the modal - disableModalWindow(); - } + // quit if click right + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) + // disable the modal + disableModalWindow(); } - // If the mouse is over a window, always consider the event is taken (avoid click behind) - handled|= isMouseOverWindow(); + // and if must quit on click left + if(mwi.ModalExitClickL) + { + // quit if click right + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + // disable the modal + disableModalWindow(); + } } - } - CDBManager::getInstance()->flushObserverCalls(); + // If the mouse is over a window, always consider the event is taken (avoid click behind) + handled|= isMouseOverWindow(); + } return handled; } - bool CWidgetManager::handleMouseMoveEvent( const CEventDescriptor &eventDesc ) { if( getPointer() == NULL ) From 4abf74d6e9738efee8830dcde5029f1c71484062 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 21 Apr 2014 19:30:33 +0200 Subject: [PATCH 002/344] We can now drag elements, they will disappear and whatnot, but at least they can be dragged! --HG-- branch : gui-editor --- code/nel/include/nel/gui/interface_element.h | 3 + code/nel/include/nel/gui/interface_group.h | 3 + code/nel/include/nel/gui/widget_manager.h | 5 ++ code/nel/src/gui/interface_group.cpp | 26 ++++++++ code/nel/src/gui/widget_manager.cpp | 63 ++++++++++++++++++-- 5 files changed, 96 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 764d165ef..db7a499c8 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -233,6 +233,9 @@ namespace NLGUI virtual void setActive (bool state); + void setXReal( sint32 x ){ _XReal = x; } + void setYReal( sint32 y ){ _YReal = y; } + void setX (sint32 x) { _X = x; } void setXAndInvalidateCoords (sint32 x) { _X = x; invalidateCoords(); } diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index f72bc6f1f..ff0efac3b 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -79,6 +79,9 @@ namespace NLGUI bool delElement (const std::string &id, bool noWarning=false); bool delElement (CInterfaceElement *pIE, bool noWarning=false); + // Take the element from the group, but don't delete it! + CInterfaceElement* takeElement( CInterfaceElement *e ); + uint getNumGroup() const { return (uint)_ChildrenGroups.size(); } CInterfaceGroup *getGroup(uint index) const; diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 6d4f47164..5d2468e7a 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -532,6 +532,11 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; + NLMISC::CRefPtr< CInterfaceElement > draggedElement; + + bool startDragging(); + void stopDragging(); + // What is under pointer std::vector< CViewBase* > _ViewsUnderPointer; std::vector< CCtrlBase* > _CtrlsUnderPointer; diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 5fa83e1c5..4d37eda1c 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -1638,6 +1638,32 @@ namespace NLGUI return delView(static_cast(pIE)); } + // ------------------------------------------------------------------------------------------------ + CInterfaceElement* CInterfaceGroup::takeElement( CInterfaceElement *e ) + { + bool ok = false; + + if( e->isGroup() ) + { + ok = delGroup( static_cast< CInterfaceGroup* >( e ), true ); + } + else + if( e->isCtrl() ) + { + ok = delCtrl( static_cast< CCtrlBase* >( e ), true ); + } + else + if( e->isView() ) + { + ok = delView( static_cast< CViewBase* >( e ), true ); + } + + if( ok ) + return e; + else + return NULL; + } + // ------------------------------------------------------------------------------------------------ bool CInterfaceGroup::isWindowUnder (sint32 x, sint32 y) { diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 2c3f1159e..e3f1064fa 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2039,6 +2039,12 @@ namespace NLGUI } } + if( draggedElement != NULL ) + { + CInterfaceElement *e = draggedElement; + static_cast< CViewBase* >( e )->draw(); + } + if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty()) { driver->setMatrixMode2D11(); @@ -2437,11 +2443,11 @@ namespace NLGUI // consider clicking on a control implies handling of the event. handled= true; - // handle the capture if( getCapturePointerLeft() != NULL ) - getCapturePointerLeft()->handleEvent(evnt); - else - _CapturedView->handleEvent( evnt ); + _CapturedView = getCapturePointerLeft(); + + // handle the capture + _CapturedView->handleEvent( evnt ); } } @@ -2534,6 +2540,11 @@ namespace NLGUI setCapturePointerLeft(NULL); handled = true; } + + _CapturedView = NULL; + + if( CInterfaceElement::getEditorMode() ) + stopDragging(); } @@ -2602,8 +2613,52 @@ namespace NLGUI ve.setY( getPointer()->getY() ); } + if( CInterfaceElement::getEditorMode() ) + { + if( ( _CapturedView != NULL ) && ( draggedElement == NULL ) ) + { + startDragging(); + } + else + if( draggedElement != NULL ) + { + draggedElement->setXReal( newX ); + draggedElement->setYReal( newY ); + draggedElement->invalidateCoords(); + } + } + return true; } + + // ------------------------------------------------------------------------------------------------ + bool CWidgetManager::startDragging() + { + CInterfaceElement *e = NULL; + + CInterfaceGroup *g = _CapturedView->getParent(); + if( g != NULL ) + { + e = g->takeElement( _CapturedView ); + if( e == NULL ) + { + nlinfo( "Something went horribly wrong :(" ); + return false; + } + } + else + e = _CapturedView; + + e->setParent( NULL ); + draggedElement = e; + + return true; + } + + void CWidgetManager::stopDragging() + { + draggedElement = NULL; + } // ------------------------------------------------------------------------------------------------ void CWidgetManager::movePointer (sint32 dx, sint32 dy) From 07a57f81f8b914f2d640d3d979ee7a967834ebee Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 14 Oct 2014 23:45:08 +0200 Subject: [PATCH 003/344] Shadow should not be taken into account for font height, breaks vertical centering --HG-- branch : develop --- code/nel/src/gui/view_text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 815007723..a70194c7b 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -2547,8 +2547,8 @@ namespace NLGUI // Letter size UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext - _FontHeight = (uint) si.StringHeight + (_Shadow?(_ShadowOutline?2:1):0); - _FontLegHeight = (uint) si.StringLine + (_Shadow?(_ShadowOutline?2:1):0); + _FontHeight = (uint) si.StringHeight; // + (_Shadow?(_ShadowOutline?2:1):0); + _FontLegHeight = (uint) si.StringLine; // + (_Shadow?(_ShadowOutline?2:1):0); // Space width si = TextContext->getStringInfo(ucstring(" ")); From b010f224e45233a929360d7df2a471525c848f98 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 14 Oct 2014 23:45:08 +0200 Subject: [PATCH 004/344] Don't use I18N when the required ui prefix is not in the tooltip text (convention actually dictates uitt as tooltip prefix) --HG-- branch : develop --- code/nel/src/gui/view_text.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index a70194c7b..db069a29d 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -2834,7 +2834,8 @@ namespace NLGUI pTooltip->setId(_Id+"_tt"+toString(i)); pTooltip->setAvoidResizeParent(avoidResizeParent()); pTooltip->setRenderLayer(getRenderLayer()); - pTooltip->setDefaultContextHelp(CI18N::get(tempTooltips[i].toString())); + bool isI18N = tempTooltips[i].size() >= 2 && tempTooltips[i][0] == 'u' && tempTooltips[i][1] == 'i'; + pTooltip->setDefaultContextHelp(isI18N ? CI18N::get(tempTooltips[i].toString()) : tempTooltips[i]); pTooltip->setParentPos(this); pTooltip->setParentPosRef(Hotspot_BR); pTooltip->setPosRef(Hotspot_BR); From 7487ea41357f16c1e136be1bddc8e955018e4221 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 16 Oct 2014 02:00:45 +0200 Subject: [PATCH 005/344] Higher quality outline, visual difference is relevant only for black --HG-- branch : develop --- code/nel/include/nel/3d/text_context.h | 85 ++++++++++++++++++++------ 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/code/nel/include/nel/3d/text_context.h b/code/nel/include/nel/3d/text_context.h index 064a0ef64..8cf7ad7f0 100644 --- a/code/nel/include/nel/3d/text_context.h +++ b/code/nel/include/nel/3d/text_context.h @@ -147,12 +147,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color = _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); if (_ShadeOutline) { - rCS.render2D(*_Driver, x-_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); - rCS.render2D(*_Driver, x-_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); - rCS.render2D(*_Driver, x+_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + float rext = _ShadeExtent * 0.7071f; + rCS.render2D(*_Driver, x+rext, z-rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-rext, z-rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-rext, z+rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+rext, z+rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + } + else + { + rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); } rCS.Color= bkup; } @@ -171,12 +180,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); if (_ShadeOutline) { - rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); - rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); - rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + float rext = _ShadeExtent * 0.7071f; + rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z-rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z-rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z+rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z+rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x, z+_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x, z-_ShadeExtent, xmin, ymin, xmax, ymax); + } + else + { + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); } rCS.Color= bkup; } @@ -195,12 +213,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); if (_ShadeOutline) { - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + float rext = _ShadeExtent * 0.7071f; + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y-rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y-rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y+rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y+rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + } + else + { + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); } rCS.Color= bkup; } @@ -221,12 +248,21 @@ public: CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); if (_ShadeOutline) { - _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + float rext = _ShadeExtent * 0.7071f; + _TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + else + { + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); } _TempString.Color = bkup; } @@ -251,12 +287,21 @@ public: CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); if (_ShadeOutline) { - _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + float rext = _ShadeExtent * 0.7071f; + _TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + else + { + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); } _TempString.Color = bkup; } From fff4edb2c9bdcc9d3888b2df2e27460db8a476f5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 16 Oct 2014 02:00:53 +0200 Subject: [PATCH 006/344] Maybe solves #210 --HG-- branch : develop --- code/ryzom/client/src/main_loop.cpp | 2 ++ code/ryzom/client/src/motion/user_controls.cpp | 4 ++++ code/ryzom/client/src/motion/user_controls.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index f6d921ff8..9b39c53c9 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1013,6 +1013,7 @@ bool mainLoop() SetMouseCursor (); // Set the cursor. ContextCur.context("STAND BY"); + UserControls.reset(); // set the default box for keyboard setDefaultChatWindow(PeopleInterraction.ChatGroup.Window); @@ -2463,6 +2464,7 @@ bool mainLoop() SetMouseCursor (); // Set the cursor. ContextCur.context("STAND BY"); + UserControls.reset(); // set the default box for keyboard CChatWindow *defaultChatWindow; diff --git a/code/ryzom/client/src/motion/user_controls.cpp b/code/ryzom/client/src/motion/user_controls.cpp index 285848120..897cba9c1 100644 --- a/code/ryzom/client/src/motion/user_controls.cpp +++ b/code/ryzom/client/src/motion/user_controls.cpp @@ -174,6 +174,10 @@ void CUserControls::init() }// init // +void CUserControls::reset() +{ + init(); +} //----------------------------------------------- // needReleaseForward : diff --git a/code/ryzom/client/src/motion/user_controls.h b/code/ryzom/client/src/motion/user_controls.h index eb4de2020..018b2c8e9 100644 --- a/code/ryzom/client/src/motion/user_controls.h +++ b/code/ryzom/client/src/motion/user_controls.h @@ -152,6 +152,8 @@ public: /// Constructor CUserControls(); + void reset(); + /// Return the string associated to the motion Mode. std::string modeStr() const; /// Return the motion Mode. From 176c3d8a4a7ad36412a7e566378c05e0f51421c6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 12 Jul 2014 18:19:25 +0200 Subject: [PATCH 007/344] Add callback template class --HG-- branch : develop --- code/nel/include/nel/misc/callback.h | 327 ++++++++++++++++++ code/nel/samples/misc/CMakeLists.txt | 1 + code/nel/samples/misc/callback/CMakeLists.txt | 9 + code/nel/samples/misc/callback/main.cpp | 62 ++++ 4 files changed, 399 insertions(+) create mode 100644 code/nel/include/nel/misc/callback.h create mode 100644 code/nel/samples/misc/callback/CMakeLists.txt create mode 100644 code/nel/samples/misc/callback/main.cpp diff --git a/code/nel/include/nel/misc/callback.h b/code/nel/include/nel/misc/callback.h new file mode 100644 index 000000000..ca5140f6f --- /dev/null +++ b/code/nel/include/nel/misc/callback.h @@ -0,0 +1,327 @@ +/* + +Copyright (c) 2009-2014, Jan BOON +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NLMISC_CALLBACK_H +#define NLMISC_CALLBACK_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NLMISC { + +#define NLMISC_CALLBACK_TEMPLATE \ +/** \ + * \brief NLMISC_CALLBACK_ARGS_CLASS \ + * \date 2009-03-03 18:09GMT \ + * \author Jan BOON \ + * Callback template \ + */ \ +template \ +class NLMISC_CALLBACK_ARGS_CLASS \ +{ \ + /* Very simple reference counting callback base */ \ + class CCallbackBase \ + { \ + public: \ + CCallbackBase() : m_RefCount(0) \ + { \ + \ + } \ + \ + virtual ~CCallbackBase() \ + { \ + nlassert(!m_RefCount); \ + } \ + \ + void refAdd() \ + { \ + ++m_RefCount; \ + } \ + \ + void refRemove() \ + { \ + --m_RefCount; \ + if (!m_RefCount) \ + delete this; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) = 0; \ + \ + virtual bool equals(const CCallbackBase *callbackBase) = 0; \ + \ + /* disable copy */ \ + CCallbackBase(const CCallbackBase &); \ + CCallbackBase &operator=(const CCallbackBase &); \ + \ + private: \ + uint m_RefCount; \ + }; \ + \ + typedef TReturn TCallbackFunction(NLMISC_CALLBACK_ARGS_DECL); \ + class CCallbackFunction : public CCallbackBase \ + { \ + public: \ + CCallbackFunction(TCallbackFunction *callbackFunction) : m_CallbackFunction(callbackFunction) \ + { \ + nlassert(m_CallbackFunction); \ + } \ + \ + virtual ~CCallbackFunction() \ + { \ + m_CallbackFunction = NULL; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + return m_CallbackFunction(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + virtual bool equals(const CCallbackBase *callbackBase) \ + { \ + const CCallbackFunction *callbackFunction = \ + dynamic_cast(callbackBase); \ + if (!callbackFunction) return false; \ + return m_CallbackFunction == callbackFunction->m_CallbackFunction; \ + } \ + \ + private: \ + TCallbackFunction *m_CallbackFunction; \ + }; \ + \ + template \ + class CCallbackMethod : public CCallbackBase \ + { \ + typedef TReturn (TClass::*TCallbackMethod)(NLMISC_CALLBACK_ARGS_DECL); \ + public: \ + CCallbackMethod(TClass *callbackObject, TCallbackMethod callbackMethod) : m_CallbackObject(callbackObject), m_CallbackMethod(callbackMethod) \ + { \ + nlassert(m_CallbackObject); \ + nlassert(m_CallbackMethod); \ + } \ + \ + virtual ~CCallbackMethod() \ + { \ + m_CallbackObject = NULL; \ + m_CallbackMethod = NULL; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + return (m_CallbackObject->*m_CallbackMethod)(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + virtual bool equals(const CCallbackBase *callbackBase) \ + { \ + const CCallbackMethod *callbackMethod = \ + dynamic_cast(callbackBase); \ + if (!callbackMethod) return false; \ + return m_CallbackObject == callbackMethod->m_CallbackObject \ + && m_CallbackMethod == callbackMethod->m_CallbackMethod; \ + } \ + \ + private: \ + TClass *m_CallbackObject; \ + TCallbackMethod m_CallbackMethod; \ + }; \ + \ +public: \ + CCallback() : m_CallbackBase(NULL) \ + { \ + \ + } \ + \ + CCallback(TCallbackFunction *callbackFunction) : m_CallbackBase(new CCallbackFunction(callbackFunction)) \ + { \ + nlassert(m_CallbackBase); \ + m_CallbackBase->refAdd(); \ + } \ + \ + template \ + CCallback(TClass *callbackObject, TReturn (TClass::*callbackMethod)(NLMISC_CALLBACK_ARGS_DECL)) : m_CallbackBase(new CCallbackMethod(callbackObject, callbackMethod)) \ + { \ + nlassert(m_CallbackBase); \ + m_CallbackBase->refAdd(); \ + } \ + \ + CCallback(const CCallback &callback) \ + { \ + m_CallbackBase = callback.m_CallbackBase; \ + if (m_CallbackBase) \ + m_CallbackBase->refAdd(); \ + } \ + \ + CCallback &operator=(const CCallback &callback) \ + { \ + if (m_CallbackBase != callback.m_CallbackBase) \ + { \ + if (m_CallbackBase) \ + m_CallbackBase->refRemove(); \ + m_CallbackBase = callback.m_CallbackBase; \ + if (m_CallbackBase) \ + m_CallbackBase->refAdd(); \ + } \ + return *this; \ + } \ + \ + ~CCallback() \ + { \ + if (m_CallbackBase) \ + { \ + m_CallbackBase->refRemove(); \ + m_CallbackBase = NULL; \ + } \ + } \ + \ + TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + nlassert(m_CallbackBase); \ + return m_CallbackBase->callback(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + TReturn operator()(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + nlassert(m_CallbackBase); \ + return m_CallbackBase->callback(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + bool valid() const \ + { \ + return m_CallbackBase != NULL; \ + } \ + \ + operator bool() const \ + { \ + return m_CallbackBase != NULL; \ + } \ + \ + bool operator==(const CCallback &callback) \ + { \ + return m_CallbackBase->equals(callback.m_CallbackBase); \ + } \ + \ +private: \ + CCallbackBase *m_CallbackBase; \ + \ +}; /* class CCallback */ \ + +template +class CCallback; + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME +#define NLMISC_CALLBACK_ARGS_DECL +#define NLMISC_CALLBACK_ARGS_IMPL +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA +#define NLMISC_CALLBACK_ARGS_IMPL argsA +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF, typename TArgsG +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF, TArgsG argsG +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF, argsG +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL +#undef NLMISC_CALLBACK_ARGS_CLASSNAME + +#undef NLMISC_CALLBACK_TEMPLATE + +} /* namespace NLMISC */ + +#endif /* #ifndef NLMISC_CALLBACK_H */ + +/* end of file */ diff --git a/code/nel/samples/misc/CMakeLists.txt b/code/nel/samples/misc/CMakeLists.txt index 753b418ae..d00a54952 100644 --- a/code/nel/samples/misc/CMakeLists.txt +++ b/code/nel/samples/misc/CMakeLists.txt @@ -1,3 +1,4 @@ +ADD_SUBDIRECTORY(callback) ADD_SUBDIRECTORY(command) ADD_SUBDIRECTORY(configfile) ADD_SUBDIRECTORY(debug) diff --git a/code/nel/samples/misc/callback/CMakeLists.txt b/code/nel/samples/misc/callback/CMakeLists.txt new file mode 100644 index 000000000..62626b0a7 --- /dev/null +++ b/code/nel/samples/misc/callback/CMakeLists.txt @@ -0,0 +1,9 @@ +FILE(GLOB SRC *.cpp) + +ADD_EXECUTABLE(nl_sample_callback ${SRC}) + +TARGET_LINK_LIBRARIES(nl_sample_callback nelmisc) +NL_DEFAULT_PROPS(nl_sample_callback "NeL, Samples, Misc: Callback") +NL_ADD_RUNTIME_FLAGS(nl_sample_callback) + +INSTALL(TARGETS nl_sample_callback RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT samplesmisc) diff --git a/code/nel/samples/misc/callback/main.cpp b/code/nel/samples/misc/callback/main.cpp new file mode 100644 index 000000000..157f3b259 --- /dev/null +++ b/code/nel/samples/misc/callback/main.cpp @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014, Jan BOON +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +class CTestClass +{ +public: + void helloWorld(int y) + { + nldebug("Method call: %i, %i", y, x); + } + int x; +}; + +void functionCall(int i) +{ + nldebug("Function call: %i", i); +} + +typedef NLMISC::CCallback TCallbackType; + +int main(int argc, char **argv) +{ + CTestClass tc; + tc.x = 42; + + TCallbackType cbMethod = TCallbackType(&tc, &CTestClass::helloWorld); + TCallbackType cbFunction = TCallbackType(functionCall); + cbMethod(100); + cbFunction(99); + + getchar(); + + return EXIT_SUCCESS; +} From 094a23bd09fea6198e575be6565c1b7b5b86bb45 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Tue, 16 Sep 2014 20:34:26 +0200 Subject: [PATCH 009/344] fixing #206 : passwords are now stored using SHA-512 instead of traditional DES --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- .../common/src/game_share/CMakeLists.txt | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 + .../src/game_share/{crypt.h => ccrypt.h} | 0 code/ryzom/common/src/game_share/crypt.cpp | 980 ------------------ .../src/monitor_service/service_main.cpp | 12 +- code/web/private_php/ams/autoload/users.php | 8 +- code/web/private_php/setup/sql/nel_00001.sql | 2 +- .../private_php/setup/sql/nel_ams_00001.sql | 2 +- code/web/public_php/ams/autoload/webusers.php | 9 +- code/web/public_php/ams/sql/db.sql | 4 +- code/web/public_php/login/r2_login.php | 17 +- 12 files changed, 75 insertions(+), 993 deletions(-) create mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp rename code/ryzom/common/src/game_share/{crypt.h => ccrypt.h} (100%) delete mode 100644 code/ryzom/common/src/game_share/crypt.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 091e24a80..673a5b5f4 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/crypt.h" +#include "game_share/ccrypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/CMakeLists.txt b/code/ryzom/common/src/game_share/CMakeLists.txt index 2648416ec..cbccfd6dd 100644 --- a/code/ryzom/common/src/game_share/CMakeLists.txt +++ b/code/ryzom/common/src/game_share/CMakeLists.txt @@ -30,7 +30,7 @@ NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC} ${R2}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges crypt ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) NL_DEFAULT_PROPS(ryzom_gameshare "Ryzom, Library: Game Share") NL_ADD_RUNTIME_FLAGS(ryzom_gameshare) NL_ADD_LIB_SUFFIX(ryzom_gameshare) diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp new file mode 100644 index 000000000..ea67cf7d6 --- /dev/null +++ b/code/ryzom/common/src/game_share/ccrypt.cpp @@ -0,0 +1,30 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "ccrypt.h" + +#define _GNU_SOURCE 1 +#include + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::crypt(password.c_str(), salt.c_str()); + + return result; +} diff --git a/code/ryzom/common/src/game_share/crypt.h b/code/ryzom/common/src/game_share/ccrypt.h similarity index 100% rename from code/ryzom/common/src/game_share/crypt.h rename to code/ryzom/common/src/game_share/ccrypt.h diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp deleted file mode 100644 index 0da908817..000000000 --- a/code/ryzom/common/src/game_share/crypt.cpp +++ /dev/null @@ -1,980 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "crypt.h" - -char * rz_crypt(register const char *key, register const char *setting); - - - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::rz_crypt(password.c_str(), salt.c_str()); - - return result; -} - - - - - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Tom Truscott. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -/* #include */ -#include -#include -#define RZ__PASSWORD_EFMT1 '-' - -#if DEBUG_CRYPT -void prtab(char *s, unsigned char *t, int num_rows); -#endif - -/* - * UNIX password, and DES, encryption. - * By Tom Truscott, trt@rti.rti.org, - * from algorithms by Robert W. Baldwin and James Gillogly. - * - * References: - * "Mathematical Cryptology for Computer Scientists and Mathematicians," - * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. - * - * "Password Security: A Case History," R. Morris and Ken Thompson, - * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. - * - * "DES will be Totally Insecure within Ten Years," M.E. Hellman, - * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. - */ - -/* ===== Configuration ==================== */ - -/* - * define "MUST_ALIGN" if your compiler cannot load/store - * long integers at arbitrary (e.g. odd) memory locations. - * (Either that or never pass unaligned addresses to des_cipher!) - */ -#if !defined(vax) -#define MUST_ALIGN -#endif - -#ifdef CHAR_BITS -#if CHAR_BITS != 8 - #error C_block structure assumes 8 bit characters -#endif -#endif - -/* - * define "LONG_IS_32_BITS" only if sizeof(long)==4. - * This avoids use of bit fields (your compiler may be sloppy with them). - */ -#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) -#define LONG_IS_32_BITS -#endif - -/* - * define "B64" to be the declaration for a 64 bit integer. - * XXX this feature is currently unused, see "endian" comment below. - */ -#if defined(cray) || defined(__LP64__) || defined(_LP64) -#define B64 long -#endif -#if defined(convex) -#define B64 long long -#endif - -/* - * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes - * of lookup tables. This speeds up des_setkey() and des_cipher(), but has - * little effect on crypt(). - */ -#if defined(notdef) -#define LARGEDATA -#endif - -/* ==================================== */ - -/* - * Cipher-block representation (Bob Baldwin): - * - * DES operates on groups of 64 bits, numbered 1..64 (sigh). One - * representation is to store one bit per byte in an array of bytes. Bit N of - * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. - * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the - * first byte, 9..16 in the second, and so on. The DES spec apparently has - * bit 1 in the MSB of the first byte, but that is particularly noxious so we - * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is - * the MSB of the first byte. Specifically, the 64-bit input data and key are - * converted to LSB format, and the output 64-bit block is converted back into - * MSB format. - * - * DES operates internally on groups of 32 bits which are expanded to 48 bits - * by permutation E and shrunk back to 32 bits by the S boxes. To speed up - * the computation, the expansion is applied only once, the expanded - * representation is maintained during the encryption, and a compression - * permutation is applied only at the end. To speed up the S-box lookups, - * the 48 bits are maintained as eight 6 bit groups, one per byte, which - * directly feed the eight S-boxes. Within each byte, the 6 bits are the - * most significant ones. The low two bits of each byte are zero. (Thus, - * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the - * first byte in the eight byte representation, bit 2 of the 48 bit value is - * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is - * used, in which the output is the 64 bit result of an S-box lookup which - * has been permuted by P and expanded by E, and is ready for use in the next - * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this - * lookup. Since each byte in the 48 bit path is a multiple of four, indexed - * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and - * "salt" are also converted to this 8*(6+2) format. The SPE table size is - * 8*64*8 = 4K bytes. - * - * To speed up bit-parallel operations (such as XOR), the 8 byte - * representation is "union"ed with 32 bit values "i0" and "i1", and, on - * machines which support it, a 64 bit value "b64". This data structure, - * "C_block", has two problems. First, alignment restrictions must be - * honored. Second, the byte-order (e.g. little-endian or big-endian) of - * the architecture becomes visible. - * - * The byte-order problem is unfortunate, since on the one hand it is good - * to have a machine-independent C_block representation (bits 1..8 in the - * first byte, etc.), and on the other hand it is good for the LSB of the - * first byte to be the LSB of i0. We cannot have both these things, so we - * currently use the "little-endian" representation and avoid any multi-byte - * operations that depend on byte order. This largely precludes use of the - * 64-bit datatype since the relative order of i0 and i1 are unknown. It - * also inhibits grouping the SPE table to look up 12 bits at a time. (The - * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 - * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the - * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup - * requires a 128 kilobyte table, so perhaps this is not a big loss. - * - * Permutation representation (Jim Gillogly): - * - * A transformation is defined by its effect on each of the 8 bytes of the - * 64-bit input. For each byte we give a 64-bit output that has the bits in - * the input distributed appropriately. The transformation is then the OR - * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for - * each transformation. Unless LARGEDATA is defined, however, a more compact - * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. - * The smaller table uses 16*16*8 = 2K bytes for each transformation. This - * is slower but tolerable, particularly for password encryption in which - * the SPE transformation is iterated many times. The small tables total 9K - * bytes, the large tables total 72K bytes. - * - * The transformations used are: - * IE3264: MSB->LSB conversion, initial permutation, and expansion. - * This is done by collecting the 32 even-numbered bits and applying - * a 32->64 bit transformation, and then collecting the 32 odd-numbered - * bits and applying the same transformation. Since there are only - * 32 input bits, the IE3264 transformation table is half the size of - * the usual table. - * CF6464: Compression, final permutation, and LSB->MSB conversion. - * This is done by two trivial 48->32 bit compressions to obtain - * a 64-bit block (the bit numbering is given in the "CIFP" table) - * followed by a 64->64 bit "cleanup" transformation. (It would - * be possible to group the bits in the 64-bit block so that 2 - * identical 32->32 bit transformations could be used instead, - * saving a factor of 4 in space and possibly 2 in time, but - * byte-ordering and other complications rear their ugly head. - * Similar opportunities/problems arise in the key schedule - * transforms.) - * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. - * This admittedly baroque 64->64 bit transformation is used to - * produce the first code (in 8*(6+2) format) of the key schedule. - * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. - * It would be possible to define 15 more transformations, each - * with a different rotation, to generate the entire key schedule. - * To save space, however, we instead permute each code into the - * next by using a transformation that "undoes" the PC2 permutation, - * rotates the code, and then applies PC2. Unfortunately, PC2 - * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not - * invertible. We get around that problem by using a modified PC2 - * which retains the 8 otherwise-lost bits in the unused low-order - * bits of each byte. The low-order bits are cleared when the - * codes are stored into the key schedule. - * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. - * This is faster than applying PC2ROT[0] twice, - * - * The Bell Labs "salt" (Bob Baldwin): - * - * The salting is a simple permutation applied to the 48-bit result of E. - * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and - * i+24 of the result are swapped. The salt is thus a 24 bit number, with - * 16777216 possible values. (The original salt was 12 bits and could not - * swap bits 13..24 with 36..48.) - * - * It is possible, but ugly, to warp the SPE table to account for the salt - * permutation. Fortunately, the conditional bit swapping requires only - * about four machine instructions and can be done on-the-fly with about an - * 8% performance penalty. - */ - -typedef union { - unsigned char b[8]; - struct { -#if defined(LONG_IS_32_BITS) - /* long is often faster than a 32-bit bit field */ - long i0; - long i1; -#else - long i0: 32; - long i1: 32; -#endif - } b32; -#if defined(B64) - B64 b64; -#endif -} C_block; - -/* - * Convert twenty-four-bit long in host-order - * to six bits (and 2 low-order zeroes) per char little-endian format. - */ -#define TO_SIX_BIT(rslt, src) { \ - C_block cvt; \ - cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[3] = (unsigned char) (src&0xFF); \ - rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ - } - -/* - * These macros may someday permit efficient use of 64-bit integers. - */ -#define ZERO(d,d0,d1) d0 = 0, d1 = 0 -#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 -#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 -#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 -#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 -#define DCL_BLOCK(d,d0,d1) long d0, d1 - -#if defined(LARGEDATA) - /* Waste memory like crazy. Also, do permutations in line */ -#define LGCHUNKBITS 3 -#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); - STORE(D,D0,D1,*out); -} -#endif /* LARGEDATA */ - - -/* ===== (mostly) Standard DES Tables ==================== */ - -static unsigned char IP[] = { /* initial permutation */ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, -}; - -/* The final permutation is the inverse of IP - no table is necessary */ - -static unsigned char ExpandTr[] = { /* expansion operation */ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1, -}; - -static unsigned char PC1[] = { /* permuted choice table 1 */ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4, -}; - -static unsigned char Rotates[] = { /* PC1 rotation schedule */ - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, -}; - -/* note: each "row" of PC2 is left-padded with bits that make it invertible */ -static unsigned char PC2[] = { /* permuted choice table 2 */ - 9, 18, 14, 17, 11, 24, 1, 5, - 22, 25, 3, 28, 15, 6, 21, 10, - 35, 38, 23, 19, 12, 4, 26, 8, - 43, 54, 16, 7, 27, 20, 13, 2, - - 0, 0, 41, 52, 31, 37, 47, 55, - 0, 0, 30, 40, 51, 45, 33, 48, - 0, 0, 44, 49, 39, 56, 34, 53, - 0, 0, 46, 42, 50, 36, 29, 32, -}; - -static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ - /* S[1] */ - {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, - /* S[2] */ - {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, - /* S[3] */ - {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, - /* S[4] */ - { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, - /* S[5] */ - { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, - /* S[6] */ - {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, - /* S[7] */ - { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, - /* S[8] */ - {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} -}; - -static unsigned char P32Tr[] = { /* 32-bit permutation function */ - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25, -}; - -static unsigned char CIFP[] = { /* compressed/interleaved permutation */ - 1, 2, 3, 4, 17, 18, 19, 20, - 5, 6, 7, 8, 21, 22, 23, 24, - 9, 10, 11, 12, 25, 26, 27, 28, - 13, 14, 15, 16, 29, 30, 31, 32, - - 33, 34, 35, 36, 49, 50, 51, 52, - 37, 38, 39, 40, 53, 54, 55, 56, - 41, 42, 43, 44, 57, 58, 59, 60, - 45, 46, 47, 48, 61, 62, 63, 64, -}; - -static unsigned char itoa64[] = /* 0..63 => ascii-64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - -/* ===== Tables that are initialized at run time ==================== */ - - -static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ - -/* Initial key schedule permutation */ -static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ -static C_block CF6464[64/CHUNKBITS][1<= 0; ) { - if ((t = (unsigned char)setting[i]) == '\0') - t = '.'; - encp[i] = t; - num_iter = (num_iter<<6) | a64toi[t]; - } - setting += 4; - encp += 4; - salt_size = 4; - break; - default: - num_iter = 25; - salt_size = 2; - } - - salt = 0; - for (i = salt_size; --i >= 0; ) { - if ((t = (unsigned char)setting[i]) == '\0') - t = '.'; - encp[i] = t; - salt = (salt<<6) | a64toi[t]; - } - encp += salt_size; - if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, - salt, num_iter)) - return (NULL); - - /* - * Encode the 64 cipher bits as 11 ascii characters. - */ - i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; - encp[3] = itoa64[i&0x3f]; i >>= 6; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; encp += 4; - i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; - encp[3] = itoa64[i&0x3f]; i >>= 6; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; encp += 4; - i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; - - encp[3] = 0; - - return (cryptresult); -} - - -/* - * The Key Schedule, filled in by des_setkey() or setkey(). - */ -#define KS_SIZE 16 -static C_block KS[KS_SIZE]; - -/* - * Set up the key schedule from the key. - */ -int rz_des_setkey(register const char *key) { - register DCL_BLOCK(K, K0, K1); - register C_block *ptabp; - register int i; - static int des_ready = 0; - - if (!des_ready) { - rz_init_des(); - des_ready = 1; - } - - PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); - key = (char *)&KS[0]; - STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); - for (i = 1; i < 16; i++) { - key += sizeof(C_block); - STORE(K,K0,K1,*(C_block *)key); - ptabp = (C_block *)PC2ROT[Rotates[i]-1]; - PERM6464(K,K0,K1,(unsigned char *)key,ptabp); - STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); - } - return (0); -} - -/* - * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) - * iterations of DES, using the given 24-bit salt and the pre-computed key - * schedule, and store the resulting 8 chars at "out" (in == out is permitted). - * - * NOTE: the performance of this routine is critically dependent on your - * compiler and machine architecture. - */ -int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { - /* variables that we want in registers, most important first */ -#if defined(pdp11) - register int j; -#endif - register long L0, L1, R0, R1, k; - register C_block *kp; - register int ks_inc, loop_count; - C_block B; - - L0 = salt; - TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ - -#if defined(vax) || defined(pdp11) - salt = ~salt; /* "x &~ y" is faster than "x & y". */ -#define SALT (~salt) -#else -#define SALT salt -#endif - -#if defined(MUST_ALIGN) - B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; - B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; - LOAD(L,L0,L1,B); -#else - LOAD(L,L0,L1,*(C_block *)in); -#endif - LOADREG(R,R0,R1,L,L0,L1); - L0 &= 0x55555555L; - L1 &= 0x55555555L; - L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ - R0 &= 0xaaaaaaaaL; - R1 = (R1 >> 1) & 0x55555555L; - L1 = R0 | R1; /* L1 is the odd-numbered input bits */ - STORE(L,L0,L1,B); - PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ - PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ - - if (num_iter >= 0) - { /* encryption */ - kp = &KS[0]; - ks_inc = sizeof(*kp); - } - else - { /* decryption */ - num_iter = -num_iter; - kp = &KS[KS_SIZE-1]; - ks_inc = -((int) sizeof(*kp)); - } - - while (--num_iter >= 0) { - loop_count = 8; - do { - -#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) -#if defined(gould) - /* use this if B.b[i] is evaluated just once ... */ -#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); -#else -#if defined(pdp11) - /* use this if your "long" int indexing is slow */ -#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); -#else - /* use this if "k" is allocated to a register ... */ -#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); -#endif -#endif - -#define CRUNCH(p0, p1, q0, q1) \ - k = (q0 ^ q1) & SALT; \ - B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ - B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ - kp = (C_block *)((char *)kp+ks_inc); \ - \ - DOXOR(p0, p1, 0); \ - DOXOR(p0, p1, 1); \ - DOXOR(p0, p1, 2); \ - DOXOR(p0, p1, 3); \ - DOXOR(p0, p1, 4); \ - DOXOR(p0, p1, 5); \ - DOXOR(p0, p1, 6); \ - DOXOR(p0, p1, 7); - - CRUNCH(L0, L1, R0, R1); - CRUNCH(R0, R1, L0, L1); - } while (--loop_count != 0); - kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); - - - /* swap L and R */ - L0 ^= R0; L1 ^= R1; - R0 ^= L0; R1 ^= L1; - L0 ^= R0; L1 ^= R1; - } - - /* store the encrypted (or decrypted) result */ - L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); - L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); - STORE(L,L0,L1,B); - PERM6464(L,L0,L1,B.b, (C_block *)CF6464); -#if defined(MUST_ALIGN) - STORE(L,L0,L1,B); - out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; - out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; -#else - STORE(L,L0,L1,*(C_block *)out); -#endif - return (0); -} - - -/* - * Initialize various tables. This need only be done once. It could even be - * done at compile time, if the compiler were capable of that sort of thing. - */ -/* STATIC */void rz_init_des() { - register int i, j; - register long k; - register int tableno; - static unsigned char perm[64], tmp32[32]; /* "static" for speed */ - - /* - * table that converts chars "./0-9A-Za-z"to integers 0-63. - */ - for (i = 0; i < 64; i++) - a64toi[itoa64[i]] = i; - - /* - * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. - */ - for (i = 0; i < 64; i++) - perm[i] = 0; - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - k += Rotates[0]-1; - if ((k%28) < Rotates[0]) k -= 28; - k = PC1[k]; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[i] = (unsigned char) k; - } -#ifdef DEBUG_CRYPT - prtab("pc1tab", perm, 8); -#endif - rz_init_perm(PC1ROT, perm, 8, 8); - - /* - * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. - */ - for (j = 0; j < 2; j++) { - unsigned char pc2inv[64]; - for (i = 0; i < 64; i++) - perm[i] = pc2inv[i] = 0; - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - pc2inv[k-1] = i+1; - } - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - k += j; - if ((k%28) <= j) k -= 28; - perm[i] = pc2inv[k]; - } -#ifdef DEBUG_CRYPT - prtab("pc2tab", perm, 8); -#endif - rz_init_perm(PC2ROT[j], perm, 8, 8); - } - - /* - * Bit reverse, then initial permutation, then expansion. - */ - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; - if (k > 32) - k -= 32; - else if (k > 0) - k--; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[i*8+j] = (unsigned char) k; - } - } -#ifdef DEBUG_CRYPT - prtab("ietab", perm, 8); -#endif - rz_init_perm(IE3264, perm, 4, 8); - - /* - * Compression, then final permutation, then bit reverse. - */ - for (i = 0; i < 64; i++) { - k = IP[CIFP[i]-1]; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[k-1] = i+1; - } -#ifdef DEBUG_CRYPT - prtab("cftab", perm, 8); -#endif - rz_init_perm(CF6464, perm, 8, 8); - - /* - * SPE table - */ - for (i = 0; i < 48; i++) - perm[i] = P32Tr[ExpandTr[i]-1]; - for (tableno = 0; tableno < 8; tableno++) { - for (j = 0; j < 64; j++) { - k = (((j >> 0) &01) << 5)| - (((j >> 1) &01) << 3)| - (((j >> 2) &01) << 2)| - (((j >> 3) &01) << 1)| - (((j >> 4) &01) << 0)| - (((j >> 5) &01) << 4); - k = S[tableno][k]; - k = (((k >> 3)&01) << 0)| - (((k >> 2)&01) << 1)| - (((k >> 1)&01) << 2)| - (((k >> 0)&01) << 3); - for (i = 0; i < 32; i++) - tmp32[i] = 0; - for (i = 0; i < 4; i++) - tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); - k = 0; - for (i = 24; --i >= 0; ) - k = (k<<1) | tmp32[perm[i]-1]; - TO_SIX_BIT(SPE[0][tableno][j], k); - k = 0; - for (i = 24; --i >= 0; ) - k = (k<<1) | tmp32[perm[i+24]-1]; - TO_SIX_BIT(SPE[1][tableno][j], k); - } - } -} - -/* - * Initialize "perm" to represent transformation "p", which rearranges - * (perhaps with expansion and/or contraction) one packed array of bits - * (of size "chars_in" characters) into another array (of size "chars_out" - * characters). - * - * "perm" must be all-zeroes on entry to this routine. - */ -/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ - l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ - for (j = 0; j < (1<>3] |= 1<<(k&07); - } - } -} - -/* - * "setkey" routine (for backwards compatibility) - */ -int rz_setkey(register const char *key) { - register int i, j, k; - C_block keyblock; - - for (i = 0; i < 8; i++) { - k = 0; - for (j = 0; j < 8; j++) { - k <<= 1; - k |= (unsigned char)*key++; - } - keyblock.b[i] = k; - } - return (rz_des_setkey((char *)keyblock.b)); -} - -/* - * "encrypt" routine (for backwards compatibility) - */ -int rz_encrypt(register char *block, int flag) { - register int i, j, k; - C_block cblock; - - for (i = 0; i < 8; i++) { - k = 0; - for (j = 0; j < 8; j++) { - k <<= 1; - k |= (unsigned char)*block++; - } - cblock.b[i] = k; - } - if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) - return (1); - for (i = 7; i >= 0; i--) { - k = cblock.b[i]; - for (j = 7; j >= 0; j--) { - *--block = k&01; - k >>= 1; - } - } - return (0); -} - -#ifdef DEBUG_CRYPT -void prtab(char *s, unsigned char *t, int num_rows) -{ - register int i, j; - - (void)printf("%s:\n", s); - for (i = 0; i < num_rows; i++) { - for (j = 0; j < 8; j++) { - (void)printf("%3d", t[i*8+j]); - } - (void)printf("\n"); - } - (void)printf("\n"); -} -#endif diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index a0e577269..aa559b78d 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/crypt.h" +#include "game_share/ccrypt.h" #include "nel/misc/time_nl.h" #include "client.h" @@ -392,7 +392,15 @@ void clientAuthentication(CMessage &msgin, TSockId from, CCallbackNetBase &netba { if (strlen(row[0]) > 2) { - std::string salt = std::string(row[0], row[0] + 2); + std::string salt; + if (row[0][0] == '$') + { + salt = std::string(row[0], row[0] + 19); + } + else + { + salt = std::string(row[0], row[0] + 2); + } std::string cryptedVersion = CCrypt::crypt(password, salt); if (cryptedVersion == row[0]) { diff --git a/code/web/private_php/ams/autoload/users.php b/code/web/private_php/ams/autoload/users.php index ffc04ace2..67ed9af88 100644 --- a/code/web/private_php/ams/autoload/users.php +++ b/code/web/private_php/ams/autoload/users.php @@ -252,8 +252,8 @@ class Users{ * @param $length the length of the SALT which is by default 2 * @return a random salt of 2 chars */ - public static function generateSALT( $length = 2 ) - { + public static function generateSALT( $length = 16 ) + { // start with a blank salt $salt = ""; // define possible characters - any character in this string can be @@ -282,6 +282,10 @@ class Users{ } } // done! + if ($length > 2) + { + $salt = '$6$'.$salt; + } return $salt; } diff --git a/code/web/private_php/setup/sql/nel_00001.sql b/code/web/private_php/setup/sql/nel_00001.sql index 70e14419b..15743b1b9 100644 --- a/code/web/private_php/setup/sql/nel_00001.sql +++ b/code/web/private_php/setup/sql/nel_00001.sql @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `shard` ( CREATE TABLE IF NOT EXISTS `user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `ShardId` int(10) NOT NULL DEFAULT '-1', `State` enum('Offline','Online') NOT NULL DEFAULT 'Offline', `Privilege` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_ams_00001.sql b/code/web/private_php/setup/sql/nel_ams_00001.sql index c2b0a8895..38085bc1f 100644 --- a/code/web/private_php/setup/sql/nel_ams_00001.sql +++ b/code/web/private_php/setup/sql/nel_ams_00001.sql @@ -29,7 +29,7 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT '1', `FirstName` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/public_php/ams/autoload/webusers.php b/code/web/public_php/ams/autoload/webusers.php index b01ddf02d..ebc654f5d 100644 --- a/code/web/public_php/ams/autoload/webusers.php +++ b/code/web/public_php/ams/autoload/webusers.php @@ -80,7 +80,14 @@ class WebUsers extends Users{ $dbw = new DBLayer("web"); $statement = $dbw->select("ams_user", array('value' => $value),"Login=:value OR Email=:value"); $row = $statement->fetch(); - $salt = substr($row['Password'],0,2); + if ($row['Password'][0] == '$') + { + $salt = substr($row['Password'], 0, 19); + } + else + { + $salt = substr($row['Password'], 0, 2); + } $hashed_input_pass = crypt($password, $salt); if($hashed_input_pass == $row['Password']){ return $row; diff --git a/code/web/public_php/ams/sql/db.sql b/code/web/public_php/ams/sql/db.sql index ccc214125..6620a9856 100644 --- a/code/web/public_php/ams/sql/db.sql +++ b/code/web/public_php/ams/sql/db.sql @@ -5,7 +5,7 @@ DROP TABLE IF EXISTS ams_user; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL AUTO_INCREMENT, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT 1, PRIMARY KEY (`UId`) @@ -21,4 +21,4 @@ CREATE TABLE ams_querycache ( `SID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `type` VARCHAR( 64 ) NOT NULL , `query` VARCHAR( 512 ) NOT NULL -); \ No newline at end of file +); diff --git a/code/web/public_php/login/r2_login.php b/code/web/public_php/login/r2_login.php index ee4b68819..fdce63958 100644 --- a/code/web/public_php/login/r2_login.php +++ b/code/web/public_php/login/r2_login.php @@ -14,6 +14,19 @@ include_once('../ring/join_shard.php'); + function get_salt($password) + { + if ($password[0] == '$') + { + $salt = substr($password, 0, 19); + } + else + { + $salt = substr($password, 0, 2); + } + return $salt; + } + // see errorMsg function errorMsgBlock($errNum=GENERIC_ERROR_NUM) // $mixedArgs { @@ -331,7 +344,7 @@ else { $row = mysqli_fetch_assoc ($result); - $salt = substr($row["Password"],0,2); + $salt = get_salt($row["Password"]); if (($cp && $row["Password"] == $password) || (!$cp && $row["Password"] == crypt($password, $salt))) { // Store the real login (with correct case) @@ -488,7 +501,7 @@ else { $res_array = mysqli_fetch_assoc($result); - $salt = substr($res_array['Password'], 0, 2); + $salt = get_salt($res_array['Password']); } echo "1:".$salt; From 5c2cc95dc98390addc04f19f83b6ba4fc3ee98cb Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Tue, 16 Sep 2014 22:43:36 +0200 Subject: [PATCH 010/344] Fixing the database migration system for issue #206 --HG-- branch : sha512-auth --- code/web/private_php/setup/sql/nel_00001.sql | 2 +- code/web/private_php/setup/sql/nel_00004.sql | 1 + code/web/private_php/setup/sql/nel_ams_00001.sql | 2 +- code/web/private_php/setup/sql/nel_ams_00002.sql | 1 + code/web/public_php/ams/sql/db.sql | 2 +- code/web/public_php/setup/database.php | 4 ++-- 6 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 code/web/private_php/setup/sql/nel_00004.sql create mode 100644 code/web/private_php/setup/sql/nel_ams_00002.sql diff --git a/code/web/private_php/setup/sql/nel_00001.sql b/code/web/private_php/setup/sql/nel_00001.sql index 15743b1b9..70e14419b 100644 --- a/code/web/private_php/setup/sql/nel_00001.sql +++ b/code/web/private_php/setup/sql/nel_00001.sql @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `shard` ( CREATE TABLE IF NOT EXISTS `user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `ShardId` int(10) NOT NULL DEFAULT '-1', `State` enum('Offline','Online') NOT NULL DEFAULT 'Offline', `Privilege` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_00004.sql b/code/web/private_php/setup/sql/nel_00004.sql new file mode 100644 index 000000000..8d48a4c8c --- /dev/null +++ b/code/web/private_php/setup/sql/nel_00004.sql @@ -0,0 +1 @@ +ALTER TABLE `user` MODIFY `Password` VARCHAR(106); diff --git a/code/web/private_php/setup/sql/nel_ams_00001.sql b/code/web/private_php/setup/sql/nel_ams_00001.sql index 38085bc1f..c2b0a8895 100644 --- a/code/web/private_php/setup/sql/nel_ams_00001.sql +++ b/code/web/private_php/setup/sql/nel_ams_00001.sql @@ -29,7 +29,7 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT '1', `FirstName` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_ams_00002.sql b/code/web/private_php/setup/sql/nel_ams_00002.sql new file mode 100644 index 000000000..b1a9c9df4 --- /dev/null +++ b/code/web/private_php/setup/sql/nel_ams_00002.sql @@ -0,0 +1 @@ +ALTER TABLE `ams_user` MODIFY `Password` VARCHAR(106); diff --git a/code/web/public_php/ams/sql/db.sql b/code/web/public_php/ams/sql/db.sql index 6620a9856..b52ae65ed 100644 --- a/code/web/public_php/ams/sql/db.sql +++ b/code/web/public_php/ams/sql/db.sql @@ -5,7 +5,7 @@ DROP TABLE IF EXISTS ams_user; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL AUTO_INCREMENT, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT 1, PRIMARY KEY (`UId`) diff --git a/code/web/public_php/setup/database.php b/code/web/public_php/setup/database.php index 6a1b836ea..3e195f2b8 100644 --- a/code/web/public_php/setup/database.php +++ b/code/web/public_php/setup/database.php @@ -1,11 +1,11 @@ Date: Wed, 17 Sep 2014 20:49:26 +0200 Subject: [PATCH 011/344] Added the rest of the expression files. --HG-- branch : dfighter-tools --- .../studio/src/plugins/gui_editor/expressions/abs.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/band.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/bnot.xml | 8 ++++++++ .../studio/src/plugins/gui_editor/expressions/bor.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/bxor.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/dbcount.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/depends.xml | 8 ++++++++ .../plugins/gui_editor/expressions/extSign11To64.xml | 8 ++++++++ .../plugins/gui_editor/expressions/extSign8To64.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getAlpha.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getBlue.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getGreen.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getRed.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getbit.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/getprop.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/identity.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/ilinear.xml | 10 ++++++++++ .../studio/src/plugins/gui_editor/expressions/int.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/intToColor.xml | 8 ++++++++ .../plugins/gui_editor/expressions/isFinalVersion.xml | 5 +++++ .../src/plugins/gui_editor/expressions/localize.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/makeRGB.xml | 11 +++++++++++ .../studio/src/plugins/gui_editor/expressions/max.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/min.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/mod.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/oldvalue.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/rand.xml | 5 +++++ .../studio/src/plugins/gui_editor/expressions/sal.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/sar.xml | 9 +++++++++ .../gui_editor/expressions/secondsToTimeString.xml | 8 ++++++++ .../expressions/secondsToTimeStringShort.xml | 8 ++++++++ .../studio/src/plugins/gui_editor/expressions/shl.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/shr.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/str.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/switch.xml | 10 ++++++++++ 35 files changed, 293 insertions(+) create mode 100644 code/studio/src/plugins/gui_editor/expressions/abs.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/band.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bnot.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bxor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/dbcount.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/depends.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getAlpha.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getBlue.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getGreen.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getRed.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getbit.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getprop.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/identity.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/ilinear.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/int.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/intToColor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/localize.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/makeRGB.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/max.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/min.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/mod.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/oldvalue.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/rand.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/sal.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/sar.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/shl.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/shr.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/str.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/switch.xml diff --git a/code/studio/src/plugins/gui_editor/expressions/abs.xml b/code/studio/src/plugins/gui_editor/expressions/abs.xml new file mode 100644 index 000000000..5a5fe2c70 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/abs.xml @@ -0,0 +1,8 @@ + +Mathematical +abs +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/band.xml b/code/studio/src/plugins/gui_editor/expressions/band.xml new file mode 100644 index 000000000..1ce1534ec --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/band.xml @@ -0,0 +1,9 @@ + +Bits +band +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bnot.xml b/code/studio/src/plugins/gui_editor/expressions/bnot.xml new file mode 100644 index 000000000..bde93f6e7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bnot.xml @@ -0,0 +1,8 @@ + +Bits +bnot +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bor.xml b/code/studio/src/plugins/gui_editor/expressions/bor.xml new file mode 100644 index 000000000..906678bc2 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bor.xml @@ -0,0 +1,9 @@ + +Bits +bor +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bxor.xml b/code/studio/src/plugins/gui_editor/expressions/bxor.xml new file mode 100644 index 000000000..2bfedb167 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bxor.xml @@ -0,0 +1,9 @@ + +Bits +bxor +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/dbcount.xml b/code/studio/src/plugins/gui_editor/expressions/dbcount.xml new file mode 100644 index 000000000..df8e0aac6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/dbcount.xml @@ -0,0 +1,8 @@ + +Database +dbcount +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/depends.xml b/code/studio/src/plugins/gui_editor/expressions/depends.xml new file mode 100644 index 000000000..225d48dd6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/depends.xml @@ -0,0 +1,8 @@ + +Logical +depends +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml b/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml new file mode 100644 index 000000000..e227fc8cb --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml @@ -0,0 +1,8 @@ + +Bits +extSign11To64 +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml b/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml new file mode 100644 index 000000000..f029c15fc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml @@ -0,0 +1,8 @@ + +Bits +extSign8To64 +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml b/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml new file mode 100644 index 000000000..acdc5e322 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml @@ -0,0 +1,8 @@ + +Color +getAlpha +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getBlue.xml b/code/studio/src/plugins/gui_editor/expressions/getBlue.xml new file mode 100644 index 000000000..be35a6c17 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getBlue.xml @@ -0,0 +1,8 @@ + +Color +getBlue +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getGreen.xml b/code/studio/src/plugins/gui_editor/expressions/getGreen.xml new file mode 100644 index 000000000..da8e16bc4 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getGreen.xml @@ -0,0 +1,8 @@ + +Color +getGreen +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getRed.xml b/code/studio/src/plugins/gui_editor/expressions/getRed.xml new file mode 100644 index 000000000..3a918857b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getRed.xml @@ -0,0 +1,8 @@ + +Color +getRed +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getbit.xml b/code/studio/src/plugins/gui_editor/expressions/getbit.xml new file mode 100644 index 000000000..6cc08e10b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getbit.xml @@ -0,0 +1,9 @@ + +Bits +getbit +false + +Integer +Bit + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getprop.xml b/code/studio/src/plugins/gui_editor/expressions/getprop.xml new file mode 100644 index 000000000..1098635aa --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getprop.xml @@ -0,0 +1,8 @@ + +Database +getprop +false + +property + + diff --git a/code/studio/src/plugins/gui_editor/expressions/identity.xml b/code/studio/src/plugins/gui_editor/expressions/identity.xml new file mode 100644 index 000000000..cd36facd6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/identity.xml @@ -0,0 +1,8 @@ + +Mathematical +identity +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ilinear.xml b/code/studio/src/plugins/gui_editor/expressions/ilinear.xml new file mode 100644 index 000000000..9284b4e82 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ilinear.xml @@ -0,0 +1,10 @@ + +Mathematical +ilinear +false + +Interpolant +Start +End + + diff --git a/code/studio/src/plugins/gui_editor/expressions/int.xml b/code/studio/src/plugins/gui_editor/expressions/int.xml new file mode 100644 index 000000000..117225b6b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/int.xml @@ -0,0 +1,8 @@ + +Mathematical +int +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/intToColor.xml b/code/studio/src/plugins/gui_editor/expressions/intToColor.xml new file mode 100644 index 000000000..2993365d7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/intToColor.xml @@ -0,0 +1,8 @@ + +Color +intToColor +false + +Integer + + diff --git a/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml b/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml new file mode 100644 index 000000000..3c9ddc64c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml @@ -0,0 +1,5 @@ + +Nel +isFinalVersion +false + diff --git a/code/studio/src/plugins/gui_editor/expressions/localize.xml b/code/studio/src/plugins/gui_editor/expressions/localize.xml new file mode 100644 index 000000000..f8d3f0f4e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/localize.xml @@ -0,0 +1,8 @@ + +Localization +localize +false + +String + + diff --git a/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml b/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml new file mode 100644 index 000000000..a2cb2d352 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml @@ -0,0 +1,11 @@ + +Color +makeRGB +false + +R +G +B +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/max.xml b/code/studio/src/plugins/gui_editor/expressions/max.xml new file mode 100644 index 000000000..6592aecd7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/max.xml @@ -0,0 +1,9 @@ + +Mathematical +max +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/min.xml b/code/studio/src/plugins/gui_editor/expressions/min.xml new file mode 100644 index 000000000..753955ed9 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/min.xml @@ -0,0 +1,9 @@ + +Mathematical +min +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/mod.xml b/code/studio/src/plugins/gui_editor/expressions/mod.xml new file mode 100644 index 000000000..d306f3371 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/mod.xml @@ -0,0 +1,9 @@ + +Mathematical +mod +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml b/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml new file mode 100644 index 000000000..299706c79 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml @@ -0,0 +1,8 @@ + +Database +oldvalue +false + +property + + diff --git a/code/studio/src/plugins/gui_editor/expressions/rand.xml b/code/studio/src/plugins/gui_editor/expressions/rand.xml new file mode 100644 index 000000000..b284dc241 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/rand.xml @@ -0,0 +1,5 @@ + +Mathematical +rand +false + diff --git a/code/studio/src/plugins/gui_editor/expressions/sal.xml b/code/studio/src/plugins/gui_editor/expressions/sal.xml new file mode 100644 index 000000000..3190f4420 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sal.xml @@ -0,0 +1,9 @@ + +Bits +sal +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/sar.xml b/code/studio/src/plugins/gui_editor/expressions/sar.xml new file mode 100644 index 000000000..75fcd57d7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sar.xml @@ -0,0 +1,9 @@ + +Bits +sar +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml new file mode 100644 index 000000000..fda7dd1c8 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml @@ -0,0 +1,8 @@ + +Time +secondsToTimeString +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml new file mode 100644 index 000000000..042cf06de --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml @@ -0,0 +1,8 @@ + +Time +secondsToTimeStringShort +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/shl.xml b/code/studio/src/plugins/gui_editor/expressions/shl.xml new file mode 100644 index 000000000..653a142a6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/shl.xml @@ -0,0 +1,9 @@ + +Bits +shl +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/shr.xml b/code/studio/src/plugins/gui_editor/expressions/shr.xml new file mode 100644 index 000000000..435816f6e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/shr.xml @@ -0,0 +1,9 @@ + +Bits +shr +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/str.xml b/code/studio/src/plugins/gui_editor/expressions/str.xml new file mode 100644 index 000000000..c98ae89eb --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/str.xml @@ -0,0 +1,9 @@ + +String +str +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/switch.xml b/code/studio/src/plugins/gui_editor/expressions/switch.xml new file mode 100644 index 000000000..19f94f9d3 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/switch.xml @@ -0,0 +1,10 @@ + +Logical +switch +true + +A +B +C + + From 4d760c751586bbe57bb4f3017ea38ef810e3b3b9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 20:51:45 +0200 Subject: [PATCH 012/344] When removing the root node, don't retain the pointer to it... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_editor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 392bdca41..858c63c9c 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -176,6 +176,9 @@ void ExpressionEditor::onDeleteSelection() } } + if( item == m_pvt->m_root ) + m_pvt->m_root = NULL; + m_scene->removeItem( item ); delete item; } From 012fae0ef687f7f96840d6ed4ec2f334b035c861 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 20:54:16 +0200 Subject: [PATCH 013/344] don't evaluate the child-nodes when there are none, directly just return () --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_node.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8a0ef774b..80ef571e2 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -297,9 +297,16 @@ QString ExpressionNode::build() const QStringList l = m_name.split( ' ' ); result = l[ 0 ]; - result += "( "; int c = m_links.count(); + if( c == 1 ) + { + result += "()"; + return result; + } + + result += "( "; + for( int i = 1; i < c; i++ ) { ExpressionLink *link = m_links[ i ]; From 780394f989c129688570c2d83495c5485ac90102 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 22:36:58 +0200 Subject: [PATCH 014/344] Fixed Object Viewer build. --HG-- branch : dfighter-tools --- code/studio/src/plugins/object_viewer/object_viewer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/object_viewer/object_viewer.cpp b/code/studio/src/plugins/object_viewer/object_viewer.cpp index 566869e84..240a0d9e9 100644 --- a/code/studio/src/plugins/object_viewer/object_viewer.cpp +++ b/code/studio/src/plugins/object_viewer/object_viewer.cpp @@ -120,7 +120,7 @@ void CObjectViewer::init( NL3D::UDriver *driver ) NL3D::CBloomEffect::instance().setDriver(_Driver); NL3D::CBloomEffect::instance().setScene(_Scene); - NL3D::CBloomEffect::instance().init(!_Direct3D); + NL3D::CBloomEffect::instance().init(); NL3D::CBloomEffect::instance().setDensityBloom(uint8(_BloomDensity)); NL3D::CBloomEffect::instance().setSquareBloom(_BloomSquare); @@ -172,7 +172,7 @@ void CObjectViewer::renderDriver() // Render the scene. if((NL3D::CBloomEffect::instance().getDriver() != 0) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().initBloom(); + NL3D::CBloomEffect::instance().init(); } _Driver->clearBuffers(_BackgroundColor); } @@ -184,8 +184,7 @@ void CObjectViewer::renderScene() if((NL3D::CBloomEffect::instance().getDriver() != 0) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().endBloom(); - NL3D::CBloomEffect::instance().endInterfacesDisplayBloom(); + NL3D::CBloomEffect::instance().applyBloom(); } } From 0ed6e8111bbc136b9879e97ddb91ed17490f2ec1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 21:55:34 +0200 Subject: [PATCH 015/344] Increment web version --HG-- branch : sha512-auth --- code/web/public_php/setup/version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/public_php/setup/version.php b/code/web/public_php/setup/version.php index 3204d1e7b..476c514f0 100644 --- a/code/web/public_php/setup/version.php +++ b/code/web/public_php/setup/version.php @@ -1,6 +1,6 @@ Date: Fri, 19 Sep 2014 19:48:17 +0200 Subject: [PATCH 016/344] Add extra search paths --HG-- branch : develop --- code/nel/tools/build_gamedata/processes/clodbank/0_setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py b/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py index 532113523..a4ab0f4df 100755 --- a/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py +++ b/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py @@ -74,6 +74,8 @@ cfgOut.write("{\n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ClodExportDirectory + "\", \n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + SkelExportDirectory + "\", \n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + AnimBuildDirectory + "\", \n") +cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ShapeOptimizedBuildDirectory + "\", \n") +cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ShapeWithCoarseMeshBuildDirectory + "\", \n") cfgOut.write("};\n") cfgOut.write("\n") cfgOut.close() From 5b7bc8cc549b6996a5893a24316e52fe5229607f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 20 Sep 2014 20:51:08 +0200 Subject: [PATCH 017/344] GUI Editor should no longer crash on Linux --HG-- branch : dfighter-tools --- .../plugins/core/Nel3DWidget/nel3d_widget.cpp | 3 +-- .../src/plugins/core/Nel3DWidget/nel3d_widget.h | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp index dc0bb858b..bc83b5d78 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp @@ -14,7 +14,6 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . - #include "nel3d_widget.h" #include "nel/3d/u_driver.h" #include "nel/3d/text_context.h" @@ -29,7 +28,7 @@ #include Nel3DWidget::Nel3DWidget( QWidget *parent ) : -QWidget( parent ) +NEL3DWIDGET( parent ) { driver = NULL; textContext = NULL; diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h index 059e1b738..afed4cf65 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h @@ -18,10 +18,22 @@ #ifndef NEL3D_WIDGET_H #define NEL3D_WIDGET_H -#include #include "nel/misc/types_nl.h" #include +#ifdef NEL3DWIDGET +#undef NEL3DWIDGET +#endif + +#ifdef NL_OS_WINDOWS +#include +#define NEL3DWIDGET QWidget +#else +#include +#define NEL3DWIDGET QGLWidget +#endif + + #include "../core_global.h" namespace NL3D @@ -31,7 +43,7 @@ namespace NL3D } /// Nel 3D interface to Qt -class CORE_EXPORT Nel3DWidget : public QWidget +class CORE_EXPORT Nel3DWidget : public QGLWidget { Q_OBJECT public: From 648b2cb46b39097bc98997e26f75aa13d4150efd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 20 Sep 2014 20:55:30 +0200 Subject: [PATCH 018/344] oups --HG-- branch : dfighter-tools --- code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h index afed4cf65..254001b25 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h @@ -43,7 +43,7 @@ namespace NL3D } /// Nel 3D interface to Qt -class CORE_EXPORT Nel3DWidget : public QGLWidget +class CORE_EXPORT Nel3DWidget : public NEL3DWIDGET { Q_OBJECT public: From cec992c4a59d360b66e7b7d3e18b75b6542d6b88 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 21 Sep 2014 12:31:02 +0200 Subject: [PATCH 019/344] Fix double delete --HG-- branch : develop --- .../server/build_world_packed_col/build_world_packed_col.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp index 9bd4f7f3c..f03489196 100644 --- a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp @@ -211,7 +211,7 @@ int main(int argc, char* argv[]) catch(const EStream &) { mustRebuild = true; // damaged file or bad version ? -> force rebuild - delete packedIsland; // remove whatever was serialized + // delete packedIsland; // remove whatever was serialized // NOPE. smart pointer packedIsland = new CPackedWorldHolder; } } From eff07ebbf9b13459b587d84315f81410fdb7641b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 21 Sep 2014 13:24:33 +0200 Subject: [PATCH 020/344] Add an assert --HG-- branch : develop --- .../tools/client/r2_islands_textures/screenshot_islands.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index 8228c3e2e..4f167ea9c 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -1784,6 +1784,7 @@ void CScreenshotIslands::buildBackTextureHLS(const std::string & islandName, con // keep more filled eighth of circle + nlassert(!sortedHLS.empty()); // If it crashes here, you may be missing .zonel's. itHLS = sortedHLS.begin(); uint h, s, v; RGB2HSV(*itHLS, h, s, v); From f61438d7d966df264f853b6b636b34c9f319de88 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 22 Sep 2014 23:24:48 +0200 Subject: [PATCH 021/344] Studio should no longer crash when multiple plugins that use LIGO are loaded. LIGO classes are now guarded against multiple registrations. If it's tried log messages are generated. Mission Compiler and World Editor will now apply their own LIGO configs when the user switches to their tab. --HG-- branch : dfighter-tools --- code/nel/src/ligo/primitive.cpp | 11 ++++ .../src/plugins/core/context_manager.cpp | 4 +- code/studio/src/plugins/core/icontext.h | 2 + .../mission_compiler_main_window.cpp | 5 ++ .../mission_compiler_main_window.h | 2 + .../mission_compiler_plugin.h | 6 ++ .../world_editor/world_editor_plugin.cpp | 65 ++++++++++--------- .../world_editor/world_editor_plugin.h | 6 +- .../world_editor/world_editor_window.h | 1 + 9 files changed, 69 insertions(+), 33 deletions(-) diff --git a/code/nel/src/ligo/primitive.cpp b/code/nel/src/ligo/primitive.cpp index 9cf7df13f..ba9b69435 100644 --- a/code/nel/src/ligo/primitive.cpp +++ b/code/nel/src/ligo/primitive.cpp @@ -2738,8 +2738,17 @@ CPrimitiveContext::CPrimitiveContext(): } +static bool LIGORegistered = false; + + void Register () { + if( LIGORegistered ) + { + nlinfo( "LIGO classes have already been registered." ); + return; + } + NLMISC_REGISTER_CLASS(CPropertyString); NLMISC_REGISTER_CLASS(CPropertyStringArray); NLMISC_REGISTER_CLASS(CPropertyColor); @@ -2748,6 +2757,8 @@ void Register () NLMISC_REGISTER_CLASS(CPrimPath); NLMISC_REGISTER_CLASS(CPrimZone); NLMISC_REGISTER_CLASS(CPrimAlias); + + LIGORegistered = true; } // *************************************************************************** diff --git a/code/studio/src/plugins/core/context_manager.cpp b/code/studio/src/plugins/core/context_manager.cpp index 3b02b411c..203738faf 100644 --- a/code/studio/src/plugins/core/context_manager.cpp +++ b/code/studio/src/plugins/core/context_manager.cpp @@ -143,6 +143,8 @@ void ContextManager::currentTabChanged(int index) if (index >= 0) { IContext *context = d->m_contexts.at(index); + context->onActivated(); + Q_EMIT currentContextChanged(context); } } @@ -158,4 +160,4 @@ int ContextManager::indexOf(const QString &id) const return -1; } -} /* namespace Core */ \ No newline at end of file +} /* namespace Core */ diff --git a/code/studio/src/plugins/core/icontext.h b/code/studio/src/plugins/core/icontext.h index d2cbb412c..616e0db14 100644 --- a/code/studio/src/plugins/core/icontext.h +++ b/code/studio/src/plugins/core/icontext.h @@ -69,6 +69,8 @@ public: virtual void newDocument(){} virtual void close(){} + + virtual void onActivated(){} }; } // namespace Core diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp index 10985aa38..efadd3949 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp @@ -484,6 +484,11 @@ void MissionCompilerMainWindow::saveConfig() { settings->sync(); } +void MissionCompilerMainWindow::onActivated() +{ + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; +} + void MissionCompilerMainWindow::handleChangedSettings() { QStringList servers; diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h index dc19db1c6..3d59e206a 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h @@ -31,6 +31,8 @@ public: void saveConfig(); QUndoStack *getUndoStack() { return m_undoStack; } + void onActivated(); + typedef std::map TMissionContainer; public Q_SLOTS: diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h b/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h index 2ad92b40f..cc2cac47c 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h @@ -83,6 +83,12 @@ public: virtual void open() {} + void onActivated() + { + m_missionCompilerMainWindow->onActivated(); + } + + MissionCompilerMainWindow *m_missionCompilerMainWindow; }; diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp index 3170bce60..722c14733 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp @@ -54,36 +54,6 @@ bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManage WorldEditorSettingsPage *weSettings = new WorldEditorSettingsPage(this); addAutoReleasedObject(weSettings); - - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(Constants::WORLD_EDITOR_SECTION); - m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); - m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); - m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt(); - QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString(); - settings->endGroup(); - try - { - // Search path of file world_editor_classes.xml - std::string ligoPath = NLMISC::CPath::lookup(fileName.toUtf8().constData()); - // Init LIGO - m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true); - NLLIGO::Register(); - NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; - } - catch (NLMISC::Exception &e) - { - *errorString = tr("(%1)").arg(e.what()); - return false; - } - - // Reset - m_ligoConfig.resetPrimitiveConfiguration (); - - // TODO: get file names! from settings - m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); - - addAutoReleasedObject(new WorldEditorContext(this)); return true; } @@ -117,6 +87,34 @@ WorldEditorContext::WorldEditorContext(QObject *parent) m_worldEditorWindow(0) { m_worldEditorWindow = new WorldEditorWindow(); + + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::WORLD_EDITOR_SECTION); + m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); + m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); + m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt(); + QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString(); + settings->endGroup(); + try + { + // Search path of file world_editor_classes.xml + std::string ligoPath = NLMISC::CPath::lookup(fileName.toUtf8().constData()); + // Init LIGO + m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true); + NLLIGO::Register(); + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; + } + catch (NLMISC::Exception &e) + { + nlinfo( "Error starting LIGO." ); + } + + // Reset + m_ligoConfig.resetPrimitiveConfiguration (); + + // TODO: get file names! from settings + m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); + } QUndoStack *WorldEditorContext::undoStack() @@ -124,6 +122,11 @@ QUndoStack *WorldEditorContext::undoStack() return m_worldEditorWindow->undoStack(); } +void WorldEditorContext::onActivated() +{ + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; +} + void WorldEditorContext::open() { m_worldEditorWindow->open(); @@ -136,4 +139,4 @@ QWidget *WorldEditorContext::widget() } -Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin) \ No newline at end of file +Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin) diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.h b/code/studio/src/plugins/world_editor/world_editor_plugin.h index 686b87e14..cfb5448e3 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.h +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.h @@ -59,7 +59,6 @@ protected: NLMISC::CLibraryContext *m_libContext; private: - NLLIGO::CLigoConfig m_ligoConfig; ExtensionSystem::IPluginManager *m_plugMan; QList m_autoReleaseObjects; }; @@ -88,9 +87,14 @@ public: virtual QUndoStack *undoStack(); + void onActivated(); + virtual QWidget *widget(); WorldEditorWindow *m_worldEditorWindow; + +private: + NLLIGO::CLigoConfig m_ligoConfig; }; } // namespace WorldEditor diff --git a/code/studio/src/plugins/world_editor/world_editor_window.h b/code/studio/src/plugins/world_editor/world_editor_window.h index 60a6a988a..9080187f9 100644 --- a/code/studio/src/plugins/world_editor/world_editor_window.h +++ b/code/studio/src/plugins/world_editor/world_editor_window.h @@ -46,6 +46,7 @@ public: ~WorldEditorWindow(); QUndoStack *undoStack() const; + void onActivated(); void maybeSave(); Q_SIGNALS: From e67e9594e1efe4e298c37b62574e4445f0ec693f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 22 Sep 2014 23:41:55 +0200 Subject: [PATCH 022/344] Call the onActivate method of the current context after all plugins are initialized. --HG-- branch : dfighter-tools --- code/studio/src/plugins/core/main_window.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/core/main_window.cpp b/code/studio/src/plugins/core/main_window.cpp index 4ccd32564..c181376e8 100644 --- a/code/studio/src/plugins/core/main_window.cpp +++ b/code/studio/src/plugins/core/main_window.cpp @@ -108,8 +108,14 @@ void MainWindow::extensionsInitialized() readSettings(); connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext *)), this, SLOT(updateContext(Core::IContext *))); - if (m_contextManager->currentContext() != NULL) - updateContext(m_contextManager->currentContext()); + + Core::IContext *context = m_contextManager->currentContext(); + if (context != NULL) + { + updateContext(context); + context->onActivated(); + } + show(); } From 7ef9920bace7e1eceab2cc9f64d9e942ebf24e8a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 23 Sep 2014 00:16:57 +0200 Subject: [PATCH 023/344] Instantiate the Wold Editor window after the LIGO setup. --HG-- branch : dfighter-tools --- code/studio/src/plugins/world_editor/world_editor_plugin.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp index 722c14733..9b9622d00 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp @@ -86,9 +86,7 @@ WorldEditorContext::WorldEditorContext(QObject *parent) : IContext(parent), m_worldEditorWindow(0) { - m_worldEditorWindow = new WorldEditorWindow(); - - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Constants::WORLD_EDITOR_SECTION); m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); @@ -115,6 +113,7 @@ WorldEditorContext::WorldEditorContext(QObject *parent) // TODO: get file names! from settings m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); + m_worldEditorWindow = new WorldEditorWindow(); } QUndoStack *WorldEditorContext::undoStack() From e714e37c4c9f331069c03b10a64c3fcdd441a5f4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 13:54:02 +0200 Subject: [PATCH 024/344] Fix EGS sheet rebuild crashes --HG-- branch : develop --- .../egs_sheets/egs_static_game_item.cpp | 90 +++++++++---------- .../egs_sheets/egs_static_game_item.h | 4 +- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp index f36fe91ab..42517c190 100644 --- a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp +++ b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp @@ -237,24 +237,12 @@ void SItemSpecialEffects::serial(class NLMISC::IStream &f) //-------------------------------------------------------------- // init() //-------------------------------------------------------------- -void CStaticItem::init() +void CStaticItem::init(bool doDelete) { Family = ITEMFAMILY::UNDEFINED; Type = ITEM_TYPE::UNDEFINED; - Armor = NULL; - MeleeWeapon = NULL; - RangeWeapon = NULL; - Ammo = NULL; - Shield = NULL; - TamingTool = NULL; - Mp = NULL; - GuildOption = NULL; - Cosmetics = NULL; - ItemServiceData = NULL; - ConsumableItem = NULL; - XpCatalyser = NULL; - CommandTicket = NULL; + clearPtrs(doDelete); Skill = SKILLS::unknown; MinSkill = 0; @@ -287,16 +275,54 @@ void CStaticItem::init() RequiredCharacQualityFactor = 0.0f; RequiredCharacQualityOffset = 0; - ItemSpecialEffects = NULL; } // init // +// *************************************************************************** +void CStaticItem::clearPtrs(bool doDelete) +{ + if (doDelete) + { + delete Armor; + delete MeleeWeapon; + delete RangeWeapon; + delete Ammo; + delete Shield; + delete TamingTool; + delete Mp; + delete GuildOption; + delete Cosmetics; + delete ItemServiceData; + delete ConsumableItem; + delete XpCatalyser; + delete CommandTicket; + delete ItemSpecialEffects; + } + + Armor = NULL; + MeleeWeapon = NULL; + RangeWeapon = NULL; + Ammo = NULL; + Shield = NULL; + TamingTool = NULL; + Mp = NULL; + GuildOption = NULL; + Cosmetics = NULL; + ItemServiceData = NULL; + ConsumableItem = NULL; + XpCatalyser = NULL; + CommandTicket = NULL; + ItemSpecialEffects = NULL; +} + //-------------------------------------------------------------- // copy constructor //-------------------------------------------------------------- CStaticItem::CStaticItem( const CStaticItem& itm ) { + clearPtrs(false); + *this = itm; if(itm.Armor) { @@ -1443,6 +1469,9 @@ void CStaticItem::readGeorges (const NLMISC::CSmartPtr &form, if (form == NULL) return; + // Clear pointers to previous data + clearPtrs(true); + // Get the root node, always exist UFormElm &root = form->getRootNode (); @@ -1993,37 +2022,6 @@ float CStaticItem::getBaseWeight() const } #endif -// *************************************************************************** -void CStaticItem::clearPtrs(bool doDelete) -{ - if(doDelete) - { - if (Ammo != NULL ) delete Ammo; - if (Armor != NULL ) delete Armor; - if (MeleeWeapon != NULL ) delete MeleeWeapon; - if (RangeWeapon != NULL ) delete RangeWeapon; - if (Cosmetics != NULL ) delete Cosmetics; - if (Mp != NULL ) delete Mp; - if (GuildOption != NULL ) delete GuildOption; - if (Shield != NULL ) delete Shield; - if (TamingTool != NULL) delete TamingTool; - if (ItemServiceData != NULL) delete ItemServiceData; - if (CommandTicket != NULL) delete CommandTicket; - } - - Ammo = NULL; - Armor = NULL; - MeleeWeapon = NULL; - RangeWeapon = NULL; - Cosmetics = NULL; - Mp = NULL; - GuildOption = NULL; - Shield = NULL; - TamingTool = NULL; - ItemServiceData = NULL; - CommandTicket = NULL; -} - uint32 CStaticItem::getMaxStackSize() const { diff --git a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h index ddea7be9c..96aae2e98 100644 --- a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h +++ b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h @@ -812,13 +812,13 @@ public: public: /// Constructor - CStaticItem() { init(); } + CStaticItem() { init(false); } /// copy constructor CStaticItem( const CStaticItem& itm ); /// init method - void init(); + void init(bool doDelete = true); /// destructor virtual ~CStaticItem(); From cb022c6bbbc6c4ff322d0eda8f757d34e822cc70 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 18:18:14 +0200 Subject: [PATCH 025/344] Remove debug message --HG-- branch : develop --- code/ryzom/client/src/progress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/src/progress.cpp b/code/ryzom/client/src/progress.cpp index 8b5f72941..2631984e7 100644 --- a/code/ryzom/client/src/progress.cpp +++ b/code/ryzom/client/src/progress.cpp @@ -225,7 +225,7 @@ void CProgress::internalProgress (float value) if (!stereoHMD || StereoDisplay->wantInterface2D()) { - nldebug("Draw progress 2D"); + // nldebug("Draw progress 2D"); // Font factor float fontFactor = 1; From 6551881171338bfbaece82c122b625aab0171d8a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 19:47:06 +0200 Subject: [PATCH 026/344] Handle GUI event only once --HG-- branch : develop --- code/nel/src/gui/widget_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e3f1064fa..18a1f066f 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2313,7 +2313,9 @@ namespace NLGUI getCapturePointerLeft() != getCapturePointerRight() ) handled|= getCapturePointerRight()->handleEvent(evnt); - if( _CapturedView != NULL ) + if( _CapturedView != NULL && + _CapturedView != getCapturePointerLeft() && + _CapturedView != getCapturePointerRight() ) _CapturedView->handleEvent( evnt ); CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); From 27cbd59a0fae25bb3505a9917385bf3a0ee74ec4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 24 Sep 2014 01:07:12 +0200 Subject: [PATCH 027/344] Add some more practical data build batch scripts --HG-- branch : develop --- code/nel/tools/build_gamedata/characters_dev.bat | 11 +++++++++++ code/nel/tools/build_gamedata/panoply_dev.bat | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 code/nel/tools/build_gamedata/characters_dev.bat create mode 100644 code/nel/tools/build_gamedata/panoply_dev.bat diff --git a/code/nel/tools/build_gamedata/characters_dev.bat b/code/nel/tools/build_gamedata/characters_dev.bat new file mode 100644 index 000000000..f2b374c47 --- /dev/null +++ b/code/nel/tools/build_gamedata/characters_dev.bat @@ -0,0 +1,11 @@ +title Ryzom Core: 1_export.py (CHARACTERS) +1_export.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: 2_build.py (CHARACTERS) +2_build.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: 3_install.py (CHARACTERS) +3_install.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: b1_client_dev.py (CHARACTERS) +b1_client_dev.py +title Ryzom Core: b2_shard_data.py (CHARACTERS) +b2_shard_data.py +title Ryzom Core: Ready (CHARACTERS) diff --git a/code/nel/tools/build_gamedata/panoply_dev.bat b/code/nel/tools/build_gamedata/panoply_dev.bat new file mode 100644 index 000000000..13afac56c --- /dev/null +++ b/code/nel/tools/build_gamedata/panoply_dev.bat @@ -0,0 +1,11 @@ +title Ryzom Core: 1_export.py (PANOPLY) +1_export.py -ipj common/characters_maps_hr +title Ryzom Core: 2_build.py (PANOPLY) +2_build.py -ipj common/characters_maps_hr +title Ryzom Core: 3_install.py (PANOPLY) +3_install.py -ipj common/characters_maps_hr +title Ryzom Core: b1_client_dev.py (PANOPLY) +b1_client_dev.py +title Ryzom Core: b2_shard_data.py (PANOPLY) +b2_shard_data.py +title Ryzom Core: Ready (PANOPLY) From 3bd552ebb0b49009c1ab60d67fe6f5ba3a2afd55 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 24 Sep 2014 12:34:40 +0200 Subject: [PATCH 028/344] Add useful default config variables to dev client --HG-- branch : develop --- code/nel/tools/build_gamedata/b1_client_dev.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/tools/build_gamedata/b1_client_dev.py b/code/nel/tools/build_gamedata/b1_client_dev.py index d8c77c1fa..a23ee693c 100755 --- a/code/nel/tools/build_gamedata/b1_client_dev.py +++ b/code/nel/tools/build_gamedata/b1_client_dev.py @@ -52,6 +52,10 @@ if not os.path.isfile(ClientDevDirectory + "/client.cfg"): cfg.write("PreDataPath = {\n") cfg.write("\t\"" + InstallDirectory + "\", \"user\", \"patch\", \"data\", \"examples\" \n") cfg.write("};\n") + cfg.write("PatchWanted = 0;\n") + cfg.write("DisplayLuaDebugInfo = 1;\n") + cfg.write("AllowDebugLua = 1;\n") + cfg.write("FullScreen = 0;\n") printLog(log, "") printLog(log, ">>> Install data <<<") From 62744db86d24b6aad5f61ff19394875c877d83f8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:20:25 +0200 Subject: [PATCH 029/344] Dragged elements will no longer disappear. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 ++- code/nel/src/gui/widget_manager.cpp | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 5d2468e7a..ccf561d45 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -532,7 +532,8 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; - NLMISC::CRefPtr< CInterfaceElement > draggedElement; + NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging + std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e3f1064fa..c985557c5 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1036,6 +1036,8 @@ namespace NLGUI setCapturePointerLeft(NULL); setCapturePointerRight(NULL); _CapturedView = NULL; + + _OrphanElements.clear(); resetColorProps(); resetAlphaRolloverSpeedProps(); @@ -2039,6 +2041,15 @@ namespace NLGUI } } + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); + while( oeitr != _OrphanElements.end() ) + { + CInterfaceElement *e = *oeitr; + CViewBase *v = dynamic_cast< CViewBase* >( e ); + v->draw(); + ++oeitr; + } + if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2657,7 +2668,11 @@ namespace NLGUI void CWidgetManager::stopDragging() { - draggedElement = NULL; + if( draggedElement != NULL ) + { + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; + } } // ------------------------------------------------------------------------------------------------ @@ -3454,6 +3469,8 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { + _OrphanElements.clear(); + for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From f9dbef7df70fb0cc5e21723fe3caa77d8109bd6a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:31:26 +0200 Subject: [PATCH 030/344] Set dragged widgets' coordinates based on the move rather than the mouse pointer's coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c985557c5..5b131ee36 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,8 +2633,11 @@ namespace NLGUI else if( draggedElement != NULL ) { - draggedElement->setXReal( newX ); - draggedElement->setYReal( newY ); + sint32 dx = newX - oldX; + sint32 dy = newY - oldY; + + draggedElement->setXReal( draggedElement->getXReal() + dx ); + draggedElement->setYReal( draggedElement->getYReal() + dy ); draggedElement->invalidateCoords(); } } From bd7cb1eea3d4e3d974279b8f4b5e412a1c65bda1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 18:45:52 +0200 Subject: [PATCH 031/344] Add widget to a new parent when the widget being dragged is dropped, otherwise add it to the orphanlist so that it's drawn anyways. NOTE: The dropped widget can be clipped. If it is clipped, it never shows up even tho it's there. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 1 + code/nel/src/gui/interface_group.cpp | 30 ++++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 19 +++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index ff0efac3b..daf6d2d53 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -57,6 +57,7 @@ namespace NLGUI CInterfaceElement* findFromShortId(const std::string &id); /// Dynamic creation + virtual void addElement (CInterfaceElement *child, sint eltOrder = -1 ); virtual void addView (CViewBase *child , sint eltOrder = -1); virtual void addCtrl (CCtrlBase *child, sint eltOrder = -1); virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 4d37eda1c..05f210568 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -911,6 +911,31 @@ namespace NLGUI } } + // ------------------------------------------------------------------------------------------------ + void CInterfaceGroup::addElement (CInterfaceElement *child, sint eltOrder /*= -1*/) + { + if (!child) + { + nlwarning(" : tried to add a NULL view"); + return; + } + + if( child->isGroup() ) + { + addGroup( static_cast< CInterfaceGroup* >( child ), eltOrder ); + } + else + if( child->isCtrl() ) + { + addCtrl( static_cast< CCtrlBase* >( child ), eltOrder ); + } + else + if( child->isView() ) + { + addView( static_cast< CViewBase* >( child ), eltOrder ); + } + } + // ------------------------------------------------------------------------------------------------ void CInterfaceGroup::addView (CViewBase *child, sint eltOrder /*= -1*/) { @@ -1312,6 +1337,11 @@ namespace NLGUI for (ite = _EltOrder.begin() ; ite != _EltOrder.end(); ite++) { CViewBase *pVB = *ite; + if( pVB->getName() == "=MARKED=" ) + { + nlinfo( "=MARKED=" ); + } + if (pVB->getActive()) pVB->draw(); } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b131ee36..e44fa4d15 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2673,7 +2673,24 @@ namespace NLGUI { if( draggedElement != NULL ) { - _OrphanElements.push_back( draggedElement ); + CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + + if( g != NULL ) + { + CInterfaceElement *e = draggedElement; + e->setName( "=MARKED=" ); + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + g->addElement( e ); + + e->setParentPos( g ); + e->setParentSize( g ); + + checkCoords(); + } + else + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; } } From e7ab56beea0861700c24a414db2eb7454af41690 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 20:40:37 +0200 Subject: [PATCH 032/344] Orphaned widgets won't get stuck. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 62 ++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e44fa4d15..771bcf50e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2410,20 +2410,45 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + + if( CInterfaceElement::getEditorMode() ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); + while( itr != _OrphanElements.rend() ) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + CInterfaceElement *e = *itr; + + int x = getPointer()->getXReal(); + int y = getPointer()->getYReal(); + + if( e->isIn( x, y ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); + _CapturedView = static_cast< CViewBase* >( e ); captured = true; + break; + } + + ++itr; + } + } + + if( !captured ) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + { + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + { + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } @@ -2674,23 +2699,22 @@ namespace NLGUI if( draggedElement != NULL ) { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + CInterfaceElement *e = draggedElement; + + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + e->setParentPos( g ); + e->setParentSize( g ); if( g != NULL ) { - CInterfaceElement *e = draggedElement; - e->setName( "=MARKED=" ); - e->setParent( g ); - e->setIdRecurse( e->getShortId() ); g->addElement( e ); - - e->setParentPos( g ); - e->setParentSize( g ); - - checkCoords(); } else _OrphanElements.push_back( draggedElement ); + checkCoords(); + draggedElement = NULL; } } From a658be39b71bf9d16946b3e3e89944bd2b027fd9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 22:59:40 +0200 Subject: [PATCH 033/344] No need for free floating elements when we can simply reparent to the top window... --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 1 - code/nel/src/gui/widget_manager.cpp | 73 +++++------------------ 2 files changed, 16 insertions(+), 58 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index ccf561d45..8bd9052e5 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -533,7 +533,6 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging - std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 771bcf50e..40df50cb2 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1037,8 +1037,6 @@ namespace NLGUI setCapturePointerRight(NULL); _CapturedView = NULL; - _OrphanElements.clear(); - resetColorProps(); resetAlphaRolloverSpeedProps(); resetGlobalAlphasProps(); @@ -2041,15 +2039,6 @@ namespace NLGUI } } - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); - while( oeitr != _OrphanElements.end() ) - { - CInterfaceElement *e = *oeitr; - CViewBase *v = dynamic_cast< CViewBase* >( e ); - v->draw(); - ++oeitr; - } - if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2411,44 +2400,20 @@ namespace NLGUI if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); - while( itr != _OrphanElements.rend() ) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CInterfaceElement *e = *itr; - - int x = getPointer()->getXReal(); - int y = getPointer()->getYReal(); - - if( e->isIn( x, y ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - _CapturedView = static_cast< CViewBase* >( e ); + nMaxDepth = d; + setCapturePointerLeft( ctrl ); captured = true; - break; - } - - ++itr; - } - } - - if( !captured ) - { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) - { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) - { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; - } } } } @@ -2690,7 +2655,7 @@ namespace NLGUI e->setParent( NULL ); draggedElement = e; - + return true; } @@ -2700,20 +2665,16 @@ namespace NLGUI { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); CInterfaceElement *e = draggedElement; + CInterfaceGroup *tw = getTopWindow(); + + if( g == NULL ) + g = tw; e->setParent( g ); e->setIdRecurse( e->getShortId() ); e->setParentPos( g ); e->setParentSize( g ); - - if( g != NULL ) - { - g->addElement( e ); - } - else - _OrphanElements.push_back( draggedElement ); - - checkCoords(); + g->addElement( e ); draggedElement = NULL; } @@ -3513,8 +3474,6 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { - _OrphanElements.clear(); - for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From 006f87278b78ae7ef08d3de6a6d0856194f29559 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:32:24 +0200 Subject: [PATCH 034/344] Refactored IWidgetAdditionWatcher, now it's called IWidgetWatcher and it also reports widget moves. --HG-- branch : dfighter-tools --- .../include/nel/gui/widget_addition_watcher.h | 32 ------------- code/nel/include/nel/gui/widget_manager.h | 22 ++++++--- code/nel/src/gui/widget_manager.cpp | 45 ++++++++++++------- .../plugins/gui_editor/widget_hierarchy.cpp | 29 +++++++----- .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 5 files changed, 66 insertions(+), 63 deletions(-) delete mode 100644 code/nel/include/nel/gui/widget_addition_watcher.h diff --git a/code/nel/include/nel/gui/widget_addition_watcher.h b/code/nel/include/nel/gui/widget_addition_watcher.h deleted file mode 100644 index a2717e398..000000000 --- a/code/nel/include/nel/gui/widget_addition_watcher.h +++ /dev/null @@ -1,32 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef WIDGET_ADD_WATCHER -#define WIDGET_ADD_WATCHER - -#include - -namespace NLGUI -{ - class IWidgetAdditionWatcher - { - public: - virtual void widgetAdded( const std::string &name ) = 0; - }; -} - -#endif - diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8bd9052e5..89023c445 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -75,6 +75,16 @@ namespace NLGUI virtual void process() = 0; }; + // Interface for event handlers that can be called when widgets are added or moved + class IWidgetWatcher + { + public: + IWidgetWatcher(){} + virtual ~IWidgetWatcher(){} + virtual void onWidgetAdded( const std::string &name ) = 0; + virtual void onWidgetMoved( const std::string &oldid, const std::string &newid ) = 0; + }; + /// Frame render times struct SInterfaceTimes { @@ -498,10 +508,12 @@ namespace NLGUI void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); - - void notifyAdditionWatchers( const std::string &widgetName ); - void registerAdditionWatcher( IWidgetAdditionWatcher *watcher ); - void unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ); + + + void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); + void registerWidgetWatcher( IWidgetWatcher *watcher ); + void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); @@ -594,7 +606,7 @@ namespace NLGUI std::vector< INewScreenSizeHandler* > newScreenSizeHandlers; std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers; std::vector< IEditorSelectionWatcher* > selectionWatchers; - std::vector< IWidgetAdditionWatcher* > additionWatchers; + std::vector< IWidgetWatcher* > widgetWatchers; std::string currentEditorSelection; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 40df50cb2..11ad888f4 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -34,7 +34,6 @@ #include "nel/gui/interface_expr.h" #include "nel/gui/reflect_register.h" #include "nel/gui/editor_selection_watcher.h" -#include "nel/gui/widget_addition_watcher.h" #include "nel/misc/events.h" namespace NLGUI @@ -2669,6 +2668,8 @@ namespace NLGUI if( g == NULL ) g = tw; + + std::string oldid = e->getId(); e->setParent( g ); e->setIdRecurse( e->getShortId() ); @@ -2677,6 +2678,8 @@ namespace NLGUI g->addElement( e ); draggedElement = NULL; + + onWidgetMoved( oldid, e->getId() ); } } @@ -3364,36 +3367,46 @@ namespace NLGUI selectionWatchers.erase( itr ); } - void CWidgetManager::notifyAdditionWatchers( const std::string &widgetName ) + void CWidgetManager::onWidgetAdded( const std::string &id ) + { + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) + { + (*itr)->onWidgetAdded( id ); + ++itr; + } + } + + void CWidgetManager::onWidgetMoved( const std::string &oldid, const std::string &newid ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr = additionWatchers.begin(); - while( itr != additionWatchers.end() ) + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) { - (*itr)->widgetAdded( widgetName ); + (*itr)->onWidgetMoved( oldid, newid ); ++itr; } } - void CWidgetManager::registerAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::registerWidgetWatcher( IWidgetWatcher *watcher ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); + std::vector< IWidgetWatcher* >::const_iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); // already exists - if( itr != additionWatchers.end() ) + if( itr != widgetWatchers.end() ) return; - additionWatchers.push_back( watcher ); + widgetWatchers.push_back( watcher ); } - void CWidgetManager::unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::unregisterWidgetWatcher( IWidgetWatcher *watcher ) { - std::vector< IWidgetAdditionWatcher* >::iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); + std::vector< IWidgetWatcher* >::iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); // doesn't exist - if( itr == additionWatchers.end() ) + if( itr == widgetWatchers.end() ) return; - additionWatchers.erase( itr ); + widgetWatchers.erase( itr ); } CInterfaceElement* CWidgetManager::addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ) @@ -3426,7 +3439,7 @@ namespace NLGUI else g->addView( v ); - notifyAdditionWatchers( v->getId() ); + onWidgetAdded( v->getId() ); return v; } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 24208f4a3..8318ea926 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -18,7 +18,6 @@ #include "widget_hierarchy.h" #include "nel/gui/interface_group.h" #include "nel/gui/widget_manager.h" -#include "nel/gui/widget_addition_watcher.h" namespace { @@ -76,18 +75,24 @@ namespace GUIEditor::WidgetHierarchy *h; }; - class CWidgetAdditionWatcher : public IWidgetAdditionWatcher + class CWidgetWatcher : public CWidgetManager::IWidgetWatcher { public: - CWidgetAdditionWatcher(){ h = NULL; } - ~CWidgetAdditionWatcher(){} + CWidgetWatcher(){ h = NULL; } + ~CWidgetWatcher(){} - void widgetAdded( const std::string &name ) + void onWidgetAdded( const std::string &name ) { if( h != NULL ) h->onWidgetAdded( name ); } - + + void onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + if( h != NULL ) + h->onWidgetMoved( oldid, newid ); + } + void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; } private: @@ -95,7 +100,7 @@ namespace }; CWidgetDeletionWatcher deletionWatcher; - CWidgetAdditionWatcher additionWatcher; + CWidgetWatcher widgetwatcher; } namespace GUIEditor @@ -107,7 +112,7 @@ namespace GUIEditor connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); deletionWatcher.setWidgetHierarchy( this ); - additionWatcher.setWidgetHierarchy( this ); + widgetwatcher.setWidgetHierarchy( this ); } WidgetHierarchy::~WidgetHierarchy() @@ -117,7 +122,7 @@ namespace GUIEditor void WidgetHierarchy::clearHierarchy() { CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->unregisterAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->unregisterWidgetWatcher( &widgetwatcher ); widgetHT->clear(); widgetHierarchyMap.clear(); } @@ -126,7 +131,7 @@ namespace GUIEditor { clearHierarchy(); CInterfaceElement::registerDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->registerAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->registerWidgetWatcher( &widgetwatcher ); CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup ); if( mg != NULL ) @@ -231,6 +236,10 @@ namespace GUIEditor widgetHierarchyMap[ id ] = item; } + void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + } + void WidgetHierarchy::getCurrentGroup( QString &g ) { std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 4641c8ce8..e416ec145 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -44,6 +44,7 @@ namespace GUIEditor void onWidgetDeleted( const std::string &id ); void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); void getCurrentGroup( QString &g ); From 9cae0c179397b26b44312d2b1f4fc152eba24937 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:56:11 +0200 Subject: [PATCH 035/344] When repareting a widget, remove the old item from the hierarchy and add a new one at the right place. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 48 +++++++++++++++++++ .../src/plugins/gui_editor/widget_hierarchy.h | 2 + 2 files changed, 50 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 8318ea926..333386aca 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -182,6 +182,27 @@ namespace GUIEditor } } + QTreeWidgetItem* WidgetHierarchy::findItem( const std::string &id ) + { + std::map< std::string, QTreeWidgetItem* >::iterator itr + = widgetHierarchyMap.find( id ); + if( itr == widgetHierarchyMap.end() ) + return NULL; + else + return itr->second; + } + + QTreeWidgetItem* WidgetHierarchy::findParent( const std::string &id ) + { + // Get the parent's name + std::string::size_type p = id.find_last_of( ':' ); + if( p == std::string::npos ) + return NULL; + std::string parentId = id.substr( 0, p ); + + return findItem( parentId ); + } + void WidgetHierarchy::onWidgetDeleted( const std::string &id ) { std::map< std::string, QTreeWidgetItem* >::iterator itr @@ -238,6 +259,33 @@ namespace GUIEditor void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) { + QTreeWidgetItem *newParent = NULL; + QTreeWidgetItem *item = NULL; + QString id; + + newParent = findParent( newid ); + item = findItem( oldid ); + + if( ( newParent == NULL ) || ( item == NULL ) ) + return; + + // Remove old item + QTreeWidgetItem *p = item->parent(); + if( p != NULL ) + p->setExpanded( false ); + id = item->data( 0, Qt::DisplayRole ).toString(); + delete item; + item = NULL; + + // Remove reference to old item + widgetHierarchyMap.erase( oldid ); + + // Add new item + item = new QTreeWidgetItem(); + item->setData( 0, Qt::DisplayRole, id ); + item->setSelected( true ); + newParent->addChild( item ); + newParent->setExpanded( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index e416ec145..3d748e15f 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -50,6 +50,8 @@ namespace GUIEditor private: void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); + QTreeWidgetItem* findItem( const std::string &id ); + QTreeWidgetItem* findParent( const std::string &id ); public Q_SLOTS: void onGUILoaded(); From 4ec13e57e4097b9962e67d63203e1047037e3281 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 25 Sep 2014 00:37:25 +0200 Subject: [PATCH 036/344] Collapse the tree, and only expand the items that are needed to get to the selected items. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 34 +++++++++++++------ .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 333386aca..d52f55e27 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -285,7 +285,24 @@ namespace GUIEditor item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - newParent->setExpanded( true ); + + + selectItem( item ); + } + + void WidgetHierarchy::selectItem( QTreeWidgetItem *item ) + { + widgetHT->collapseAll(); + + QTreeWidgetItem *currItem = item; + while( currItem != NULL ) + { + currItem->setExpanded( true ); + currItem = currItem->parent(); + } + + widgetHT->setCurrentItem( item ); + item->setSelected( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) @@ -345,18 +362,11 @@ namespace GUIEditor if( widgetHT->currentItem() != NULL ) widgetHT->currentItem()->setSelected( false ); - // expand the tree items, so that we can see the selected item - QTreeWidgetItem *item = itr->second; - QTreeWidgetItem *currItem = item; - while( currItem != NULL ) - { - currItem->setExpanded( true ); - currItem = currItem->parent(); - } + widgetHT->collapseAll(); // select the current item - item->setSelected( true ); - widgetHT->setCurrentItem( item ); + QTreeWidgetItem *item = itr->second; + selectItem( item ); currentSelection = newSelection; } @@ -364,6 +374,8 @@ namespace GUIEditor { if( item->parent() == NULL ) return; + + selectItem( item ); std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 3d748e15f..27218715d 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -52,6 +52,7 @@ namespace GUIEditor void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); QTreeWidgetItem* findItem( const std::string &id ); QTreeWidgetItem* findParent( const std::string &id ); + void selectItem( QTreeWidgetItem *item ); public Q_SLOTS: void onGUILoaded(); From 8bc49f5b4b0c87fb886f0d5c1d9f12262125daeb Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Fri, 26 Sep 2014 22:30:56 +0200 Subject: [PATCH 037/344] rolling back to include a crypt(3) implementation and adding sha512 support --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 - code/ryzom/common/src/game_share/crypt.cpp | 985 ++++++++++++++++++ .../src/game_share/{ccrypt.h => crypt.h} | 0 .../common/src/game_share/crypt_sha512.cpp | 371 +++++++ .../src/monitor_service/service_main.cpp | 2 +- 6 files changed, 1358 insertions(+), 32 deletions(-) delete mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp create mode 100644 code/ryzom/common/src/game_share/crypt.cpp rename code/ryzom/common/src/game_share/{ccrypt.h => crypt.h} (100%) create mode 100644 code/ryzom/common/src/game_share/crypt_sha512.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 673a5b5f4..091e24a80 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp deleted file mode 100644 index ea67cf7d6..000000000 --- a/code/ryzom/common/src/game_share/ccrypt.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "ccrypt.h" - -#define _GNU_SOURCE 1 -#include - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::crypt(password.c_str(), salt.c_str()); - - return result; -} diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp new file mode 100644 index 000000000..881b42f1e --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -0,0 +1,985 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "crypt.h" + +char * rz_crypt(register const char *key, register const char *setting); +char *__crypt_sha512(const char *key, const char *setting, char *output); + + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::rz_crypt(password.c_str(), salt.c_str()); + + return result; +} + + + + + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* #include */ +#include +#include +#define RZ__PASSWORD_EFMT1 '-' + +#if DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows); +#endif + +/* + * UNIX password, and DES, encryption. + * By Tom Truscott, trt@rti.rti.org, + * from algorithms by Robert W. Baldwin and James Gillogly. + * + * References: + * "Mathematical Cryptology for Computer Scientists and Mathematicians," + * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. + * + * "Password Security: A Case History," R. Morris and Ken Thompson, + * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. + * + * "DES will be Totally Insecure within Ten Years," M.E. Hellman, + * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. + */ + +/* ===== Configuration ==================== */ + +/* + * define "MUST_ALIGN" if your compiler cannot load/store + * long integers at arbitrary (e.g. odd) memory locations. + * (Either that or never pass unaligned addresses to des_cipher!) + */ +#if !defined(vax) +#define MUST_ALIGN +#endif + +#ifdef CHAR_BITS +#if CHAR_BITS != 8 + #error C_block structure assumes 8 bit characters +#endif +#endif + +/* + * define "LONG_IS_32_BITS" only if sizeof(long)==4. + * This avoids use of bit fields (your compiler may be sloppy with them). + */ +#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) +#define LONG_IS_32_BITS +#endif + +/* + * define "B64" to be the declaration for a 64 bit integer. + * XXX this feature is currently unused, see "endian" comment below. + */ +#if defined(cray) || defined(__LP64__) || defined(_LP64) +#define B64 long +#endif +#if defined(convex) +#define B64 long long +#endif + +/* + * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes + * of lookup tables. This speeds up des_setkey() and des_cipher(), but has + * little effect on crypt(). + */ +#if defined(notdef) +#define LARGEDATA +#endif + +/* ==================================== */ + +/* + * Cipher-block representation (Bob Baldwin): + * + * DES operates on groups of 64 bits, numbered 1..64 (sigh). One + * representation is to store one bit per byte in an array of bytes. Bit N of + * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. + * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the + * first byte, 9..16 in the second, and so on. The DES spec apparently has + * bit 1 in the MSB of the first byte, but that is particularly noxious so we + * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is + * the MSB of the first byte. Specifically, the 64-bit input data and key are + * converted to LSB format, and the output 64-bit block is converted back into + * MSB format. + * + * DES operates internally on groups of 32 bits which are expanded to 48 bits + * by permutation E and shrunk back to 32 bits by the S boxes. To speed up + * the computation, the expansion is applied only once, the expanded + * representation is maintained during the encryption, and a compression + * permutation is applied only at the end. To speed up the S-box lookups, + * the 48 bits are maintained as eight 6 bit groups, one per byte, which + * directly feed the eight S-boxes. Within each byte, the 6 bits are the + * most significant ones. The low two bits of each byte are zero. (Thus, + * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the + * first byte in the eight byte representation, bit 2 of the 48 bit value is + * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is + * used, in which the output is the 64 bit result of an S-box lookup which + * has been permuted by P and expanded by E, and is ready for use in the next + * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this + * lookup. Since each byte in the 48 bit path is a multiple of four, indexed + * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and + * "salt" are also converted to this 8*(6+2) format. The SPE table size is + * 8*64*8 = 4K bytes. + * + * To speed up bit-parallel operations (such as XOR), the 8 byte + * representation is "union"ed with 32 bit values "i0" and "i1", and, on + * machines which support it, a 64 bit value "b64". This data structure, + * "C_block", has two problems. First, alignment restrictions must be + * honored. Second, the byte-order (e.g. little-endian or big-endian) of + * the architecture becomes visible. + * + * The byte-order problem is unfortunate, since on the one hand it is good + * to have a machine-independent C_block representation (bits 1..8 in the + * first byte, etc.), and on the other hand it is good for the LSB of the + * first byte to be the LSB of i0. We cannot have both these things, so we + * currently use the "little-endian" representation and avoid any multi-byte + * operations that depend on byte order. This largely precludes use of the + * 64-bit datatype since the relative order of i0 and i1 are unknown. It + * also inhibits grouping the SPE table to look up 12 bits at a time. (The + * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 + * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the + * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup + * requires a 128 kilobyte table, so perhaps this is not a big loss. + * + * Permutation representation (Jim Gillogly): + * + * A transformation is defined by its effect on each of the 8 bytes of the + * 64-bit input. For each byte we give a 64-bit output that has the bits in + * the input distributed appropriately. The transformation is then the OR + * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for + * each transformation. Unless LARGEDATA is defined, however, a more compact + * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. + * The smaller table uses 16*16*8 = 2K bytes for each transformation. This + * is slower but tolerable, particularly for password encryption in which + * the SPE transformation is iterated many times. The small tables total 9K + * bytes, the large tables total 72K bytes. + * + * The transformations used are: + * IE3264: MSB->LSB conversion, initial permutation, and expansion. + * This is done by collecting the 32 even-numbered bits and applying + * a 32->64 bit transformation, and then collecting the 32 odd-numbered + * bits and applying the same transformation. Since there are only + * 32 input bits, the IE3264 transformation table is half the size of + * the usual table. + * CF6464: Compression, final permutation, and LSB->MSB conversion. + * This is done by two trivial 48->32 bit compressions to obtain + * a 64-bit block (the bit numbering is given in the "CIFP" table) + * followed by a 64->64 bit "cleanup" transformation. (It would + * be possible to group the bits in the 64-bit block so that 2 + * identical 32->32 bit transformations could be used instead, + * saving a factor of 4 in space and possibly 2 in time, but + * byte-ordering and other complications rear their ugly head. + * Similar opportunities/problems arise in the key schedule + * transforms.) + * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. + * This admittedly baroque 64->64 bit transformation is used to + * produce the first code (in 8*(6+2) format) of the key schedule. + * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. + * It would be possible to define 15 more transformations, each + * with a different rotation, to generate the entire key schedule. + * To save space, however, we instead permute each code into the + * next by using a transformation that "undoes" the PC2 permutation, + * rotates the code, and then applies PC2. Unfortunately, PC2 + * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not + * invertible. We get around that problem by using a modified PC2 + * which retains the 8 otherwise-lost bits in the unused low-order + * bits of each byte. The low-order bits are cleared when the + * codes are stored into the key schedule. + * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. + * This is faster than applying PC2ROT[0] twice, + * + * The Bell Labs "salt" (Bob Baldwin): + * + * The salting is a simple permutation applied to the 48-bit result of E. + * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and + * i+24 of the result are swapped. The salt is thus a 24 bit number, with + * 16777216 possible values. (The original salt was 12 bits and could not + * swap bits 13..24 with 36..48.) + * + * It is possible, but ugly, to warp the SPE table to account for the salt + * permutation. Fortunately, the conditional bit swapping requires only + * about four machine instructions and can be done on-the-fly with about an + * 8% performance penalty. + */ + +typedef union { + unsigned char b[8]; + struct { +#if defined(LONG_IS_32_BITS) + /* long is often faster than a 32-bit bit field */ + long i0; + long i1; +#else + long i0: 32; + long i1: 32; +#endif + } b32; +#if defined(B64) + B64 b64; +#endif +} C_block; + +/* + * Convert twenty-four-bit long in host-order + * to six bits (and 2 low-order zeroes) per char little-endian format. + */ +#define TO_SIX_BIT(rslt, src) { \ + C_block cvt; \ + cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[3] = (unsigned char) (src&0xFF); \ + rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ + } + +/* + * These macros may someday permit efficient use of 64-bit integers. + */ +#define ZERO(d,d0,d1) d0 = 0, d1 = 0 +#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 +#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 +#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 +#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 +#define DCL_BLOCK(d,d0,d1) long d0, d1 + +#if defined(LARGEDATA) + /* Waste memory like crazy. Also, do permutations in line */ +#define LGCHUNKBITS 3 +#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); + STORE(D,D0,D1,*out); +} +#endif /* LARGEDATA */ + + +/* ===== (mostly) Standard DES Tables ==================== */ + +static unsigned char IP[] = { /* initial permutation */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* The final permutation is the inverse of IP - no table is necessary */ + +static unsigned char ExpandTr[] = { /* expansion operation */ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +static unsigned char PC1[] = { /* permuted choice table 1 */ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +static unsigned char Rotates[] = { /* PC1 rotation schedule */ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* note: each "row" of PC2 is left-padded with bits that make it invertible */ +static unsigned char PC2[] = { /* permuted choice table 2 */ + 9, 18, 14, 17, 11, 24, 1, 5, + 22, 25, 3, 28, 15, 6, 21, 10, + 35, 38, 23, 19, 12, 4, 26, 8, + 43, 54, 16, 7, 27, 20, 13, 2, + + 0, 0, 41, 52, 31, 37, 47, 55, + 0, 0, 30, 40, 51, 45, 33, 48, + 0, 0, 44, 49, 39, 56, 34, 53, + 0, 0, 46, 42, 50, 36, 29, 32, +}; + +static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ + /* S[1] */ + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + /* S[2] */ + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + /* S[3] */ + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + /* S[4] */ + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + /* S[5] */ + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + /* S[6] */ + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + /* S[7] */ + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + /* S[8] */ + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} +}; + +static unsigned char P32Tr[] = { /* 32-bit permutation function */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +static unsigned char CIFP[] = { /* compressed/interleaved permutation */ + 1, 2, 3, 4, 17, 18, 19, 20, + 5, 6, 7, 8, 21, 22, 23, 24, + 9, 10, 11, 12, 25, 26, 27, 28, + 13, 14, 15, 16, 29, 30, 31, 32, + + 33, 34, 35, 36, 49, 50, 51, 52, + 37, 38, 39, 40, 53, 54, 55, 56, + 41, 42, 43, 44, 57, 58, 59, 60, + 45, 46, 47, 48, 61, 62, 63, 64, +}; + +static unsigned char itoa64[] = /* 0..63 => ascii-64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + +/* ===== Tables that are initialized at run time ==================== */ + + +static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ + +/* Initial key schedule permutation */ +static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ +static C_block CF6464[64/CHUNKBITS][1<= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + num_iter = (num_iter<<6) | a64toi[t]; + } + setting += 4; + encp += 4; + salt_size = 4; + break; + default: + num_iter = 25; + salt_size = 2; + } + + salt = 0; + for (i = salt_size; --i >= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + salt = (salt<<6) | a64toi[t]; + } + encp += salt_size; + if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, + salt, num_iter)) + return (NULL); + + /* + * Encode the 64 cipher bits as 11 ascii characters. + */ + i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; + + encp[3] = 0; + + return (cryptresult); +} + + +/* + * The Key Schedule, filled in by des_setkey() or setkey(). + */ +#define KS_SIZE 16 +static C_block KS[KS_SIZE]; + +/* + * Set up the key schedule from the key. + */ +int rz_des_setkey(register const char *key) { + register DCL_BLOCK(K, K0, K1); + register C_block *ptabp; + register int i; + static int des_ready = 0; + + if (!des_ready) { + rz_init_des(); + des_ready = 1; + } + + PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); + key = (char *)&KS[0]; + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + for (i = 1; i < 16; i++) { + key += sizeof(C_block); + STORE(K,K0,K1,*(C_block *)key); + ptabp = (C_block *)PC2ROT[Rotates[i]-1]; + PERM6464(K,K0,K1,(unsigned char *)key,ptabp); + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + } + return (0); +} + +/* + * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) + * iterations of DES, using the given 24-bit salt and the pre-computed key + * schedule, and store the resulting 8 chars at "out" (in == out is permitted). + * + * NOTE: the performance of this routine is critically dependent on your + * compiler and machine architecture. + */ +int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { + /* variables that we want in registers, most important first */ +#if defined(pdp11) + register int j; +#endif + register long L0, L1, R0, R1, k; + register C_block *kp; + register int ks_inc, loop_count; + C_block B; + + L0 = salt; + TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ + +#if defined(vax) || defined(pdp11) + salt = ~salt; /* "x &~ y" is faster than "x & y". */ +#define SALT (~salt) +#else +#define SALT salt +#endif + +#if defined(MUST_ALIGN) + B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; + B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; + LOAD(L,L0,L1,B); +#else + LOAD(L,L0,L1,*(C_block *)in); +#endif + LOADREG(R,R0,R1,L,L0,L1); + L0 &= 0x55555555L; + L1 &= 0x55555555L; + L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ + R0 &= 0xaaaaaaaaL; + R1 = (R1 >> 1) & 0x55555555L; + L1 = R0 | R1; /* L1 is the odd-numbered input bits */ + STORE(L,L0,L1,B); + PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ + PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ + + if (num_iter >= 0) + { /* encryption */ + kp = &KS[0]; + ks_inc = sizeof(*kp); + } + else + { /* decryption */ + num_iter = -num_iter; + kp = &KS[KS_SIZE-1]; + ks_inc = -((int) sizeof(*kp)); + } + + while (--num_iter >= 0) { + loop_count = 8; + do { + +#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) +#if defined(gould) + /* use this if B.b[i] is evaluated just once ... */ +#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); +#else +#if defined(pdp11) + /* use this if your "long" int indexing is slow */ +#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); +#else + /* use this if "k" is allocated to a register ... */ +#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); +#endif +#endif + +#define CRUNCH(p0, p1, q0, q1) \ + k = (q0 ^ q1) & SALT; \ + B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ + B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ + kp = (C_block *)((char *)kp+ks_inc); \ + \ + DOXOR(p0, p1, 0); \ + DOXOR(p0, p1, 1); \ + DOXOR(p0, p1, 2); \ + DOXOR(p0, p1, 3); \ + DOXOR(p0, p1, 4); \ + DOXOR(p0, p1, 5); \ + DOXOR(p0, p1, 6); \ + DOXOR(p0, p1, 7); + + CRUNCH(L0, L1, R0, R1); + CRUNCH(R0, R1, L0, L1); + } while (--loop_count != 0); + kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); + + + /* swap L and R */ + L0 ^= R0; L1 ^= R1; + R0 ^= L0; R1 ^= L1; + L0 ^= R0; L1 ^= R1; + } + + /* store the encrypted (or decrypted) result */ + L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); + L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); + STORE(L,L0,L1,B); + PERM6464(L,L0,L1,B.b, (C_block *)CF6464); +#if defined(MUST_ALIGN) + STORE(L,L0,L1,B); + out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; + out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; +#else + STORE(L,L0,L1,*(C_block *)out); +#endif + return (0); +} + + +/* + * Initialize various tables. This need only be done once. It could even be + * done at compile time, if the compiler were capable of that sort of thing. + */ +/* STATIC */void rz_init_des() { + register int i, j; + register long k; + register int tableno; + static unsigned char perm[64], tmp32[32]; /* "static" for speed */ + + /* + * table that converts chars "./0-9A-Za-z"to integers 0-63. + */ + for (i = 0; i < 64; i++) + a64toi[itoa64[i]] = i; + + /* + * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. + */ + for (i = 0; i < 64; i++) + perm[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += Rotates[0]-1; + if ((k%28) < Rotates[0]) k -= 28; + k = PC1[k]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i] = (unsigned char) k; + } +#ifdef DEBUG_CRYPT + prtab("pc1tab", perm, 8); +#endif + rz_init_perm(PC1ROT, perm, 8, 8); + + /* + * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. + */ + for (j = 0; j < 2; j++) { + unsigned char pc2inv[64]; + for (i = 0; i < 64; i++) + perm[i] = pc2inv[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + pc2inv[k-1] = i+1; + } + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += j; + if ((k%28) <= j) k -= 28; + perm[i] = pc2inv[k]; + } +#ifdef DEBUG_CRYPT + prtab("pc2tab", perm, 8); +#endif + rz_init_perm(PC2ROT[j], perm, 8, 8); + } + + /* + * Bit reverse, then initial permutation, then expansion. + */ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; + if (k > 32) + k -= 32; + else if (k > 0) + k--; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i*8+j] = (unsigned char) k; + } + } +#ifdef DEBUG_CRYPT + prtab("ietab", perm, 8); +#endif + rz_init_perm(IE3264, perm, 4, 8); + + /* + * Compression, then final permutation, then bit reverse. + */ + for (i = 0; i < 64; i++) { + k = IP[CIFP[i]-1]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[k-1] = i+1; + } +#ifdef DEBUG_CRYPT + prtab("cftab", perm, 8); +#endif + rz_init_perm(CF6464, perm, 8, 8); + + /* + * SPE table + */ + for (i = 0; i < 48; i++) + perm[i] = P32Tr[ExpandTr[i]-1]; + for (tableno = 0; tableno < 8; tableno++) { + for (j = 0; j < 64; j++) { + k = (((j >> 0) &01) << 5)| + (((j >> 1) &01) << 3)| + (((j >> 2) &01) << 2)| + (((j >> 3) &01) << 1)| + (((j >> 4) &01) << 0)| + (((j >> 5) &01) << 4); + k = S[tableno][k]; + k = (((k >> 3)&01) << 0)| + (((k >> 2)&01) << 1)| + (((k >> 1)&01) << 2)| + (((k >> 0)&01) << 3); + for (i = 0; i < 32; i++) + tmp32[i] = 0; + for (i = 0; i < 4; i++) + tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i]-1]; + TO_SIX_BIT(SPE[0][tableno][j], k); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i+24]-1]; + TO_SIX_BIT(SPE[1][tableno][j], k); + } + } +} + +/* + * Initialize "perm" to represent transformation "p", which rearranges + * (perhaps with expansion and/or contraction) one packed array of bits + * (of size "chars_in" characters) into another array (of size "chars_out" + * characters). + * + * "perm" must be all-zeroes on entry to this routine. + */ +/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ + l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ + for (j = 0; j < (1<>3] |= 1<<(k&07); + } + } +} + +/* + * "setkey" routine (for backwards compatibility) + */ +int rz_setkey(register const char *key) { + register int i, j, k; + C_block keyblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*key++; + } + keyblock.b[i] = k; + } + return (rz_des_setkey((char *)keyblock.b)); +} + +/* + * "encrypt" routine (for backwards compatibility) + */ +int rz_encrypt(register char *block, int flag) { + register int i, j, k; + C_block cblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*block++; + } + cblock.b[i] = k; + } + if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) + return (1); + for (i = 7; i >= 0; i--) { + k = cblock.b[i]; + for (j = 7; j >= 0; j--) { + *--block = k&01; + k >>= 1; + } + } + return (0); +} + +#ifdef DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows) +{ + register int i, j; + + (void)printf("%s:\n", s); + for (i = 0; i < num_rows; i++) { + for (j = 0; j < 8; j++) { + (void)printf("%3d", t[i*8+j]); + } + (void)printf("\n"); + } + (void)printf("\n"); +} +#endif diff --git a/code/ryzom/common/src/game_share/ccrypt.h b/code/ryzom/common/src/game_share/crypt.h similarity index 100% rename from code/ryzom/common/src/game_share/ccrypt.h rename to code/ryzom/common/src/game_share/crypt.h diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp new file mode 100644 index 000000000..c12359485 --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -0,0 +1,371 @@ +/* + * public domain sha512 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha512 implementation based on fips180-3 */ +/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ + +struct sha512 { + uint64_t len; /* processed message length */ + uint64_t h[8]; /* hash state */ + uint8_t buf[128]; /* message block buffer */ +}; + +static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) +#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) +#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) +#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) + +static const uint64_t K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +static void processblock(struct sha512 *s, const uint8_t *buf) +{ + uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint64_t)buf[8*i]<<56; + W[i] |= (uint64_t)buf[8*i+1]<<48; + W[i] |= (uint64_t)buf[8*i+2]<<40; + W[i] |= (uint64_t)buf[8*i+3]<<32; + W[i] |= (uint64_t)buf[8*i+4]<<24; + W[i] |= (uint64_t)buf[8*i+5]<<16; + W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] |= buf[8*i+7]; + } + for (; i < 80; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 80; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha512 *s) +{ + unsigned r = s->len % 128; + + s->buf[r++] = 0x80; + if (r > 112) { + memset(s->buf + r, 0, 128 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 120 - r); + s->len *= 8; + s->buf[120] = s->len >> 56; + s->buf[121] = s->len >> 48; + s->buf[122] = s->len >> 40; + s->buf[123] = s->len >> 32; + s->buf[124] = s->len >> 24; + s->buf[125] = s->len >> 16; + s->buf[126] = s->len >> 8; + s->buf[127] = s->len; + processblock(s, s->buf); +} + +static void sha512_init(struct sha512 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667f3bcc908ULL; + s->h[1] = 0xbb67ae8584caa73bULL; + s->h[2] = 0x3c6ef372fe94f82bULL; + s->h[3] = 0xa54ff53a5f1d36f1ULL; + s->h[4] = 0x510e527fade682d1ULL; + s->h[5] = 0x9b05688c2b3e6c1fULL; + s->h[6] = 0x1f83d9abfb41bd6bULL; + s->h[7] = 0x5be0cd19137e2179ULL; +} + +static void sha512_sum(struct sha512 *s, uint8_t *md) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[8*i] = s->h[i] >> 56; + md[8*i+1] = s->h[i] >> 48; + md[8*i+2] = s->h[i] >> 40; + md[8*i+3] = s->h[i] >> 32; + md[8*i+4] = s->h[i] >> 24; + md[8*i+5] = s->h[i] >> 16; + md[8*i+6] = s->h[i] >> 8; + md[8*i+7] = s->h[i]; + } +} + +static void sha512_update(struct sha512 *s, const void *m, unsigned long len) +{ + const uint8_t *p = (uint8_t *)m; + unsigned r = s->len % 128; + + s->len += len; + if (r) { + if (len < 128 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 128 - r); + len -= 128 - r; + p += 128 - r; + processblock(s, s->buf); + } + for (; len >= 128; len -= 128, p += 128) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static const unsigned char b64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 9999999 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha512 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 64; i -= 64) + sha512_update(s, md, 64); + sha512_update(s, md, i); +} + +static char *sha512crypt(const char *key, const char *setting, char *output) +{ + struct sha512 ctx; + unsigned char md[64], kmd[64], smd[64]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + for (i = 0; i <= KEY_MAX && key[i]; i++); + if (i > KEY_MAX) + return 0; + klen = i; + + /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$6$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha512_update(&ctx, md, sizeof md); + else + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha512_init(&ctx); + for (i = 0; i < klen; i++) + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha512_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha512_update(&ctx, salt, slen); + sha512_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha512_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha512_update(&ctx, md, sizeof md); + if (i % 3) + sha512_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha512_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha512_sum(&ctx, md); + } + + /* output is $6$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); +#if 1 + static const unsigned char perm[][3] = { + 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, + 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, + 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, + 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, + 62,20,41 }; + for (i=0; i<21; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); +#else + p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); + p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); + p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); + p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); + p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); + p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); + p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); + p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); + p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); + p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); + p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); + p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); + p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); + p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); + p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); + p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); + p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); + p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); + p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); + p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); + p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); +#endif + p = to64(p, md[63], 2); + *p = 0; + return output; +} + +char *__crypt_sha512(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; + static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; + char testbuf[128]; + char *p, *q; + + p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha512crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index aa559b78d..84bbcbe86 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "nel/misc/time_nl.h" #include "client.h" From 938c36027d1e175ce1f4714739d7b041a0c00617 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 26 Sep 2014 23:29:38 +0200 Subject: [PATCH 038/344] Editbox selection should be stopped when the mouse button goes up, even if it happens outside of the box. --HG-- branch : develop --- code/nel/src/gui/group_editbox.cpp | 21 +++++++++++---------- code/nel/src/gui/widget_manager.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 751d9241b..c18c69134 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -1320,6 +1320,16 @@ namespace NLGUI } } + // if click, and not frozen, then get the focus + if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen) + { + _SelectingText = false; + if (_SelectCursorPos == _CursorPos) + _CurrSelection = NULL; + + return true; + } + if (!isIn(eventDesc.getX(), eventDesc.getY())) return false; @@ -1329,6 +1339,7 @@ namespace NLGUI _SelectingText = true; stopParentBlink(); CWidgetManager::getInstance()->setCaptureKeyboard (this); + CWidgetManager::getInstance()->setCapturePointerLeft (this); // set the right cursor position uint newCurPos; bool cursorAtPreviousLineEnd; @@ -1356,16 +1367,6 @@ namespace NLGUI return true; } - // if click, and not frozen, then get the focus - if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen) - { - _SelectingText = false; - if (_SelectCursorPos == _CursorPos) - _CurrSelection = NULL; - - return true; - } - if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown) { CWidgetManager::getInstance()->setCapturePointerRight(this); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 18a1f066f..a448603c0 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2539,6 +2539,12 @@ namespace NLGUI { if ( getCapturePointerLeft() != NULL) { + if( !handled ) + { + CCtrlBase *c = getCapturePointerLeft(); + c->handleEvent( evnt ); + } + setCapturePointerLeft(NULL); handled = true; } From 8c3702f826f8826e0044b01647a4d1db5924ebee Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:00:52 +0200 Subject: [PATCH 039/344] Update coords when changing something. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bd73fb7fa..bfdd0d6fa 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -493,6 +493,10 @@ namespace GUIEditor if( e == NULL ) return; e->setProperty( propName.toUtf8().constData(), propValue.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); // Make sure the changes are applied @@ -631,6 +635,16 @@ namespace GUIEditor e->setProperty( propName.toUtf8().constData(), v ); } + + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e != NULL ) + { + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); + } + } @@ -643,6 +657,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::onTexturePropertyChanged( QtProperty *p, const QString &v ) @@ -654,6 +672,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::enablePropertyWatchers() From 0af278e50a7fe94d8d8e83e19bbbd202691d6219 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:04:49 +0200 Subject: [PATCH 040/344] A little bit of refactoring. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bfdd0d6fa..c005f80e5 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -518,13 +518,12 @@ namespace GUIEditor return; std::string type = itr->second; + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e == NULL ) + return; if( type == "button_type" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelButtonType::toString( value ); if( v.empty() ) @@ -535,10 +534,6 @@ namespace GUIEditor else if( type == "text_justification" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelTxtJustification::toString( value ); if( v.empty() ) @@ -549,10 +544,6 @@ namespace GUIEditor else if( type == "posref" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRef::toString( value ); if( v.empty() ) return; @@ -562,10 +553,6 @@ namespace GUIEditor else if( type == "posreftt" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRefTT::toString( value ); if( v.empty() ) return; @@ -612,10 +599,6 @@ namespace GUIEditor else if( type == "tooltip_parent" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelTTParent::toString( value ); if( v.empty() ) return; @@ -625,10 +608,6 @@ namespace GUIEditor else if( type == "bitmap_align" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelBMAlign::toString( value ); if( v.empty() ) return; @@ -637,13 +616,9 @@ namespace GUIEditor } - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e != NULL ) - { - CInterfaceGroup *g = e->getParent(); - if( g != NULL ) - g->updateCoords(); - } + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } From 0d6265015946c73504fd77fedd7338f60aca2920 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 27 Sep 2014 15:55:57 +0300 Subject: [PATCH 041/344] Add maxlength attribute to input and textarea tags --HG-- branch : html-maxlength-attr --- code/nel/include/nel/gui/group_html.h | 3 ++- code/nel/include/nel/gui/libwww.h | 1 + code/nel/src/gui/group_html.cpp | 27 +++++++++++++++++---------- code/nel/src/gui/libwww.cpp | 1 + 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 3f5526197..ba34af2dd 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -285,7 +285,7 @@ namespace NLGUI void addImage(const char *image, bool globalColor, bool reloadImg=false); // Add a text area in the current paragraph - CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content); + CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength); // Add a combo box in the current paragraph CDBGroupComboBox *addComboBox(const std::string &templateName, const char *name); @@ -557,6 +557,7 @@ namespace NLGUI std::string _TextAreaName; uint _TextAreaRow; uint _TextAreaCols; + uint _TextAreaMaxLength; // current mode is in select option bool _SelectOption; diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index 8da217382..ec23cafd2 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -189,6 +189,7 @@ namespace NLGUI HTML_ATTR(TEXTAREA,DISABLED), HTML_ATTR(TEXTAREA,ID), HTML_ATTR(TEXTAREA,LANG), + HTML_ATTR(TEXTAREA,MAXLENGTH), HTML_ATTR(TEXTAREA,NAME), HTML_ATTR(TEXTAREA,READONLY), HTML_ATTR(TEXTAREA,ROWS), diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 9f19f383a..1a2ae5b4b 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1289,16 +1289,19 @@ namespace NLGUI string name; ucstring ucValue; uint size = 120; + uint maxlength = 1024; if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME]) name = value[MY_HTML_INPUT_NAME]; if (present[MY_HTML_INPUT_SIZE] && value[MY_HTML_INPUT_SIZE]) fromString(value[MY_HTML_INPUT_SIZE], size); if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE]) ucValue.fromUtf8(value[MY_HTML_INPUT_VALUE]); + if (present[MY_HTML_INPUT_MAXLENGTH] && value[MY_HTML_INPUT_MAXLENGTH]) + fromString(value[MY_HTML_INPUT_MAXLENGTH], maxlength); string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup); // Add the editbox - CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue); + CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength); if (textArea) { // Add the text area to the form @@ -1553,12 +1556,15 @@ namespace NLGUI _TextAreaRow = 1; _TextAreaCols = 10; _TextAreaContent = ""; - if (present[HTML_TEXTAREA_NAME] && value[HTML_TEXTAREA_NAME]) - _TextAreaName = value[HTML_TEXTAREA_NAME]; - if (present[HTML_TEXTAREA_ROWS] && value[HTML_TEXTAREA_ROWS]) - fromString(value[HTML_TEXTAREA_ROWS], _TextAreaRow); - if (present[HTML_TEXTAREA_COLS] && value[HTML_TEXTAREA_COLS]) - fromString(value[HTML_TEXTAREA_COLS], _TextAreaCols); + _TextAreaMaxLength = 1024; + if (present[MY_HTML_TEXTAREA_NAME] && value[MY_HTML_TEXTAREA_NAME]) + _TextAreaName = value[MY_HTML_TEXTAREA_NAME]; + if (present[MY_HTML_TEXTAREA_ROWS] && value[MY_HTML_TEXTAREA_ROWS]) + fromString(value[MY_HTML_TEXTAREA_ROWS], _TextAreaRow); + if (present[MY_HTML_TEXTAREA_COLS] && value[MY_HTML_TEXTAREA_COLS]) + fromString(value[MY_HTML_TEXTAREA_COLS], _TextAreaCols); + if (present[MY_HTML_TEXTAREA_MAXLENGTH] && value[MY_HTML_TEXTAREA_MAXLENGTH]) + fromString(value[MY_HTML_TEXTAREA_MAXLENGTH], _TextAreaMaxLength); _TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup; _TextArea = true; @@ -1680,7 +1686,7 @@ namespace NLGUI // nlinfo("textarea name '%s'", _TextAreaName.c_str()); // nlinfo("textarea %d %d", _TextAreaRow, _TextAreaCols); // nlinfo("textarea content '%s'", _TextAreaContent.toUtf8().c_str()); - CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent); + CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); if (textArea) { // Add the text area to the form @@ -3258,7 +3264,7 @@ namespace NLGUI // *************************************************************************** - CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content) + CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content, uint maxlength) { // In a paragraph ? if (!_Paragraph) @@ -3280,7 +3286,8 @@ namespace NLGUI templateParams.push_back (std::pair ("multiline", multiLine?"true":"false")); templateParams.push_back (std::pair ("want_return", multiLine?"true":"false")); templateParams.push_back (std::pair ("enter_recover_focus", "false")); - templateParams.push_back (std::pair ("max_num_chars", "1024")); + if (maxlength > 0) + templateParams.push_back (std::pair ("max_num_chars", toString(maxlength))); CInterfaceGroup *textArea = CWidgetManager::getInstance()->getParser()->createGroupInstance (templateName.c_str(), getParagraph()->getId(), templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size()); diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp index 1e5f7a226..0b759a7aa 100644 --- a/code/nel/src/gui/libwww.cpp +++ b/code/nel/src/gui/libwww.cpp @@ -201,6 +201,7 @@ namespace NLGUI HTML_ATTR(TEXTAREA,DISABLED), HTML_ATTR(TEXTAREA,ID), HTML_ATTR(TEXTAREA,LANG), + HTML_ATTR(TEXTAREA,MAXLENGTH), HTML_ATTR(TEXTAREA,NAME), HTML_ATTR(TEXTAREA,READONLY), HTML_ATTR(TEXTAREA,ROWS), From c6df57adf1267e12841cbd18740033ede6613a36 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 18:20:29 +0200 Subject: [PATCH 042/344] Initialize struct member before use... --HG-- branch : develop --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 751e72149..5bea65771 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1851,6 +1851,9 @@ bool CDriverGL::setMode(const GfxMode& mode) #if defined(NL_OS_WINDOWS) // save relative cursor POINT cursorPos; + cursorPos.x = 0; + cursorPos.y = 0; + BOOL cursorPosOk = isSystemCursorInClientArea() && GetCursorPos(&cursorPos) && ScreenToClient(_win, &cursorPos); From 4797b150d8015c209ef3f268d0dc69f449d641d4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 19:54:19 +0200 Subject: [PATCH 043/344] Move the text too with the text button. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/view_text.h | 9 ++++++++- code/nel/src/gui/ctrl_text_button.cpp | 22 ++++++++++------------ code/nel/src/gui/view_text.cpp | 13 +++++++++++-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index df3cf27e3..e7cc54d82 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -202,7 +202,11 @@ namespace NLGUI REFLECT_EXPORT_END - virtual void serial(NLMISC::IStream &f); + virtual void serial(NLMISC::IStream &f); + + // Sets the parent element + // See the comment at the field + void setParentElm( CInterfaceElement *parent ){ _ParentElm = parent; } protected: std::string _HardtextFormat; @@ -379,6 +383,9 @@ namespace NLGUI /// Dynamic tooltips std::vector _Tooltips; + // Parent element is the element where this text belongs to + // For example: text button + CInterfaceElement *_ParentElm; private: void setup (); diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index d3a0f6765..b14fb27ca 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -66,8 +66,6 @@ namespace NLGUI { if( _ViewText != NULL ) { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); delete _ViewText; _ViewText = NULL; } @@ -569,6 +567,7 @@ namespace NLGUI ((CViewTextID*)_ViewText)->parseTextIdOptions(cur); // Same RenderLayer as us. _ViewText->setRenderLayer(getRenderLayer()); + _ViewText->setParentElm(this); // Parse the hardText (if not text id) if(!_IsViewTextId) { @@ -863,6 +862,12 @@ namespace NLGUI } if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); + + // When dragging the button, the text needs to move too + if( CInterfaceElement::editorMode ) + _ViewText->updateCoords(); + + _ViewText->draw(); } } @@ -873,6 +878,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); + _ViewText->updateCoords(); + // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) { @@ -910,15 +917,13 @@ namespace NLGUI } // setup the viewText and add to parent - _ViewText->setParent (getParent()); + _ViewText->setParentElm (this); _ViewText->setParentPos (this); _ViewText->setParentPosRef (_TextParentPosRef); _ViewText->setPosRef (_TextPosRef); _ViewText->setActive(_Active); _ViewText->setX(_TextX); _ViewText->setY(_TextY); - - getParent()->addView(_ViewText); } // *************************************************************************** @@ -1007,17 +1012,10 @@ namespace NLGUI // *************************************************************************** void CCtrlTextButton::onRemoved() { - if( _ViewText != NULL ) - { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); - } } void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { - if( e == _ViewText ) - _ViewText = NULL; } } diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6ff1930af..602126dd8 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1814,9 +1814,18 @@ namespace NLGUI if (_AutoClamp) { CViewBase::updateCoords (); - if (_Parent) + + // If there's no parent, try the parent of the parent element. + // Since we will be under the same group + CInterfaceGroup *parent = _Parent; + if( parent == NULL ) + { + if( _ParentElm != NULL ) + parent = _ParentElm->getParent(); + } + + if (parent) { - CInterfaceGroup *parent = _Parent; // avoid resizing parents to compute the limiter while (parent && (parent->getResizeFromChildW() || parent->isGroupList() )) { From 0055e2dd91d95c562c9620fddf01908f719895b8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:15:46 +0200 Subject: [PATCH 044/344] A little refactoring. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/ctrl_text_button.h | 1 + code/nel/include/nel/gui/interface_element.h | 8 ++++++++ code/nel/src/gui/ctrl_text_button.cpp | 12 ++++++++---- code/nel/src/gui/widget_manager.cpp | 4 +--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index 183b6a65e..d2b49ffa9 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -126,6 +126,7 @@ namespace NLGUI void onRemoved(); void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); protected: diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index db7a499c8..048ec4b6e 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -510,6 +510,14 @@ namespace NLGUI /// so other widgets in the group can check if it belongs to them virtual void onWidgetDeleted( CInterfaceElement *e ){} + /// Move the element by x in the X direction and y in the Y direction + // Uses real coordinates + virtual void moveBy( sint32 x, sint32 y ) + { + _XReal += x; + _YReal += y; + } + protected: bool editorSelected; diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index b14fb27ca..03db2b797 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -863,10 +863,6 @@ namespace NLGUI if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); - // When dragging the button, the text needs to move too - if( CInterfaceElement::editorMode ) - _ViewText->updateCoords(); - _ViewText->draw(); } } @@ -1017,5 +1013,13 @@ namespace NLGUI void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { } + + void CCtrlTextButton::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + if( _ViewText != NULL ) + _ViewText->updateCoords(); + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 54b180ef1..5b51fcb6b 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,9 +2633,7 @@ namespace NLGUI sint32 dx = newX - oldX; sint32 dy = newY - oldY; - draggedElement->setXReal( draggedElement->getXReal() + dx ); - draggedElement->setYReal( draggedElement->getYReal() + dy ); - draggedElement->invalidateCoords(); + draggedElement->moveBy( dx, dy ); } } From 22d9accae616b7bf2c655d148c7454e84a39d9bd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:54:44 +0200 Subject: [PATCH 045/344] When moving a widget, save the reference to the hierarchy lookup map... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_hierarchy.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index d52f55e27..5605d6439 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -279,13 +279,15 @@ namespace GUIEditor // Remove reference to old item widgetHierarchyMap.erase( oldid ); - + // Add new item item = new QTreeWidgetItem(); item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - + + // Add reference to new item + widgetHierarchyMap[ newid ] = item; selectItem( item ); } From 2603ad3a2ba040e2ee2ffbc1fe1606553c10b95b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 21:48:51 +0200 Subject: [PATCH 046/344] Refactoring. Added CInterfaceFactory. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_factory.h | 35 ++++++++++++++++++++ code/nel/src/gui/ctrl_text_button.cpp | 3 +- code/nel/src/gui/group_editbox.cpp | 3 +- code/nel/src/gui/interface_factory.cpp | 29 ++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 code/nel/include/nel/gui/interface_factory.h create mode 100644 code/nel/src/gui/interface_factory.cpp diff --git a/code/nel/include/nel/gui/interface_factory.h b/code/nel/include/nel/gui/interface_factory.h new file mode 100644 index 000000000..bd7f8352a --- /dev/null +++ b/code/nel/include/nel/gui/interface_factory.h @@ -0,0 +1,35 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef IFACE_FACTORY +#define IFACE_FACTORY + +#include + +namespace NLGUI +{ + class CViewBase; + + /// Simple interface element ( widget ) factory + class CInterfaceFactory + { + public: + static CViewBase* createClass( const std::string &name ); + }; +} + + +#endif diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index 03db2b797..a3a10d93e 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -23,6 +23,7 @@ #include "nel/gui/group_container_base.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/widget_manager.h" +#include "nel/gui/interface_factory.h" #include "nel/misc/i18n.h" using namespace std; @@ -904,7 +905,7 @@ namespace NLGUI if( _ViewText == NULL ) { - CViewBase *v = CWidgetManager::getInstance()->getParser()->createClass( "text" ); + CViewBase *v = CInterfaceFactory::createClass( "text" ); nlassert( v != NULL ); _ViewText = dynamic_cast< CViewText* >( v ); _ViewText->setId( _Id + "_text" ); diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index c18c69134..ba65a07c4 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -27,6 +27,7 @@ #include "nel/gui/widget_manager.h" #include "nel/gui/view_renderer.h" #include "nel/gui/db_manager.h" +#include "nel/gui/interface_factory.h" #include using namespace std; @@ -1543,7 +1544,7 @@ namespace NLGUI if( editorMode ) { nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() ); - _ViewText = dynamic_cast< CViewText* >( CWidgetManager::getInstance()->getParser()->createClass( "text" ) ); + _ViewText = dynamic_cast< CViewText* >( CInterfaceFactory::createClass( "text" ) ); if( _ViewText != NULL ) { _ViewText->setParent( this ); diff --git a/code/nel/src/gui/interface_factory.cpp b/code/nel/src/gui/interface_factory.cpp new file mode 100644 index 000000000..ec914baa6 --- /dev/null +++ b/code/nel/src/gui/interface_factory.cpp @@ -0,0 +1,29 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "nel/gui/interface_factory.h" +#include "nel/gui/view_base.h" +#include "nel/misc/factory.h" + +namespace NLGUI +{ + CViewBase* CInterfaceFactory::createClass( const std::string &name ) + { + return NLMISC_GET_FACTORY( CViewBase, std::string ).createObject( std::string( name ) , CViewBase::TCtorParam() ); + } +} + + From 86007c9156b50455d7140a3c13e49ebc56fa354c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:23:22 +0200 Subject: [PATCH 047/344] Posref changes in the editor should apply... --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 4 ++-- code/nel/src/gui/widget_manager.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 0225d2797..981d93a9b 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -226,13 +226,13 @@ namespace NLGUI else if( name == "posref" ) { - convertHotSpot( value.c_str() ); + _PosRef = convertHotSpot( value.c_str() ); return; } else if( name == "parentposref" ) { - convertHotSpot( value.c_str() ); + _ParentPosRef = convertHotSpot( value.c_str() ); } else if( name == "sizeref" ) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b51fcb6b..92b94b112 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,6 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); + //e->setName( "==MARKED==" ); + draggedElement = NULL; onWidgetMoved( oldid, e->getId() ); From 4571038fa665c8000e00f6ee04f1914139baf18c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:38:24 +0200 Subject: [PATCH 048/344] Update CCtrlTextButton's CViewText's coords after updating it's own coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/ctrl_text_button.cpp | 5 ++++- code/nel/src/gui/widget_manager.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index a3a10d93e..cdf9ea0d2 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -875,7 +875,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); - _ViewText->updateCoords(); + if( _Name == "==MARKED==" ) + bool marked = true; // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) @@ -890,6 +891,8 @@ namespace NLGUI } CViewBase::updateCoords(); + + _ViewText->updateCoords(); } // *************************************************************************** diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 92b94b112..65c3e101e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,7 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - //e->setName( "==MARKED==" ); + e->setName( "==MARKED==" ); draggedElement = NULL; From d2587df8c14cb748e7ff1031ce59ef2dd3ba0b46 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 20:29:04 +0200 Subject: [PATCH 049/344] From now on dragged widgets will be re-aligned on drop. They will find the nearest hotspot of the group they are dropped into, and calculate an offset so they will align to the hotspot and yet remain where they were dropped. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 9 ++ code/nel/src/gui/interface_element.cpp | 91 ++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 048ec4b6e..3b095ac85 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -518,6 +518,15 @@ namespace NLGUI _YReal += y; } + /// Retrieves the coordinates of the specified hotspot + void getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const; + + /// Tells which hotspot is the closest to the specified element + void getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ); + + /// Aligns the element to the other element specified + void alignTo( CInterfaceElement *other ); + protected: bool editorSelected; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 981d93a9b..75fee53f2 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1594,6 +1594,97 @@ namespace NLGUI } } + void CInterfaceElement::getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const + { + x = _XReal; + y = _YReal; + + if( ( hs & Hotspot_Mx ) != 0 ) + y += _HReal / 2; + else + if( ( hs & Hotspot_Tx ) != 0 ) + y += _HReal; + + + if( ( hs & Hotspot_xM ) != 0 ) + x += _WReal / 2; + else + if( ( hs & Hotspot_xR ) != 0 ) + x += _WReal; + } + + void CInterfaceElement::getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ) + { + /// Iterate over the following hotspots, calculate the distance and store the closest + + + static THotSpot hslist[] = + { + Hotspot_BL, + Hotspot_BR, + Hotspot_MM, + Hotspot_TL, + Hotspot_TR + }; + + int c = sizeof( hslist ) / sizeof( THotSpot ); + + int x,y,ox,oy,vx,vy; + float d; + float closestd = 9999999.0f; + THotSpot closestHS = Hotspot_TR; + + for( int i = 0; i < c; i++ ) + { + other->getHSCoords( hslist[ i ], ox, oy ); + getHSCoords( hslist[ i ], x, y ); + + // Make a vector between the two hotspots + vx = x - ox; + vy = y - oy; + + // Calculate length + d = sqrt( pow( vx, 2.0f ) + pow( vy, 2.0f ) ); + + // If these hotspots are the closest, store the hotspot + if( d < closestd ) + { + closestd = d; + closestHS = hslist[ i ]; + } + } + + hs = closestHS; + } + + void CInterfaceElement::alignTo( CInterfaceElement *other ) + { + if( other == this ) + return; + + // Check which hotspot is the closest + THotSpot hs; + other->getClosestHotSpot( this, hs ); + + // Get the hotspot coordinates + sint32 x, y, ox, oy; + getHSCoords( hs, x, y ); + other->getHSCoords( hs, ox, oy ); + + // Calculate the difference between the hotspot we found and our current position, + sint32 dx = ox - x; + sint32 dy = oy - y; + + // This difference is our offset, so we remain in the same position + setX( -1 * dx ); + setY( -1 * dy ); + + setPosRef( hs ); + setParentPosRef( hs ); + + invalidateCoords(); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 65c3e101e..ec22798fb 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - e->setName( "==MARKED==" ); + e->alignTo( g ); + //e->setName( "==MARKED==" ); draggedElement = NULL; From 3e209147b078c149a8de5a0599127da0c2e4afea Mon Sep 17 00:00:00 2001 From: nimetu Date: Tue, 30 Sep 2014 11:16:28 +0000 Subject: [PATCH 050/344] static libxml2 under linux requires lzma (tested on fedora/debian) --HG-- branch : nimetu/static-libxml2-under-linux-requires-lzma-1412075714030 --- code/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 071554e06..e0f3fe7ba 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -110,6 +110,10 @@ FIND_PACKAGE(Jpeg) IF(WITH_STATIC_LIBXML2) SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) + IF(NOT WIN32 AND NOT APPLE) + FIND_PACKAGE(LibLZMA REQUIRED) + SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) + ENDIF(NOT WIN32 AND NOT APPLE) ENDIF(WITH_STATIC_LIBXML2) IF(WITH_STATIC) From dcf2906b94555b4e6d74b3a824d7a5239ec0248f Mon Sep 17 00:00:00 2001 From: nimetu Date: Tue, 30 Sep 2014 11:23:16 +0000 Subject: [PATCH 051/344] find lua version for luabind under fedora --HG-- branch : nimetu/find-lua-version-for-luabind-under-fedor-1412076128442 --- code/CMakeModules/FindLuabind.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/CMakeModules/FindLuabind.cmake b/code/CMakeModules/FindLuabind.cmake index f61885be8..14f67ce44 100644 --- a/code/CMakeModules/FindLuabind.cmake +++ b/code/CMakeModules/FindLuabind.cmake @@ -11,6 +11,12 @@ MACRO(FIND_CORRECT_LUA_VERSION) SET(LUA52_LIBRARY "liblua5.2") CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA52_LIBRARY LUALIB_FOUND) + + IF(NOT LUALIB_FOUND) + # fedora (v20) + SET(LUA52_LIBRARY "liblua-5.2") + CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA52_LIBRARY LUALIB_FOUND) + ENDIF(NOT LUALIB_FOUND) IF(LUALIB_FOUND) MESSAGE(STATUS "Luabind is using Lua 5.2") From 65b902970a5a0e6547adad1cdf45c41f5c75d779 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Fri, 26 Sep 2014 22:30:56 +0200 Subject: [PATCH 052/344] ref #206 : rolling back to include a crypt(3) implementation and adding sha512 support --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 - code/ryzom/common/src/game_share/crypt.cpp | 985 ++++++++++++++++++ .../src/game_share/{ccrypt.h => crypt.h} | 0 .../common/src/game_share/crypt_sha512.cpp | 371 +++++++ .../src/monitor_service/service_main.cpp | 2 +- 6 files changed, 1358 insertions(+), 32 deletions(-) delete mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp create mode 100644 code/ryzom/common/src/game_share/crypt.cpp rename code/ryzom/common/src/game_share/{ccrypt.h => crypt.h} (100%) create mode 100644 code/ryzom/common/src/game_share/crypt_sha512.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 673a5b5f4..091e24a80 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp deleted file mode 100644 index ea67cf7d6..000000000 --- a/code/ryzom/common/src/game_share/ccrypt.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "ccrypt.h" - -#define _GNU_SOURCE 1 -#include - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::crypt(password.c_str(), salt.c_str()); - - return result; -} diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp new file mode 100644 index 000000000..881b42f1e --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -0,0 +1,985 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "crypt.h" + +char * rz_crypt(register const char *key, register const char *setting); +char *__crypt_sha512(const char *key, const char *setting, char *output); + + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::rz_crypt(password.c_str(), salt.c_str()); + + return result; +} + + + + + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* #include */ +#include +#include +#define RZ__PASSWORD_EFMT1 '-' + +#if DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows); +#endif + +/* + * UNIX password, and DES, encryption. + * By Tom Truscott, trt@rti.rti.org, + * from algorithms by Robert W. Baldwin and James Gillogly. + * + * References: + * "Mathematical Cryptology for Computer Scientists and Mathematicians," + * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. + * + * "Password Security: A Case History," R. Morris and Ken Thompson, + * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. + * + * "DES will be Totally Insecure within Ten Years," M.E. Hellman, + * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. + */ + +/* ===== Configuration ==================== */ + +/* + * define "MUST_ALIGN" if your compiler cannot load/store + * long integers at arbitrary (e.g. odd) memory locations. + * (Either that or never pass unaligned addresses to des_cipher!) + */ +#if !defined(vax) +#define MUST_ALIGN +#endif + +#ifdef CHAR_BITS +#if CHAR_BITS != 8 + #error C_block structure assumes 8 bit characters +#endif +#endif + +/* + * define "LONG_IS_32_BITS" only if sizeof(long)==4. + * This avoids use of bit fields (your compiler may be sloppy with them). + */ +#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) +#define LONG_IS_32_BITS +#endif + +/* + * define "B64" to be the declaration for a 64 bit integer. + * XXX this feature is currently unused, see "endian" comment below. + */ +#if defined(cray) || defined(__LP64__) || defined(_LP64) +#define B64 long +#endif +#if defined(convex) +#define B64 long long +#endif + +/* + * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes + * of lookup tables. This speeds up des_setkey() and des_cipher(), but has + * little effect on crypt(). + */ +#if defined(notdef) +#define LARGEDATA +#endif + +/* ==================================== */ + +/* + * Cipher-block representation (Bob Baldwin): + * + * DES operates on groups of 64 bits, numbered 1..64 (sigh). One + * representation is to store one bit per byte in an array of bytes. Bit N of + * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. + * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the + * first byte, 9..16 in the second, and so on. The DES spec apparently has + * bit 1 in the MSB of the first byte, but that is particularly noxious so we + * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is + * the MSB of the first byte. Specifically, the 64-bit input data and key are + * converted to LSB format, and the output 64-bit block is converted back into + * MSB format. + * + * DES operates internally on groups of 32 bits which are expanded to 48 bits + * by permutation E and shrunk back to 32 bits by the S boxes. To speed up + * the computation, the expansion is applied only once, the expanded + * representation is maintained during the encryption, and a compression + * permutation is applied only at the end. To speed up the S-box lookups, + * the 48 bits are maintained as eight 6 bit groups, one per byte, which + * directly feed the eight S-boxes. Within each byte, the 6 bits are the + * most significant ones. The low two bits of each byte are zero. (Thus, + * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the + * first byte in the eight byte representation, bit 2 of the 48 bit value is + * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is + * used, in which the output is the 64 bit result of an S-box lookup which + * has been permuted by P and expanded by E, and is ready for use in the next + * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this + * lookup. Since each byte in the 48 bit path is a multiple of four, indexed + * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and + * "salt" are also converted to this 8*(6+2) format. The SPE table size is + * 8*64*8 = 4K bytes. + * + * To speed up bit-parallel operations (such as XOR), the 8 byte + * representation is "union"ed with 32 bit values "i0" and "i1", and, on + * machines which support it, a 64 bit value "b64". This data structure, + * "C_block", has two problems. First, alignment restrictions must be + * honored. Second, the byte-order (e.g. little-endian or big-endian) of + * the architecture becomes visible. + * + * The byte-order problem is unfortunate, since on the one hand it is good + * to have a machine-independent C_block representation (bits 1..8 in the + * first byte, etc.), and on the other hand it is good for the LSB of the + * first byte to be the LSB of i0. We cannot have both these things, so we + * currently use the "little-endian" representation and avoid any multi-byte + * operations that depend on byte order. This largely precludes use of the + * 64-bit datatype since the relative order of i0 and i1 are unknown. It + * also inhibits grouping the SPE table to look up 12 bits at a time. (The + * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 + * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the + * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup + * requires a 128 kilobyte table, so perhaps this is not a big loss. + * + * Permutation representation (Jim Gillogly): + * + * A transformation is defined by its effect on each of the 8 bytes of the + * 64-bit input. For each byte we give a 64-bit output that has the bits in + * the input distributed appropriately. The transformation is then the OR + * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for + * each transformation. Unless LARGEDATA is defined, however, a more compact + * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. + * The smaller table uses 16*16*8 = 2K bytes for each transformation. This + * is slower but tolerable, particularly for password encryption in which + * the SPE transformation is iterated many times. The small tables total 9K + * bytes, the large tables total 72K bytes. + * + * The transformations used are: + * IE3264: MSB->LSB conversion, initial permutation, and expansion. + * This is done by collecting the 32 even-numbered bits and applying + * a 32->64 bit transformation, and then collecting the 32 odd-numbered + * bits and applying the same transformation. Since there are only + * 32 input bits, the IE3264 transformation table is half the size of + * the usual table. + * CF6464: Compression, final permutation, and LSB->MSB conversion. + * This is done by two trivial 48->32 bit compressions to obtain + * a 64-bit block (the bit numbering is given in the "CIFP" table) + * followed by a 64->64 bit "cleanup" transformation. (It would + * be possible to group the bits in the 64-bit block so that 2 + * identical 32->32 bit transformations could be used instead, + * saving a factor of 4 in space and possibly 2 in time, but + * byte-ordering and other complications rear their ugly head. + * Similar opportunities/problems arise in the key schedule + * transforms.) + * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. + * This admittedly baroque 64->64 bit transformation is used to + * produce the first code (in 8*(6+2) format) of the key schedule. + * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. + * It would be possible to define 15 more transformations, each + * with a different rotation, to generate the entire key schedule. + * To save space, however, we instead permute each code into the + * next by using a transformation that "undoes" the PC2 permutation, + * rotates the code, and then applies PC2. Unfortunately, PC2 + * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not + * invertible. We get around that problem by using a modified PC2 + * which retains the 8 otherwise-lost bits in the unused low-order + * bits of each byte. The low-order bits are cleared when the + * codes are stored into the key schedule. + * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. + * This is faster than applying PC2ROT[0] twice, + * + * The Bell Labs "salt" (Bob Baldwin): + * + * The salting is a simple permutation applied to the 48-bit result of E. + * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and + * i+24 of the result are swapped. The salt is thus a 24 bit number, with + * 16777216 possible values. (The original salt was 12 bits and could not + * swap bits 13..24 with 36..48.) + * + * It is possible, but ugly, to warp the SPE table to account for the salt + * permutation. Fortunately, the conditional bit swapping requires only + * about four machine instructions and can be done on-the-fly with about an + * 8% performance penalty. + */ + +typedef union { + unsigned char b[8]; + struct { +#if defined(LONG_IS_32_BITS) + /* long is often faster than a 32-bit bit field */ + long i0; + long i1; +#else + long i0: 32; + long i1: 32; +#endif + } b32; +#if defined(B64) + B64 b64; +#endif +} C_block; + +/* + * Convert twenty-four-bit long in host-order + * to six bits (and 2 low-order zeroes) per char little-endian format. + */ +#define TO_SIX_BIT(rslt, src) { \ + C_block cvt; \ + cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[3] = (unsigned char) (src&0xFF); \ + rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ + } + +/* + * These macros may someday permit efficient use of 64-bit integers. + */ +#define ZERO(d,d0,d1) d0 = 0, d1 = 0 +#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 +#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 +#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 +#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 +#define DCL_BLOCK(d,d0,d1) long d0, d1 + +#if defined(LARGEDATA) + /* Waste memory like crazy. Also, do permutations in line */ +#define LGCHUNKBITS 3 +#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); + STORE(D,D0,D1,*out); +} +#endif /* LARGEDATA */ + + +/* ===== (mostly) Standard DES Tables ==================== */ + +static unsigned char IP[] = { /* initial permutation */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* The final permutation is the inverse of IP - no table is necessary */ + +static unsigned char ExpandTr[] = { /* expansion operation */ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +static unsigned char PC1[] = { /* permuted choice table 1 */ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +static unsigned char Rotates[] = { /* PC1 rotation schedule */ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* note: each "row" of PC2 is left-padded with bits that make it invertible */ +static unsigned char PC2[] = { /* permuted choice table 2 */ + 9, 18, 14, 17, 11, 24, 1, 5, + 22, 25, 3, 28, 15, 6, 21, 10, + 35, 38, 23, 19, 12, 4, 26, 8, + 43, 54, 16, 7, 27, 20, 13, 2, + + 0, 0, 41, 52, 31, 37, 47, 55, + 0, 0, 30, 40, 51, 45, 33, 48, + 0, 0, 44, 49, 39, 56, 34, 53, + 0, 0, 46, 42, 50, 36, 29, 32, +}; + +static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ + /* S[1] */ + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + /* S[2] */ + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + /* S[3] */ + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + /* S[4] */ + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + /* S[5] */ + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + /* S[6] */ + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + /* S[7] */ + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + /* S[8] */ + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} +}; + +static unsigned char P32Tr[] = { /* 32-bit permutation function */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +static unsigned char CIFP[] = { /* compressed/interleaved permutation */ + 1, 2, 3, 4, 17, 18, 19, 20, + 5, 6, 7, 8, 21, 22, 23, 24, + 9, 10, 11, 12, 25, 26, 27, 28, + 13, 14, 15, 16, 29, 30, 31, 32, + + 33, 34, 35, 36, 49, 50, 51, 52, + 37, 38, 39, 40, 53, 54, 55, 56, + 41, 42, 43, 44, 57, 58, 59, 60, + 45, 46, 47, 48, 61, 62, 63, 64, +}; + +static unsigned char itoa64[] = /* 0..63 => ascii-64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + +/* ===== Tables that are initialized at run time ==================== */ + + +static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ + +/* Initial key schedule permutation */ +static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ +static C_block CF6464[64/CHUNKBITS][1<= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + num_iter = (num_iter<<6) | a64toi[t]; + } + setting += 4; + encp += 4; + salt_size = 4; + break; + default: + num_iter = 25; + salt_size = 2; + } + + salt = 0; + for (i = salt_size; --i >= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + salt = (salt<<6) | a64toi[t]; + } + encp += salt_size; + if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, + salt, num_iter)) + return (NULL); + + /* + * Encode the 64 cipher bits as 11 ascii characters. + */ + i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; + + encp[3] = 0; + + return (cryptresult); +} + + +/* + * The Key Schedule, filled in by des_setkey() or setkey(). + */ +#define KS_SIZE 16 +static C_block KS[KS_SIZE]; + +/* + * Set up the key schedule from the key. + */ +int rz_des_setkey(register const char *key) { + register DCL_BLOCK(K, K0, K1); + register C_block *ptabp; + register int i; + static int des_ready = 0; + + if (!des_ready) { + rz_init_des(); + des_ready = 1; + } + + PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); + key = (char *)&KS[0]; + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + for (i = 1; i < 16; i++) { + key += sizeof(C_block); + STORE(K,K0,K1,*(C_block *)key); + ptabp = (C_block *)PC2ROT[Rotates[i]-1]; + PERM6464(K,K0,K1,(unsigned char *)key,ptabp); + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + } + return (0); +} + +/* + * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) + * iterations of DES, using the given 24-bit salt and the pre-computed key + * schedule, and store the resulting 8 chars at "out" (in == out is permitted). + * + * NOTE: the performance of this routine is critically dependent on your + * compiler and machine architecture. + */ +int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { + /* variables that we want in registers, most important first */ +#if defined(pdp11) + register int j; +#endif + register long L0, L1, R0, R1, k; + register C_block *kp; + register int ks_inc, loop_count; + C_block B; + + L0 = salt; + TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ + +#if defined(vax) || defined(pdp11) + salt = ~salt; /* "x &~ y" is faster than "x & y". */ +#define SALT (~salt) +#else +#define SALT salt +#endif + +#if defined(MUST_ALIGN) + B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; + B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; + LOAD(L,L0,L1,B); +#else + LOAD(L,L0,L1,*(C_block *)in); +#endif + LOADREG(R,R0,R1,L,L0,L1); + L0 &= 0x55555555L; + L1 &= 0x55555555L; + L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ + R0 &= 0xaaaaaaaaL; + R1 = (R1 >> 1) & 0x55555555L; + L1 = R0 | R1; /* L1 is the odd-numbered input bits */ + STORE(L,L0,L1,B); + PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ + PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ + + if (num_iter >= 0) + { /* encryption */ + kp = &KS[0]; + ks_inc = sizeof(*kp); + } + else + { /* decryption */ + num_iter = -num_iter; + kp = &KS[KS_SIZE-1]; + ks_inc = -((int) sizeof(*kp)); + } + + while (--num_iter >= 0) { + loop_count = 8; + do { + +#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) +#if defined(gould) + /* use this if B.b[i] is evaluated just once ... */ +#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); +#else +#if defined(pdp11) + /* use this if your "long" int indexing is slow */ +#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); +#else + /* use this if "k" is allocated to a register ... */ +#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); +#endif +#endif + +#define CRUNCH(p0, p1, q0, q1) \ + k = (q0 ^ q1) & SALT; \ + B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ + B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ + kp = (C_block *)((char *)kp+ks_inc); \ + \ + DOXOR(p0, p1, 0); \ + DOXOR(p0, p1, 1); \ + DOXOR(p0, p1, 2); \ + DOXOR(p0, p1, 3); \ + DOXOR(p0, p1, 4); \ + DOXOR(p0, p1, 5); \ + DOXOR(p0, p1, 6); \ + DOXOR(p0, p1, 7); + + CRUNCH(L0, L1, R0, R1); + CRUNCH(R0, R1, L0, L1); + } while (--loop_count != 0); + kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); + + + /* swap L and R */ + L0 ^= R0; L1 ^= R1; + R0 ^= L0; R1 ^= L1; + L0 ^= R0; L1 ^= R1; + } + + /* store the encrypted (or decrypted) result */ + L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); + L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); + STORE(L,L0,L1,B); + PERM6464(L,L0,L1,B.b, (C_block *)CF6464); +#if defined(MUST_ALIGN) + STORE(L,L0,L1,B); + out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; + out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; +#else + STORE(L,L0,L1,*(C_block *)out); +#endif + return (0); +} + + +/* + * Initialize various tables. This need only be done once. It could even be + * done at compile time, if the compiler were capable of that sort of thing. + */ +/* STATIC */void rz_init_des() { + register int i, j; + register long k; + register int tableno; + static unsigned char perm[64], tmp32[32]; /* "static" for speed */ + + /* + * table that converts chars "./0-9A-Za-z"to integers 0-63. + */ + for (i = 0; i < 64; i++) + a64toi[itoa64[i]] = i; + + /* + * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. + */ + for (i = 0; i < 64; i++) + perm[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += Rotates[0]-1; + if ((k%28) < Rotates[0]) k -= 28; + k = PC1[k]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i] = (unsigned char) k; + } +#ifdef DEBUG_CRYPT + prtab("pc1tab", perm, 8); +#endif + rz_init_perm(PC1ROT, perm, 8, 8); + + /* + * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. + */ + for (j = 0; j < 2; j++) { + unsigned char pc2inv[64]; + for (i = 0; i < 64; i++) + perm[i] = pc2inv[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + pc2inv[k-1] = i+1; + } + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += j; + if ((k%28) <= j) k -= 28; + perm[i] = pc2inv[k]; + } +#ifdef DEBUG_CRYPT + prtab("pc2tab", perm, 8); +#endif + rz_init_perm(PC2ROT[j], perm, 8, 8); + } + + /* + * Bit reverse, then initial permutation, then expansion. + */ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; + if (k > 32) + k -= 32; + else if (k > 0) + k--; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i*8+j] = (unsigned char) k; + } + } +#ifdef DEBUG_CRYPT + prtab("ietab", perm, 8); +#endif + rz_init_perm(IE3264, perm, 4, 8); + + /* + * Compression, then final permutation, then bit reverse. + */ + for (i = 0; i < 64; i++) { + k = IP[CIFP[i]-1]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[k-1] = i+1; + } +#ifdef DEBUG_CRYPT + prtab("cftab", perm, 8); +#endif + rz_init_perm(CF6464, perm, 8, 8); + + /* + * SPE table + */ + for (i = 0; i < 48; i++) + perm[i] = P32Tr[ExpandTr[i]-1]; + for (tableno = 0; tableno < 8; tableno++) { + for (j = 0; j < 64; j++) { + k = (((j >> 0) &01) << 5)| + (((j >> 1) &01) << 3)| + (((j >> 2) &01) << 2)| + (((j >> 3) &01) << 1)| + (((j >> 4) &01) << 0)| + (((j >> 5) &01) << 4); + k = S[tableno][k]; + k = (((k >> 3)&01) << 0)| + (((k >> 2)&01) << 1)| + (((k >> 1)&01) << 2)| + (((k >> 0)&01) << 3); + for (i = 0; i < 32; i++) + tmp32[i] = 0; + for (i = 0; i < 4; i++) + tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i]-1]; + TO_SIX_BIT(SPE[0][tableno][j], k); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i+24]-1]; + TO_SIX_BIT(SPE[1][tableno][j], k); + } + } +} + +/* + * Initialize "perm" to represent transformation "p", which rearranges + * (perhaps with expansion and/or contraction) one packed array of bits + * (of size "chars_in" characters) into another array (of size "chars_out" + * characters). + * + * "perm" must be all-zeroes on entry to this routine. + */ +/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ + l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ + for (j = 0; j < (1<>3] |= 1<<(k&07); + } + } +} + +/* + * "setkey" routine (for backwards compatibility) + */ +int rz_setkey(register const char *key) { + register int i, j, k; + C_block keyblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*key++; + } + keyblock.b[i] = k; + } + return (rz_des_setkey((char *)keyblock.b)); +} + +/* + * "encrypt" routine (for backwards compatibility) + */ +int rz_encrypt(register char *block, int flag) { + register int i, j, k; + C_block cblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*block++; + } + cblock.b[i] = k; + } + if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) + return (1); + for (i = 7; i >= 0; i--) { + k = cblock.b[i]; + for (j = 7; j >= 0; j--) { + *--block = k&01; + k >>= 1; + } + } + return (0); +} + +#ifdef DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows) +{ + register int i, j; + + (void)printf("%s:\n", s); + for (i = 0; i < num_rows; i++) { + for (j = 0; j < 8; j++) { + (void)printf("%3d", t[i*8+j]); + } + (void)printf("\n"); + } + (void)printf("\n"); +} +#endif diff --git a/code/ryzom/common/src/game_share/ccrypt.h b/code/ryzom/common/src/game_share/crypt.h similarity index 100% rename from code/ryzom/common/src/game_share/ccrypt.h rename to code/ryzom/common/src/game_share/crypt.h diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp new file mode 100644 index 000000000..c12359485 --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -0,0 +1,371 @@ +/* + * public domain sha512 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha512 implementation based on fips180-3 */ +/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ + +struct sha512 { + uint64_t len; /* processed message length */ + uint64_t h[8]; /* hash state */ + uint8_t buf[128]; /* message block buffer */ +}; + +static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) +#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) +#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) +#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) + +static const uint64_t K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +static void processblock(struct sha512 *s, const uint8_t *buf) +{ + uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint64_t)buf[8*i]<<56; + W[i] |= (uint64_t)buf[8*i+1]<<48; + W[i] |= (uint64_t)buf[8*i+2]<<40; + W[i] |= (uint64_t)buf[8*i+3]<<32; + W[i] |= (uint64_t)buf[8*i+4]<<24; + W[i] |= (uint64_t)buf[8*i+5]<<16; + W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] |= buf[8*i+7]; + } + for (; i < 80; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 80; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha512 *s) +{ + unsigned r = s->len % 128; + + s->buf[r++] = 0x80; + if (r > 112) { + memset(s->buf + r, 0, 128 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 120 - r); + s->len *= 8; + s->buf[120] = s->len >> 56; + s->buf[121] = s->len >> 48; + s->buf[122] = s->len >> 40; + s->buf[123] = s->len >> 32; + s->buf[124] = s->len >> 24; + s->buf[125] = s->len >> 16; + s->buf[126] = s->len >> 8; + s->buf[127] = s->len; + processblock(s, s->buf); +} + +static void sha512_init(struct sha512 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667f3bcc908ULL; + s->h[1] = 0xbb67ae8584caa73bULL; + s->h[2] = 0x3c6ef372fe94f82bULL; + s->h[3] = 0xa54ff53a5f1d36f1ULL; + s->h[4] = 0x510e527fade682d1ULL; + s->h[5] = 0x9b05688c2b3e6c1fULL; + s->h[6] = 0x1f83d9abfb41bd6bULL; + s->h[7] = 0x5be0cd19137e2179ULL; +} + +static void sha512_sum(struct sha512 *s, uint8_t *md) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[8*i] = s->h[i] >> 56; + md[8*i+1] = s->h[i] >> 48; + md[8*i+2] = s->h[i] >> 40; + md[8*i+3] = s->h[i] >> 32; + md[8*i+4] = s->h[i] >> 24; + md[8*i+5] = s->h[i] >> 16; + md[8*i+6] = s->h[i] >> 8; + md[8*i+7] = s->h[i]; + } +} + +static void sha512_update(struct sha512 *s, const void *m, unsigned long len) +{ + const uint8_t *p = (uint8_t *)m; + unsigned r = s->len % 128; + + s->len += len; + if (r) { + if (len < 128 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 128 - r); + len -= 128 - r; + p += 128 - r; + processblock(s, s->buf); + } + for (; len >= 128; len -= 128, p += 128) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static const unsigned char b64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 9999999 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha512 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 64; i -= 64) + sha512_update(s, md, 64); + sha512_update(s, md, i); +} + +static char *sha512crypt(const char *key, const char *setting, char *output) +{ + struct sha512 ctx; + unsigned char md[64], kmd[64], smd[64]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + for (i = 0; i <= KEY_MAX && key[i]; i++); + if (i > KEY_MAX) + return 0; + klen = i; + + /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$6$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha512_update(&ctx, md, sizeof md); + else + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha512_init(&ctx); + for (i = 0; i < klen; i++) + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha512_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha512_update(&ctx, salt, slen); + sha512_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha512_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha512_update(&ctx, md, sizeof md); + if (i % 3) + sha512_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha512_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha512_sum(&ctx, md); + } + + /* output is $6$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); +#if 1 + static const unsigned char perm[][3] = { + 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, + 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, + 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, + 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, + 62,20,41 }; + for (i=0; i<21; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); +#else + p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); + p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); + p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); + p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); + p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); + p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); + p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); + p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); + p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); + p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); + p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); + p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); + p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); + p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); + p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); + p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); + p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); + p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); + p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); + p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); + p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); +#endif + p = to64(p, md[63], 2); + *p = 0; + return output; +} + +char *__crypt_sha512(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; + static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; + char testbuf[128]; + char *p, *q; + + p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha512crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index aa559b78d..84bbcbe86 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "nel/misc/time_nl.h" #include "client.h" From bb9d0d91d3979dc859210a1ac697820a39f0b34d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 1 Oct 2014 23:24:56 +0200 Subject: [PATCH 053/344] Fix #207, FXAA orientation under D3D --HG-- branch : develop --- code/nel/src/3d/fxaa.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index f19bcd8b4..89d1c59cd 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -148,7 +148,7 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); - if (drv->textureCoordinateAlternativeMode()) + /*if (drv->textureCoordinateAlternativeMode()) { m_QuadUV.Uv0 = CUV(0.f, 1.f); m_QuadUV.Uv1 = CUV(1.f, 1.f); @@ -156,12 +156,12 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_QuadUV.Uv3 = CUV(0.f, 0.f); } else - { + {*/ m_QuadUV.Uv0 = CUV(0.f, 0.f); m_QuadUV.Uv1 = CUV(1.f, 0.f); m_QuadUV.Uv2 = CUV(1.f, 1.f); m_QuadUV.Uv3 = CUV(0.f, 1.f); - } + /*}*/ /*CVertexBuffer &vb = m_VB; vb.clearValueEx(); From 81d5294fc391fa0d8e0c774b0ac89d2e891a6940 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Thu, 2 Oct 2014 18:21:56 +0200 Subject: [PATCH 054/344] ref #206 : removing unused crypt lib reference --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/CMakeLists.txt b/code/ryzom/common/src/game_share/CMakeLists.txt index cbccfd6dd..2648416ec 100644 --- a/code/ryzom/common/src/game_share/CMakeLists.txt +++ b/code/ryzom/common/src/game_share/CMakeLists.txt @@ -30,7 +30,7 @@ NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC} ${R2}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges crypt ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) NL_DEFAULT_PROPS(ryzom_gameshare "Ryzom, Library: Game Share") NL_ADD_RUNTIME_FLAGS(ryzom_gameshare) NL_ADD_LIB_SUFFIX(ryzom_gameshare) From 4c2be7ea1f4452d26bd5dadb4697d222382e7333 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Thu, 2 Oct 2014 19:14:25 +0200 Subject: [PATCH 055/344] ref #206 : hacking the types so it may compile on windows --HG-- branch : sha512-auth --- .../common/src/game_share/crypt_sha512.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index c12359485..fef7465de 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -11,18 +11,18 @@ #include #include #include -#include +#include /* public domain sha512 implementation based on fips180-3 */ /* >=2^64 bits messages are not supported (about 2000 peta bytes) */ struct sha512 { - uint64_t len; /* processed message length */ - uint64_t h[8]; /* hash state */ + uint64 len; /* processed message length */ + uint64 h[8]; /* hash state */ uint8_t buf[128]; /* message block buffer */ }; -static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +static uint64 ror(uint64 n, int k) { return (n >> k) | (n << (64-k)); } #define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Maj(x,y,z) ((x & y) | (z & (x | y))) #define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) @@ -30,7 +30,7 @@ static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } #define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) #define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) -static const uint64_t K[80] = { +static const uint64 K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, @@ -55,17 +55,17 @@ static const uint64_t K[80] = { static void processblock(struct sha512 *s, const uint8_t *buf) { - uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + uint64 W[80], t1, t2, a, b, c, d, e, f, g, h; int i; for (i = 0; i < 16; i++) { - W[i] = (uint64_t)buf[8*i]<<56; - W[i] |= (uint64_t)buf[8*i+1]<<48; - W[i] |= (uint64_t)buf[8*i+2]<<40; - W[i] |= (uint64_t)buf[8*i+3]<<32; - W[i] |= (uint64_t)buf[8*i+4]<<24; - W[i] |= (uint64_t)buf[8*i+5]<<16; - W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] = (uint64)buf[8*i]<<56; + W[i] |= (uint64)buf[8*i+1]<<48; + W[i] |= (uint64)buf[8*i+2]<<40; + W[i] |= (uint64)buf[8*i+3]<<32; + W[i] |= (uint64)buf[8*i+4]<<24; + W[i] |= (uint64)buf[8*i+5]<<16; + W[i] |= (uint64)buf[8*i+6]<<8; W[i] |= buf[8*i+7]; } for (; i < 80; i++) From 25f1aa62472ef71e9420aea3477f3ec0904c2d66 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 4 Oct 2014 01:43:13 +0200 Subject: [PATCH 056/344] Fix a bad copy paste in NLGUI --HG-- branch : develop --- code/nel/src/gui/group_container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index c3a7834c5..aace7b0be 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2856,7 +2856,7 @@ namespace NLGUI else rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col); // Right - if (pLayer->Tile_T == 0) // Tiling ? + if (pLayer->Tile_R == 0) // Tiling ? rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, col); else rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col); From 88a9a809a9f5b63f5762f45d9ede00fb39dbbe19 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 4 Oct 2014 01:43:27 +0200 Subject: [PATCH 057/344] Add inset_t parameter to layer options, allows putting header graphics in top texture --HG-- branch : develop --- code/nel/include/nel/gui/interface_options.h | 3 ++- code/nel/src/gui/group_container.cpp | 20 ++++++++++---------- code/nel/src/gui/interface_options.cpp | 1 + 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/gui/interface_options.h b/code/nel/include/nel/gui/interface_options.h index f52b9479a..6501cd2b0 100644 --- a/code/nel/include/nel/gui/interface_options.h +++ b/code/nel/include/nel/gui/interface_options.h @@ -159,7 +159,8 @@ namespace NLGUI sint32 TxId_B_HighLight; sint32 TxId_BR_HighLight; - sint32 HeaderH; + sint32 HeaderH; + sint32 InsetT; // Offset height of top texture }; // *************************************************************************** diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index aace7b0be..80c561f2e 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2373,7 +2373,7 @@ namespace NLGUI { setMaxH(_PopupMaxH); // _W is given by scripter-man - newH = pLayer->H_T; + newH = (pLayer->H_T - pLayer->InsetT); } else { @@ -2382,7 +2382,7 @@ namespace NLGUI _W = _Parent->getW(); } setMaxH (16384); // No scrollbar for container of layer > 0 - newH = pLayer->H_T; + newH = (pLayer->H_T - pLayer->InsetT); } if (_Opened) @@ -2396,11 +2396,11 @@ namespace NLGUI _HeaderOpened->setY (- newH); _HeaderOpened->setW (_W-(pLayer->W_L+pLayer->W_R)); _HeaderOpened->updateCoords(); - newH += max (_HeaderOpened->getHReal(), pLayer->getValSInt32 ("header_h")); + newH += max (_HeaderOpened->getHReal(), pLayer->HeaderH); } else { - newH += pLayer->getValSInt32 ("header_h"); + newH += pLayer->HeaderH; } newH -= (sint32) _ContentYOffset; @@ -2448,12 +2448,12 @@ namespace NLGUI if (_LayerSetup == 0) { // zeH is the height to substract to total height of the container to obtain height of the list - sint32 zeH = pLayer->H_T + pLayer->H_B_Open + pLayer->H_EM_Open; + sint32 zeH = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open + pLayer->H_EM_Open; if (_HeaderOpened != NULL) - zeH += max (_HeaderOpened->getHReal(), pLayer->getValSInt32 ("header_h")); + zeH += max (_HeaderOpened->getHReal(), pLayer->HeaderH); else - zeH += pLayer->getValSInt32 ("header_h"); + zeH += pLayer->HeaderH; if (_Content != NULL) zeH += _Content->getHReal(); @@ -2513,11 +2513,11 @@ namespace NLGUI _HeaderClosed->setY (-newH); _HeaderClosed->setW (_W-(pLayer->W_L+pLayer->W_R)); _HeaderClosed->updateCoords(); - newH += max (_HeaderClosed->getHReal(), pLayer->getValSInt32 ("header_h")); + newH += max (_HeaderClosed->getHReal(), pLayer->HeaderH); } else { - newH += pLayer->getValSInt32 ("header_h"); + newH += pLayer->HeaderH; } newH += pLayer->H_B; @@ -2731,7 +2731,7 @@ namespace NLGUI // h is the size of what is on top of the child list sint32 x, y, w, h; - h = pLayer->H_T + pLayer->H_B_Open; + h = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open; if (_Opened) { diff --git a/code/nel/src/gui/interface_options.cpp b/code/nel/src/gui/interface_options.cpp index 9f70ceeff..70141e0a3 100644 --- a/code/nel/src/gui/interface_options.cpp +++ b/code/nel/src/gui/interface_options.cpp @@ -281,6 +281,7 @@ namespace NLGUI // HeaderH = getValSInt32("header_h"); + InsetT = getValSInt32("inset_t"); return true; } From b98c6f6a5993cb806b96223329fe29abffa59b39 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 01:14:03 +0200 Subject: [PATCH 058/344] Set version --HG-- branch : develop --- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index 2dfdca48e..1c13b7ed1 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "RYZOM CORE" +#define RYZOM_VERSION "ryzomcore/v0.10.0-dev" #endif // RYZOM_VERSION_H From 650dba5c5175b2c487d46b8c3d887fed3ac319c8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 01:20:57 +0200 Subject: [PATCH 059/344] Require setup upgrade --HG-- branch : sha512-auth --- code/web/public_php/setup/version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/public_php/setup/version.php b/code/web/public_php/setup/version.php index 476c514f0..baffede3f 100644 --- a/code/web/public_php/setup/version.php +++ b/code/web/public_php/setup/version.php @@ -1,6 +1,6 @@ Date: Tue, 7 Oct 2014 01:44:43 +0200 Subject: [PATCH 060/344] Compile fixes --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/crypt_sha512.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index fef7465de..f3ebc5997 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -7,11 +7,13 @@ * in the salt and rounds= setting must contain a valid iteration count, * on error "*" is returned. */ + +#include + #include #include #include #include -#include /* public domain sha512 implementation based on fips180-3 */ /* >=2^64 bits messages are not supported (about 2000 peta bytes) */ @@ -19,7 +21,7 @@ struct sha512 { uint64 len; /* processed message length */ uint64 h[8]; /* hash state */ - uint8_t buf[128]; /* message block buffer */ + uint8 buf[128]; /* message block buffer */ }; static uint64 ror(uint64 n, int k) { return (n >> k) | (n << (64-k)); } @@ -53,7 +55,7 @@ static const uint64 K[80] = { 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; -static void processblock(struct sha512 *s, const uint8_t *buf) +static void processblock(struct sha512 *s, const uint8 *buf) { uint64 W[80], t1, t2, a, b, c, d, e, f, g, h; int i; @@ -136,7 +138,7 @@ static void sha512_init(struct sha512 *s) s->h[7] = 0x5be0cd19137e2179ULL; } -static void sha512_sum(struct sha512 *s, uint8_t *md) +static void sha512_sum(struct sha512 *s, uint8 *md) { int i; @@ -155,7 +157,7 @@ static void sha512_sum(struct sha512 *s, uint8_t *md) static void sha512_update(struct sha512 *s, const void *m, unsigned long len) { - const uint8_t *p = (uint8_t *)m; + const uint8 *p = (uint8 *)m; unsigned r = s->len % 128; s->len += len; From 025d7b6260177cc8e53f50421e2a5677c472d2f1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 03:00:34 +0200 Subject: [PATCH 061/344] Fix crypt --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/crypt.cpp | 16 +++++++--------- code/ryzom/common/src/game_share/crypt.h | 2 +- .../ryzom/common/src/game_share/crypt_sha512.cpp | 4 +++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp index 881b42f1e..9a46281f7 100644 --- a/code/ryzom/common/src/game_share/crypt.cpp +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -18,16 +18,15 @@ #include "crypt.h" -char * rz_crypt(register const char *key, register const char *setting); +char * rz_crypt(register const char *key, register const char *setting, char *buf); char *__crypt_sha512(const char *key, const char *setting, char *output); // Crypts password using salt std::string CCrypt::crypt(const std::string& password, const std::string& salt) { - std::string result = ::rz_crypt(password.c_str(), salt.c_str()); - - return result; + char buf[128]; + return ::rz_crypt(password.c_str(), salt.c_str(), buf); } @@ -506,7 +505,7 @@ static char cryptresult[1+4+4+11+1]; /* encrypted result */ * Return a pointer to static data consisting of the "setting" * followed by an encryption produced by the "key" and "setting". */ -char * rz_crypt(register const char *key, register const char *setting) { +char * rz_crypt(register const char *key, register const char *setting, char *buf) { register char *encp; register long i; register int t; @@ -521,10 +520,9 @@ char * rz_crypt(register const char *key, register const char *setting) { return buff; #endif - static char buf[128]; - if (key[0] == '$' && key[1] == '6') { - return __crypt_sha512(key, setting, buf); - } + if (setting[0] == '$' && setting[1] == '6') { + return __crypt_sha512(key, setting, buf); + } for (i = 0; i < 8; i++) { if ((t = 2*(unsigned char)(*key)) != 0) diff --git a/code/ryzom/common/src/game_share/crypt.h b/code/ryzom/common/src/game_share/crypt.h index ea479d74f..b9fa8556b 100644 --- a/code/ryzom/common/src/game_share/crypt.h +++ b/code/ryzom/common/src/game_share/crypt.h @@ -32,7 +32,7 @@ class CCrypt public: /// Crypts password using salt - static std::string crypt(const std::string& password, const std::string& salt); + static std::string crypt(const std::string& password, const std::string& salt); }; diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index f3ebc5997..4d151880d 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -365,9 +365,11 @@ char *__crypt_sha512(const char *key, const char *setting, char *output) char *p, *q; p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ q = sha512crypt(testkey, testsetting, testbuf); - if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof(testhash))) return "*"; + return p; } From ec6ea26323396499e09d1b3d751ca252bdf61294 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:30:59 +0200 Subject: [PATCH 062/344] Fix when tx_b and tx_b_open have different heights --HG-- branch : develop --- code/nel/src/gui/group_container.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index 80c561f2e..c7d3227e8 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2731,7 +2731,8 @@ namespace NLGUI // h is the size of what is on top of the child list sint32 x, y, w, h; - h = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open; + bool bHasChild = (_List->getNbElement() > 0); + h = (pLayer->H_T - pLayer->InsetT) + (((!_Opened) || (!bHasChild)) ? pLayer->H_B : pLayer->H_B_Open); if (_Opened) { @@ -2749,7 +2750,6 @@ namespace NLGUI { h = _HReal; } - bool bHasChild = (_List->getNbElement() > 0); x = _XReal; y = _YReal+_HReal-h; @@ -2767,7 +2767,7 @@ namespace NLGUI // Top Right rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col); - if ((!_Opened) || (_Opened && !bHasChild)) + if ((!_Opened) || (!bHasChild)) { // Not opened // Left if (pLayer->Tile_L == 0) // Tiling ? @@ -2817,9 +2817,9 @@ namespace NLGUI rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR_Open, y, pLayer->W_BR_Open, pLayer->H_BR_Open, 0, false, pLayer->TxId_BR_Open, col); // Content if (pLayer->Tile_Blank == 0) // Tiling ? - rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col); + rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col); else - rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col); + rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col); // ScrollBar Placement if (pLayer->Tile_M_Open == 0) // Tiling ? rVR.drawRotFlipBitmap (rl, x, _YReal+pLayer->H_EL_Open, pLayer->W_M_Open, _HReal-h-pLayer->H_EL_Open, 0, false, pLayer->TxId_M_Open, col); @@ -2848,7 +2848,7 @@ namespace NLGUI // Top Right rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col); - if ((!_Opened) || (_Opened && !bHasChild)) + if ((!_Opened) || (!bHasChild)) { // Left if (pLayer->Tile_L == 0) // Tiling ? From ec68d2c317ee8724e3c2418cc59f385fddb95850 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:31:13 +0200 Subject: [PATCH 063/344] Fix rendering of specially sized window highlights --HG-- branch : develop --- code/nel/include/nel/gui/interface_options.h | 16 ++++++++-------- code/nel/src/gui/group_container.cpp | 18 ++++++++---------- code/nel/src/gui/interface_options.cpp | 8 ++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/code/nel/include/nel/gui/interface_options.h b/code/nel/include/nel/gui/interface_options.h index 6501cd2b0..da0ea7de8 100644 --- a/code/nel/include/nel/gui/interface_options.h +++ b/code/nel/include/nel/gui/interface_options.h @@ -150,14 +150,14 @@ namespace NLGUI sint32 TxId_E_Open, W_E_Open, H_E_Open; sint32 TxId_M_Open, W_M_Open, H_M_Open; - sint32 TxId_TL_HighLight; - sint32 TxId_T_HighLight; - sint32 TxId_TR_HighLight; - sint32 TxId_L_HighLight; - sint32 TxId_R_HighLight; - sint32 TxId_BL_HighLight; - sint32 TxId_B_HighLight; - sint32 TxId_BR_HighLight; + sint32 TxId_TL_HighLight, W_TL_HighLight, H_TL_HighLight; + sint32 TxId_T_HighLight, W_T_HighLight, H_T_HighLight; + sint32 TxId_TR_HighLight, W_TR_HighLight, H_TR_HighLight; + sint32 TxId_L_HighLight, W_L_HighLight, H_L_HighLight; + sint32 TxId_R_HighLight, W_R_HighLight, H_R_HighLight; + sint32 TxId_BL_HighLight, W_BL_HighLight, H_BL_HighLight; + sint32 TxId_B_HighLight, W_B_HighLight, H_B_HighLight; + sint32 TxId_BR_HighLight, W_BR_HighLight, H_BR_HighLight; sint32 HeaderH; sint32 InsetT; // Offset height of top texture diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index c7d3227e8..5c3a29e8b 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -3003,18 +3003,16 @@ namespace NLGUI col.A = nInverted; else col.A = max(_HighLightedAlpha, nInverted); - sint32 hw, hh; // size of highlight texture - rVR.getTextureSizeFromId(pLayer->TxId_TL_HighLight, hw, hh); // corners - rVR.drawRotFlipBitmap (_RenderLayer, x, y + h - hh, hw, hh, 0, false, pLayer->TxId_TL_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, y + h - hh, hw, hh, 0, false, pLayer->TxId_TR_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal, hw, hh, 0, false, pLayer->TxId_BL_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, _YReal, hw, hh, 0, false, pLayer->TxId_BR_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, y + h - pLayer->H_T_HighLight, pLayer->W_TL_HighLight, pLayer->H_TL_HighLight, 0, false, pLayer->TxId_TL_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_TR_HighLight, y + h - pLayer->H_T_HighLight, pLayer->W_TR_HighLight, pLayer->H_TR_HighLight, 0, false, pLayer->TxId_TR_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal, pLayer->W_BL_HighLight, pLayer->H_BL_HighLight, 0, false, pLayer->TxId_BL_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_BR_HighLight, _YReal, pLayer->W_BR_HighLight, pLayer->H_BR_HighLight, 0, false, pLayer->TxId_BR_HighLight, col); // border - rVR.drawRotFlipBitmap (_RenderLayer, x + hw, y + h - hh, _WReal - 2 * hw, hh, 0, false, pLayer->TxId_T_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + hw, _YReal, _WReal - 2 * hw, hh, 0, false, pLayer->TxId_B_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal + hh, hw, _HReal - 2 * hh, 0, false, pLayer->TxId_L_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, _YReal + hh, hw, _HReal - 2 * hh, 0, false, pLayer->TxId_R_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_TL_HighLight, y + h - pLayer->H_T_HighLight, _WReal - pLayer->W_TL_HighLight - pLayer->W_TR_HighLight, pLayer->H_T_HighLight, 0, false, pLayer->TxId_T_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_BL_HighLight, _YReal, _WReal - pLayer->W_BL_HighLight - pLayer->W_BR_HighLight, pLayer->H_B_HighLight, 0, false, pLayer->TxId_B_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal + pLayer->H_B_HighLight, pLayer->W_L_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_L_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_R_HighLight, _YReal + pLayer->H_B_HighLight, pLayer->W_R_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_R_HighLight, col); } diff --git a/code/nel/src/gui/interface_options.cpp b/code/nel/src/gui/interface_options.cpp index 70141e0a3..3de015d65 100644 --- a/code/nel/src/gui/interface_options.cpp +++ b/code/nel/src/gui/interface_options.cpp @@ -271,13 +271,21 @@ namespace NLGUI // TxId_TL_HighLight = rVR.getTextureIdFromName (getValStr("tx_tl_highlight")); + rVR.getTextureSizeFromId(TxId_TL_HighLight, W_TL_HighLight, H_TL_HighLight); TxId_T_HighLight = rVR.getTextureIdFromName (getValStr("tx_t_highlight")); + rVR.getTextureSizeFromId(TxId_T_HighLight, W_T_HighLight, H_T_HighLight); TxId_TR_HighLight = rVR.getTextureIdFromName (getValStr("tx_tr_highlight")); + rVR.getTextureSizeFromId(TxId_TR_HighLight, W_TR_HighLight, H_TR_HighLight); TxId_L_HighLight = rVR.getTextureIdFromName (getValStr("tx_l_highlight")); + rVR.getTextureSizeFromId(TxId_L_HighLight, W_L_HighLight, H_L_HighLight); TxId_R_HighLight = rVR.getTextureIdFromName (getValStr("tx_r_highlight")); + rVR.getTextureSizeFromId(TxId_R_HighLight, W_R_HighLight, H_R_HighLight); TxId_BL_HighLight = rVR.getTextureIdFromName (getValStr("tx_bl_highlight")); + rVR.getTextureSizeFromId(TxId_BL_HighLight, W_BL_HighLight, H_BL_HighLight); TxId_B_HighLight = rVR.getTextureIdFromName (getValStr("tx_b_highlight")); + rVR.getTextureSizeFromId(TxId_B_HighLight, W_B_HighLight, H_B_HighLight); TxId_BR_HighLight = rVR.getTextureIdFromName (getValStr("tx_br_highlight")); + rVR.getTextureSizeFromId(TxId_BR_HighLight, W_BR_HighLight, H_BR_HighLight); // HeaderH = getValSInt32("header_h"); From dc3238b11102e47e71b869b0fc89ae383e07d176 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:31:45 +0200 Subject: [PATCH 064/344] Disable dumb loading strings --HG-- branch : develop --- code/ryzom/client/client_default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index 2846713fc..55e56b012 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -419,7 +419,7 @@ PrintfCommandsFreeTrial = { DisplayMissingAnimFile = 0; -LoadingStringCount = 54; +LoadingStringCount = 0; // Some R2 parameters ... From 97ddd3573d3ede76420775e282889546389a22ba Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:37:05 +0200 Subject: [PATCH 065/344] Select groups first. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 35 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index ec22798fb..734547512 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2400,21 +2400,34 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) + { + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + { + _CapturedView = g; + captured = true; + break; + } + } - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + if( !captured ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } From 5d5bf860d4729b1114308efa28d015bcfca2fcfe Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:42:18 +0200 Subject: [PATCH 066/344] Reparent items in widget hierarchy instead of deleting and creating a new item... --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/widget_hierarchy.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 5605d6439..1439fea9e 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -269,21 +269,16 @@ namespace GUIEditor if( ( newParent == NULL ) || ( item == NULL ) ) return; - // Remove old item + // Remove item from old parent QTreeWidgetItem *p = item->parent(); if( p != NULL ) p->setExpanded( false ); - id = item->data( 0, Qt::DisplayRole ).toString(); - delete item; - item = NULL; + p->removeChild( item ); // Remove reference to old item widgetHierarchyMap.erase( oldid ); - // Add new item - item = new QTreeWidgetItem(); - item->setData( 0, Qt::DisplayRole, id ); - item->setSelected( true ); + // Add item to new parent newParent->addChild( item ); // Add reference to new item From 64571abd478d9956bf2da10760302b03e83674a8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:52:56 +0200 Subject: [PATCH 067/344] When moving a group draw it's children too. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 2 ++ code/nel/src/gui/interface_group.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index daf6d2d53..62e61373e 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -328,6 +328,8 @@ namespace NLGUI void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 05f210568..ac6b57fb0 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2544,5 +2544,16 @@ namespace NLGUI for( std::vector< CInterfaceGroup* >::iterator itr = _ChildrenGroups.begin(); itr != _ChildrenGroups.end(); ++itr ) (*itr)->onWidgetDeleted( e ); } + + void CInterfaceGroup::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->updateCoords(); + } + } } From ad9e9839fbc7b544e65b26777a7cc581e2402838 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:59:39 +0200 Subject: [PATCH 068/344] Don't try to handle the right mouse button actions in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 734547512..950306750 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2302,6 +2302,14 @@ namespace NLGUI eventDesc.setX( _Pointer->getX() ); eventDesc.setY( _Pointer->getY() ); + if( CInterfaceElement::getEditorMode() ) + { + // Let's pretend we've handled the event... or actually we have! + if( ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) || + ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) ) + return true; + } + if( isMouseHandlingEnabled() ) { // First thing to do : Capture handling From 08b6675b3db7f2fe2030259bd74c261db5f1b295 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:00:54 +0200 Subject: [PATCH 069/344] Only select a group first in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 950306750..f0fbe1b1a 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,14 +2408,17 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) + if( CInterfaceElement::getEditorMode() ) { - CInterfaceGroup *g = _GroupsUnderPointer[ i ]; - if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { - _CapturedView = g; - captured = true; - break; + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + { + _CapturedView = g; + captured = true; + break; + } } } From d7d62e690c0700195bde583f6206e2b920179f54 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:45:17 +0200 Subject: [PATCH 070/344] Make group selection optional. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 +++ code/nel/src/gui/widget_manager.cpp | 3 ++- .../plugins/gui_editor/editor_message_processor.cpp | 5 +++++ .../src/plugins/gui_editor/editor_message_processor.h | 1 + .../src/plugins/gui_editor/gui_editor_window.cpp | 10 ++++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 89023c445..8790fc272 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -516,6 +516,8 @@ namespace NLGUI void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); + + void setGroupSelection( bool b ){ groupSelection = b; } private: CWidgetManager(); @@ -610,6 +612,7 @@ namespace NLGUI std::string currentEditorSelection; + bool groupSelection; }; } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index f0fbe1b1a..c6068b363 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + if( CInterfaceElement::getEditorMode() && groupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3516,6 +3516,7 @@ namespace NLGUI setScreenWH( 0, 0 ); currentEditorSelection = ""; + groupSelection = false; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 691dbdead..e834aa21f 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -130,5 +130,10 @@ namespace GUIEditor e->setActive( false ); e->setActive( true ); } + + void CEditorMessageProcessor::onSetGroupSelection( bool b ) + { + CWidgetManager::getInstance()->setGroupSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5c19a03c2..5d4098272 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -38,6 +38,7 @@ namespace GUIEditor public Q_SLOTS: void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); + void onSetGroupSelection( bool b ); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 9f6568936..3a4f982aa 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,16 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + + // ---------------------------------------------------------------------------------- + m->addSeparator(); + + a = new QAction( "Select groups", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } From 3ffe56b862850eafe088f5abee6df32486943cd3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 20:36:16 +0200 Subject: [PATCH 071/344] Added support for ungrouping. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 3 ++ code/nel/include/nel/gui/widget_manager.h | 1 + code/nel/src/gui/interface_group.cpp | 40 +++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 34 ++++++++++++++++ .../gui_editor/editor_message_processor.cpp | 12 ++++++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 95 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index 62e61373e..cdfd182e7 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -330,6 +330,9 @@ namespace NLGUI void moveBy( sint32 x, sint32 y ); + // Blows up the group, moves it's children to it's parent + bool explode(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8790fc272..917a0e9ba 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -518,6 +518,7 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); void setGroupSelection( bool b ){ groupSelection = b; } + bool unGroupSelection(); private: CWidgetManager(); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index ac6b57fb0..35b493ecb 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2555,5 +2555,45 @@ namespace NLGUI v->updateCoords(); } } + + bool CInterfaceGroup::explode() + { + CInterfaceGroup *p = getParent(); + if( p == NULL ) + return false; + + std::string oldId; + + // Reparent children + for( sint32 i = 0; i < _EltOrder.size(); i++ ) + { + CInterfaceElement *e = _EltOrder[ i ]; + + oldId = e->getId(); + + e->setParent( p ); + + if( e->getParentPos() == this ) + e->setParentPos( p ); + + if( e->getParentSize() == this ) + e->setParentSize( p ); + + if( e->getParentPos() == p ) + e->alignTo( p ); + + p->addElement( e ); + e->setIdRecurse( e->getShortId() ); + + CWidgetManager::getInstance()->onWidgetMoved( oldId, e->getId() ); + } + + _EltOrder.clear(); + _Views.clear(); + _Controls.clear(); + _ChildrenGroups.clear(); + + return true; + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c6068b363..21c9bd53d 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -3477,6 +3477,40 @@ namespace NLGUI return v; } + bool CWidgetManager::unGroupSelection() + { + if( currentEditorSelection.empty() ) + return false; + + // Does the element exist? + CInterfaceElement *e = getElementFromId( currentEditorSelection ); + if( e == NULL ) + return false; + + // Is the element a group? + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( e ); + if( g == NULL ) + return false; + + // Can't blow up a root group :( + CInterfaceGroup *p = g->getParent(); + if( p == NULL ) + return false; + + // KABOOM! + bool ok = g->explode(); + if( !ok ) + return false; + + p->delElement( g ); + + setCurrentEditorSelection( "" ); + + p->updateCoords(); + + return true; + } + CWidgetManager::CWidgetManager() { diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index e834aa21f..4c48a4fa4 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -135,5 +135,17 @@ namespace GUIEditor { CWidgetManager::getInstance()->setGroupSelection( b ); } + + void CEditorMessageProcessor::onUngroup() + { + bool ok = CWidgetManager::getInstance()->unGroupSelection(); + + if( !ok ) + { + QMessageBox::critical( NULL, + tr( "Ungrouping widgets" ), + tr( "Couldn't ungroup widgets." ) ); + } + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5d4098272..9e6d3cf89 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onUngroup(); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 3a4f982aa..01433bf9e 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Ungroup", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); + m->addAction( a ); + // ---------------------------------------------------------------------------------- m->addSeparator(); From bec078af25601d743ae3f35b5da8931c42fe73ea Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:00:56 +0200 Subject: [PATCH 072/344] Sizes should remain the same when ungrouping. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_group.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 35b493ecb..516a2f6aa 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2571,16 +2571,15 @@ namespace NLGUI oldId = e->getId(); + e->setW( e->getWReal() ); + e->setH( e->getHReal() ); + e->setSizeRef( "" ); + e->setParent( p ); - if( e->getParentPos() == this ) - e->setParentPos( p ); - - if( e->getParentSize() == this ) - e->setParentSize( p ); - - if( e->getParentPos() == p ) - e->alignTo( p ); + e->setParentPos( p ); + e->setParentSize( p ); + e->alignTo( p ); p->addElement( e ); e->setIdRecurse( e->getShortId() ); From a1e2c5667a03436f9dcb6ecaa7bfc46db7059626 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:28:20 +0200 Subject: [PATCH 073/344] A little crash fix. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 2 +- code/nel/src/gui/interface_element.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 3b095ac85..0be4c02e3 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -508,7 +508,7 @@ namespace NLGUI /// Called when the widget is deleted, /// so other widgets in the group can check if it belongs to them - virtual void onWidgetDeleted( CInterfaceElement *e ){} + virtual void onWidgetDeleted( CInterfaceElement *e ); /// Move the element by x in the X direction and y in the Y direction // Uses real coordinates diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 75fee53f2..c9b480516 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1685,6 +1685,14 @@ namespace NLGUI invalidateCoords(); } + void CInterfaceElement::onWidgetDeleted( CInterfaceElement *e ) + { + if( e == getParentPos() ) + setParentPos( NULL ); + if( e == getParentSize() ) + setParentSize( NULL ); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; From 3edfd56c75af371081b7db326a2efbaf724474a2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:34 +0200 Subject: [PATCH 074/344] Implement text shade outline --HG-- branch : develop --- code/nel/include/nel/3d/text_context.h | 65 ++++++++++++++++----- code/nel/include/nel/3d/text_context_user.h | 28 ++++----- code/nel/include/nel/3d/u_text_context.h | 9 +++ code/nel/src/3d/text_context.cpp | 1 + code/nel/src/3d/text_context_user.cpp | 12 ++++ 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/code/nel/include/nel/3d/text_context.h b/code/nel/include/nel/3d/text_context.h index 203e2b3c3..064a0ef64 100644 --- a/code/nel/include/nel/3d/text_context.h +++ b/code/nel/include/nel/3d/text_context.h @@ -82,6 +82,8 @@ public: void setShaded (bool b) { _Shaded = b; } + void setShadeOutline (bool b) { _ShadeOutline = b; } + void setShadeExtent (float shext) { _ShadeExtent = shext; } /// The alpha of the shade is multiplied at each draw with the alpha of the color. Default: (0,0,0,255) @@ -107,6 +109,8 @@ public: bool getShaded() const { return _Shaded; } + bool getShadeOutline() const { return _ShadeOutline; } + bool getKeep800x600Ratio() const {return _Keep800x600Ratio;} NLMISC::CRGBA getShadeColor () const { return _ShadeColor; } @@ -138,15 +142,21 @@ public: { nlassert (index < _CacheStrings.size()); CComputedString &rCS = _CacheStrings[index]; - if(_Shaded) + if (_Shaded) { - CRGBA bkup = rCS.Color; + CRGBA bkup = rCS.Color; rCS.Color = _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2D (*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + if (_ShadeOutline) + { + rCS.render2D(*_Driver, x-_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + } rCS.Color= bkup; } - rCS.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /** Clip and print a string that is in the cache (it leaves the string in the cache) @@ -162,6 +172,12 @@ public: rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); + if (_ShadeOutline) + { + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + } rCS.Color= bkup; } rCS.render2DClip (*_Driver, rdrBuffer, x, z, xmin, ymin, xmax, ymax); @@ -174,12 +190,18 @@ public: { nlassert (index < _CacheStrings.size()); CComputedString &rCS = _CacheStrings[index]; - if(_Shaded) + if (_Shaded) { CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + if (_ShadeOutline) + { + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + } rCS.Color= bkup; } rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y, depth, xmin, ymin, xmax, ymax); @@ -194,17 +216,23 @@ public: _FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); // draw shaded - if(_Shaded) + if (_Shaded) { CRGBA bkup = _TempString.Color; - _TempString.Color= _ShadeColor; + _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D (*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.Color= bkup; + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + if (_ShadeOutline) + { + _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + _TempString.Color = bkup; } // draw - _TempString.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + _TempString.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /// Directly print a string @@ -218,17 +246,23 @@ public: _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); // draw shaded - if(_Shaded) + if (_Shaded) { CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D (*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.Color= bkup; + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + if (_ShadeOutline) + { + _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + _TempString.Color = bkup; } // draw - _TempString.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + _TempString.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /// Get computed string from index @@ -317,6 +351,9 @@ private: /// true if text is shaded bool _Shaded; + /// true if shade appears as an outline + bool _ShadeOutline; + /// shade's extent (shadow size) float _ShadeExtent; diff --git a/code/nel/include/nel/3d/text_context_user.h b/code/nel/include/nel/3d/text_context_user.h index a95fb2ca1..8e14dc878 100644 --- a/code/nel/include/nel/3d/text_context_user.h +++ b/code/nel/include/nel/3d/text_context_user.h @@ -64,19 +64,21 @@ public: /// \name Text look. // @{ void setColor(NLMISC::CRGBA color); - void setFontSize(uint32 fontSize) ; - uint32 getFontSize() const ; - void setHotSpot(THotSpot hotSpot) ; - THotSpot getHotSpot() const ; - void setScaleX(float scaleX) ; - void setScaleY(float scaleY) ; - float getScaleX() const ; - float getScaleY() const ; - void setShaded(bool b) ; - bool getShaded() const ; - void setShadeExtent(float shext) ; - void setShadeColor (NLMISC::CRGBA sc); - NLMISC::CRGBA getShadeColor () const; + void setFontSize(uint32 fontSize); + uint32 getFontSize() const; + void setHotSpot(THotSpot hotSpot); + THotSpot getHotSpot() const; + void setScaleX(float scaleX); + void setScaleY(float scaleY); + float getScaleX() const; + float getScaleY() const; + void setShaded(bool b); + bool getShaded() const; + void setShadeOutline(bool b); + bool getShadeOutline() const; + void setShadeExtent(float shext) ; + void setShadeColor (NLMISC::CRGBA sc); + NLMISC::CRGBA getShadeColor () const; void setKeep800x600Ratio(bool keep); bool getKeep800x600Ratio() const; // @} diff --git a/code/nel/include/nel/3d/u_text_context.h b/code/nel/include/nel/3d/u_text_context.h index dcaa1949a..1056d3839 100644 --- a/code/nel/include/nel/3d/u_text_context.h +++ b/code/nel/include/nel/3d/u_text_context.h @@ -174,6 +174,15 @@ public: * \return the shade state */ virtual bool getShaded () const = 0; + /** + * set the shade states + * \param the shade state + */ + virtual void setShadeOutline (bool b) = 0; + /** + * \return the shade state + */ + virtual bool getShadeOutline () const = 0; /** * set the shadow's size * \param the shade extent diff --git a/code/nel/src/3d/text_context.cpp b/code/nel/src/3d/text_context.cpp index 4b6e46c85..456ab77a6 100644 --- a/code/nel/src/3d/text_context.cpp +++ b/code/nel/src/3d/text_context.cpp @@ -40,6 +40,7 @@ CTextContext::CTextContext() _ScaleZ = 1.0f; _Shaded = false; + _ShadeOutline = false; _ShadeExtent = 0.001f; _ShadeColor = NLMISC::CRGBA(0,0,0); diff --git a/code/nel/src/3d/text_context_user.cpp b/code/nel/src/3d/text_context_user.cpp index 570c879f9..6ee880d91 100644 --- a/code/nel/src/3d/text_context_user.cpp +++ b/code/nel/src/3d/text_context_user.cpp @@ -148,6 +148,18 @@ bool CTextContextUser::getShaded() const return _TextContext.getShaded(); } +void CTextContextUser::setShadeOutline(bool b) +{ + H_AUTO2; + + _TextContext.setShadeOutline(b); +} +bool CTextContextUser::getShadeOutline() const +{ + H_AUTO2; + + return _TextContext.getShadeOutline(); +} void CTextContextUser::setShadeExtent(float shext) { H_AUTO2; From 74827a1808678ed78e4d7b413006e7c0aa340735 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:35 +0200 Subject: [PATCH 075/344] Handle shadow outline in gui --HG-- branch : develop --- code/nel/include/nel/gui/group_menu.h | 1 + code/nel/include/nel/gui/view_text.h | 5 ++- code/nel/src/gui/group_container.cpp | 2 ++ code/nel/src/gui/group_menu.cpp | 22 +++++++++++++ code/nel/src/gui/view_text.cpp | 45 +++++++++++++++++++++++++-- code/nel/src/gui/widget_manager.cpp | 1 + 6 files changed, 72 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/group_menu.h b/code/nel/include/nel/gui/group_menu.h index 56b9fb0e3..420967347 100644 --- a/code/nel/include/nel/gui/group_menu.h +++ b/code/nel/include/nel/gui/group_menu.h @@ -381,6 +381,7 @@ namespace NLGUI bool _CloseSubMenuUsingPopModal; bool _Shadow; + bool _ShadowOutline; bool _Formatted; uint8 _Space; sint32 _FontSize; diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index df3cf27e3..a14713dcc 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -48,7 +48,7 @@ namespace NLGUI /// Constructor CViewText (const std::string& id, const std::string Text="", sint FontSize=12, - NLMISC::CRGBA Color=NLMISC::CRGBA(255,255,255), bool Shadow=false); + NLMISC::CRGBA Color=NLMISC::CRGBA(255,255,255), bool Shadow=false, bool ShadowOutline=false); virtual ~CViewText(); @@ -83,6 +83,7 @@ namespace NLGUI void setFontSize (sint nFontSize); void setColor (const NLMISC::CRGBA &color); void setShadow (bool bShadow); + void setShadowOutline (bool bShadowOutline); void setShadowColor (const NLMISC::CRGBA &color); void setLineMaxW (sint nMaxW, bool invalidate=true); void setMultiLine (bool bMultiLine); @@ -102,6 +103,7 @@ namespace NLGUI sint getFontSize() const; NLMISC::CRGBA getColor() { return _Color; } bool getShadow() { return _Shadow; } + bool getShadowOutline() { return _ShadowOutline; } NLMISC::CRGBA getShadowColor() { return _ShadowColor; } sint getLineMaxW() const { return _LineMaxW; } bool getMultiLine() const { return _MultiLine; } @@ -225,6 +227,7 @@ namespace NLGUI NLMISC::CRGBA _Color; /// the shadow mode bool _Shadow; + bool _ShadowOutline; /// the case mode TCaseMode _CaseMode; /// the text shadow color diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index 5c3a29e8b..18a65bc5f 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -3713,6 +3713,7 @@ namespace NLGUI _TitleOpened->setParentPosRef (Hotspot_TL); _TitleOpened->setPosRef (Hotspot_TL); _TitleOpened->setShadow (true); + _TitleOpened->setShadowOutline (false); _TitleOpened->setColor (CRGBA(255,255,255,255)); _TitleOpened->setModulateGlobalColor(getModulateGlobalColor()); _TitleOpened->setOverExtendViewText(_TitleOverExtendViewText); @@ -3764,6 +3765,7 @@ namespace NLGUI _TitleClosed->setParentPosRef (Hotspot_TL); _TitleClosed->setPosRef (Hotspot_TL); _TitleClosed->setShadow (true); + _TitleClosed->setShadowOutline (false); _TitleClosed->setColor (CRGBA(255,255,255,255)); _TitleClosed->setModulateGlobalColor(getModulateGlobalColor()); _TitleClosed->setOverExtendViewText(_TitleOverExtendViewText); diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp index 85ed1959e..08f887e9e 100644 --- a/code/nel/src/gui/group_menu.cpp +++ b/code/nel/src/gui/group_menu.cpp @@ -1203,6 +1203,7 @@ namespace NLGUI pV->setColor (_GroupMenu->_Color); pV->setFontSize (_GroupMenu->_FontSize); pV->setShadow (_GroupMenu->_Shadow); + pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); pV->setChecked(checked); pV->setModulateGlobalColor(_GroupMenu->_ModulateGlobalColor); @@ -1282,6 +1283,7 @@ namespace NLGUI pV->setColor (_GroupMenu->_Color); pV->setFontSize (_GroupMenu->_FontSize); pV->setShadow (_GroupMenu->_Shadow); + pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); pV->setChecked(checked); pV->setModulateGlobalColor(_GroupMenu->_ModulateGlobalColor); @@ -1922,6 +1924,7 @@ namespace NLGUI _HighLightOver.set(128, 0, 0, 255); _FontSize = 12; _Shadow = false; + _ShadowOutline = false; _ResizeFromChildH = _ResizeFromChildW = true; _DisplayFrame = false; _RootMenu = NULL; @@ -1998,6 +2001,11 @@ namespace NLGUI return toString( _Shadow ); } else + if( name == "shadow_outline" ) + { + return toString( _ShadowOutline ); + } + else if( name == "formatted" ) { return toString( _Formatted ); @@ -2110,6 +2118,14 @@ namespace NLGUI return; } else + if( name == "shadow_outline" ) + { + bool b; + if( fromString( value, b ) ) + _ShadowOutline = b; + return; + } + else if( name == "formatted" ) { bool b; @@ -2152,6 +2168,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "space", BAD_CAST toString( _Space ).c_str() ); xmlSetProp( node, BAD_CAST "fontsize", BAD_CAST toString( _FontSize ).c_str() ); xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() ); + xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() ); xmlSetProp( node, BAD_CAST "formatted", BAD_CAST toString( _Formatted ).c_str() ); if( _RootMenu == NULL ) @@ -2197,6 +2214,7 @@ namespace NLGUI _Color = gm->_Color; _ShadowColor = gm->_ShadowColor; _Shadow = gm->_Shadow; + _ShadowOutline = gm->_ShadowOutline; _FontSize = gm->_FontSize; _ColorOver = gm->_ColorOver; _ShadowColorOver = gm->_ShadowColorOver; @@ -2266,6 +2284,10 @@ namespace NLGUI if (prop) _Shadow = convertBool(prop); + prop = (char*) xmlGetProp( in, (xmlChar*)"shadow_outline" ); + if (prop) + _ShadowOutline = convertBool(prop); + prop = (char*) xmlGetProp( in, (xmlChar*)"formatted" ); if (prop) _Formatted = convertBool(prop); diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6ff1930af..0186938f7 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -62,6 +62,7 @@ namespace NLGUI CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32(); _Color = CRGBA(255,255,255,255); _Shadow = false; + _ShadowOutline = false; _ShadowColor = CRGBA(0,0,0,255); _MultiLine = false; @@ -111,7 +112,7 @@ namespace NLGUI ///constructor // *************************************************************************** CViewText:: CViewText (const std::string& id, const std::string Text, sint FontSize, - NLMISC::CRGBA Color, bool Shadow) + NLMISC::CRGBA Color, bool Shadow, bool ShadowOutline) :CViewBase(TCtorParam()) { _Id = id; @@ -120,6 +121,7 @@ namespace NLGUI _FontSize = FontSize + CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32(); _Color = Color; _Shadow = Shadow; + _ShadowOutline = ShadowOutline; setText(Text); computeFontSize (); } @@ -159,6 +161,7 @@ namespace NLGUI _FontSize = vt._FontSize; _Color = vt._Color; _Shadow = vt._Shadow; + _ShadowOutline = vt._ShadowOutline; _ShadowColor = vt._ShadowColor; _MultiLine = false; @@ -225,6 +228,11 @@ namespace NLGUI return toString( _Shadow ); } else + if( name == "shadow_outline" ) + { + return toString( _ShadowOutline ); + } + else if( name == "shadow_color" ) { return toString( _ShadowColor ); @@ -360,6 +368,14 @@ namespace NLGUI return true; } else + if( name == "shadow_outline" ) + { + bool b; + if( fromString( value, b ) ) + _ShadowOutline = b; + return true; + } + else if( name == "shadow_color" ) { CRGBA c; @@ -520,6 +536,7 @@ namespace NLGUI ).c_str() ); xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() ); + xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() ); xmlSetProp( node, BAD_CAST "shadow_color", BAD_CAST toString( _ShadowColor ).c_str() ); xmlSetProp( node, BAD_CAST "multi_line", BAD_CAST toString( _MultiLine ).c_str() ); @@ -604,6 +621,11 @@ namespace NLGUI if (prop) _Shadow = convertBool(prop); + prop = (char*) xmlGetProp( cur, (xmlChar*)"shadow_outline" ); + _ShadowOutline = false; + if (prop) + _ShadowOutline = convertBool(prop); + prop= (char*) xmlGetProp( cur, (xmlChar*)"shadow_color" ); _ShadowColor = CRGBA(0,0,0,255); if (prop) @@ -864,6 +886,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); @@ -978,6 +1001,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); @@ -1146,6 +1170,14 @@ namespace NLGUI invalidateContent(); } + // *************************************************************************** + void CViewText::setShadowOutline (bool bShadowOutline) + { + _ShadowOutline = bShadowOutline; + computeFontSize (); + invalidateContent(); + } + // *************************************************************************** void CViewText::setShadowColor(const NLMISC::CRGBA & color) { @@ -1647,6 +1679,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // default state @@ -1958,6 +1991,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // CViewRenderer &rVR = *CViewRenderer::getInstance(); height = getFontHeight(); @@ -2089,6 +2123,7 @@ namespace NLGUI // setup the text context TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // find the line where the character is // CViewRenderer &rVR = *CViewRenderer::getInstance(); @@ -2363,6 +2398,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); TCharPos linePos = 0; @@ -2447,6 +2483,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // Current position in text @@ -2498,12 +2535,13 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // Letter size UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext - _FontHeight = (uint) si.StringHeight + (_Shadow?1:0); - _FontLegHeight = (uint) si.StringLine + (_Shadow?1:0); + _FontHeight = (uint) si.StringHeight + (_Shadow?(_ShadowOutline?2:1):0); + _FontLegHeight = (uint) si.StringLine + (_Shadow?(_ShadowOutline?2:1):0); // Space width si = TextContext->getStringInfo(ucstring(" ")); @@ -2960,6 +2998,7 @@ namespace NLGUI f.serial(_SpaceWidth); f.serial(_Color); f.serial(_Shadow); + f.serial(_ShadowOutline); f.serialEnum(_CaseMode); f.serial(_ShadowColor); f.serial(_LineMaxW); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index a448603c0..9b9a74e77 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1186,6 +1186,7 @@ namespace NLGUI vtDst->setColor (vtSrc->getColor()); vtDst->setModulateGlobalColor(vtSrc->getModulateGlobalColor()); vtDst->setShadow(vtSrc->getShadow()); + vtDst->setShadowOutline(vtSrc->getShadowOutline()); vtDst->setShadowColor(vtSrc->getShadowColor()); vtDst->setCaseMode(vtSrc->getCaseMode()); vtDst->setUnderlined(vtSrc->getUnderlined()); From 5fd4f96a597a197ac58847efed15a5aa9521a195 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:35 +0200 Subject: [PATCH 076/344] Configure shadow outline in applications --HG-- branch : develop --- code/ryzom/client/src/debug_client.cpp | 3 +++ code/ryzom/client/src/graph.cpp | 1 + code/ryzom/client/src/ground_fx_manager.cpp | 1 + code/ryzom/client/src/interface_v3/chat_text_manager.cpp | 1 + .../client/src/interface_v3/dbgroup_list_sheet_text.cpp | 1 + .../dbgroup_list_sheet_text_brick_composition.cpp | 1 + .../src/interface_v3/dbgroup_list_sheet_text_share.cpp | 2 ++ code/ryzom/client/src/interface_v3/group_map.cpp | 1 + code/ryzom/client/src/main_loop.cpp | 2 ++ code/ryzom/client/src/main_loop_debug.cpp | 6 ++++++ code/ryzom/client/src/r2/editor.cpp | 1 + code/ryzom/client/src/timed_fx_manager.cpp | 1 + .../tools/leveldesign/world_editor/world_editor/display.cpp | 1 + code/snowballs2/client/src/snowballs_client.cpp | 1 + 14 files changed, 23 insertions(+) diff --git a/code/ryzom/client/src/debug_client.cpp b/code/ryzom/client/src/debug_client.cpp index 8800384ba..0af4207ae 100644 --- a/code/ryzom/client/src/debug_client.cpp +++ b/code/ryzom/client/src/debug_client.cpp @@ -345,6 +345,7 @@ void displayStreamingDebug () //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -390,6 +391,7 @@ void displayStreamingDebug () // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); } } @@ -567,6 +569,7 @@ void displayNetDebug () //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color diff --git a/code/ryzom/client/src/graph.cpp b/code/ryzom/client/src/graph.cpp index 1bf370db0..8270762fb 100644 --- a/code/ryzom/client/src/graph.cpp +++ b/code/ryzom/client/src/graph.cpp @@ -134,6 +134,7 @@ void CGraph::renderGraph () if (TextContext != NULL) { TextContext->setShaded (false); + TextContext->setShadeOutline(false); TextContext->setHotSpot (UTextContext::MiddleLeft); TextContext->setColor (frontCol); TextContext->setFontSize (10); diff --git a/code/ryzom/client/src/ground_fx_manager.cpp b/code/ryzom/client/src/ground_fx_manager.cpp index dc064415f..f13309183 100644 --- a/code/ryzom/client/src/ground_fx_manager.cpp +++ b/code/ryzom/client/src/ground_fx_manager.cpp @@ -807,6 +807,7 @@ void CTestGroundFX::displayFXBoxes() const Driver->setFrustum(fr); TextContext->setColor(CRGBA::Green); TextContext->setShaded(false); + TextContext->setShadeOutline(false); TextContext->setFontSize(12); // float size = 0.4f; diff --git a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp index 10fd2d29c..faaf86092 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -157,6 +157,7 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA CViewText *vt = new CViewText(CViewText::TCtorParam()); // get parameters from config.xml vt->setShadow(isTextShadowed()); + vt->setShadowOutline(false); vt->setFontSize(getTextFontSize()); vt->setMultiLine(true); vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp index a05d1e4aa..772f99418 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp @@ -880,6 +880,7 @@ void CDBGroupListSheetText::setup() text->setFontSize(_TextTemplate.getFontSize()); text->setColor(_TextTemplate.getColor()); text->setShadow(_TextTemplate.getShadow()); + text->setShadowOutline(_TextTemplate.getShadowOutline()); text->setLineMaxW(_TextTemplate.getLineMaxW()); text->setMultiLine(_TextTemplate.getMultiLine()); if(text->getMultiLine()) diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp index 67079ba55..c67e69660 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp @@ -95,6 +95,7 @@ void CDBGroupListSheetTextBrickComposition::CSheetChildBrick::init(CDBGroupListS text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp index 35cd90a7e..fcef370e0 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp @@ -121,6 +121,7 @@ void CDBGroupListSheetTextShare::CSheetChildShare::init(CDBGroupListSheetText *p text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); // Add it to the scrolled list. @@ -139,6 +140,7 @@ void CDBGroupListSheetTextShare::CSheetChildShare::init(CDBGroupListSheetText *p text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); // Add it to the scrolled list. diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 31d70d0d7..558ab960c 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -2333,6 +2333,7 @@ void CGroupMap::createLMWidgets(const std::vector &lms) pNewText->setColor(CRGBA(255,255,255,255)); pNewText->setShadow(true); + pNewText->setShadowOutline(false); pNewText->setShadowColor(CRGBA(0,0,0,255)); pNewText->setModulateGlobalColor(false); pNewText->Type = rCLM.Type; diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 1ac6a4a0c..f6d921ff8 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1924,6 +1924,7 @@ bool mainLoop() // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(10); // Set the text color @@ -2586,6 +2587,7 @@ void displaySpecialTextProgress(const char *text) { // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(12); // Set the text color diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp index 8b224f27f..19ea38414 100644 --- a/code/ryzom/client/src/main_loop_debug.cpp +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -80,6 +80,7 @@ void displayDebug() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -470,6 +471,7 @@ void displayDebug() // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); }// displayDebug // // ******************************************************************** @@ -491,6 +493,7 @@ void displayDebugFps() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -533,6 +536,7 @@ void displayDebugUIUnderMouse() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); @@ -707,6 +711,7 @@ void displayHelp() // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.HelpFontSize); // Set the text color @@ -763,6 +768,7 @@ void displayHelp() // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); }// displayHelp // // ******************************************************************** diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp index bb09bec52..2bceb4200 100644 --- a/code/ryzom/client/src/r2/editor.cpp +++ b/code/ryzom/client/src/r2/editor.cpp @@ -1789,6 +1789,7 @@ void CEditor::waitScenarioScreen() if (!waitScreen) { TextContext->setShaded(true); + TextContext->setShadeOutline(false); TextContext->setFontSize(40); TextContext->setColor(CRGBA::White); diff --git a/code/ryzom/client/src/timed_fx_manager.cpp b/code/ryzom/client/src/timed_fx_manager.cpp index 9f7f40caf..d37ab782f 100644 --- a/code/ryzom/client/src/timed_fx_manager.cpp +++ b/code/ryzom/client/src/timed_fx_manager.cpp @@ -829,6 +829,7 @@ void CTimedFXManager::displayFXBoxes(TDebugDisplayMode displayMode) const Driver->setFrustum(fr); TextContext->setColor(CRGBA::Blue); TextContext->setShaded(false); + TextContext->setShadeOutline(false); TextContext->setFontSize(10); // float size = 0.4f; diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp index dd2a17d82..09763d27c 100644 --- a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp +++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp @@ -309,6 +309,7 @@ void CDisplay::init (CMainFrame *pMF) _TextContext->setFontGenerator(NLMISC::CPath::getWindowsDirectory() + "Fonts\\arial.ttf"); _TextContext->setKeep800x600Ratio(true); _TextContext->setShaded(true); + _TextContext->setShadeOutline(false); _TextContext->setShadeColor(NLMISC::CRGBA::Black); } catch(...) diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 68cdc47fa..7e019412b 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -327,6 +327,7 @@ void initCore() ConfigFile->getVar("ScreenFull").asInt()==0)); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext->setShaded(true); + TextContext->setShadeOutline(false); TextContext->setKeep800x600Ratio(false); // You can't call displayLoadingState() before init the loading state system displayLoadingState("Initialize Loading"); From aaa044203e1e1e27a6febd3f47dd32799fd3ab35 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 10 Oct 2014 13:07:54 +0200 Subject: [PATCH 077/344] Fix some warnings --HG-- branch : develop --- code/nel/src/misc/config_file/cf_bison.simple | 2 +- code/nel/src/misc/config_file/cf_flex.skl | 2 +- code/nel/src/misc/config_file/cf_lexical.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/nel/src/misc/config_file/cf_bison.simple b/code/nel/src/misc/config_file/cf_bison.simple index 3ab0e5b1a..64e930f27 100644 --- a/code/nel/src/misc/config_file/cf_bison.simple +++ b/code/nel/src/misc/config_file/cf_bison.simple @@ -328,7 +328,7 @@ yynewstate: #endif /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; + int size = (int)(yyssp - yyss + 1); #ifdef yyoverflow /* Each stack pointer address is followed by the size of diff --git a/code/nel/src/misc/config_file/cf_flex.skl b/code/nel/src/misc/config_file/cf_flex.skl index 5da2aa3f6..b69bed057 100644 --- a/code/nel/src/misc/config_file/cf_flex.skl +++ b/code/nel/src/misc/config_file/cf_flex.skl @@ -1000,7 +1000,7 @@ int yyFlexLexer::yyinput() else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; + int offset = (int)(yy_c_buf_p - yytext_ptr); ++yy_c_buf_p; switch ( yy_get_next_buffer() ) diff --git a/code/nel/src/misc/config_file/cf_lexical.cpp b/code/nel/src/misc/config_file/cf_lexical.cpp index f47696ff9..80fd4fd36 100644 --- a/code/nel/src/misc/config_file/cf_lexical.cpp +++ b/code/nel/src/misc/config_file/cf_lexical.cpp @@ -2773,7 +2773,7 @@ static int input() else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; + int offset = (int)(yy_c_buf_p - yytext_ptr); ++yy_c_buf_p; switch ( yy_get_next_buffer() ) From e34ba83f266f8ddf4d7e38c1318ece251858d277 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 10 Oct 2014 13:08:14 +0200 Subject: [PATCH 078/344] Minor changes --HG-- branch : develop --- code/CMakeModules/FindDirectXSDK.cmake | 6 ------ code/nel/include/nel/3d/anim_detail_trav.h | 2 +- code/nel/tools/misc/data_mirror/StdAfx.h | 3 --- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/code/CMakeModules/FindDirectXSDK.cmake b/code/CMakeModules/FindDirectXSDK.cmake index 3cf91ec3c..b64fca6ea 100644 --- a/code/CMakeModules/FindDirectXSDK.cmake +++ b/code/CMakeModules/FindDirectXSDK.cmake @@ -52,12 +52,6 @@ IF(DXSDK_DIR) FIND_DXSDK_LIBRARY(DXSDK_XAUDIO_LIBRARY x3daudio) FIND_DXSDK_LIBRARY(DXSDK_D3DX9_LIBRARY d3dx9) FIND_DXSDK_LIBRARY(DXSDK_D3D9_LIBRARY d3d9) - - #FIND_DXSDK_LIBRARY(DXSDK_MESH_LIBRARY mesh) - #FIND_DXSDK_LIBRARY(DXSDK_MAXUTIL_LIBRARY maxutil) - #FIND_DXSDK_LIBRARY(DXSDK_MAXSCRIPT_LIBRARY maxscrpt) - #FIND_DXSDK_LIBRARY(DXSDK_PARAMBLK2_LIBRARY paramblk2) - #FIND_DXSDK_LIBRARY(DXSDK_BMM_LIBRARY bmm) ENDIF(DXSDK_DIR) # Handle the QUIETLY and REQUIRED arguments and set DXSDK_FOUND to TRUE if diff --git a/code/nel/include/nel/3d/anim_detail_trav.h b/code/nel/include/nel/3d/anim_detail_trav.h index 7b51afe84..0a94fe376 100644 --- a/code/nel/include/nel/3d/anim_detail_trav.h +++ b/code/nel/include/nel/3d/anim_detail_trav.h @@ -71,7 +71,7 @@ public: // For clipTrav. cleared at beginning of CClipTrav::traverse void clearVisibleList(); - // For ClipTrav only. NB: list is cleared at begininng of traverse(). NB: only CTransform are supported + // For ClipTrav only. NB: list is cleared at beginning of traverse(). NB: only CTransform are supported void addVisibleModel(CTransform *model) { _VisibleList[_CurrentNumVisibleModels]= model; diff --git a/code/nel/tools/misc/data_mirror/StdAfx.h b/code/nel/tools/misc/data_mirror/StdAfx.h index 90fe14511..a065be4ed 100644 --- a/code/nel/tools/misc/data_mirror/StdAfx.h +++ b/code/nel/tools/misc/data_mirror/StdAfx.h @@ -10,9 +10,6 @@ #pragma once #endif // _MSC_VER > 1000 -#include "nel/misc/types_nl.h" -#include "nel/misc/file.h" - #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include // MFC core and standard components From 8cec8de3a068f856d6c97bd16b0bf3063e7a70ef Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 17:33:57 +0200 Subject: [PATCH 079/344] Unselect selection when clicking 'nothing'. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 21c9bd53d..c26a23231 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2475,6 +2475,11 @@ namespace NLGUI // handle the capture _CapturedView->handleEvent( evnt ); } + else + { + if( CInterfaceElement::getEditorMode() ) + setCurrentEditorSelection( "" ); + } } // Manage RightClick From aac2fd41a16f871c7cfccd84aac8597bf98289f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 20:25:25 +0200 Subject: [PATCH 080/344] Allow multiselection. --HG-- branch : dfighter-tools --- .../nel/gui/editor_selection_watcher.h | 3 +- code/nel/include/nel/gui/widget_manager.h | 16 +++-- code/nel/src/gui/view_base.cpp | 2 +- code/nel/src/gui/widget_manager.cpp | 68 +++++++++++++------ .../gui_editor/editor_message_processor.cpp | 42 +++++++----- .../gui_editor/editor_message_processor.h | 1 + .../gui_editor/editor_selection_watcher.cpp | 4 +- .../gui_editor/editor_selection_watcher.h | 4 +- .../plugins/gui_editor/gui_editor_window.cpp | 14 ++-- .../gui_editor/property_browser_ctrl.cpp | 12 +++- .../gui_editor/property_browser_ctrl.h | 2 +- .../plugins/gui_editor/widget_hierarchy.cpp | 19 ++++-- .../src/plugins/gui_editor/widget_hierarchy.h | 2 +- 13 files changed, 130 insertions(+), 59 deletions(-) diff --git a/code/nel/include/nel/gui/editor_selection_watcher.h b/code/nel/include/nel/gui/editor_selection_watcher.h index 415f4f9db..7e262bdf1 100644 --- a/code/nel/include/nel/gui/editor_selection_watcher.h +++ b/code/nel/include/nel/gui/editor_selection_watcher.h @@ -15,6 +15,7 @@ // along with this program. If not, see . #include +#include namespace NLGUI { @@ -24,7 +25,7 @@ namespace NLGUI public: /// Notifies the watcher about the change - virtual void selectionChanged( std::string &newSelection ) = 0; + virtual void selectionChanged() = 0; }; } diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 917a0e9ba..243847ad7 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -503,8 +503,15 @@ namespace NLGUI IParser* getParser() const{ return parser; } - std::string& getCurrentEditorSelection(){ return currentEditorSelection; } - void setCurrentEditorSelection( const std::string &name ); + /// Retrieves the Id of the currently selected widgets + void getEditorSelection( std::vector< std::string > &selection ); + + /// Adds the widget with the specified Id to the selected widgets + void selectWidget( const std::string &name ); + + /// Clears the selection + void clearEditorSelection(); + void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); @@ -519,6 +526,7 @@ namespace NLGUI void setGroupSelection( bool b ){ groupSelection = b; } bool unGroupSelection(); + void setMultiSelection( bool b ){ multiSelection = b; } private: CWidgetManager(); @@ -611,9 +619,9 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* > selectionWatchers; std::vector< IWidgetWatcher* > widgetWatchers; - - std::string currentEditorSelection; + std::vector< std::string > editorSelection; bool groupSelection; + bool multiSelection; }; } diff --git a/code/nel/src/gui/view_base.cpp b/code/nel/src/gui/view_base.cpp index 05d958d3e..2b09061a9 100644 --- a/code/nel/src/gui/view_base.cpp +++ b/code/nel/src/gui/view_base.cpp @@ -57,7 +57,7 @@ namespace NLGUI { if( editorMode ) { - CWidgetManager::getInstance()->setCurrentEditorSelection( getId() ); + CWidgetManager::getInstance()->selectWidget( getId() ); return true; } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c26a23231..6ee1588c3 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2077,9 +2077,9 @@ namespace NLGUI if( CInterfaceElement::getEditorMode() ) { - if( !currentEditorSelection.empty() ) + for( int i = 0; i < editorSelection.size(); i++ ) { - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); if( e != NULL ) e->drawHighlight(); } @@ -2478,7 +2478,7 @@ namespace NLGUI else { if( CInterfaceElement::getEditorMode() ) - setCurrentEditorSelection( "" ); + clearEditorSelection(); } } @@ -3349,25 +3349,53 @@ namespace NLGUI } } + void CWidgetManager::getEditorSelection( std::vector< std::string > &selection ) + { + selection.clear(); + for( int i = 0; i < editorSelection.size(); i++ ) + selection.push_back( editorSelection[ i ] ); + } - void CWidgetManager::setCurrentEditorSelection( const std::string &name ) + void CWidgetManager::selectWidget( const std::string &name ) { + std::vector< std::string >::iterator itr + = std::find( editorSelection.begin(), editorSelection.end(), name ); + CInterfaceElement *e = getElementFromId( name ); - if( e != NULL ) + + if( itr != editorSelection.end() ) { - if( !currentEditorSelection.empty() ) + // If multiselection is on unselect if already selected + if( multiSelection ) { - CInterfaceElement *prev = getElementFromId( currentEditorSelection ); - if( prev != NULL ) - prev->setEditorSelected( false ); + editorSelection.erase( itr ); + if( e != NULL ) + e->setEditorSelected( false ); } - e->setEditorSelected( true ); } else - if( !name.empty() ) - return; - - currentEditorSelection = name; + { + // Select if not yet selected + if( e != NULL ) + { + // If multiselection is off, we can only have 1 widget selected + if( !multiSelection ) + { + editorSelection.clear(); + } + + e->setEditorSelected( true ); + editorSelection.push_back( name ); + } + + } + + notifySelectionWatchers(); + } + + void CWidgetManager::clearEditorSelection() + { + editorSelection.clear(); notifySelectionWatchers(); } @@ -3376,7 +3404,7 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* >::iterator itr = selectionWatchers.begin(); while( itr != selectionWatchers.end() ) { - (*itr)->selectionChanged( currentEditorSelection ); + (*itr)->selectionChanged(); ++itr; } } @@ -3484,11 +3512,11 @@ namespace NLGUI bool CWidgetManager::unGroupSelection() { - if( currentEditorSelection.empty() ) + if( editorSelection.size() != 1 ) return false; // Does the element exist? - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ 0 ] ); if( e == NULL ) return false; @@ -3509,7 +3537,7 @@ namespace NLGUI p->delElement( g ); - setCurrentEditorSelection( "" ); + clearEditorSelection(); p->updateCoords(); @@ -3554,8 +3582,8 @@ namespace NLGUI setScreenWH( 0, 0 ); - currentEditorSelection = ""; groupSelection = false; + multiSelection = false; } CWidgetManager::~CWidgetManager() @@ -3569,6 +3597,8 @@ namespace NLGUI curContextHelp = NULL; CStringShared::deleteStringMapper(); + + editorSelection.clear(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 4c48a4fa4..a818cf174 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -25,35 +25,40 @@ namespace GUIEditor { void CEditorMessageProcessor::onDelete() { - std::string selection = CWidgetManager::getInstance()->getCurrentEditorSelection(); + std::vector< std::string > selection; + + CWidgetManager::getInstance()->getEditorSelection( selection ); if( selection.empty() ) return; QMessageBox::StandardButton r = QMessageBox::question( NULL, tr( "Deleting widget" ), - tr( "Are you sure you want to delete %1?" ).arg( selection.c_str() ), + tr( "Are you sure you want to delete these?" ), QMessageBox::Yes | QMessageBox::No ); if( r != QMessageBox::Yes ) return; - CInterfaceElement *e = - CWidgetManager::getInstance()->getElementFromId( selection ); - if( e == NULL ) - return; + for( int i = 0; i < selection.size(); i++ ) + { + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ i ] ); + if( e == NULL ) + continue; - CInterfaceElement *p = e->getParent(); - if( p == NULL ) - return; - - CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); - if( g == NULL ) - return; + CInterfaceElement *p = e->getParent(); + if( p == NULL ) + continue; + + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); + if( g == NULL ) + continue; + + g->delElement( e ); - if( g->delElement( e ) ) - { - CWidgetManager::getInstance()->setCurrentEditorSelection( "" ); } + + + CWidgetManager::getInstance()->clearEditorSelection(); } void CEditorMessageProcessor::onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ) @@ -147,5 +152,10 @@ namespace GUIEditor tr( "Couldn't ungroup widgets." ) ); } } + + void CEditorMessageProcessor::onSetMultiSelection( bool b ) + { + CWidgetManager::getInstance()->setMultiSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 9e6d3cf89..c3483e2ef 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -40,6 +40,7 @@ namespace GUIEditor void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); void onUngroup(); + void onSetMultiSelection( bool b ); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp index ee3a079ad..7647c8abb 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp @@ -18,9 +18,9 @@ namespace GUIEditor { - void CEditorSelectionWatcher::selectionChanged( std::string &newSelection ) + void CEditorSelectionWatcher::selectionChanged() { - Q_EMIT sgnSelectionChanged( newSelection ); + Q_EMIT sgnSelectionChanged(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h index 61218c0cd..2eab68310 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h @@ -27,10 +27,10 @@ namespace GUIEditor public: CEditorSelectionWatcher() : QObject( NULL ){} - void selectionChanged( std::string &newSelection ); + void selectionChanged(); Q_SIGNALS: - void sgnSelectionChanged( std::string &id ); + void sgnSelectionChanged(); }; } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 01433bf9e..6cc072ce8 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -283,8 +283,8 @@ namespace GUIEditor CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); projectFiles.clearAll(); projectWindow->clear(); @@ -322,8 +322,8 @@ namespace GUIEditor linkList->onGUILoaded(); CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); } void GUIEditorWindow::onAddWidgetClicked() @@ -413,6 +413,12 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); m->addAction( a ); + a = new QAction( "Multiselect", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetMultiSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index c005f80e5..84302bcf0 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -436,7 +436,7 @@ namespace GUIEditor browser->clear(); } - void CPropBrowserCtrl::onSelectionChanged( std::string &id ) + void CPropBrowserCtrl::onSelectionChanged() { if( browser == NULL ) return; @@ -444,14 +444,20 @@ namespace GUIEditor disablePropertyWatchers(); browser->clear(); - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( id ); + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { enablePropertyWatchers(); return; } - currentElement = id; + currentElement = selection[ 0 ]; std::string n = e->getClassName(); diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h index abf80d7de..3d72d92ba 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h @@ -59,7 +59,7 @@ namespace GUIEditor void clear(); public Q_SLOTS: - void onSelectionChanged( std::string &id ); + void onSelectionChanged(); private Q_SLOTS: void onPropertyChanged( QtProperty *prop, const QVariant &v ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 1439fea9e..343d8efd8 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -304,14 +304,15 @@ namespace GUIEditor void WidgetHierarchy::getCurrentGroup( QString &g ) { - std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); - if( s.empty() ) + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + if( selection.size() != 1 ) { g = ""; return; } - NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( s ); + NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { g = ""; @@ -342,8 +343,16 @@ namespace GUIEditor currentSelection.clear(); } - void WidgetHierarchy::onSelectionChanged( std::string &newSelection ) + void WidgetHierarchy::onSelectionChanged() { + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + std::string newSelection = selection[ 0 ]; + if( newSelection == currentSelection ) return; @@ -376,6 +385,6 @@ namespace GUIEditor std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); - CWidgetManager::getInstance()->setCurrentEditorSelection( currentSelection ); + CWidgetManager::getInstance()->selectWidget( currentSelection ); } } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 27218715d..cdfc9a741 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -56,7 +56,7 @@ namespace GUIEditor public Q_SLOTS: void onGUILoaded(); - void onSelectionChanged( std::string &newSelection ); + void onSelectionChanged(); private Q_SLOTS: void onItemDblClicked( QTreeWidgetItem *item ); From 7b45a05562ac762d5022104d5741fc59ae8f434d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 00:42:43 +0200 Subject: [PATCH 081/344] Added support for grouping widgets. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 6 ++ code/nel/include/nel/gui/widget_manager.h | 6 +- code/nel/src/gui/interface_group.cpp | 46 ++++++++++++++ code/nel/src/gui/widget_manager.cpp | 63 ++++++++++++++++++- .../gui_editor/editor_message_processor.cpp | 5 ++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index cdfd182e7..b9efd3357 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -333,6 +333,12 @@ namespace NLGUI // Blows up the group, moves it's children to it's parent bool explode(); + /// Adjusts the group's size so that all elements are fully inside the borders + void spanElements(); + + /// Aligns the elements - used for forming groups + void alignElements(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 243847ad7..d722a9165 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -524,7 +524,8 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); - void setGroupSelection( bool b ){ groupSelection = b; } + void setGroupSelection( bool b ){ _GroupSelection = b; } + bool groupSelection(); bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } @@ -620,8 +621,9 @@ namespace NLGUI std::vector< IWidgetWatcher* > widgetWatchers; std::vector< std::string > editorSelection; - bool groupSelection; + bool _GroupSelection; bool multiSelection; + uint32 _WidgetCount; }; } diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 516a2f6aa..29ad75f8c 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2594,5 +2594,51 @@ namespace NLGUI return true; } + + void CInterfaceGroup::spanElements() + { + sint32 minx = std::numeric_limits< sint32 >::max(); + sint32 miny = std::numeric_limits< sint32 >::max(); + sint32 maxx = std::numeric_limits< sint32 >::min(); + sint32 maxy = std::numeric_limits< sint32 >::min(); + + sint32 tlx,tly,brx,bry; + + // Find the min and max coordinates of the elements + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + + v->getHSCoords( Hotspot_TL, tlx, tly ); + v->getHSCoords( Hotspot_BR, brx, bry ); + + if( tlx < minx ) + minx = tlx; + if( brx > maxx ) + maxx = brx; + if( bry < miny ) + miny = bry; + if( tly > maxy ) + maxy = tly; + } + + // Set the position and the width and height based on these coords + setW( maxx - minx ); + setH( maxy - miny ); + _WReal = getW(); + _HReal = getH(); + _XReal = minx; + _YReal = miny; + } + + void CInterfaceGroup::alignElements() + { + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->alignTo( this ); + } + } + } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 6ee1588c3..e2689f5a0 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() && groupSelection ) + if( CInterfaceElement::getEditorMode() && _GroupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3510,6 +3510,64 @@ namespace NLGUI return v; } + bool CWidgetManager::groupSelection() + { + std::vector< CInterfaceElement* > elms; + + // Resolve the widget names + for( int i = 0; i < editorSelection.size(); i++ ) + { + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); + if( e != NULL ) + elms.push_back( e ); + } + + editorSelection.clear(); + + if( elms.empty() ) + return false; + + // Create the group as the subgroup of the top window + CInterfaceGroup *g = static_cast< CInterfaceGroup* >( getParser()->createClass( "interface_group" ) ); + getTopWindow()->addGroup( g ); + g->setParent( getTopWindow() ); + g->setIdRecurse( std::string( "group" ) + NLMISC::toString( _WidgetCount ) ); + _WidgetCount++; + onWidgetAdded( g->getId() ); + + std::string oldId; + + // Reparent the widgets to the new group + for( int i = 0; i < elms.size(); i++ ) + { + CInterfaceElement *e = elms[ i ]; + oldId = e->getId(); + CInterfaceGroup *p = e->getParent(); + if( p != NULL ) + p->takeElement( e ); + + g->addElement( e ); + e->setParent( g ); + e->setParentPos( g ); + e->setParentSize( g ); + e->setIdRecurse( e->getShortId() ); + + onWidgetMoved( oldId, e->getId() ); + } + elms.clear(); + + // Make sure widgets aren't clipped because the group isn't big enough + g->spanElements(); + // Make sure widgets are aligned + g->alignElements(); + // Align the new group to the top window + g->alignTo( getTopWindow() ); + + g->setActive( true ); + + return true; + } + bool CWidgetManager::unGroupSelection() { if( editorSelection.size() != 1 ) @@ -3582,8 +3640,9 @@ namespace NLGUI setScreenWH( 0, 0 ); - groupSelection = false; + _GroupSelection = false; multiSelection = false; + _WidgetCount = 0; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index a818cf174..ef99c87fc 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -141,6 +141,11 @@ namespace GUIEditor CWidgetManager::getInstance()->setGroupSelection( b ); } + void CEditorMessageProcessor::onGroup() + { + CWidgetManager::getInstance()->groupSelection(); + } + void CEditorMessageProcessor::onUngroup() { bool ok = CWidgetManager::getInstance()->unGroupSelection(); diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index c3483e2ef..ee55fcda7 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onGroup(); void onUngroup(); void onSetMultiSelection( bool b ); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 6cc072ce8..ca5e240e7 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Group", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onGroup() ) ); + m->addAction( a ); + a = new QAction( "Ungroup", this ); connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); m->addAction( a ); From fe89e8f77cf197ce39689c1385203b8581cbbd0b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 13:04:03 +0200 Subject: [PATCH 082/344] Added limits to pch, should fix Linux build. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox.cpp | 1 - code/nel/src/gui/stdpch.h | 1 + code/nel/src/gui/view_text.cpp | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index ba65a07c4..92ae46703 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -28,7 +28,6 @@ #include "nel/gui/view_renderer.h" #include "nel/gui/db_manager.h" #include "nel/gui/interface_factory.h" -#include using namespace std; using namespace NLMISC; diff --git a/code/nel/src/gui/stdpch.h b/code/nel/src/gui/stdpch.h index bb983f77c..3270e6482 100644 --- a/code/nel/src/gui/stdpch.h +++ b/code/nel/src/gui/stdpch.h @@ -18,6 +18,7 @@ #define NELGUI_H #include +#include #include "nel/misc/types_nl.h" #include "nel/misc/algo.h" diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 743ba4ce7..815007723 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -28,8 +28,6 @@ #include "nel/gui/lua_ihm.h" #include "nel/gui/view_pointer_base.h" -#include - using namespace std; using namespace NLMISC; using namespace NL3D; From 99a3b93703f4c651605f5179d7f88ae61bb8a0c2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 14:44:16 +0200 Subject: [PATCH 083/344] Restored lost class names --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml | 1 + code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml | 1 + code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml | 1 + .../src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupList.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupModal.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTab.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTable.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTree.xml | 1 + code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml | 1 + .../src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewText.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml | 1 + .../studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml | 1 + 28 files changed, 28 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml index 12b82e7f6..c081f3dae 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml @@ -2,6 +2,7 @@
CtrlButton CCtrlButton + button CtrlBaseButton false diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml index ea2ba6171..7ab3e2f48 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml @@ -2,6 +2,7 @@
CtrlColPick CCtrlColPick + colpick CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml index 1ad970f31..9f5fcfc60 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml @@ -2,6 +2,7 @@
CtrlScroll CCtrlScroll + scroll CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml b/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml index 624ded887..7d78fc6b9 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml @@ -2,6 +2,7 @@
DBGroupSelectNumber CDBGroupSelectNumber + select_number InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml index c7f644fa4..878f9b563 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml @@ -2,6 +2,7 @@
DBViewBar CDBViewBar + bar ViewBitmap false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml index 8295c5f30..db635eb27 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml @@ -2,6 +2,7 @@
DBViewBar3 CDBViewBar3 + bar3 ViewBitmap false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml index 0c12445f9..1a659fd91 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml @@ -2,6 +2,7 @@
DBViewDigit CDBViewDigit + digit CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml index c1861df61..36a7d23ce 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml @@ -2,6 +2,7 @@
DBViewNumber CDBViewNumber + text_number ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml index c24379c96..c11c1a4cc 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml @@ -2,6 +2,7 @@
DBViewQuantity CDBViewQuantity + text_quantity ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml b/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml index 3d879a150..a3c9aade7 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml @@ -2,6 +2,7 @@
GroupContainer CGroupContainer + container InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml b/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml index 31ca205c7..578262a20 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml @@ -2,6 +2,7 @@
GroupEditBox CGroupEditBox + edit_box InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml b/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml index 5f0521be8..894580734 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml @@ -2,6 +2,7 @@
GroupHTML CGroupHTML + html GroupScrollText false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml b/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml index cc96fd742..91dd73e36 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml @@ -2,6 +2,7 @@
GroupHeader CGroupHeader + header GroupList false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupList.xml b/code/studio/src/plugins/gui_editor/widgets/GroupList.xml index 3ca2db95c..569aa8d9d 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupList.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupList.xml @@ -2,6 +2,7 @@
GroupList CGroupList + list InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml b/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml index cdd42ba95..3bd0c5506 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml @@ -2,6 +2,7 @@
GroupMenu CGroupMenu + menu GroupModal false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml b/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml index 034e3025e..33bd6fd08 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml @@ -2,6 +2,7 @@
GroupModal CGroupModal + modal GroupFrame false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml b/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml index 95719398d..53092a456 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml @@ -2,6 +2,7 @@
GroupScrollText CGroupScrollText + scroll_text InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml index df148a0a3..e2e1a8bf1 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml @@ -2,6 +2,7 @@
GroupTab CGroupTab + tab InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml index 9fa957741..dfbc4e2a8 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml @@ -2,6 +2,7 @@
GroupTable CGroupTable + table InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml index 73b1dea3b..b20c74733 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml @@ -2,6 +2,7 @@
GroupTree CGroupTree + tree InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml index ddcdf01e6..50f7c3e83 100644 --- a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml +++ b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml @@ -2,6 +2,7 @@
InterfaceGroup CInterfaceGroup + interface_group CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml index b095ecac5..6a35671cd 100644 --- a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml +++ b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml @@ -2,6 +2,7 @@
InterfaceGroupWheel CInterfaceGroupWheel + group_wheel InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml index 21ef7daff..7d78f6c40 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml @@ -2,6 +2,7 @@
ViewBitmap CViewBitmap + bitmap CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml b/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml index 8fc579675..461f69c55 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml @@ -2,6 +2,7 @@
ViewBitmapCombo CViewBitmapCombo + bitmap_combo CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml index 415c3167e..f515f7b3d 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml @@ -2,6 +2,7 @@
ViewText CViewText + text InterfaceElement false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml index cabd081f0..36aa68102 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml @@ -2,6 +2,7 @@
ViewTextFormated CViewTextFormated + text_formated ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml index 52e010ec6..43ac442c0 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml @@ -2,6 +2,7 @@
ViewTextID CViewTextID + text_id ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml index af8dd54eb..32b08f156 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml @@ -2,6 +2,7 @@
ViewTextIDFormated CViewTextIDFormated + text_id_formated ViewTextID false From 7e16e95c3570dcfd28684703ff7a30a2d823560d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:26:38 +0200 Subject: [PATCH 084/344] CInterfaceParser in editor mode should look for files in the working directory first. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_parser.h | 8 +++++++ code/nel/include/nel/gui/parser.h | 1 + code/nel/src/gui/interface_parser.cpp | 24 +++++++++++++++---- .../plugins/gui_editor/gui_editor_window.cpp | 2 ++ .../src/plugins/gui_editor/nelgui_ctrl.cpp | 6 +++++ .../src/plugins/gui_editor/nelgui_ctrl.h | 2 ++ 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_parser.h b/code/nel/include/nel/gui/interface_parser.h index 2bf1df9a8..c1b3fa109 100644 --- a/code/nel/include/nel/gui/interface_parser.h +++ b/code/nel/include/nel/gui/interface_parser.h @@ -353,7 +353,15 @@ namespace NLGUI std::map< std::string, std::string > pointerSettings; std::map< std::string, std::map< std::string, std::string > > keySettings; + std::string _WorkDir; + public: + /// Sets the working directory, where files should be looked for + void setWorkDir( const std::string &workdir ){ _WorkDir = workdir; } + + /// Looks up a file in either the working directory or using CPath::lookup + std::string lookup( const std::string &file ); + void initLUA(); void uninitLUA(); bool isLuaInitialized() const{ return luaInitialized; } diff --git a/code/nel/include/nel/gui/parser.h b/code/nel/include/nel/gui/parser.h index db868f70d..0378c22ec 100644 --- a/code/nel/include/nel/gui/parser.h +++ b/code/nel/include/nel/gui/parser.h @@ -88,6 +88,7 @@ namespace NLGUI virtual bool serializePointerSettings( xmlNodePtr parentNode ) const = 0; virtual bool serializeKeySettings( xmlNodePtr parentNode ) const = 0; virtual CViewBase* createClass( const std::string &name ) = 0; + virtual void setWorkDir( const std::string &workdir ) = 0; }; } diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index b26a403c4..f052224ff 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -233,6 +233,22 @@ namespace NLGUI destStream.seek(0, NLMISC::IStream::begin); } + std::string CInterfaceParser::lookup( const std::string &file ) + { + std::string filename; + + if( editorMode && !_WorkDir.empty() ) + { + std::string wdpath = CPath::standardizePath( _WorkDir ) + file; + if( CFile::fileExists( wdpath ) ) + filename = wdpath; + } + if( filename.empty() ) + filename = CPath::lookup( file ); + + return filename; + } + // ---------------------------------------------------------------------------- bool CInterfaceParser::parseInterface (const std::vector & strings, bool reload, bool isFilename, bool checkInData) { @@ -270,7 +286,7 @@ namespace NLGUI { //get the first file document pointer firstFileName = *it; - string filename = CPath::lookup(firstFileName); + string filename = lookup( firstFileName ); bool isInData = false; string::size_type pos = filename.find ("@"); if (pos != string::npos) @@ -283,7 +299,7 @@ namespace NLGUI isInData = true; } - if ((needCheck && !isInData) || !file.open (CPath::lookup(firstFileName))) + if ((needCheck && !isInData) || !file.open (lookup(firstFileName))) { // todo hulud interface syntax error nlwarning ("could not open file %s, skipping xml parsing",firstFileName.c_str()); @@ -331,7 +347,7 @@ namespace NLGUI { saveParseResult = true; std::string archive = CPath::lookup(nextFileName + "_compressed", false, false); - std::string current = CPath::lookup(nextFileName, false, false); + std::string current = lookup(nextFileName); if (!archive.empty() && !current.empty()) { if (CFile::getFileModificationDate(current) <= CFile::getFileModificationDate(archive)) @@ -351,7 +367,7 @@ namespace NLGUI { if (isFilename) { - if (!file.open(CPath::lookup(nextFileName, false, false))) + if (!file.open(lookup(nextFileName))) { // todo hulud interface syntax error nlwarning ("could not open file %s, skipping xml parsing",nextFileName.c_str()); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index ca5e240e7..5b3d835a2 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -181,6 +181,8 @@ namespace GUIEditor currentProject = projectFiles.projectName.c_str(); currentProjectFile = fileName; projectWindow->setupFiles( projectFiles ); + GUICtrl->setWorkDir( _lastDir ); + if( GUICtrl->parse( projectFiles ) ) { hierarchyView->buildHierarchy( projectFiles.masterGroup ); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index 03f784944..8f0f56711 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -187,6 +187,12 @@ namespace GUIEditor } } + void NelGUICtrl::setWorkDir( const QString &dir ) + { + IParser *parser = CWidgetManager::getInstance()->getParser(); + parser->setWorkDir( std::string( dir.toUtf8().constData() ) ); + } + QWidget* NelGUICtrl::getViewPort() { return w; diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index b3c68ff32..63118d947 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -52,6 +52,8 @@ namespace GUIEditor void show(); void hide(); + void setWorkDir( const QString &dir ); + Q_SIGNALS: void guiLoadComplete(); From 816e89c967874194b5f6c705a521af8024aa5403 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:40:41 +0200 Subject: [PATCH 085/344] Another classname. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml index ca66dbd62..6ad8334c5 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml @@ -2,6 +2,7 @@
CtrlTextButton CCtrlTextButton + text_button CtrlBaseButton false From 5217b38f58fd9e6e6b45ceb90386852bd430d400 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:47:39 +0200 Subject: [PATCH 086/344] Some defaults. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/widgets/CtrlTextButton.xml | 10 +++++----- .../studio/src/plugins/gui_editor/widgets/ViewText.xml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml index 6ad8334c5..6afd06cdf 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml @@ -12,22 +12,22 @@ tx_normal string - + but tx_pushed string - + but tx_over string - + but_over hardtext string - + push me wmargin @@ -157,7 +157,7 @@ line_maxw int - 0 + 100 multi_line_space diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml index f515f7b3d..4862517aa 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml @@ -47,7 +47,7 @@ line_maxw int - 0 + 100 multi_line_space @@ -102,7 +102,7 @@ hardtext string - + Some text hardtext_format From 03c041310ec73d37e3ac285dbf57189139ac039e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 18:56:24 +0200 Subject: [PATCH 087/344] Added dialog for the new GUI action. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/CMakeLists.txt | 2 + .../plugins/gui_editor/gui_editor_window.cpp | 14 +++- .../src/plugins/gui_editor/new_gui_dlg.cpp | 72 ++++++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 44 ++++++++++ .../src/plugins/gui_editor/new_gui_dlg.ui | 84 +++++++++++++++++++ 5 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.cpp create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.h create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.ui diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 2b46e2cdc..e1e8b38be 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -36,6 +36,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR texture_property_manager.h expression_editor.h expr_link_dlg.h + new_gui_dlg.h ) SET(OVQT_PLUGIN_GUI_EDITOR_UIS @@ -55,6 +56,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS texture_chooser.ui expression_editor.ui expr_link_dlg.ui + new_gui_dlg.ui ) SET(QT_USE_QTGUI TRUE) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 5b3d835a2..1f3c372c0 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -44,6 +44,7 @@ #include "editor_selection_watcher.h" #include "editor_message_processor.h" #include "add_widget_widget.h" +#include "new_gui_dlg.h" namespace GUIEditor { @@ -199,6 +200,13 @@ namespace GUIEditor void GUIEditorWindow::newDocument() { + NewGUIDlg d; + int result = d.exec(); + + if( result == QDialog::Rejected ) + return; + + close(); } void GUIEditorWindow::save() @@ -358,14 +366,14 @@ namespace GUIEditor void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); - //QAction *newAction = mm->action( Core::Constants::NEW ); + QAction *newAction = mm->action( Core::Constants::NEW ); QAction *saveAction = mm->action( Core::Constants::SAVE ); QAction *saveAsAction = mm->action( Core::Constants::SAVE_AS ); QAction *closeAction = mm->action( Core::Constants::CLOSE ); QAction *delAction = mm->action( Core::Constants::DEL ); - //if( newAction != NULL ) - // newAction->setEnabled( true ); + if( newAction != NULL ) + newAction->setEnabled( true ); if( saveAction != NULL ) saveAction->setEnabled( true ); if( saveAsAction != NULL ) diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp new file mode 100644 index 000000000..8dc7abb1e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -0,0 +1,72 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "new_gui_dlg.h" +#include + +NewGUIDlg::NewGUIDlg( QWidget *parent ) : +QDialog( parent ) +{ + m_ui.setupUi( this ); + + connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); + connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + +} + +NewGUIDlg::~NewGUIDlg() +{ +} + +QString NewGUIDlg::getProjectName() const +{ + return m_ui.projectEdit->text(); +} + +QString NewGUIDlg::getWindowName() const +{ + return m_ui.windowEdit->text(); +} + +void NewGUIDlg::onOKClicked() +{ + if( m_ui.projectEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a project name!" ) ); + return; + } + + if( m_ui.windowEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a window name!" ) ); + return; + } + + accept(); +} + +void NewGUIDlg::onCancelClicked() +{ + reject(); +} + + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h new file mode 100644 index 000000000..3e290545c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -0,0 +1,44 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef NEW_GUI_DLG_H +#define NEW_GUI_DLG_H + +#include "ui_new_gui_dlg.h" + +class NewGUIDlg : public QDialog +{ + Q_OBJECT + +public: + NewGUIDlg( QWidget *parent = NULL ); + ~NewGUIDlg(); + + QString getProjectName() const; + QString getWindowName() const; + +private Q_SLOTS: + void onOKClicked(); + void onCancelClicked(); + +private: + Ui::NewGUIDialog m_ui; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui new file mode 100644 index 000000000..a144c58e8 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -0,0 +1,84 @@ + + + NewGUIDialog + + + + 0 + 0 + 292 + 95 + + + + New GUI + + + + + + Project name + + + + + + + + + + Window name + + + + + + + + + + Qt::Horizontal + + + + 107 + 20 + + + + + + + + + + + 0 + 0 + + + + OK + + + + + + + + 0 + 0 + + + + Cancel + + + + + + + + + + From e5d2e9293d1c2fe1e8fb1c4a447572257ce7b7a0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 19:30:30 +0200 Subject: [PATCH 088/344] Moved CRootGroup out of CInterfaceParser. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/root_group.h | 46 +++++++++++++ code/nel/src/gui/interface_parser.cpp | 81 +---------------------- code/nel/src/gui/root_group.cpp | 94 +++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 80 deletions(-) create mode 100644 code/nel/include/nel/gui/root_group.h create mode 100644 code/nel/src/gui/root_group.cpp diff --git a/code/nel/include/nel/gui/root_group.h b/code/nel/include/nel/gui/root_group.h new file mode 100644 index 000000000..58963a3b2 --- /dev/null +++ b/code/nel/include/nel/gui/root_group.h @@ -0,0 +1,46 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef ROOT_GROUP_H +#define ROOT_GROUP_H + +#include +#include + +#include "nel/gui/interface_group.h" + +namespace NLGUI +{ + + class CRootGroup : public CInterfaceGroup + { + public: + CRootGroup(const TCtorParam ¶m); + virtual ~CRootGroup(); + + virtual CInterfaceElement* getElement (const std::string &id); + virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1); + virtual bool delGroup (CInterfaceGroup *child, bool dontDelete = false); + + private: + std::map< std::string, CInterfaceGroup* > _Accel; + }; + +} + +#endif + diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index f052224ff..7bf44c6f6 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -37,6 +37,7 @@ #include "nel/gui/lua_helper.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/lua_manager.h" +#include "nel/gui/root_group.h" #ifdef LUA_NEVRAX_VERSION #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger @@ -113,86 +114,6 @@ namespace NLGUI return node; } - - - // ---------------------------------------------------------------------------- - // CRootGroup - // ---------------------------------------------------------------------------- - - class CRootGroup : public CInterfaceGroup - { - public: - CRootGroup(const TCtorParam ¶m) - : CInterfaceGroup(param) - { } - - /// Destructor - virtual ~CRootGroup() { } - - virtual CInterfaceElement* getElement (const std::string &id) - { - if (_Id == id) - return this; - - if (id.substr(0, _Id.size()) != _Id) - return NULL; - - vector::const_iterator itv; - for (itv = _Views.begin(); itv != _Views.end(); itv++) - { - CViewBase *pVB = *itv; - if (pVB->getId() == id) - return pVB; - } - - vector::const_iterator itc; - for (itc = _Controls.begin(); itc != _Controls.end(); itc++) - { - CCtrlBase* ctrl = *itc; - if (ctrl->getId() == id) - return ctrl; - } - - // Accelerate - string sTmp = id; - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - string::size_type pos = sTmp.find(':'); - if (pos != string::npos) - sTmp = sTmp.substr(0,pos); - - map::iterator it = _Accel.find(sTmp); - if (it != _Accel.end()) - { - CInterfaceGroup *pIG = it->second; - return pIG->getElement(id); - } - return NULL; - } - - virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1) - { - string sTmp = child->getId(); - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - _Accel.insert(pair(sTmp, child)); - CInterfaceGroup::addGroup(child,eltOrder); - } - - virtual bool delGroup (CInterfaceGroup *child, bool dontDelete = false) - { - string sTmp = child->getId(); - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - map::iterator it = _Accel.find(sTmp); - if (it != _Accel.end()) - { - _Accel.erase(it); - } - return CInterfaceGroup::delGroup(child,dontDelete); - } - - private: - map _Accel; - }; - // ---------------------------------------------------------------------------- // CInterfaceParser // ---------------------------------------------------------------------------- diff --git a/code/nel/src/gui/root_group.cpp b/code/nel/src/gui/root_group.cpp new file mode 100644 index 000000000..bffdd5579 --- /dev/null +++ b/code/nel/src/gui/root_group.cpp @@ -0,0 +1,94 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "nel/gui/root_group.h" +#include + +namespace NLGUI +{ + + CRootGroup::CRootGroup(const TCtorParam ¶m) : + CInterfaceGroup(param) + { + } + + CRootGroup::~CRootGroup() + { + } + + CInterfaceElement* CRootGroup::getElement (const std::string &id) + { + if (_Id == id) + return this; + + if (id.substr(0, _Id.size()) != _Id) + return NULL; + + std::vector::const_iterator itv; + for (itv = _Views.begin(); itv != _Views.end(); itv++) + { + CViewBase *pVB = *itv; + if (pVB->getId() == id) + return pVB; + } + + std::vector::const_iterator itc; + for (itc = _Controls.begin(); itc != _Controls.end(); itc++) + { + CCtrlBase* ctrl = *itc; + if (ctrl->getId() == id) + return ctrl; + } + + // Accelerate + std::string sTmp = id; + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + std::string::size_type pos = sTmp.find(':'); + if (pos != std::string::npos) + sTmp = sTmp.substr(0,pos); + + std::map::iterator it = _Accel.find(sTmp); + if (it != _Accel.end()) + { + CInterfaceGroup *pIG = it->second; + return pIG->getElement(id); + } + return NULL; + } + + void CRootGroup::addGroup (CInterfaceGroup *child, sint eltOrder) + { + std::string sTmp = child->getId(); + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + _Accel.insert(std::pair(sTmp, child)); + CInterfaceGroup::addGroup(child,eltOrder); + } + + bool CRootGroup::delGroup (CInterfaceGroup *child, bool dontDelete) + { + std::string sTmp = child->getId(); + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + std::map::iterator it = _Accel.find(sTmp); + if (it != _Accel.end()) + { + _Accel.erase(it); + } + return CInterfaceGroup::delGroup(child,dontDelete); + } + +} + From ded18b266c1e4fe5579933c3b177880bc50e4934 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 21:43:28 +0200 Subject: [PATCH 089/344] Implemented new action. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 2 + code/nel/src/gui/widget_manager.cpp | 45 +++++++++++++++++++ .../plugins/gui_editor/gui_editor_window.cpp | 40 ++++++++++++----- .../plugins/gui_editor/gui_editor_window.h | 1 + .../src/plugins/gui_editor/nelgui_ctrl.cpp | 35 +++++++++++++-- .../src/plugins/gui_editor/nelgui_ctrl.h | 3 ++ 6 files changed, 112 insertions(+), 14 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index d722a9165..6d2336047 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -528,6 +528,8 @@ namespace NLGUI bool groupSelection(); bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } + + bool createNewGUI( const std::string &project, const std::string &window ); private: CWidgetManager(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c68a2c963..803889a79 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -35,6 +35,7 @@ #include "nel/gui/reflect_register.h" #include "nel/gui/editor_selection_watcher.h" #include "nel/misc/events.h" +#include "nel/gui/root_group.h" namespace NLGUI { @@ -1041,6 +1042,8 @@ namespace NLGUI resetGlobalAlphasProps(); activeAnims.clear(); + + editorSelection.clear(); } @@ -3604,6 +3607,48 @@ namespace NLGUI } + bool CWidgetManager::createNewGUI( const std::string &project, const std::string &window ) + { + reset(); + + for( int i = 0; i < _MasterGroups.size(); i++ ) + delete _MasterGroups[i].Group; + _MasterGroups.clear(); + + // First create the master group + CRootGroup *root = new CRootGroup( CViewBase::TCtorParam() ); + + SMasterGroup mg; + mg.Group = root; + + root->setIdRecurse( project ); + root->setW( 1024 ); + root->setH( 768 ); + root->setActive( true ); + + // Create the first / main window + CInterfaceGroup *wnd = new CInterfaceGroup( CViewBase::TCtorParam() ); + wnd->setW( 1024 ); + wnd->setH( 768 ); + wnd->setParent( root ); + wnd->setParentPos( root ); + wnd->setParentSize( root ); + wnd->setPosRef( Hotspot_MM ); + wnd->setParentPosRef( Hotspot_MM ); + wnd->setIdRecurse( window ); + wnd->setActive( true ); + + // Add the window + root->addElement( wnd ); + mg.addWindow( wnd, wnd->getPriority() ); + _MasterGroups.push_back( mg ); + + _Pointer = new CViewPointer( CViewBase::TCtorParam() ); + + return true; + } + + CWidgetManager::CWidgetManager() { LinkHack(); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 1f3c372c0..aedeea5d6 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -207,6 +207,21 @@ namespace GUIEditor return; close(); + + std::string proj = d.getProjectName().toUtf8().constData(); + std::string wnd = d.getWindowName().toUtf8().constData(); + + bool b = GUICtrl->createNewGUI( proj, wnd ); + if( !b ) + { + QMessageBox::information( this, + tr( "Creating new GUI project" ), + tr( "Failed to create new GUI project :(" ) ); + reset(); + } + + std::string mg = std::string( "ui:" ) + proj; + hierarchyView->buildHierarchy( mg ); } void GUIEditorWindow::save() @@ -279,6 +294,20 @@ namespace GUIEditor } + void GUIEditorWindow::reset() + { + projectFiles.clearAll(); + projectWindow->clear(); + hierarchyView->clearHierarchy(); + GUICtrl->reset(); + browserCtrl.clear(); + linkList->clear(); + procList->clear(); + currentProject = ""; + currentProjectFile = ""; + projectParser.clear(); + } + bool GUIEditorWindow::close() { if( currentProject.isEmpty() ) @@ -296,16 +325,7 @@ namespace GUIEditor disconnect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); disconnect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); - projectFiles.clearAll(); - projectWindow->clear(); - hierarchyView->clearHierarchy(); - GUICtrl->reset(); - browserCtrl.clear(); - linkList->clear(); - procList->clear(); - currentProject = ""; - currentProjectFile = ""; - projectParser.clear(); + reset(); return true; } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index cc2dfbc65..4a0a919a4 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -70,6 +70,7 @@ protected: void showEvent( QShowEvent *evnt ); private: + void reset(); void createMenus(); void removeMenus(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index 8f0f56711..c1e7af3df 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -114,11 +114,29 @@ namespace GUIEditor if( e != NULL ) e->setActive( true ); - timerID = startTimer( 200 ); - guiLoaded = true; - Q_EMIT guiLoadComplete(); + onGUILoaded(); - CWidgetManager::getInstance()->registerSelectionWatcher( watcher ); + return true; + } + + bool NelGUICtrl::createNewGUI( const std::string &project, const std::string &window ) + { + reset(); + bool ok = CWidgetManager::getInstance()->createNewGUI( project, window ); + if( !ok ) + return false; + + std::string mg = std::string( "ui:" ) + project; + std::string ag = mg + ":" + window; + + CWidgetManager::getInstance()->updateAllLocalisedElements(); + CWidgetManager::getInstance()->activateMasterGroup( mg, true ); + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( ag ); + if( e != NULL ) + e->setActive( true ); + + onGUILoaded(); return true; } @@ -160,6 +178,15 @@ namespace GUIEditor } } + void NelGUICtrl::onGUILoaded() + { + timerID = startTimer( 200 ); + guiLoaded = true; + Q_EMIT guiLoadComplete(); + + CWidgetManager::getInstance()->registerSelectionWatcher( watcher ); + } + void NelGUICtrl::show() { if( timerID == 0 ) diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index 63118d947..d7d157ccf 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -43,6 +43,7 @@ namespace GUIEditor void init(); bool parse( SProjectFiles &files ); + bool createNewGUI( const std::string &project, const std::string &window ); void draw(); void reset(); CEditorSelectionWatcher* getWatcher(){ return watcher; } @@ -61,6 +62,8 @@ Q_SIGNALS: void timerEvent( QTimerEvent *evnt ); private: + void onGUILoaded(); + int timerID; bool guiLoaded; CEditorSelectionWatcher *watcher; From 2de4315027376e15b00075ac076c3370313d536f Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 12 Oct 2014 17:43:18 +0300 Subject: [PATCH 090/344] Fix table cellpadding --HG-- branch : html-table-rendering --- code/nel/src/gui/group_table.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 2fdd7e364..ffebca4ea 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -937,10 +937,10 @@ namespace NLGUI } } - cell->setX(currentX); - cell->setW(_Columns[column].Width); + cell->setX(currentX - CellPadding); + cell->setW(_Columns[column].Width + CellPadding*2); - cell->Group->setX(alignmentX+cell->LeftMargin); + cell->Group->setX(alignmentX + cell->LeftMargin + CellPadding); cell->Group->setW(_Columns[column].Width - widthReduceX); cell->Group->CInterfaceElement::updateCoords(); @@ -989,9 +989,9 @@ namespace NLGUI } } - cell->setY(currentY); - cell->setH (_Rows[row].Height); - cell->Group->setY(-alignmentY); + cell->setY(currentY + CellPadding); + cell->setH (_Rows[row].Height + 2*CellPadding); + cell->Group->setY(-(alignmentY + CellPadding)); } // Resize the table @@ -1179,7 +1179,7 @@ namespace NLGUI if (!_Columns.empty() && !_Rows.empty() && BgColor.A) { - sint32 border = Border + CellSpacing + CellPadding; + sint32 border = Border + CellSpacing; if (border) { CRGBA finalColor; @@ -1197,20 +1197,20 @@ namespace NLGUI rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-border, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); // Draw the inside borders - sint32 insideWidth = 2*CellPadding + CellSpacing; + sint32 insideWidth = CellSpacing; if (insideWidth) { // Draw the inside verticals uint i; - sint32 x = _XReal + _Columns[0].Width + border; + sint32 x = _XReal + border + _Columns[0].Width + 2*CellPadding; for (i=1; i<_Columns.size(); i++) { rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal+border, insideWidth, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[i].Width + insideWidth; + x += _Columns[i].Width + 2*CellPadding + insideWidth; } // Draw the inside horizontals - sint32 y = _YReal + _HReal - border - _Rows[0].Height; + sint32 y = _YReal + _HReal - border - _Rows[0].Height - 2*CellPadding; if (_Rows[0].Height != 0) { y -= insideWidth; @@ -1223,10 +1223,10 @@ namespace NLGUI { for (j=0; j<_Columns.size(); j++) { - rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[j].Width + insideWidth; + rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width + 2*CellPadding, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); + x += _Columns[j].Width + 2*CellPadding + insideWidth; } - y -= _Rows[i].Height+ insideWidth; + y -= _Rows[i].Height + insideWidth + 2*CellPadding; } } } From 2c5617cea7205510364137900ac649573ab4a957 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 20:09:42 +0200 Subject: [PATCH 091/344] When creating a new project, save it right away. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 38 ++++++++++++++++++- .../src/plugins/gui_editor/new_gui_dlg.cpp | 26 +++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 2 + .../src/plugins/gui_editor/new_gui_dlg.ui | 23 +++++++++-- .../gui_editor/project_file_parser.cpp | 5 ++- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index aedeea5d6..70f206b3b 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -210,6 +210,9 @@ namespace GUIEditor std::string proj = d.getProjectName().toUtf8().constData(); std::string wnd = d.getWindowName().toUtf8().constData(); + std::string mg = std::string( "ui:" ) + proj; + std::string dir = d.getProjectDirectory().toUtf8().constData(); + std::string uiFile = "ui_" + proj + ".xml"; bool b = GUICtrl->createNewGUI( proj, wnd ); if( !b ) @@ -220,8 +223,41 @@ namespace GUIEditor reset(); } - std::string mg = std::string( "ui:" ) + proj; hierarchyView->buildHierarchy( mg ); + + projectFiles.projectName = proj; + projectFiles.masterGroup = mg; + projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; + projectFiles.version = NEW; + projectFiles.guiFiles.push_back( uiFile ); + projectWindow->setupFiles( projectFiles ); + + currentProject = proj.c_str(); + currentProjectFile = std::string( dir + "/" + proj + ".xml" ).c_str(); + + + // Save the project file + CProjectFileSerializer serializer; + serializer.setFile( currentProjectFile.toUtf8().constData() ); + if( !serializer.serialize( projectFiles ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } + + // Save the GUI file + WidgetSerializer widgetSerializer; + widgetSerializer.setFile( dir + "/" + uiFile ); + widgetSerializer.setActiveGroup( projectFiles.activeGroup ); + if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } } void GUIEditorWindow::save() diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp index 8dc7abb1e..88d4a19fd 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -18,6 +18,7 @@ #include "new_gui_dlg.h" #include +#include NewGUIDlg::NewGUIDlg( QWidget *parent ) : QDialog( parent ) @@ -26,6 +27,7 @@ QDialog( parent ) connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + connect( m_ui.projectDirTB, SIGNAL( clicked( bool ) ), this, SLOT( onProjectDirTBClicked() ) ); } @@ -43,6 +45,11 @@ QString NewGUIDlg::getWindowName() const return m_ui.windowEdit->text(); } +QString NewGUIDlg::getProjectDirectory() const +{ + return m_ui.projectDirEdit->text(); +} + void NewGUIDlg::onOKClicked() { if( m_ui.projectEdit->text().isEmpty() ) @@ -61,6 +68,14 @@ void NewGUIDlg::onOKClicked() return; } + if( m_ui.projectDirEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a project directory!" ) ); + return; + } + accept(); } @@ -69,4 +84,15 @@ void NewGUIDlg::onCancelClicked() reject(); } +void NewGUIDlg::onProjectDirTBClicked() +{ + QString dir = QFileDialog::getExistingDirectory( this, + tr( "Specify project directory" ), + "." ); + if( dir.isEmpty() ) + return; + + m_ui.projectDirEdit->setText( dir ); +} + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h index 3e290545c..f4bf474f7 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.h +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -31,10 +31,12 @@ public: QString getProjectName() const; QString getWindowName() const; + QString getProjectDirectory() const; private Q_SLOTS: void onOKClicked(); void onCancelClicked(); + void onProjectDirTBClicked(); private: Ui::NewGUIDialog m_ui; diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui index a144c58e8..7dca6d2a3 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -6,8 +6,8 @@ 0 0 - 292 - 95 + 332 + 125 @@ -35,6 +35,23 @@ + + + Project directory + + + + + + + + + + ... + + + + Qt::Horizontal @@ -47,7 +64,7 @@ - + diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index 7213b332a..a5646c963 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -16,6 +16,7 @@ #include "project_file_parser.h" +#include "nel/misc/debug.h" namespace GUIEditor { @@ -208,7 +209,9 @@ namespace GUIEditor reader.readNext(); } if( files.mapFiles.empty() ) - return false; + { + nlinfo( "No map file(s) specified in project file." ); + } return true; } From b587acb135fd2b9e671bddcd3abc6f22f14dac35 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 21:15:13 +0200 Subject: [PATCH 092/344] Some refactoring regarding saving. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 60 +++++++++---------- .../gui_editor/project_file_parser.cpp | 4 +- .../gui_editor/project_file_serializer.cpp | 2 +- .../src/plugins/gui_editor/project_files.h | 15 ++--- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 70f206b3b..aad19c2ac 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -212,6 +212,7 @@ namespace GUIEditor std::string wnd = d.getWindowName().toUtf8().constData(); std::string mg = std::string( "ui:" ) + proj; std::string dir = d.getProjectDirectory().toUtf8().constData(); + _lastDir = dir.c_str(); std::string uiFile = "ui_" + proj + ".xml"; bool b = GUICtrl->createNewGUI( proj, wnd ); @@ -228,7 +229,7 @@ namespace GUIEditor projectFiles.projectName = proj; projectFiles.masterGroup = mg; projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; - projectFiles.version = NEW; + projectFiles.version = SProjectFiles::NEW; projectFiles.guiFiles.push_back( uiFile ); projectWindow->setupFiles( projectFiles ); @@ -278,8 +279,23 @@ namespace GUIEditor // Can't save old projects any further, since the widgets are in multiple files in them // using templates, styles and whatnot. There's no way to restore the original XML structure // after it's loaded - if( projectParser.getProjectVersion() == OLD ) + if( projectFiles.version == SProjectFiles::OLD ) return; + + std::string f = _lastDir.toUtf8().constData(); + f += "/"; + f += projectFiles.guiFiles[ 0 ]; + + WidgetSerializer widgetSerializer; + widgetSerializer.setFile( f ); + widgetSerializer.setActiveGroup( projectFiles.activeGroup ); + if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } } void GUIEditorWindow::saveAs() @@ -292,42 +308,22 @@ namespace GUIEditor if( dir.isEmpty() ) return; + _lastDir = dir; - projectFiles.guiFiles.clear(); - projectFiles.guiFiles.push_back( "ui_" + projectFiles.projectName + ".xml" ); - projectFiles.version = NEW; - - QString newFile = - dir + "/" + projectFiles.projectName.c_str() + ".xml"; - - CProjectFileSerializer serializer; - serializer.setFile( newFile.toUtf8().constData() ); - if( !serializer.serialize( projectFiles ) ) + if( projectFiles.version == SProjectFiles::OLD ) { - QMessageBox::critical( this, - tr( "Failed to save project" ), - tr( "There was an error while trying to save the project." ) ); - return; - } - - std::string guiFile = - std::string( dir.toUtf8().constData() ) + "/" + "ui_" + projectFiles.projectName + ".xml"; + projectFiles.guiFiles.clear(); + projectFiles.guiFiles.push_back( "ui_" + projectFiles.projectName + ".xml" ); + projectFiles.version = SProjectFiles::NEW; - WidgetSerializer widgetSerializer; - widgetSerializer.setFile( guiFile ); - widgetSerializer.setActiveGroup( projectFiles.activeGroup ); - if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) - { - QMessageBox::critical( this, - tr( "Failed to save project" ), - tr( "There was an error while trying to save the project." ) ); - return; } - QMessageBox::information( this, - tr( "Save successful" ), - tr( "Project saved successfully!" ) ); + currentProjectFile = _lastDir; + currentProjectFile += "/"; + currentProjectFile += projectFiles.projectName.c_str(); + currentProjectFile += ".xml"; + save(); } void GUIEditorWindow::reset() diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index a5646c963..a10f5d783 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -63,7 +63,7 @@ namespace GUIEditor unsigned long CProjectFileParser::getProjectVersion() const { if( !loaded ) - return OLD; + return SProjectFiles::OLD; return files.version; } @@ -71,7 +71,7 @@ namespace GUIEditor void CProjectFileParser::clear() { files.projectName = ""; - files.version = OLD; + files.version = SProjectFiles::OLD; files.activeGroup = ""; files.guiFiles.clear(); files.mapFiles.clear(); diff --git a/code/studio/src/plugins/gui_editor/project_file_serializer.cpp b/code/studio/src/plugins/gui_editor/project_file_serializer.cpp index 4eb442d3f..0b34f511b 100644 --- a/code/studio/src/plugins/gui_editor/project_file_serializer.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_serializer.cpp @@ -25,7 +25,7 @@ namespace GUIEditor if( fileName.empty() ) return false; - if( project.version >= MAX_PROJECTFILE_VERSION ) + if( project.version >= SProjectFiles::MAX_PROJECTFILE_VERSION ) return false; out.open( fileName.c_str() ); diff --git a/code/studio/src/plugins/gui_editor/project_files.h b/code/studio/src/plugins/gui_editor/project_files.h index 4ae58493b..786bd22e4 100644 --- a/code/studio/src/plugins/gui_editor/project_files.h +++ b/code/studio/src/plugins/gui_editor/project_files.h @@ -23,16 +23,17 @@ namespace GUIEditor { - enum ProjectVersion - { - OLD = 0, - NEW = 1, - MAX_PROJECTFILE_VERSION - }; - struct SProjectFiles { public: + + enum ProjectVersion + { + OLD = 0, + NEW = 1, + MAX_PROJECTFILE_VERSION + }; + std::string projectName; unsigned long version; std::string masterGroup; From b3dd26e01cb968e0aee8eece958a77c3c82147e2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 23:05:22 +0200 Subject: [PATCH 093/344] Parent positions should now be saved right again. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 1 + code/nel/src/gui/interface_element.cpp | 36 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 0be4c02e3..a8a04b454 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -492,6 +492,7 @@ namespace NLGUI bool isEditorSelected() const{ return editorSelected; } void setPosParent( const std::string &id ); + void getPosParent( std::string &id ) const; void setSizeParent( const std::string &id ); void setSerializable( bool b ){ serializable = b; } diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index c9b480516..e3928e85f 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -294,8 +294,10 @@ namespace NLGUI xmlNewProp( node, BAD_CAST "w", BAD_CAST toString( _W ).c_str() ); xmlNewProp( node, BAD_CAST "h", BAD_CAST toString( _H ).c_str() ); xmlNewProp( node, BAD_CAST "posref", BAD_CAST HotSpotCoupleToString( _ParentPosRef, _PosRef ).c_str() ); - xmlNewProp( node, BAD_CAST "posparent", - BAD_CAST CWidgetManager::getInstance()->getParser()->getParentPosAssociation( (CInterfaceElement*)this ).c_str() ); + + std::string pp; + getPosParent( pp ); + xmlNewProp( node, BAD_CAST "posparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "sizeref", BAD_CAST getSizeRefAsString().c_str() ); xmlNewProp( node, BAD_CAST "sizeparent", BAD_CAST CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ).c_str() ); @@ -1541,6 +1543,36 @@ namespace NLGUI } } + void CInterfaceElement::getPosParent( std::string &id ) const + { + + // If there's no pos parent set, then the parent group is the pos parent + if( getParentPos() == NULL ) + { + id = "parent"; + return; + } + + // If pos parent and parent are the same then ofc the parent group is the pos parent... + CInterfaceElement *p = getParent(); + if( getParentPos() == p ) + { + id = "parent"; + return; + } + + // If parent is in the same group, use the short id + p = getParentPos(); + if( p->isInGroup( getParent() ) ) + { + id = p->getShortId(); + return; + } + + // Otherwise use the full id + id = p->getId(); + } + void CInterfaceElement::setSizeParent( const std::string &id ) { std::string Id = stripId( id ); From 487c6a344019236b6decaeb3ec5acc2a60fef022 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 23:07:08 +0200 Subject: [PATCH 094/344] GUI Editor should show the right parent position. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index e3928e85f..0e7458f3a 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -147,7 +147,9 @@ namespace NLGUI } if( name == "posparent" ) { - return CWidgetManager::getInstance()->getParser()->getParentPosAssociation( (CInterfaceElement*)this ); + std::string pp; + getPosParent( pp ); + return pp; } else if( name == "sizeparent" ) From 283cbe8092cd04343db4155c1d1e97332853f3f8 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 13 Oct 2014 01:10:46 +0300 Subject: [PATCH 095/344] Add bordercolor attribute to table tag --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 1 + code/nel/include/nel/gui/libwww.h | 1 + code/nel/src/gui/group_html.cpp | 2 ++ code/nel/src/gui/group_table.cpp | 21 +++++++++++++++++++++ code/nel/src/gui/libwww.cpp | 1 + 5 files changed, 26 insertions(+) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index 60d3d9e63..f41b1c074 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -142,6 +142,7 @@ namespace NLGUI // Table borders sint32 Border; + NLMISC::CRGBA BorderColor; sint32 CellPadding; sint32 CellSpacing; diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index ec23cafd2..6a744b8c0 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -79,6 +79,7 @@ namespace NLGUI HTML_ATTR(TABLE,ALIGN) = 0, HTML_ATTR(TABLE,BGCOLOR), HTML_ATTR(TABLE,BORDER), + HTML_ATTR(TABLE,BORDERCOLOR), HTML_ATTR(TABLE,CELLPADDING), HTML_ATTR(TABLE,CELLSPACING), HTML_ATTR(TABLE,CLASS), diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 1a2ae5b4b..56398a10a 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1453,6 +1453,8 @@ namespace NLGUI getPercentage (table->ForceWidthMin, table->TableRatio, value[MY_HTML_TABLE_WIDTH]); if (present[MY_HTML_TABLE_BORDER] && value[MY_HTML_TABLE_BORDER]) fromString(value[MY_HTML_TABLE_BORDER], table->Border); + if (present[MY_HTML_TABLE_BORDERCOLOR] && value[MY_HTML_TABLE_BORDERCOLOR]) + table->BorderColor = getColor (value[MY_HTML_TABLE_BORDERCOLOR]); if (present[MY_HTML_TABLE_CELLSPACING] && value[MY_HTML_TABLE_CELLSPACING]) fromString(value[MY_HTML_TABLE_CELLSPACING], table->CellSpacing); if (present[MY_HTML_TABLE_CELLPADDING] && value[MY_HTML_TABLE_CELLPADDING]) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index ffebca4ea..d7933b934 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -559,6 +559,7 @@ namespace NLGUI TableRatio = 0.f; ForceWidthMin = 0; Border=0; + BorderColor = CRGBA(127, 127, 127, 255); CellPadding=0; CellSpacing=0; ContinuousUpdate = false; @@ -1243,6 +1244,11 @@ namespace NLGUI return toString( Border ); } else + if( name == "bordercolor" ) + { + return toString( BorderColor ); + } + else if( name == "cellpadding" ) { return toString( CellPadding ); @@ -1279,6 +1285,14 @@ namespace NLGUI return; } else + if( name == "bordercolor" ) + { + CRGBA c; + if( fromString( value, c ) ) + BorderColor = c; + return; + } + else if( name == "cellpadding" ) { sint32 i; @@ -1321,6 +1335,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "type", BAD_CAST "table" ); xmlSetProp( node, BAD_CAST "border", BAD_CAST toString( Border ).c_str() ); + xmlSetProp( node, BAD_CAST "bordercolor", BAD_CAST toString( BorderColor ).c_str() ); xmlSetProp( node, BAD_CAST "cellpadding", BAD_CAST toString( CellPadding ).c_str() ); xmlSetProp( node, BAD_CAST "cellspacing", BAD_CAST toString( CellSpacing ).c_str() ); xmlSetProp( node, BAD_CAST "bgcolor", BAD_CAST toString( BgColor ).c_str() ); @@ -1345,6 +1360,12 @@ namespace NLGUI fromString((const char*)ptr, Border); } // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"bordercolor" ); + if (ptr) + { + BorderColor = convertColor((const char*)ptr); + } + // ptr = (char*) xmlGetProp( cur, (xmlChar*)"cellpadding" ); if (ptr) { diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp index 0b759a7aa..b17d1cccb 100644 --- a/code/nel/src/gui/libwww.cpp +++ b/code/nel/src/gui/libwww.cpp @@ -86,6 +86,7 @@ namespace NLGUI HTML_ATTR(TABLE,ALIGN), HTML_ATTR(TABLE,BGCOLOR), HTML_ATTR(TABLE,BORDER), + HTML_ATTR(TABLE,BORDERCOLOR), HTML_ATTR(TABLE,CELLPADDING), HTML_ATTR(TABLE,CELLSPACING), HTML_ATTR(TABLE,CLASS), From 11927cca93289628c6b9d5e77e3804900670c141 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 13 Oct 2014 01:59:20 +0300 Subject: [PATCH 096/344] Render table and cell borders --HG-- branch : html-table-rendering --- code/nel/src/gui/group_table.cpp | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index d7933b934..7c6a95b24 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -499,6 +499,29 @@ namespace NLGUI } } + // Get the parent table + if (getParent ()) + { + CGroupTable *table = static_cast (getParent ()); + if (table->Border) { + CRGBA lighter = blend(table->BorderColor, CRGBA::White, 0.5f); + + CRGBA borderColorTL; + borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); + borderColorTL.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorTL.A) >> 8); + + CRGBA borderColorBR; + borderColorBR.modulateFromColor (table->BorderColor, CWidgetManager::getInstance()->getGlobalColor()); + borderColorBR.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorBR.A) >> 8); + + CViewRenderer &rVR = *CViewRenderer::getInstance(); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorTL ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorBR ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_HReal-1, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorBR ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-1, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorTL ); + } + } + CInterfaceGroup::draw (); } @@ -1178,10 +1201,10 @@ namespace NLGUI if (gr == NULL) CurrentAlpha = 255; - if (!_Columns.empty() && !_Rows.empty() && BgColor.A) + if (!_Columns.empty() && !_Rows.empty()) { sint32 border = Border + CellSpacing; - if (border) + if (border && BgColor.A) { CRGBA finalColor; finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); @@ -1232,6 +1255,29 @@ namespace NLGUI } } } + + if (Border) { + CViewRenderer &rVR = *CViewRenderer::getInstance(); + + CRGBA borderColorTL; + CRGBA lighter = blend(BorderColor, CRGBA::White, 0.5f); + borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); + borderColorTL.A = CurrentAlpha; + + CRGBA borderColorBR; + borderColorBR.modulateFromColor (BorderColor, CWidgetManager::getInstance()->getGlobalColor()); + borderColorBR.A = CurrentAlpha; + + // beveled table border + for (sint32 i=0; i Date: Mon, 13 Oct 2014 15:26:47 +0200 Subject: [PATCH 097/344] Size parent is now queried directly from the widget. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 1 + code/nel/src/gui/interface_element.cpp | 37 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index a8a04b454..0f9b271ce 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -494,6 +494,7 @@ namespace NLGUI void setPosParent( const std::string &id ); void getPosParent( std::string &id ) const; void setSizeParent( const std::string &id ); + void getSizeParent( std::string &id ) const; void setSerializable( bool b ){ serializable = b; } bool IsSerializable() const{ return serializable; } diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 0e7458f3a..a18b8e71d 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -154,7 +154,9 @@ namespace NLGUI else if( name == "sizeparent" ) { - return CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ); + std::string sp; + getSizeParent( sp ); + return sp; } else if( name == "global_color" ) @@ -301,8 +303,8 @@ namespace NLGUI getPosParent( pp ); xmlNewProp( node, BAD_CAST "posparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "sizeref", BAD_CAST getSizeRefAsString().c_str() ); - xmlNewProp( node, BAD_CAST "sizeparent", - BAD_CAST CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ).c_str() ); + getSizeParent( pp ); + xmlNewProp( node, BAD_CAST "sizeparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "global_color", BAD_CAST toString( _ModulateGlobalColor ).c_str() ); xmlNewProp( node, BAD_CAST "render_layer", BAD_CAST toString( _RenderLayer ).c_str() ); @@ -1598,6 +1600,35 @@ namespace NLGUI } } + void CInterfaceElement::getSizeParent( std::string &id ) const + { + CInterfaceElement *p = getParentSize(); + + // If there's no parent set then the size parent is the parent + if( p == NULL ) + { + id = "parent"; + return; + } + + // If the size parent is the same as the group parent, then the size parent is the parent ofc + if( p == getParent() ) + { + id = "parent"; + return; + } + + // If the size parent is in the parent group, use the short Id + if( p->isInGroup( getParent() ) ) + { + id = p->getShortId(); + return; + } + + // Otherwise use the full Id + id = p->getId(); + } + void CInterfaceElement::registerDeletionWatcher( IDeletionWatcher *watcher ) { std::vector< IDeletionWatcher* >::iterator itr From 8066717aa22475ae2dd574ea9dd0178e4bb3598a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 15:43:10 +0200 Subject: [PATCH 098/344] Pos and Size parent setters should now use the widget directly as well. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 71 ++++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index a18b8e71d..620e7dbdb 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1534,17 +1534,36 @@ namespace NLGUI void CInterfaceElement::setPosParent( const std::string &id ) { - std::string Id = stripId( id ); + // Parent or empty id simply means the group parent + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentPos( getParent() ); + return; + } + + CInterfaceElement *pp = NULL; - if( Id != "parent" ) + // Check if it's a short Id + std::string::size_type idx = id.find( "ui:" ); + if( idx == std::string::npos ) { - std::string idParent; - if( _Parent != NULL ) - idParent = _Parent->getId() + ":"; - else - idParent = "ui:"; - CWidgetManager::getInstance()->getParser()->addParentPositionAssociation( this, idParent + Id ); + // If it is, find the widget in the parent group and set as posparent + CInterfaceGroup *p = getParent(); + if( p != NULL ) + { + pp = p->findFromShortId( id ); + } + } + else + { + // If it is not, find using the widgetmanager + // TODO: refactor, shouldn't use a singleton + pp = CWidgetManager::getInstance()->getElementFromId( id ); } + + if( pp != NULL ) + setParentPos( pp ); + } void CInterfaceElement::getPosParent( std::string &id ) const @@ -1579,25 +1598,35 @@ namespace NLGUI void CInterfaceElement::setSizeParent( const std::string &id ) { - std::string Id = stripId( id ); - std::string idParent; - - if( Id != "parent" ) + // Parent or empty id simply means the group parent + if( ( id == "parent" ) || ( id.empty() ) ) { - if( _Parent != NULL ) - idParent = _Parent->getId() + ":"; - else - idParent = "ui:"; - CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, idParent + Id ); + setParentSize( getParent() ); + return; } - else + + CInterfaceElement *pp = NULL; + + // Check if it's a short Id + std::string::size_type idx = id.find( "ui:" ); + if( idx == std::string::npos ) { - if( _Parent != NULL ) + // If it is, find the widget in the parent group and set as posparent + CInterfaceGroup *p = getParent(); + if( p != NULL ) { - idParent = _Parent->getId(); - CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, idParent ); + pp = p->findFromShortId( id ); } } + else + { + // If it is not, find using the widgetmanager + // TODO: refactor, shouldn't use a singleton + pp = CWidgetManager::getInstance()->getElementFromId( id ); + } + + if( pp != NULL ) + setParentSize( pp ); } void CInterfaceElement::getSizeParent( std::string &id ) const From c5cd6990fe808fef6fc38bc126ccd449e49908a2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 17:47:42 +0200 Subject: [PATCH 099/344] When creating a new GUI set the base color to white. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_parser.h | 16 +------- code/nel/include/nel/gui/parser.h | 2 + code/nel/include/nel/gui/variable_data.h | 41 +++++++++++++++++++++ code/nel/src/gui/interface_parser.cpp | 28 ++++++++++++++ code/nel/src/gui/widget_manager.cpp | 20 ++++++++++ 5 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 code/nel/include/nel/gui/variable_data.h diff --git a/code/nel/include/nel/gui/interface_parser.h b/code/nel/include/nel/gui/interface_parser.h index c1b3fa109..18ec9045a 100644 --- a/code/nel/include/nel/gui/interface_parser.h +++ b/code/nel/include/nel/gui/interface_parser.h @@ -28,6 +28,7 @@ #include "nel/gui/proc.h" #include "nel/gui/widget_manager.h" #include "nel/gui/link_data.h" +#include "nel/gui/variable_data.h" namespace NLGUI { @@ -100,20 +101,6 @@ namespace NLGUI virtual void setupOptions() = 0; }; - - struct VariableData - { - std::string entry; - std::string type; - std::string value; - uint32 size; - - VariableData() - { - size = 0; - } - }; - CInterfaceParser(); virtual ~CInterfaceParser(); @@ -386,6 +373,7 @@ namespace NLGUI void setEditorMode( bool b ){ editorMode = b; } + void setVariable( const VariableData &v ); bool serializeVariables( xmlNodePtr parentNode ) const; bool serializeProcs( xmlNodePtr parentNode ) const; bool serializePointerSettings( xmlNodePtr parentNode ) const; diff --git a/code/nel/include/nel/gui/parser.h b/code/nel/include/nel/gui/parser.h index 0378c22ec..bc53e402d 100644 --- a/code/nel/include/nel/gui/parser.h +++ b/code/nel/include/nel/gui/parser.h @@ -23,6 +23,7 @@ #include "nel/misc/types_nl.h" #include "nel/gui/proc.h" #include "nel/gui/link_data.h" +#include "nel/gui/variable_data.h" namespace NLGUI { @@ -83,6 +84,7 @@ namespace NLGUI virtual void removeLinkData( uint32 id ) = 0; virtual bool getLinkData( uint32 id, SLinkData &linkData ) = 0; virtual void updateLinkData( uint32 id, const SLinkData &linkData ) = 0; + virtual void setVariable( const VariableData &v ) = 0; virtual bool serializeVariables( xmlNodePtr parentNode ) const = 0; virtual bool serializeProcs( xmlNodePtr parentNode ) const = 0; virtual bool serializePointerSettings( xmlNodePtr parentNode ) const = 0; diff --git a/code/nel/include/nel/gui/variable_data.h b/code/nel/include/nel/gui/variable_data.h new file mode 100644 index 000000000..cffba2bce --- /dev/null +++ b/code/nel/include/nel/gui/variable_data.h @@ -0,0 +1,41 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef VARIABLE_DATA_H +#define VARIABLE_DATA_H + +#include "nel/misc/types_nl.h" + +namespace NLGUI +{ + struct VariableData + { + std::string entry; + std::string type; + std::string value; + uint32 size; + + VariableData() + { + size = 0; + } + }; + +} + + +#endif + diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index 7bf44c6f6..096c001ae 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -2951,6 +2951,34 @@ namespace NLGUI itr->second = linkData; } + void CInterfaceParser::setVariable( const VariableData &v ) + { + CInterfaceProperty prop; + const std::string &type = v.type; + const std::string &value = v.value; + const std::string &entry = v.entry; + + if( type == "sint64" ) + prop.readSInt64( value.c_str(), entry ); + else + if( type == "sint32" ) + prop.readSInt32( value.c_str(), entry ); + else + if( type == "float" || type == "double" ) + prop.readDouble( value.c_str(), entry ); + else + if( type == "bool" ) + prop.readBool( value.c_str(), entry ); + else + if( type == "rgba" ) + prop.readRGBA( value.c_str(), entry ); + else + if( type == "hotspot" ) + prop.readHotSpot( value.c_str(), entry ); + + variableCache[ entry ] = v; + } + bool CInterfaceParser::serializeVariables( xmlNodePtr parentNode ) const { diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 803889a79..81fbaf28b 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -3645,6 +3645,26 @@ namespace NLGUI _Pointer = new CViewPointer( CViewBase::TCtorParam() ); + IParser *parser = getParser(); + + + // Set base color to white + VariableData v; + v.type = "sint32"; + v.value = "255"; + + v.entry = "UI:SAVE:COLOR:R"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:G"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:B"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:A"; + parser->setVariable( v ); + return true; } From 22a1d39ac7bf42ed4d8cdaffcf474c22bc89210e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 18:53:26 +0200 Subject: [PATCH 100/344] Map files can now be specified when creating a new GUI project. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 20 ++++++++ .../src/plugins/gui_editor/nelgui_ctrl.cpp | 36 ++++++++------ .../src/plugins/gui_editor/nelgui_ctrl.h | 1 + .../src/plugins/gui_editor/new_gui_dlg.cpp | 37 +++++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 4 ++ .../src/plugins/gui_editor/new_gui_dlg.ui | 47 +++++++++++++++---- 6 files changed, 122 insertions(+), 23 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index aad19c2ac..002002abd 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -215,6 +215,9 @@ namespace GUIEditor _lastDir = dir.c_str(); std::string uiFile = "ui_" + proj + ".xml"; + QList< QString > mapList; + d.getMapList( mapList ); + bool b = GUICtrl->createNewGUI( proj, wnd ); if( !b ) { @@ -222,6 +225,7 @@ namespace GUIEditor tr( "Creating new GUI project" ), tr( "Failed to create new GUI project :(" ) ); reset(); + return; } hierarchyView->buildHierarchy( mg ); @@ -231,6 +235,22 @@ namespace GUIEditor projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; projectFiles.version = SProjectFiles::NEW; projectFiles.guiFiles.push_back( uiFile ); + + for( int i = 0; i < mapList.size(); i++ ) + { + projectFiles.mapFiles.push_back( mapList[ i ].toUtf8().constData() ); + } + + b = GUICtrl->loadMapFiles( projectFiles.mapFiles ); + if( !b ) + { + QMessageBox::information( this, + tr( "Creating new GUI project" ), + tr( "Failed to create new GUI project: Couldn't load map files. " ) ); + reset(); + return; + } + projectWindow->setupFiles( projectFiles ); currentProject = proj.c_str(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index c1e7af3df..e9712ce4e 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -89,20 +89,8 @@ namespace GUIEditor reset(); IParser *parser = CWidgetManager::getInstance()->getParser(); - std::vector< std::string >::iterator itr; - for( itr = files.mapFiles.begin(); itr != files.mapFiles.end(); ++itr ) - { - std::string &file = *itr; - std::string::size_type i = file.find_last_of( '.' ); - std::string mapFile = file.substr( 0, i ); - mapFile.append( ".txt" ); - - if( !CViewRenderer::getInstance()->loadTextures( file, mapFile, false ) ) - { - CViewRenderer::getInstance()->reset(); - return false; - } - } + if( !loadMapFiles( files.mapFiles ) ) + return false; if( !parser->parseInterface( files.guiFiles, false ) ) return false; @@ -119,6 +107,26 @@ namespace GUIEditor return true; } + bool NelGUICtrl::loadMapFiles( const std::vector< std::string > &v ) + { + std::vector< std::string >::const_iterator itr; + for( itr = v.begin(); itr != v.end(); ++itr ) + { + const std::string &file = *itr; + std::string::size_type i = file.find_last_of( '.' ); + std::string mapFile = file.substr( 0, i ); + mapFile.append( ".txt" ); + + if( !CViewRenderer::getInstance()->loadTextures( file, mapFile, false ) ) + { + CViewRenderer::getInstance()->reset(); + return false; + } + } + + return true; + } + bool NelGUICtrl::createNewGUI( const std::string &project, const std::string &window ) { reset(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index d7d157ccf..d54c78c7a 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -43,6 +43,7 @@ namespace GUIEditor void init(); bool parse( SProjectFiles &files ); + bool loadMapFiles( const std::vector< std::string > &v ); bool createNewGUI( const std::string &project, const std::string &window ); void draw(); void reset(); diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp index 88d4a19fd..3c9208dfc 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -28,6 +28,8 @@ QDialog( parent ) connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.projectDirTB, SIGNAL( clicked( bool ) ), this, SLOT( onProjectDirTBClicked() ) ); + connect( m_ui.addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) ); + connect( m_ui.removeButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveClicked() ) ); } @@ -50,6 +52,16 @@ QString NewGUIDlg::getProjectDirectory() const return m_ui.projectDirEdit->text(); } +void NewGUIDlg::getMapList( QList< QString > &l ) +{ + l.clear(); + + for( int i = 0; i < m_ui.mapList->count(); i++ ) + { + l.push_back( m_ui.mapList->item( i )->text() ); + } +} + void NewGUIDlg::onOKClicked() { if( m_ui.projectEdit->text().isEmpty() ) @@ -95,4 +107,29 @@ void NewGUIDlg::onProjectDirTBClicked() m_ui.projectDirEdit->setText( dir ); } +void NewGUIDlg::onAddClicked() +{ + if( m_ui.mapEdit->text().isEmpty() ) + return; + + QList< QListWidgetItem* > l = m_ui.mapList->findItems( m_ui.mapEdit->text(), Qt::MatchContains ); + if( !l.isEmpty() ) + { + return; + } + + m_ui.mapList->addItem( m_ui.mapEdit->text() ); + m_ui.mapEdit->clear(); +} + +void NewGUIDlg::onRemoveClicked() +{ + QListWidgetItem *item = m_ui.mapList->currentItem(); + if( item == NULL ) + return; + + delete item; +} + + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h index f4bf474f7..0d878461c 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.h +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -20,6 +20,7 @@ #define NEW_GUI_DLG_H #include "ui_new_gui_dlg.h" +#include class NewGUIDlg : public QDialog { @@ -32,11 +33,14 @@ public: QString getProjectName() const; QString getWindowName() const; QString getProjectDirectory() const; + void getMapList( QList< QString > &l ); private Q_SLOTS: void onOKClicked(); void onCancelClicked(); void onProjectDirTBClicked(); + void onAddClicked(); + void onRemoveClicked(); private: Ui::NewGUIDialog m_ui; diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui index 7dca6d2a3..bf22e8c6b 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -6,14 +6,14 @@ 0 0 - 332 - 125 + 399 + 354 New GUI - + @@ -21,7 +21,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -41,17 +41,46 @@ - + - + ... - + + + + Map files + + + + + + Add + + + + + + + + + + Remove + + + + + + + + + + Qt::Horizontal @@ -64,7 +93,7 @@ - + From fae1e39039dc9d0b7e69c124b73bc22a6875b4f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 18:55:17 +0200 Subject: [PATCH 101/344] Don't reject an action property just because it's empty... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index 84302bcf0..c518d7acc 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -728,9 +728,6 @@ namespace GUIEditor { std::string j = element->getProperty( prop.propName ); - if( j.empty() ) - return; - QtProperty *pp = actionMgr->addProperty( prop.propName.c_str() ); if( pp == NULL ) return; From ab76b7ed85630c41abe00f84ffc6ecfa9ca6ab84 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 19:15:59 +0200 Subject: [PATCH 102/344] It's not a bad idea to actually retrieve the version if we load it... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/project_file_parser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index a10f5d783..856b3c164 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -58,6 +58,7 @@ namespace GUIEditor projectFiles.projectName = files.projectName; projectFiles.masterGroup = files.masterGroup; projectFiles.activeGroup = files.activeGroup; + projectFiles.version = files.version; } unsigned long CProjectFileParser::getProjectVersion() const From 2b5898565f4ec153c71b8b42fc65dd285c9c25a5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 20:15:41 +0200 Subject: [PATCH 103/344] Don't disable the active group before serializing. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_serializer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_serializer.cpp b/code/studio/src/plugins/gui_editor/widget_serializer.cpp index fd4e7cfbe..8006a6b50 100644 --- a/code/studio/src/plugins/gui_editor/widget_serializer.cpp +++ b/code/studio/src/plugins/gui_editor/widget_serializer.cpp @@ -93,8 +93,6 @@ namespace GUIEditor return false; } - ag->setActive( false ); - if( mg->serializeSubGroups( root ) == NULL ) { ag->setActive( true ); @@ -103,8 +101,6 @@ namespace GUIEditor return false; } - ag->setActive( true ); - if( !mg->serializeLinks( root ) ) { xmlFreeNode( root ); From a53b9305a2a6dc021479cfae0b9064ccb7602dd2 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 14 Oct 2014 15:26:14 +0300 Subject: [PATCH 104/344] Add rowspan and colspan attributes --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 2 ++ code/nel/src/gui/group_html.cpp | 8 ++++++ code/nel/src/gui/group_table.cpp | 36 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index f41b1c074..f161c04f9 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -78,6 +78,8 @@ namespace NLGUI // The Width you want in pixel. This is the parameter sint32 WidthWanted; + sint32 ColSpan; + sint32 RowSpan; // The min height of the cell sint32 Height; diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 56398a10a..6266ea769 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1519,11 +1519,19 @@ namespace NLGUI } } } + + if (present[MY_HTML_TD_COLSPAN] && value[MY_HTML_TD_COLSPAN]) + fromString(value[MY_HTML_TD_COLSPAN], _Cells.back()->ColSpan); + if (present[MY_HTML_TD_ROWSPAN] && value[MY_HTML_TD_ROWSPAN]) + fromString(value[MY_HTML_TD_ROWSPAN], _Cells.back()->RowSpan); + _Cells.back()->BgColor = _CellParams.back().BgColor; _Cells.back()->Align = _CellParams.back().Align; _Cells.back()->VAlign = _CellParams.back().VAlign; _Cells.back()->LeftMargin = _CellParams.back().LeftMargin; _Cells.back()->NoWrap = _CellParams.back().NoWrap; + _Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan); + _Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan); float temp; if (present[MY_HTML_TD_WIDTH] && value[MY_HTML_TD_WIDTH]) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 7c6a95b24..677260dbb 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -44,6 +44,8 @@ namespace NLGUI TableRatio = 0.f; WidthWanted = 0; Height = 0; + ColSpan = 1; + RowSpan = 1; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; VAlign = Top; @@ -249,6 +251,22 @@ namespace NLGUI AddChildW = b; return; } + else + if (name == "colspan" ) + { + sint32 i; + if (fromString( value, i ) ) + ColSpan = std::max(1, i); + return; + } + else + if (name == "rowspan" ) + { + sint32 i; + if (fromString( value, i ) ) + RowSpan = std::max(1, i); + return; + } else CInterfaceGroup::setProperty( name, value ); } @@ -310,6 +328,8 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "ignore_max_width", BAD_CAST toString( IgnoreMaxWidth ).c_str() ); xmlSetProp( node, BAD_CAST "ignore_min_width", BAD_CAST toString( IgnoreMinWidth ).c_str() ); xmlSetProp( node, BAD_CAST "add_child_w", BAD_CAST toString( AddChildW ).c_str() ); + xmlSetProp( node, BAD_CAST "colspan", BAD_CAST toString( ColSpan ).c_str() ); + xmlSetProp( node, BAD_CAST "rowspan", BAD_CAST toString( RowSpan ).c_str() ); return node; } @@ -422,6 +442,22 @@ namespace NLGUI { AddChildW = convertBool(ptr); } + // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"colspan" ); + if (ptr) + { + sint32 i; + if (fromString((const char*)ptr, i)) + ColSpan = std::max(1, i); + } + // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"rowspan" ); + if (ptr) + { + sint32 i; + if (fromString((const char*)ptr, i)) + RowSpan = std::max(1, i); + } return true; } From 799705b7edec693fcf295fc8731338ab2798da2b Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 14 Oct 2014 15:29:06 +0300 Subject: [PATCH 105/344] Render table with rowspan, colspan. Borders, if enabled, adds +1 to cell padding. --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 4 +- code/nel/src/gui/group_table.cpp | 203 ++++++++++++++++--------- 2 files changed, 135 insertions(+), 72 deletions(-) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index f161c04f9..746078908 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -80,6 +80,7 @@ namespace NLGUI sint32 ColSpan; sint32 RowSpan; + sint32 TableColumnIndex; // The min height of the cell sint32 Height; @@ -194,13 +195,14 @@ namespace NLGUI WidthMax = 0; WidthWanted = 0; TableRatio = 0; - Height = 0; + RowSpan = 1; } sint32 Width; sint32 Height; sint32 WidthWanted; sint32 WidthMax; float TableRatio; + sint32 RowSpan; }; // Table row diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 677260dbb..386cbacbd 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -46,6 +46,7 @@ namespace NLGUI Height = 0; ColSpan = 1; RowSpan = 1; + TableColumnIndex = 0; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; VAlign = Top; @@ -618,7 +619,7 @@ namespace NLGUI TableRatio = 0.f; ForceWidthMin = 0; Border=0; - BorderColor = CRGBA(127, 127, 127, 255); + BorderColor = CRGBA(32, 32, 32, 255); CellPadding=0; CellSpacing=0; ContinuousUpdate = false; @@ -752,35 +753,75 @@ namespace NLGUI // New cell ? if (cell->NewLine) + { + while (column < _Columns.size()) + { + if (_Columns[column].RowSpan > 1) + _Columns[column].RowSpan--; + column++; + } column = 0; + } // Resize the array if (column>=_Columns.size()) _Columns.resize(column+1); + // Handle rowspan from previous row + while (_Columns[column].RowSpan > 1) + { + _Columns[column].RowSpan--; + column++; + // if previous row had less elements, then we missing columns + if (column>=_Columns.size()) + _Columns.resize(column+1); + } + + // remember column index for later use + cell->TableColumnIndex = column; + + // new column, set rowspan from current + _Columns[column].RowSpan = cell->RowSpan; + float colspan = 1.f / cell->ColSpan; + float rowspan = 1.f / cell->RowSpan; + // Update sizes - if (cellWidth > _Columns[column].Width) - _Columns[column].Width = cellWidth; - if (cell->WidthMax > _Columns[column].WidthMax) - _Columns[column].WidthMax = cell->WidthMax; - if (cell->TableRatio > _Columns[column].TableRatio) - _Columns[column].TableRatio = cell->TableRatio; - if (cell->WidthWanted + additionnalWidth > _Columns[column].WidthWanted) - _Columns[column].WidthWanted = cell->WidthWanted + additionnalWidth; - if (cell->Height > _Columns[column].Height) - _Columns[column].Height = cell->Height; + if (cellWidth*colspan > _Columns[column].Width) + _Columns[column].Width = cellWidth*colspan; + if (cell->WidthMax*colspan > _Columns[column].WidthMax) + _Columns[column].WidthMax = cell->WidthMax*colspan; + if (cell->TableRatio*colspan > _Columns[column].TableRatio) + _Columns[column].TableRatio = cell->TableRatio*colspan; + if (cell->WidthWanted*colspan + additionnalWidth > _Columns[column].WidthWanted) + _Columns[column].WidthWanted = (sint32)(cell->WidthWanted*colspan) + additionnalWidth; if (_Columns[column].WidthWanted + additionnalWidth) _Columns[column].WidthMax = _Columns[column].WidthWanted + additionnalWidth; if (_Columns[column].WidthWanted > _Columns[column].Width) _Columns[column].Width = _Columns[column].WidthWanted; + if (cell->ColSpan > 1) { + // copy this info to all spanned columns, create new columns as needed + uint newsize = column + cell->ColSpan - 1; + if (newsize >= _Columns.size()) + _Columns.resize(newsize+1); + for(uint span = 0; span < cell->ColSpan -1; span++){ + column++; + _Columns[column].Width = _Columns[column-1].Width; + _Columns[column].WidthMax = _Columns[column-1].WidthMax; + _Columns[column].TableRatio = _Columns[column-1].TableRatio; + _Columns[column].WidthWanted = _Columns[column-1].WidthWanted; + _Columns[column].RowSpan = _Columns[column-1].RowSpan; + } + } + // Next column column++; } // Width of cells and table borders - sint32 borderWidth = 2*Border + ((sint32)_Columns.size()+1) * CellSpacing + ((sint32)_Columns.size()*2) * CellPadding; + sint32 padding = CellPadding + (Border ? 1 : 0); + sint32 borderWidth = 2*Border + ((sint32)_Columns.size()+1) * CellSpacing + ((sint32)_Columns.size()*2) * padding; // Get the width sint32 tableWidthMax = ForceWidthMin?ForceWidthMin:_LastParentW; // getWReal(); @@ -862,7 +903,6 @@ namespace NLGUI // Some space ? space = finalWidth - tableWidth; - if (space > 0) { // Then add in wanted Width cells @@ -952,6 +992,18 @@ namespace NLGUI } } } + + // If there is still space left, then sum up column widths + // and add all the remaining space to final column. + if (space > 0) + { + sint32 innerWidth = 0; + for(i=0;i<_Columns.size();i++) + innerWidth += _Columns[i].Width; + + if (innerWidth > 0 && finalWidth > innerWidth) + _Columns[_Columns.size()-1].Width += finalWidth - innerWidth; + } } } } @@ -962,7 +1014,8 @@ namespace NLGUI column = 0; sint32 row = 0; - sint32 currentX = Border + CellSpacing + CellPadding; + sint32 currentX = Border + CellSpacing + padding; + _Rows.clear (); for (i=0; i<_Cells.size(); i++) { @@ -971,25 +1024,41 @@ namespace NLGUI if (cell->NewLine) { column = 0; - currentX = Border + CellSpacing + CellPadding; + currentX = Border + CellSpacing + padding; + _Rows.push_back(CRow()); } + if (cell->TableColumnIndex > 0) + { + // we have active rowspan, must add up 'skipped' columns + for( ; columnTableColumnIndex; column++) + currentX += _Columns[column].Width + padding*2 + CellSpacing; + } + // Set the x and width // Check align sint32 alignmentX = 0; sint32 widthReduceX = 0; - if (cell->WidthMax < _Columns[column].Width) + sint32 columnWidth = _Columns[column].Width; + if (cell->ColSpan > 1) + { + // scan ahead and add up column widths as they might be different + for(int j = 1; jColSpan; j++) + columnWidth += CellSpacing + padding*2 + _Columns[column+j].Width; + } + + if (cell->WidthMax < columnWidth) { switch (cell->Align) { case CGroupCell::Center: - alignmentX = (_Columns[column].Width - cell->WidthMax) / 2; + alignmentX = (columnWidth - cell->WidthMax) / 2; widthReduceX = alignmentX * 2; break; case CGroupCell::Right: - alignmentX = _Columns[column].Width - cell->WidthMax; + alignmentX = columnWidth - cell->WidthMax; widthReduceX = alignmentX; break; default: @@ -997,11 +1066,11 @@ namespace NLGUI } } - cell->setX(currentX - CellPadding); - cell->setW(_Columns[column].Width + CellPadding*2); + cell->setX(currentX - padding); + cell->setW(columnWidth + padding*2); - cell->Group->setX(alignmentX + cell->LeftMargin + CellPadding); - cell->Group->setW(_Columns[column].Width - widthReduceX); + cell->Group->setX(alignmentX + cell->LeftMargin + padding); + cell->Group->setW(columnWidth - widthReduceX); cell->Group->CInterfaceElement::updateCoords(); // Update coords to get H @@ -1009,16 +1078,17 @@ namespace NLGUI cell->Group->updateCoords(); // Resize the row array - _Rows.back().Height = std::max(cell->Height, std::max(_Rows.back().Height, (sint32)cell->Group->getH())); + float rowspan = 1 / cell->RowSpan; + _Rows.back().Height = std::max((sint32)(cell->Height*rowspan), std::max(_Rows.back().Height, (sint32)(cell->Group->getH()*rowspan))); // Next column - currentX += _Columns[column].Width + 2*CellPadding + CellSpacing; - column ++; + currentX += columnWidth + 2*padding + CellSpacing; + column += cell->ColSpan; } // Set cell Y row = 0; - sint32 currentY = -(Border + CellSpacing + CellPadding); + sint32 currentY = -(Border + CellSpacing + padding); for (i=0; i<_Cells.size(); i++) { // New cell ? @@ -1027,37 +1097,45 @@ namespace NLGUI { if (_Rows[row].Height != 0) { - currentY -= _Rows[row].Height + 2*CellPadding + CellSpacing; + currentY -= _Rows[row].Height + 2*padding + CellSpacing; } row++; } // Check align sint32 alignmentY = 0; - if ((sint32)cell->Group->getH() < _Rows[row].Height) + sint32 rowHeight = _Rows[row].Height; + if (cell->RowSpan > 1) + { + // we need to scan down and add up row heights + int k = std::min((sint32)_Rows.size(), row + cell->RowSpan); + for(int j=row+1; jGroup->getH() < rowHeight) { switch (cell->VAlign) { case CGroupCell::Middle: - alignmentY = (_Rows[row].Height - (sint32)cell->Group->getH()) / 2; + alignmentY = (rowHeight - (sint32)cell->Group->getH()) / 2; break; case CGroupCell::Bottom: - alignmentY = _Rows[row].Height - (sint32)cell->Group->getH(); + alignmentY = rowHeight - (sint32)cell->Group->getH(); break; default: break; } } - cell->setY(currentY + CellPadding); - cell->setH (_Rows[row].Height + 2*CellPadding); - cell->Group->setY(-(alignmentY + CellPadding)); + cell->setY(currentY + padding); + cell->setH (rowHeight + 2*padding); + cell->Group->setY(-(alignmentY + padding)); } // Resize the table setW(finalWidth+borderWidth-_LastParentW); if (!_Rows.empty()) - currentY -= _Rows[row].Height + CellPadding + CellSpacing + Border; + currentY -= _Rows[row].Height + padding + CellSpacing + Border; setH(-currentY); // All done @@ -1246,53 +1324,35 @@ namespace NLGUI finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); finalColor.A = CurrentAlpha; - // Draw the top and bottom lines + // Draw the top line CViewRenderer &rVR = *CViewRenderer::getInstance(); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, border, 0, false, rVR.getBlankTextureId(), finalColor); rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal-border+_HReal, _WReal, border, 0, false, rVR.getBlankTextureId(), finalColor); - // Draw the left and right lines - sint32 insideHeight = std::max((sint32)0, (sint32)_HReal - (sint32)2*border); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-border, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); + // Draw the left line + sint32 insideHeight = std::max((sint32)0, (sint32)_HReal - (sint32)border); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); // Draw the inside borders - sint32 insideWidth = CellSpacing; - if (insideWidth) + if (CellSpacing) { - // Draw the inside verticals uint i; - sint32 x = _XReal + border + _Columns[0].Width + 2*CellPadding; - for (i=1; i<_Columns.size(); i++) - { - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal+border, insideWidth, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[i].Width + 2*CellPadding + insideWidth; - } - - // Draw the inside horizontals - sint32 y = _YReal + _HReal - border - _Rows[0].Height - 2*CellPadding; - if (_Rows[0].Height != 0) + sint32 x, y; + for (i=0; i<_Cells.size(); i++) { - y -= insideWidth; - } - for (i=1; i<_Rows.size(); i++) - { - uint j; - x = _XReal + border; - if (_Rows[i].Height != 0) - { - for (j=0; j<_Columns.size(); j++) - { - rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width + 2*CellPadding, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[j].Width + 2*CellPadding + insideWidth; - } - y -= _Rows[i].Height + insideWidth + 2*CellPadding; - } + CGroupCell *cell = _Cells[i]; + + x = cell->getXReal(); + y = cell->getYReal() - CellSpacing; + // right + rVR.drawRotFlipBitmap (_RenderLayer, x + cell->getW(), y, CellSpacing, cell->getH() + CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); + // bottom + rVR.drawRotFlipBitmap (_RenderLayer, x, y, cell->getW(), CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); } } - } - if (Border) { + } + if (Border) + { CViewRenderer &rVR = *CViewRenderer::getInstance(); CRGBA borderColorTL; @@ -1305,7 +1365,8 @@ namespace NLGUI borderColorBR.A = CurrentAlpha; // beveled table border - for (sint32 i=0; i Date: Wed, 15 Oct 2014 00:02:38 +0300 Subject: [PATCH 106/344] Change table defaults valign=middle, cellpadding=1, cellspacing=2 --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_html.h | 2 +- code/nel/src/gui/group_table.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index ba34af2dd..21d609af3 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -528,7 +528,7 @@ namespace NLGUI CCellParams () : BgColor(0,0,0,0) { Align = CGroupCell::Left; - VAlign = CGroupCell::Top; + VAlign = CGroupCell::Middle; LeftMargin = 0; NoWrap = false; } diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 386cbacbd..65ed2d93d 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -49,7 +49,7 @@ namespace NLGUI TableColumnIndex = 0; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; - VAlign = Top; + VAlign = Middle; LeftMargin = 0; NoWrap = false; IgnoreMaxWidth = false; @@ -620,8 +620,8 @@ namespace NLGUI ForceWidthMin = 0; Border=0; BorderColor = CRGBA(32, 32, 32, 255); - CellPadding=0; - CellSpacing=0; + CellPadding=1; + CellSpacing=2; ContinuousUpdate = false; } From 3209f48daa8107aaf5f8a203482bc3af0c885d1d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 12:09:57 +0200 Subject: [PATCH 107/344] Don't drop the texture property just because there's no texture assigned... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index c518d7acc..6db5423a3 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -713,9 +713,6 @@ namespace GUIEditor { std::string j = element->getProperty( prop.propName ); - if( j.empty() ) - return; - QtProperty *pp = textureMgr->addProperty( prop.propName.c_str() ); if( pp == NULL ) return; From f91846c9709d708c9f9641892e0ddbddf730b650 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 19:46:43 +0200 Subject: [PATCH 108/344] Fix parent pos and size parsing. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 2 + code/nel/src/gui/interface_element.cpp | 44 +++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 0f9b271ce..c1f6d20e7 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -491,8 +491,10 @@ namespace NLGUI void setEditorSelected( bool b ){ editorSelected = b; } bool isEditorSelected() const{ return editorSelected; } + void parsePosParent( const std::string &id ); void setPosParent( const std::string &id ); void getPosParent( std::string &id ) const; + void parseSizeParent( const std::string &id ); void setSizeParent( const std::string &id ); void getSizeParent( std::string &id ) const; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 620e7dbdb..66eee038e 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -388,13 +388,13 @@ namespace NLGUI ptr = (char*) xmlGetProp( cur, (xmlChar*)"posparent" ); if (ptr) { - setPosParent( std::string( (const char*)ptr ) ); + parsePosParent( (const char*)ptr ); } ptr = (char*) xmlGetProp( cur, (xmlChar*)"sizeparent" ); if (ptr) { - setSizeParent( std::string( (const char*)ptr ) ); + parseSizeParent( (const char*)ptr ); } ptr = (char*) xmlGetProp (cur, (xmlChar*)"sizeref"); @@ -1532,6 +1532,26 @@ namespace NLGUI return false; } + void CInterfaceElement::parsePosParent( const std::string &id ) + { + CInterfaceElement *p = getParent(); + + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentPos( p ); + return; + } + + std::string ppId; + + if( p != NULL ) + ppId = p->getId() + ":" + id; + else + ppId = std::string( "ui:" ) + id; + + CWidgetManager::getInstance()->getParser()->addParentPositionAssociation( this, ppId ); + } + void CInterfaceElement::setPosParent( const std::string &id ) { // Parent or empty id simply means the group parent @@ -1596,6 +1616,26 @@ namespace NLGUI id = p->getId(); } + void CInterfaceElement::parseSizeParent( const std::string &id ) + { + CInterfaceElement *p = getParent(); + + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentSize( p ); + return; + } + + std::string spId; + + if( p != NULL ) + spId = p->getId() + ":" + id; + else + spId = std::string( "ui:" ) + id; + + CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, spId ); + } + void CInterfaceElement::setSizeParent( const std::string &id ) { // Parent or empty id simply means the group parent From bd942ba62b0ecd33987312db3c45d5a4f8816b7a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 19:54:35 +0200 Subject: [PATCH 109/344] TEMPORARILY add the login texture map to new project by default. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/new_gui_dlg.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp index 3c9208dfc..43faabf79 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -25,6 +25,9 @@ QDialog( parent ) { m_ui.setupUi( this ); + // Login texture map - temporaty measure until we add default textures for widgets to use + m_ui.mapList->addItem( "texture_interfaces_v3_login.tga" ); + connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.projectDirTB, SIGNAL( clicked( bool ) ), this, SLOT( onProjectDirTBClicked() ) ); From cfa4129754cd67fdec0d3bc8fd6cbcc959defa3c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 20:03:46 +0200 Subject: [PATCH 110/344] Default texture for CtrlButton. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml index c081f3dae..b52bb73a5 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml @@ -12,17 +12,17 @@ tx_normal string - + tp_quit.tga tx_pushed string - + tp_quit.tga tx_over string - + tp_quit.tga scale From c9b528081e0a6ba38ba3dd3f9e64b3189b6c0d48 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 20:07:13 +0200 Subject: [PATCH 111/344] CtrlButton textures should be selectable in the texture chooser! --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml index b52bb73a5..2454f7035 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml @@ -11,17 +11,17 @@ tx_normal - string + texture tp_quit.tga tx_pushed - string + texture tp_quit.tga tx_over - string + texture tp_quit.tga From 66fe76fc064a591f6647e944462c3d304fc413b5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 20:20:44 +0200 Subject: [PATCH 112/344] A Kami will be the default texture for Bitmaps. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml index 7d78f6c40..1c22d67cd 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml @@ -37,7 +37,7 @@ texture texture - + log_kami.tga scale From f7f74b5398e27c38f1f95e1aa9aebdada7b92d7c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 23:30:36 +0200 Subject: [PATCH 113/344] Render every 25ms instead of 200ms --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index e9712ce4e..4852b227f 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -188,7 +188,7 @@ namespace GUIEditor void NelGUICtrl::onGUILoaded() { - timerID = startTimer( 200 ); + timerID = startTimer( 25 ); guiLoaded = true; Q_EMIT guiLoadComplete(); From 42ebad94f6a416ba3d30e84ff6ac541f28074eec Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 16 Oct 2014 20:25:19 +0200 Subject: [PATCH 114/344] Implemented CGroupEditBoxDecor a decorated CGroupEditBox. --HG-- branch : dfighter-tools --- .../nel/include/nel/gui/group_editbox_decor.h | 49 +++ code/nel/include/nel/gui/interface_element.h | 8 + code/nel/src/gui/group_editbox.cpp | 12 +- code/nel/src/gui/group_editbox_decor.cpp | 357 ++++++++++++++++++ code/nel/src/gui/link_hack.cpp | 2 + code/nel/src/gui/widget_manager.cpp | 6 + .../gui_editor/widget_info_tree_node.h | 4 + .../gui_editor/widgets/GroupEditBoxDecor.xml | 68 ++++ 8 files changed, 503 insertions(+), 3 deletions(-) create mode 100644 code/nel/include/nel/gui/group_editbox_decor.h create mode 100644 code/nel/src/gui/group_editbox_decor.cpp create mode 100644 code/studio/src/plugins/gui_editor/widgets/GroupEditBoxDecor.xml diff --git a/code/nel/include/nel/gui/group_editbox_decor.h b/code/nel/include/nel/gui/group_editbox_decor.h new file mode 100644 index 000000000..a2b540608 --- /dev/null +++ b/code/nel/include/nel/gui/group_editbox_decor.h @@ -0,0 +1,49 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GROUP_EDITBOX_DECOR +#define GROUP_EDITBOX_DECOR + +#include "nel/gui/group_editbox.h" + +namespace NLGUI +{ + /// Decorated CGroupEditBox + class CGroupEditBoxDecor : public CGroupEditBox + { + public: + DECLARE_UI_CLASS( CGroupEditBoxDecor ) + + CGroupEditBoxDecor( const TCtorParam ¶m ); + ~CGroupEditBoxDecor(); + + std::string getProperty( const std::string &name ) const; + void setProperty( const std::string &name, const std::string &value ); + xmlNodePtr serialize( xmlNodePtr parentNode, const char *type ) const; + bool parse( xmlNodePtr cur, CInterfaceGroup *parent ); + void draw(); + void updateCoords(); + + static void forceLink(); + + private: + class EBDPrivate *_Pvt; + }; +} + +#endif + diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index c1f6d20e7..e2f9ffc87 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -117,6 +117,7 @@ namespace NLGUI editorSelected = false; serializable = true; + _EditorSelectable = true; } // dtor @@ -531,9 +532,16 @@ namespace NLGUI /// Aligns the element to the other element specified void alignTo( CInterfaceElement *other ); + /// Specifies if the widget can be selected in the editor + void setEditorSelectable( bool b ){ _EditorSelectable = b; } + + /// Tells if the widget can be selected in the editor + bool isEditorSelectable() const{ return _EditorSelectable; } + protected: bool editorSelected; + bool _EditorSelectable; static bool editorMode; diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 92ae46703..8c8ae867c 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -1548,13 +1548,17 @@ namespace NLGUI { _ViewText->setParent( this ); _ViewText->setIdRecurse( "edit_text" ); - _ViewText->setHardText( "sometext" ); + _ViewText->setHardText( "" ); _ViewText->setPosRef( Hotspot_TL ); _ViewText->setParentPosRef( Hotspot_TL ); addView( _ViewText ); + + sint32 w,h; + w = std::max( sint32( _ViewText->getFontWidth() * _ViewText->getText().size() ), getW() ); + h = std::max( sint32( _ViewText->getFontHeight() ), getH() ); - setH( _ViewText->getFontHeight() ); - setW( _ViewText->getFontWidth() * _ViewText->getText().size() ); + setH( h ); + setW( w ); } else @@ -1562,6 +1566,8 @@ namespace NLGUI } } + _ViewText->setEditorSelectable( false ); + // For MultiLine editbox, clip the end space, else weird when edit space at end of line (nothing happens) if(_ViewText) _ViewText->setMultiLineClipEndSpace(true); diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp new file mode 100644 index 000000000..50241789e --- /dev/null +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -0,0 +1,357 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" +#include "nel/gui/group_editbox_decor.h" +#include "nel/gui/view_bitmap.h" + +namespace NLGUI +{ + class EBDPrivate + { + public: + enum Textures + { + BG, + L, + R, + TM, + BM, + TL, + TR, + BL, + BR, + TCOUNT + }; + + EBDPrivate() + { + for( int i = 0; i < TCOUNT; i++ ) + { + _Textures.push_back( new CViewBitmap( CViewBase::TCtorParam() ) ); + } + } + + ~EBDPrivate() + { + for( int i = 0; i < _Textures.size(); i++ ) + delete _Textures[ i ]; + _Textures.clear(); + } + + void draw() + { + for( int i = 0; i < _Textures.size(); i++ ) + { + CViewBitmap *bm = _Textures[ i ]; + bm->draw(); + } + } + + void updateCoords() + { + for( int i = 0; i < _Textures.size(); i++ ) + { + CViewBitmap *bm = _Textures[ i ]; + bm->fitTexture(); + } + + // W and H parameters depend on the sizes of the other textures + // Negative sizes mean that the sizes are that much smaller than the parent + sint32 w,h; + h = _Textures[ TL ]->getHReal() + _Textures[ BL ]->getHReal(); + h *= -1; + _Textures[ L ]->setH( h ); + + h = _Textures[ TR ]->getHReal() + _Textures[ BR ]->getHReal(); + h *= -1; + _Textures[ R ]->setH( h ); + + w = _Textures[ TL ]->getWReal() + _Textures[ TR ]->getWReal(); + w *= -1; + _Textures[ TM ]->setW( w ); + + w = _Textures[ BL ]->getWReal() + _Textures[ BR ]->getWReal(); + w *= -1; + _Textures[ BM ]->setW( w ); + + h = _Textures[ TM ]->getHReal() + _Textures[ BM ]->getHReal(); + h *= -1; + w = _Textures[ L ]->getWReal() + _Textures[ R ]->getWReal(); + w *= -1; + _Textures[ BG ]->setW( w ); + _Textures[ BG ]->setH( h ); + + for( int i = 0; i < _Textures.size(); i++ ) + { + CViewBitmap *bm = _Textures[ i ]; + bm->updateCoords(); + } + } + + void setup( CInterfaceGroup *parent ) + { + for( int i = 0; i < _Textures.size(); i++ ) + { + CViewBitmap *bm = _Textures[ i ]; + bm->setParent( parent ); + bm->setParentPos( parent ); + bm->setParentSize( parent ); + bm->setEditorSelectable( false ); + } + + _Textures[ TL ]->setPosRef( Hotspot_TL ); + _Textures[ TL ]->setParentPosRef( Hotspot_TL ); + + _Textures[ TM ]->setPosRef( Hotspot_TM ); + _Textures[ TM ]->setParentPosRef( Hotspot_TM ); + _Textures[ TM ]->setScale( true ); + _Textures[ TM ]->setSizeRef( "w" ); + + _Textures[ TR ]->setPosRef( Hotspot_TR ); + _Textures[ TR ]->setParentPosRef( Hotspot_TR ); + + _Textures[ BL ]->setPosRef( Hotspot_BL ); + _Textures[ BL ]->setParentPosRef( Hotspot_BL ); + + _Textures[ BM ]->setPosRef( Hotspot_BM ); + _Textures[ BM ]->setParentPosRef( Hotspot_BM ); + _Textures[ BM ]->setScale( true ); + _Textures[ BM ]->setSizeRef( "w" ); + + _Textures[ BR ]->setPosRef( Hotspot_BR ); + _Textures[ BR ]->setParentPosRef( Hotspot_BR ); + + _Textures[ L ]->setPosRef( Hotspot_ML ); + _Textures[ L ]->setParentPosRef( Hotspot_ML ); + _Textures[ L ]->setScale( true ); + _Textures[ L ]->setSizeRef( "h" ); + + _Textures[ R ]->setPosRef( Hotspot_MR ); + _Textures[ R ]->setParentPosRef( Hotspot_MR ); + _Textures[ R ]->setScale( true ); + _Textures[ R ]->setSizeRef( "h" ); + + _Textures[ BG ]->setPosRef( Hotspot_MM ); + _Textures[ BG ]->setParentPosRef( Hotspot_MM ); + _Textures[ BG ]->setScale( true ); + _Textures[ BG ]->setSizeRef( "wh" ); + _Textures[ BG ]->setRenderLayer( -1 ); + } + + std::vector< CViewBitmap* > _Textures; + }; + + NLMISC_REGISTER_OBJECT( CViewBase, CGroupEditBoxDecor, std::string, "edit_box_decor" ); + + CGroupEditBoxDecor::CGroupEditBoxDecor( const TCtorParam ¶m ) : + CGroupEditBox( param ) + { + _Pvt = new EBDPrivate(); + _Pvt->setup( this ); + } + + CGroupEditBoxDecor::~CGroupEditBoxDecor() + { + delete _Pvt; + _Pvt = NULL; + } + + std::string CGroupEditBoxDecor::getProperty( const std::string &name ) const + { + if( name == "tx_tl" ) + { + return _Pvt->_Textures[ EBDPrivate::TL ]->getTexture(); + } + else + if( name == "tx_tm" ) + { + return _Pvt->_Textures[ EBDPrivate::TM ]->getTexture(); + } + else + if( name == "tx_tr" ) + { + return _Pvt->_Textures[ EBDPrivate::TR ]->getTexture(); + } + else + if( name == "tx_bl" ) + { + return _Pvt->_Textures[ EBDPrivate::BL ]->getTexture(); + } + else + if( name == "tx_bm" ) + { + return _Pvt->_Textures[ EBDPrivate::BM ]->getTexture(); + } + else + if( name == "tx_br" ) + { + return _Pvt->_Textures[ EBDPrivate::BR ]->getTexture(); + } + else + if( name == "tx_l" ) + { + return _Pvt->_Textures[ EBDPrivate::L ]->getTexture(); + } + else + if( name == "tx_r" ) + { + return _Pvt->_Textures[ EBDPrivate::R ]->getTexture(); + } + else + if( name == "tx_bg" ) + { + return _Pvt->_Textures[ EBDPrivate::BG ]->getTexture(); + } + else + return CGroupEditBox::getProperty( name ); + } + + void CGroupEditBoxDecor::setProperty( const std::string &name, const std::string &value ) + { + if( name == "tx_tl" ) + { + _Pvt->_Textures[ EBDPrivate::TL ]->setTexture( value ); + } + else + if( name == "tx_tm" ) + { + _Pvt->_Textures[ EBDPrivate::TM ]->setTexture( value ); + } + else + if( name == "tx_tr" ) + { + _Pvt->_Textures[ EBDPrivate::TR ]->setTexture( value ); + } + else + if( name == "tx_bl" ) + { + _Pvt->_Textures[ EBDPrivate::BL ]->setTexture( value ); + } + else + if( name == "tx_bm" ) + { + _Pvt->_Textures[ EBDPrivate::BM ]->setTexture( value ); + } + else + if( name == "tx_br" ) + { + _Pvt->_Textures[ EBDPrivate::BR ]->setTexture( value ); + } + else + if( name == "tx_l" ) + { + _Pvt->_Textures[ EBDPrivate::L ]->setTexture( value ); + } + else + if( name == "tx_r" ) + { + _Pvt->_Textures[ EBDPrivate::R ]->setTexture( value ); + } + else + if( name == "tx_bg" ) + { + _Pvt->_Textures[ EBDPrivate::BG ]->setTexture( value ); + } + else + CGroupEditBox::setProperty( name, value ); + } + + xmlNodePtr CGroupEditBoxDecor::serialize( xmlNodePtr parentNode, const char *type ) const + { + xmlNodePtr node = CGroupEditBox::serialize( parentNode, type ); + if( node == NULL ) + return NULL; + + xmlSetProp( node, BAD_CAST "tx_tl", BAD_CAST _Pvt->_Textures[ EBDPrivate::TL ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_tr", BAD_CAST _Pvt->_Textures[ EBDPrivate::TM ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_tm", BAD_CAST _Pvt->_Textures[ EBDPrivate::TR ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_bl", BAD_CAST _Pvt->_Textures[ EBDPrivate::BL ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_bm", BAD_CAST _Pvt->_Textures[ EBDPrivate::BM ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_br", BAD_CAST _Pvt->_Textures[ EBDPrivate::BR ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_l", BAD_CAST _Pvt->_Textures[ EBDPrivate::L ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_r", BAD_CAST _Pvt->_Textures[ EBDPrivate::R ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_bg", BAD_CAST _Pvt->_Textures[ EBDPrivate::BG ]->getTexture().c_str() ); + + return node; + } + + bool CGroupEditBoxDecor::parse( xmlNodePtr cur, CInterfaceGroup *parent ) + { + if( !CGroupEditBox::parse( cur, parent ) ) + return false; + + CXMLAutoPtr prop; + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_tl" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::TL ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_tm" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::TM ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_tr" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::TR ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_bl" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::BL ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_bm" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::BM ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_br" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::BR ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_l" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::L ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_r" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::R ]->setTexture( ( const char* )prop ); + + prop = ( char* ) xmlGetProp( cur, BAD_CAST "tx_bg" ); + if( prop ) + _Pvt->_Textures[ EBDPrivate::BG ]->setTexture( ( const char* )prop ); + + return true; + } + + void CGroupEditBoxDecor::draw() + { + CGroupEditBox::draw(); + + _Pvt->draw(); + } + + void CGroupEditBoxDecor::updateCoords() + { + CGroupEditBox::updateCoords(); + _Pvt->updateCoords(); + } + + void CGroupEditBoxDecor::forceLink() + { + } +} + + diff --git a/code/nel/src/gui/link_hack.cpp b/code/nel/src/gui/link_hack.cpp index 06a8c23e8..3ecc6fb0a 100644 --- a/code/nel/src/gui/link_hack.cpp +++ b/code/nel/src/gui/link_hack.cpp @@ -20,6 +20,7 @@ #include "nel/gui/dbview_number.h" #include "nel/gui/dbview_quantity.h" #include "nel/gui/view_pointer.h" +#include "nel/gui/group_editbox_decor.h" namespace NLGUI { @@ -39,5 +40,6 @@ namespace NLGUI force_link_dbgroup_select_number_cpp(); force_link_dbgroup_combo_box_cpp(); force_link_group_wheel_cpp(); + CGroupEditBoxDecor::forceLink(); } } \ No newline at end of file diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 81fbaf28b..4591d7554 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2436,6 +2436,9 @@ namespace NLGUI CCtrlBase *ctrl= _CtrlsUnderPointer[i]; if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { + if( CInterfaceElement::getEditorMode() && !ctrl->isEditorSelectable() ) + continue; + uint d = ctrl->getDepth( pNewCurrentWnd ); if (d > nMaxDepth) { @@ -2454,6 +2457,9 @@ namespace NLGUI CViewBase *v = _ViewsUnderPointer[i]; if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) ) { + if( CInterfaceElement::getEditorMode() && !v->isEditorSelectable() ) + continue; + _CapturedView = v; captured = true; break; diff --git a/code/studio/src/plugins/gui_editor/widget_info_tree_node.h b/code/studio/src/plugins/gui_editor/widget_info_tree_node.h index 0de9e6977..8aefe6f0f 100644 --- a/code/studio/src/plugins/gui_editor/widget_info_tree_node.h +++ b/code/studio/src/plugins/gui_editor/widget_info_tree_node.h @@ -75,6 +75,10 @@ namespace GUIEditor // copy the properties to the child, since they inherit them for( std::vector< SPropEntry >::const_iterator itr = this->info.props.begin(); itr != this->info.props.end(); ++itr ) { + // Don't add property if already exists, since it's an override. + if( node->hasProperty( itr->propName ) ) + continue; + node->addProperty( *itr ); } } diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupEditBoxDecor.xml b/code/studio/src/plugins/gui_editor/widgets/GroupEditBoxDecor.xml new file mode 100644 index 000000000..67865e707 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/widgets/GroupEditBoxDecor.xml @@ -0,0 +1,68 @@ + +
+ GroupEditBoxDecor + CGroupEditBoxDecor + edit_box_decor + GroupEditBox + + false + +
+ + + w + int + 150 + + + h + int + 25 + + + tx_tl + texture + log_eb_tl.tga + + + tx_tm + texture + log_eb_t.tga + + + tx_tr + texture + log_eb_tr.tga + + + tx_bl + texture + log_eb_bl.tga + + + tx_bm + texture + log_eb_b.tga + + + tx_br + texture + log_eb_br.tga + + + tx_l + texture + log_eb_l.tga + + + tx_r + texture + log_eb_r.tga + + + tx_bg + texture + log_eb_m.tga + + +
From 274efe67987aaeff065e8a1eb2736c2d65237c1e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 16 Oct 2014 20:29:36 +0200 Subject: [PATCH 115/344] Allow selection of CGroupEditBox. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 8c8ae867c..049222210 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -1336,6 +1336,11 @@ namespace NLGUI // if click, and not frozen, then get the focus if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && !_Frozen) { + if( getEditorMode() ) + { + return CViewBase::handleEvent( event ); + } + _SelectingText = true; stopParentBlink(); CWidgetManager::getInstance()->setCaptureKeyboard (this); From 18866c88afe0330fd28610aafc85fa1f0ff95920 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 16 Oct 2014 20:58:47 +0200 Subject: [PATCH 116/344] Update decorated edit box decoration coords while dragging. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/group_editbox_decor.h | 2 ++ code/nel/src/gui/group_editbox_decor.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/group_editbox_decor.h b/code/nel/include/nel/gui/group_editbox_decor.h index a2b540608..153f48a25 100644 --- a/code/nel/include/nel/gui/group_editbox_decor.h +++ b/code/nel/include/nel/gui/group_editbox_decor.h @@ -31,6 +31,8 @@ namespace NLGUI CGroupEditBoxDecor( const TCtorParam ¶m ); ~CGroupEditBoxDecor(); + void moveBy( sint32 x, sint32 y ); + std::string getProperty( const std::string &name ) const; void setProperty( const std::string &name, const std::string &value ); xmlNodePtr serialize( xmlNodePtr parentNode, const char *type ) const; diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index 50241789e..dd6b58b66 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -150,7 +150,6 @@ namespace NLGUI _Textures[ BG ]->setParentPosRef( Hotspot_MM ); _Textures[ BG ]->setScale( true ); _Textures[ BG ]->setSizeRef( "wh" ); - _Textures[ BG ]->setRenderLayer( -1 ); } std::vector< CViewBitmap* > _Textures; @@ -171,6 +170,13 @@ namespace NLGUI _Pvt = NULL; } + void CGroupEditBoxDecor::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + _Pvt->updateCoords(); + } + std::string CGroupEditBoxDecor::getProperty( const std::string &name ) const { if( name == "tx_tl" ) From 210f93a4f28314d97975dca3b64ebd3e35a7ff96 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 16 Oct 2014 21:03:58 +0200 Subject: [PATCH 117/344] Save decorated edit box as such. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox_decor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index dd6b58b66..78de4ead0 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -283,6 +283,7 @@ namespace NLGUI if( node == NULL ) return NULL; + xmlSetProp( node, BAD_CAST "type", BAD_CAST "edit_box_decor" ); xmlSetProp( node, BAD_CAST "tx_tl", BAD_CAST _Pvt->_Textures[ EBDPrivate::TL ]->getTexture().c_str() ); xmlSetProp( node, BAD_CAST "tx_tr", BAD_CAST _Pvt->_Textures[ EBDPrivate::TM ]->getTexture().c_str() ); xmlSetProp( node, BAD_CAST "tx_tm", BAD_CAST _Pvt->_Textures[ EBDPrivate::TR ]->getTexture().c_str() ); From ba1e3c9919c02ccc80f80f68845c60b68a1fcaa1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 17 Oct 2014 16:01:50 +0200 Subject: [PATCH 118/344] Fixed a typo that messed up the textures of decorated editbox. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox_decor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index 78de4ead0..899ea660c 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -285,8 +285,8 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "type", BAD_CAST "edit_box_decor" ); xmlSetProp( node, BAD_CAST "tx_tl", BAD_CAST _Pvt->_Textures[ EBDPrivate::TL ]->getTexture().c_str() ); - xmlSetProp( node, BAD_CAST "tx_tr", BAD_CAST _Pvt->_Textures[ EBDPrivate::TM ]->getTexture().c_str() ); - xmlSetProp( node, BAD_CAST "tx_tm", BAD_CAST _Pvt->_Textures[ EBDPrivate::TR ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_tr", BAD_CAST _Pvt->_Textures[ EBDPrivate::TR ]->getTexture().c_str() ); + xmlSetProp( node, BAD_CAST "tx_tm", BAD_CAST _Pvt->_Textures[ EBDPrivate::TM ]->getTexture().c_str() ); xmlSetProp( node, BAD_CAST "tx_bl", BAD_CAST _Pvt->_Textures[ EBDPrivate::BL ]->getTexture().c_str() ); xmlSetProp( node, BAD_CAST "tx_bm", BAD_CAST _Pvt->_Textures[ EBDPrivate::BM ]->getTexture().c_str() ); xmlSetProp( node, BAD_CAST "tx_br", BAD_CAST _Pvt->_Textures[ EBDPrivate::BR ]->getTexture().c_str() ); From 923b36f0e56bba7f8a1a2637d4f5a8fa6cb2a062 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 17 Oct 2014 21:18:26 +0200 Subject: [PATCH 119/344] Create the viewtext of the decorated edit box when the box is created, also adjust it so the text is drawn to the right of the left texture. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/group_editbox.h | 4 ++ code/nel/src/gui/group_editbox.cpp | 59 +++++++++++++----------- code/nel/src/gui/group_editbox_decor.cpp | 8 ++++ 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/code/nel/include/nel/gui/group_editbox.h b/code/nel/include/nel/gui/group_editbox.h index 7ea2ab529..771bdc482 100644 --- a/code/nel/include/nel/gui/group_editbox.h +++ b/code/nel/include/nel/gui/group_editbox.h @@ -283,6 +283,10 @@ namespace NLGUI sint32 _ViewTextDeltaX; + CViewText* getVT() const{ return _ViewText; } + + void createViewText(); + private: void setupDisplayText(); void makeTopWindow(); diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 049222210..0dd4ffbda 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -1536,40 +1536,43 @@ namespace NLGUI CInterfaceGroup::clearViews(); } + // ---------------------------------------------------------------------------- + + void CGroupEditBox::createViewText() + { + nlwarning("Interface: CGroupEditBox: text 'edit_text' missing or bad type"); + nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() ); + _ViewText = dynamic_cast< CViewText* >( CInterfaceFactory::createClass( "text" ) ); + if( _ViewText == NULL ) + { + nlwarning( "Failed to create new 'edit_text' for %s", getId().c_str() ); + return; + } + + _ViewText->setParent( this ); + _ViewText->setIdRecurse( "edit_text" ); + _ViewText->setHardText( "" ); + _ViewText->setPosRef( Hotspot_ML ); + _ViewText->setParentPosRef( Hotspot_ML ); + addView( _ViewText ); + + sint32 w,h; + w = std::max( sint32( _ViewText->getFontWidth() * _ViewText->getText().size() ), getW() ); + h = std::max( sint32( _ViewText->getFontHeight() ), getH() ); + + setH( h ); + setW( w ); + } + // ---------------------------------------------------------------------------- void CGroupEditBox::setup() { // bind to the controls - _ViewText = dynamic_cast(CInterfaceGroup::getView("edit_text")); + if( _ViewText == NULL ) + _ViewText = dynamic_cast(CInterfaceGroup::getView("edit_text")); if(_ViewText == NULL) - { - nlwarning("Interface: CGroupEditBox: text 'edit_text' missing or bad type"); - if( editorMode ) - { - nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() ); - _ViewText = dynamic_cast< CViewText* >( CInterfaceFactory::createClass( "text" ) ); - if( _ViewText != NULL ) - { - _ViewText->setParent( this ); - _ViewText->setIdRecurse( "edit_text" ); - _ViewText->setHardText( "" ); - _ViewText->setPosRef( Hotspot_TL ); - _ViewText->setParentPosRef( Hotspot_TL ); - addView( _ViewText ); - - sint32 w,h; - w = std::max( sint32( _ViewText->getFontWidth() * _ViewText->getText().size() ), getW() ); - h = std::max( sint32( _ViewText->getFontHeight() ), getH() ); - - setH( h ); - setW( w ); - - } - else - nlwarning( "Failed to create new 'edit_text' for %s", getId().c_str() ); - } - } + createViewText(); _ViewText->setEditorSelectable( false ); diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index 899ea660c..a5a2c8239 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -18,6 +18,7 @@ #include "stdpch.h" #include "nel/gui/group_editbox_decor.h" #include "nel/gui/view_bitmap.h" +#include "nel/gui/view_text.h" namespace NLGUI { @@ -162,6 +163,10 @@ namespace NLGUI { _Pvt = new EBDPrivate(); _Pvt->setup( this ); + + createViewText(); + getVT()->setSerializable( false ); + getVT()->setEditorSelectable( false ); } CGroupEditBoxDecor::~CGroupEditBoxDecor() @@ -352,6 +357,9 @@ namespace NLGUI void CGroupEditBoxDecor::updateCoords() { + sint32 tw = _Pvt->_Textures[ EBDPrivate::L ]->getWReal(); + getVT()->setX( tw + 1 ); + CGroupEditBox::updateCoords(); _Pvt->updateCoords(); } From fd5a1a6834e6b78d5cc1179d3c75666a8b66bb98 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 17 Oct 2014 21:23:00 +0200 Subject: [PATCH 120/344] Don't add non-selectable widgets to the hierarchy tree. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_hierarchy.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 343d8efd8..17e7f6e57 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -166,6 +166,9 @@ namespace GUIEditor std::vector< CCtrlBase* >::const_iterator citr; for( citr = controls.begin(); citr != controls.end(); ++citr ) { + if( !(*citr)->isEditorSelectable() ) + continue; + QTreeWidgetItem *subItem = new QTreeWidgetItem( item ); subItem->setText( 0, makeNodeName( (*citr)->getId() ).c_str() ); widgetHierarchyMap[ (*citr)->getId() ] = subItem; @@ -176,6 +179,9 @@ namespace GUIEditor std::vector< CViewBase* >::const_iterator vitr; for( vitr = views.begin(); vitr != views.end(); ++vitr ) { + if( !(*vitr)->isEditorSelectable() ) + continue; + QTreeWidgetItem *subItem = new QTreeWidgetItem( item ); subItem->setText( 0, makeNodeName( (*vitr)->getId() ).c_str() ); widgetHierarchyMap[ (*vitr)->getId() ] = subItem; From 67aa7a50d2853d827dc86400c7cf2772adafe053 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 17 Oct 2014 22:25:30 +0200 Subject: [PATCH 121/344] set the Id of the text properly when loading the decorated edit box. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox_decor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index a5a2c8239..fd7f1110d 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -345,6 +345,8 @@ namespace NLGUI if( prop ) _Pvt->_Textures[ EBDPrivate::BG ]->setTexture( ( const char* )prop ); + getVT()->setIdRecurse( "edit_text" ); + return true; } From 48b346fed8fe4c26d5f5f6cd48f363e26cfcb925 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 18 Oct 2014 00:15:51 +0300 Subject: [PATCH 122/344] Fix crash when using textarea without form --HG-- branch : develop --- code/nel/src/gui/group_html.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 1a2ae5b4b..d42e1fed3 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1681,21 +1681,19 @@ namespace NLGUI break; case HTML_TEXTAREA: { - // Add the editbox - // nlinfo("textarea temp '%s'", _TextAreaTemplate.c_str()); - // nlinfo("textarea name '%s'", _TextAreaName.c_str()); - // nlinfo("textarea %d %d", _TextAreaRow, _TextAreaCols); - // nlinfo("textarea content '%s'", _TextAreaContent.toUtf8().c_str()); - CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); - if (textArea) + _TextArea = false; + if (!(_Forms.empty())) { - // Add the text area to the form - CGroupHTML::CForm::CEntry entry; - entry.Name = _TextAreaName; - entry.TextArea = textArea; - _Forms.back().Entries.push_back (entry); + CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); + if (textArea) + { + // Add the text area to the form + CGroupHTML::CForm::CEntry entry; + entry.Name = _TextAreaName; + entry.TextArea = textArea; + _Forms.back().Entries.push_back (entry); + } } - _TextArea = false; } break; case HTML_TITLE: From 78e1bb6147b176b8bff9dd999daa0c5bad47a853 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 18 Oct 2014 01:20:56 +0300 Subject: [PATCH 123/344] Fix html img not showing on some cases, clean up addImage method --HG-- branch : develop --- code/nel/src/gui/group_html.cpp | 132 ++++++++++---------------------- 1 file changed, 39 insertions(+), 93 deletions(-) diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index d42e1fed3..7de0ab96b 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -3153,111 +3153,57 @@ namespace NLGUI void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg) { // In a paragraph ? - if (_Paragraph) + if (!_Paragraph) { - string finalUrl; + newParagraph (0); + paragraphChange (); + } + + string finalUrl; + // No more text in this text view + _CurrentViewLink = NULL; + + // Not added ? + CViewBitmap *newImage = new CViewBitmap (TCtorParam()); + + // + // 1/ try to load the image with the old system (local files in bnp) + // + string image = CFile::getPath(img) + CFile::getFilenameWithoutExtension(img) + ".tga"; + if (lookupLocalFile (finalUrl, image.c_str(), false)) + { + newImage->setRenderLayer(getRenderLayer()+1); + image = finalUrl; + } + else + { // - // 1/ try to load the image with the old system (local files in bnp) + // 2/ if it doesn't work, try to load the image in cache // - string image = CFile::getPath(img) + CFile::getFilenameWithoutExtension(img) + ".tga"; - if (lookupLocalFile (finalUrl, image.c_str(), false)) + image = localImageName(img); + if (!reloadImg && lookupLocalFile (finalUrl, image.c_str(), false)) { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - newImage->setRenderLayer(getRenderLayer()+1); - newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); + // don't display image that are not power of 2 + uint32 w, h; + CBitmap::loadSize (image, w, h); + if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) + image.clear(); } else { // - // 2/ if it doesn't work, try to load the image in cache + // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache // - image = localImageName(img); - if (!reloadImg && lookupLocalFile (finalUrl, image.c_str(), false)) - { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - - // don't display image that are not power of 2 - uint32 w, h; - CBitmap::loadSize (image, w, h); - if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) - image.clear(); - - newImage->setTexture (image); - // newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); - } - else - { - - // - // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache - // - image = "web_del.tga"; - if (lookupLocalFile (finalUrl, image.c_str(), false)) - { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - newImage->setTexture (image); - // newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - addImageDownload(img, newImage); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); - } - } + image = "web_del.tga"; + addImageDownload(img, newImage); } } + newImage->setTexture (image); + newImage->setModulateGlobalColor(globalColor); + + getParagraph()->addChild(newImage); + paragraphChange (); } // *************************************************************************** From 2fe207717036b79e3f80cd167e692a8436384694 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 20 Oct 2014 18:51:53 +0200 Subject: [PATCH 124/344] When setting the Id of the decorated edit box, set the Id of the text as well. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/group_editbox_decor.h | 2 ++ code/nel/src/gui/group_editbox_decor.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/code/nel/include/nel/gui/group_editbox_decor.h b/code/nel/include/nel/gui/group_editbox_decor.h index 153f48a25..975177612 100644 --- a/code/nel/include/nel/gui/group_editbox_decor.h +++ b/code/nel/include/nel/gui/group_editbox_decor.h @@ -33,6 +33,8 @@ namespace NLGUI void moveBy( sint32 x, sint32 y ); + void setIdRecurse( const std::string &newID ); + std::string getProperty( const std::string &name ) const; void setProperty( const std::string &name, const std::string &value ); xmlNodePtr serialize( xmlNodePtr parentNode, const char *type ) const; diff --git a/code/nel/src/gui/group_editbox_decor.cpp b/code/nel/src/gui/group_editbox_decor.cpp index fd7f1110d..ae31513de 100644 --- a/code/nel/src/gui/group_editbox_decor.cpp +++ b/code/nel/src/gui/group_editbox_decor.cpp @@ -182,6 +182,12 @@ namespace NLGUI _Pvt->updateCoords(); } + void CGroupEditBoxDecor::setIdRecurse( const std::string &newID ) + { + CInterfaceElement::setIdRecurse( newID ); + _ViewText->setIdRecurse( _ViewText->getShortId() ); + } + std::string CGroupEditBoxDecor::getProperty( const std::string &name ) const { if( name == "tx_tl" ) From b6d9e3285f58d8f8ce41b7c3cd7cfa60cf81b4e3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 20 Oct 2014 20:57:08 +0200 Subject: [PATCH 125/344] DBViewNumber shouldn't crash anymore. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/dbview_number.h | 4 +--- code/nel/include/nel/gui/interface_property.h | 9 +++++++++ code/nel/src/gui/dbview_number.cpp | 11 +++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/gui/dbview_number.h b/code/nel/include/nel/gui/dbview_number.h index 2c76a255d..bfa963fb6 100644 --- a/code/nel/include/nel/gui/dbview_number.h +++ b/code/nel/include/nel/gui/dbview_number.h @@ -55,9 +55,7 @@ namespace NLGUI static void forceLink(); protected: - - sint64 getVal() { if (_Modulo == 0) return (_Number.getSInt64() / _Divisor); - else return (_Number.getSInt64() / _Divisor)%_Modulo; } + sint64 getVal(); protected: diff --git a/code/nel/include/nel/gui/interface_property.h b/code/nel/include/nel/gui/interface_property.h index 63a62ef0e..4ed6e701e 100644 --- a/code/nel/include/nel/gui/interface_property.h +++ b/code/nel/include/nel/gui/interface_property.h @@ -47,6 +47,15 @@ namespace NLGUI _VolatileValue = NULL; } + /// Tells if this property has a value + bool hasValue() const + { + if( _VolatileValue != NULL ) + return true; + else + return false; + } + NLMISC::CCDBNodeLeaf* getNodePtr() const { return _VolatileValue; diff --git a/code/nel/src/gui/dbview_number.cpp b/code/nel/src/gui/dbview_number.cpp index a0b6dfb02..bd193c47d 100644 --- a/code/nel/src/gui/dbview_number.cpp +++ b/code/nel/src/gui/dbview_number.cpp @@ -249,5 +249,16 @@ namespace NLGUI { } + sint64 CDBViewNumber::getVal() + { + if( !_Number.hasValue() ) + return 0; + + if( _Modulo == 0 ) + return _Number.getSInt64() / _Divisor; + else + return ( _Number.getSInt64() / _Divisor ) % _Modulo; + } + } From 8c5ad811990b5352ce5ba94a3f68a0a6aace8b63 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 20 Oct 2014 22:21:59 +0200 Subject: [PATCH 126/344] it's not a bad idea to store the value in the right variable... --HG-- branch : dfighter-tools --- code/nel/src/gui/dbview_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/gui/dbview_number.cpp b/code/nel/src/gui/dbview_number.cpp index bd193c47d..e844bf4c0 100644 --- a/code/nel/src/gui/dbview_number.cpp +++ b/code/nel/src/gui/dbview_number.cpp @@ -121,7 +121,7 @@ namespace NLGUI { sint64 i; if( fromString( value, i ) ) - _Divisor = i; + _Modulo = i; return; } else From d2ca66c57477a844da0b86d9fcf4898dbaf1a837 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 20 Oct 2014 22:27:33 +0200 Subject: [PATCH 127/344] Default text for DBViewNumber. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml index 36a7d23ce..99cc153ce 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml @@ -9,6 +9,11 @@
+ + hardtext + string + 0 + value string From 0ac94e3e7237660c8d506043f29515e20711a840 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 20 Oct 2014 22:49:46 +0200 Subject: [PATCH 128/344] CDBViewQuantity shouldn't crash in the editor. --HG-- branch : dfighter-tools --- code/nel/src/gui/dbview_quantity.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/code/nel/src/gui/dbview_quantity.cpp b/code/nel/src/gui/dbview_quantity.cpp index ad651f582..12dfce4b8 100644 --- a/code/nel/src/gui/dbview_quantity.cpp +++ b/code/nel/src/gui/dbview_quantity.cpp @@ -157,14 +157,17 @@ namespace NLGUI // *************************************************************************** void CDBViewQuantity::draw () { - // change text - sint32 val= _Number.getSInt32(); - sint32 valMax= _NumberMax.getSInt32(); - if(_Cache!=val || _CacheMax!=valMax) + if( _Number.hasValue() && _NumberMax.hasValue() ) { - _Cache= val; - _CacheMax=valMax; - buildTextFromCache(); + // change text + sint32 val= _Number.getSInt32(); + sint32 valMax= _NumberMax.getSInt32(); + if(_Cache!=val || _CacheMax!=valMax) + { + _Cache= val; + _CacheMax=valMax; + buildTextFromCache(); + } } // parent call From 933420690b1aedb07f489c51c617c884eb5c7cee Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:02:50 +0100 Subject: [PATCH 129/344] Change patchman example domain --HG-- branch : develop --- .../patchman_cfg/admin_install/bin/startup | 4 +- .../admin_install/bin/sync_rrd_graphs.sh | 2 +- .../admin_executor_service_default.mini01.cfg | 2 +- .../admin_executor_service_default.std01.cfg | 2 +- .../admin_install/patchman/patchman_list | 42 ++++---- .../patchman/patchman_service.default.cfg | 4 +- .../patchman/patchman_service.mini01.cfg | 4 +- .../patchman_service.mini01_bridge.cfg | 2 +- .../patchman/patchman_service.std01.cfg | 4 +- .../patchman/special_patchman_list | 6 +- .../admin_install/patchman_service_local.cfg | 2 +- .../server/patchman_cfg/shard_ctrl_mini01.txt | 30 +++--- .../server/patchman_cfg/shard_ctrl_std01.txt | 96 +++++++++---------- .../terminal_mini01/patchman_service.cfg | 4 +- 14 files changed, 102 insertions(+), 102 deletions(-) diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/startup b/code/ryzom/server/patchman_cfg/admin_install/bin/startup index 16bf59fd3..a63c6a3f7 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/startup +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/startup @@ -4,8 +4,8 @@ cd /srv/core rm */*.state */*/*.launch_ctrl */*/*.state /bin/bash /srv/core/bin/admin start -# special case for the "ep1.std01.ryzomcore.org" machine - start the admin tool graph sync script -if [ $(hostname) = "ep1.std01.ryzomcore.org" ] +# special case for the "ep1.std01.ryzomcore.local" machine - start the admin tool graph sync script +if [ $(hostname) = "ep1.std01.ryzomcore.local" ] then nohup /bin/sh /srv/core/bin/sync_rrd_graphs.sh & fi diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh b/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh index b23fc285b..cc78fbaf1 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh @@ -4,7 +4,7 @@ echo Launched: $(date) while true do # retrieve ATS files from ATS admin tool machine - rsync -t ep1.std01.ryzomcore.org:ats/graph_datas/* /srv/core/mini01/rrd_graphs/ + rsync -t ep1.std01.ryzomcore.local:ats/graph_datas/* /srv/core/mini01/rrd_graphs/ # deal with live files - duplicate files that correspond to unique services to aid with graphing of su & co cd /srv/core/std01/rrd_graphs/ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg index bc7be84e9..0e8af6ed9 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg @@ -10,7 +10,7 @@ AESAliasName= "aes"; DontUseStdIn = 0; // Adress ofthe admin service (default port is 49996) -ASHost = "ep1.mini01.ryzomcore.org"; +ASHost = "ep1.mini01.ryzomcore.local"; // Config for AES AESPort = "46712"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg index 7bfb80b27..7a4176b93 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg @@ -10,7 +10,7 @@ AESAliasName= "aes"; DontUseStdIn = 0; // Adress ofthe admin service (default port is 49996) -ASHost = "ep1.std01.ryzomcore.org"; +ASHost = "ep1.std01.ryzomcore.local"; // Config for AES AESPort = "46702"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list index e90230704..9a9341e9a 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list @@ -1,23 +1,23 @@ // default values for different sites -mini01 ep1.mini01.ryzomcore.org -std01 ep1.std01.ryzomcore.org -std01 su1.std01.ryzomcore.org -std01 pd1.std01.ryzomcore.org -std01 pd2.std01.ryzomcore.org -std01 pd3.std01.ryzomcore.org -std01 pd4.std01.ryzomcore.org -std01 mla1.std01.ryzomcore.org -std01 mla2.std01.ryzomcore.org -std01 mla3.std01.ryzomcore.org -std01 mla4.std01.ryzomcore.org -std01 mla5.std01.ryzomcore.org -std01 mlb1.std01.ryzomcore.org -std01 mlb2.std01.ryzomcore.org -std01 mlb3.std01.ryzomcore.org -std01 mlb4.std01.ryzomcore.org -std01 mlb5.std01.ryzomcore.org -std01 rra1.std01.ryzomcore.org -std01 rra2.std01.ryzomcore.org -std01 rrb1.std01.ryzomcore.org -std01 rrb2.std01.ryzomcore.org +mini01 ep1.mini01.ryzomcore.local +std01 ep1.std01.ryzomcore.local +std01 su1.std01.ryzomcore.local +std01 pd1.std01.ryzomcore.local +std01 pd2.std01.ryzomcore.local +std01 pd3.std01.ryzomcore.local +std01 pd4.std01.ryzomcore.local +std01 mla1.std01.ryzomcore.local +std01 mla2.std01.ryzomcore.local +std01 mla3.std01.ryzomcore.local +std01 mla4.std01.ryzomcore.local +std01 mla5.std01.ryzomcore.local +std01 mlb1.std01.ryzomcore.local +std01 mlb2.std01.ryzomcore.local +std01 mlb3.std01.ryzomcore.local +std01 mlb4.std01.ryzomcore.local +std01 mlb5.std01.ryzomcore.local +std01 rra1.std01.ryzomcore.local +std01 rra2.std01.ryzomcore.local +std01 rrb1.std01.ryzomcore.local +std01 rrb2.std01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg index 981654046..184fca55a 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44752)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44752)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg index 41c283b63..0bd04c5eb 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg index 32166d6bf..737177202 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg @@ -43,7 +43,7 @@ StartCommands += // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg index e8c2d5787..8fc5a64c9 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.std01.ryzomcore.org:44752)", + "spm_gw.transportCmd l3client(connect addr=ep1.std01.ryzomcore.local:44752)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list b/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list index b42636e55..bb1114027 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list @@ -1,10 +1,10 @@ // mini01 - mini manager -mini01_spm ep1.mini01.ryzomcore.org -mini01_bridge ep1.mini01.ryzomcore.org +mini01_spm ep1.mini01.ryzomcore.local +mini01_bridge ep1.mini01.ryzomcore.local // std01 - std manager -std01_spm ep1.std01.ryzomcore.org +std01_spm ep1.std01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg index 45f2afe3f..5b2f35f5f 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg @@ -1 +1 @@ -SPAHost = "ep1.mini01.ryzomcore.org"; +SPAHost = "ep1.mini01.ryzomcore.local"; diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt index a17f6f922..e09f106ac 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt @@ -30,15 +30,15 @@ define domain_mini01 // domain hosts cfg AESHost = "localhost"; - cfg SUHost = "ep1.mini01.ryzomcore.org"; - cfg MFSHost = "ep1.mini01.ryzomcore.org"; - cfg BSHost = "ep1.mini01.ryzomcore.org:49990"; - cfg SlaveBSHost= "ep1.mini01.ryzomcore.org:49991"; - cfg MasterLGSHost = "ep1.mini01.ryzomcore.org"; - cfg SlaveLGSHost = "ep1.mini01.ryzomcore.org"; - cfg LGSBSHost = "ep1.mini01.ryzomcore.org"; - cfg DBHost = "localhost"; // FIXME "sql.core.ryzomcore.org"; - cfgAfter WebSrvHost = "http://ep1.mini01.ryzomcore.org:50000/"; + cfg SUHost = "ep1.mini01.ryzomcore.local"; + cfg MFSHost = "ep1.mini01.ryzomcore.local"; + cfg BSHost = "ep1.mini01.ryzomcore.local:49990"; + cfg SlaveBSHost= "ep1.mini01.ryzomcore.local:49991"; + cfg MasterLGSHost = "ep1.mini01.ryzomcore.local"; + cfg SlaveLGSHost = "ep1.mini01.ryzomcore.local"; + cfg LGSBSHost = "ep1.mini01.ryzomcore.local"; + cfg DBHost = "ep1.mini01.ryzomcore.local"; + cfgAfter WebSrvHost = "http://ep1.mini01.ryzomcore.local:50000/"; // initial config files cfgFile ../cfg/00_base.cfg @@ -84,7 +84,7 @@ define shard_mini01_unifier use exe_set_std_lgs_slave use backup_lgs cfg DBPass = DBNelPass; - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local // shard mainland01 ---------------- @@ -95,10 +95,10 @@ define shard_mini01_mainland01 cfg ShardId = 301; cfg BasePort = 52000; cfg SaveFilesDirectory="mini01_mainland01/"; - cfg NSHost = "ep1.mini01.ryzomcore.org"; - cfg FSListenHost = "ep1.mini01.ryzomcore.org"; + cfg NSHost = "ep1.mini01.ryzomcore.local"; + cfg FSListenHost = "ep1.mini01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_mini_mainland.cfg - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local // shard ring01 -------------------- @@ -110,7 +110,7 @@ define shard_mini01_ring01 cfg BasePort = 52400; cfg SaveFilesDirectory="mini01_ring01/"; cfg NSPort = 51100; - cfg NSHost = "ep1.mini01.ryzomcore.org" + 51100; + cfg NSHost = "ep1.mini01.ryzomcore.local" + 51100; cfgFile ../cfg/02_shard_type_std_ring.cfg - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt index 311261110..5492d6af3 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt @@ -32,15 +32,15 @@ define domain_std01 // domain hosts cfg AESHost = "localhost"; - cfg SUHost = "su1.std01.ryzomcore.org"; - cfg MFSHost = "su1.std01.ryzomcore.org"; - cfg BSHost = "pd1.std01.ryzomcore.org:49990"; // Backup service host for domain - cfg SlaveBSHost= "pd2.std01.ryzomcore.org:49991"; - cfg MasterLGSHost = "pd3.std01.ryzomcore.org"; - cfg SlaveLGSHost = "pd4.std01.ryzomcore.org"; - cfg LGSBSHost = "csr.core.ryzomcore.org"; // Backup service host for log service - cfg DBHost = "sql.core.ryzomcore.org"; - cfgAfter WebSrvHost = "http://su1.std01.ryzomcore.org:50000/"; + cfg SUHost = "su1.std01.ryzomcore.local"; + cfg MFSHost = "su1.std01.ryzomcore.local"; + cfg BSHost = "pd1.std01.ryzomcore.local:49990"; // Backup service host for domain + cfg SlaveBSHost= "pd2.std01.ryzomcore.local:49991"; + cfg MasterLGSHost = "pd3.std01.ryzomcore.local"; + cfg SlaveLGSHost = "pd4.std01.ryzomcore.local"; + cfg LGSBSHost = "csr.core.ryzomcore.local"; // Backup service host for log service + cfg DBHost = "sql.core.ryzomcore.local"; + cfgAfter WebSrvHost = "http://su1.std01.ryzomcore.local:50000/"; // initial config files cfgFile ../cfg/00_base.cfg @@ -86,11 +86,11 @@ define shard_std01_unifier define shard_exe_set_std01_ras use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local define shard_exe_set_std01_unifier use exe_set_std_unifier - host su1.std01.ryzomcore.org + host su1.std01.ryzomcore.local cfg DBPass = DBNelPass; @@ -106,30 +106,30 @@ define shard_std01_mainland01 cfg ShardId = 101; cfg BasePort = 51000; cfg SaveFilesDirectory="std01_mainland01/"; - cfg NSHost = "mla1.std01.ryzomcore.org"; + cfg NSHost = "mla1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_mainland.cfg define shard_exe_set_std01_mainland01_be01 use exe_set_std_mainland_be01 - host mla1.std01.ryzomcore.org + host mla1.std01.ryzomcore.local define shard_exe_set_std01_mainland01_be02 use exe_set_std_mainland_be02 - host mla2.std01.ryzomcore.org + host mla2.std01.ryzomcore.local define shard_exe_set_std01_mainland01_be03 use exe_set_std_mainland_be03 - host mla3.std01.ryzomcore.org + host mla3.std01.ryzomcore.local define shard_exe_set_std01_mainland01_fe01 use exe_set_std_mainland_fe - host mla4.std01.ryzomcore.org - cfg FSListenHost = "mla4.std01.ryzomcore.org"; + host mla4.std01.ryzomcore.local + cfg FSListenHost = "mla4.std01.ryzomcore.local"; define shard_exe_set_std01_mainland01_fe02 use exe_set_std_mainland_fe - host mla5.std01.ryzomcore.org - cfg FSListenHost = "mla5.std01.ryzomcore.org"; + host mla5.std01.ryzomcore.local + cfg FSListenHost = "mla5.std01.ryzomcore.local"; // shard mainland02 ---------------- @@ -144,30 +144,30 @@ define shard_std01_mainland02 cfg ShardId = 102; cfg BasePort = 51100; cfg SaveFilesDirectory="std01_mainland02/"; - cfg NSHost = "mlb1.std01.ryzomcore.org"; + cfg NSHost = "mlb1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_mainland.cfg define shard_exe_set_std01_mainland02_be01 use exe_set_std_mainland_be01 - host mlb1.std01.ryzomcore.org + host mlb1.std01.ryzomcore.local define shard_exe_set_std01_mainland02_be02 use exe_set_std_mainland_be02 - host mlb2.std01.ryzomcore.org + host mlb2.std01.ryzomcore.local define shard_exe_set_std01_mainland02_be03 use exe_set_std_mainland_be03 - host mlb3.std01.ryzomcore.org + host mlb3.std01.ryzomcore.local define shard_exe_set_std01_mainland02_fe01 use exe_set_std_mainland_fe - host mlb4.std01.ryzomcore.org - cfg FSListenHost = "mlb4.std01.ryzomcore.org"; + host mlb4.std01.ryzomcore.local + cfg FSListenHost = "mlb4.std01.ryzomcore.local"; define shard_exe_set_std01_mainland02_fe02 use exe_set_std_mainland_fe - host mlb5.std01.ryzomcore.org - cfg FSListenHost = "mlb5.std01.ryzomcore.org"; + host mlb5.std01.ryzomcore.local + cfg FSListenHost = "mlb5.std01.ryzomcore.local"; // shard ring01 -------------------- @@ -179,17 +179,17 @@ define shard_std01_ring01 cfg ShardId = 201; cfg BasePort = 51400; cfg SaveFilesDirectory="std01_ring01/"; - cfg NSHost = "rra1.std01.ryzomcore.org"; + cfg NSHost = "rra1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_ring.cfg define shard_exe_set_std01_ring01_be use exe_set_std_ring_be - host rra1.std01.ryzomcore.org + host rra1.std01.ryzomcore.local define shard_exe_set_std01_ring01_fe use exe_set_std_ring_fe - host rra2.std01.ryzomcore.org - cfg FSListenHost = "rra2.std01.ryzomcore.org"; + host rra2.std01.ryzomcore.local + cfg FSListenHost = "rra2.std01.ryzomcore.local"; // shard ring02 -------------------- @@ -201,17 +201,17 @@ define shard_std01_ring02 cfg ShardId = 202; cfg BasePort = 51500; cfg SaveFilesDirectory="std01_ring02/"; - cfg NSHost = "rrb1.std01.ryzomcore.org"; + cfg NSHost = "rrb1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_ring.cfg define shard_exe_set_std01_ring02_be use exe_set_std_ring_be - host rrb1.std01.ryzomcore.org + host rrb1.std01.ryzomcore.local define shard_exe_set_std01_ring02_fe use exe_set_std_ring_fe - host rrb2.std01.ryzomcore.org - cfg FSListenHost = "rrb2.std01.ryzomcore.org"; + host rrb2.std01.ryzomcore.local + cfg FSListenHost = "rrb2.std01.ryzomcore.local"; // the std01 backup domain ---------- @@ -260,7 +260,7 @@ define shard_std01_backup_ras shard std01_backup_ras cfg ShardId = 100; use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local // the main backup pair ------------ @@ -273,15 +273,15 @@ define shard_std01_backup define shard_exe_set_std01_backup_master name bs_master use exe_set_std_backup_master - host pd1.std01.ryzomcore.org + host pd1.std01.ryzomcore.local define shard_exe_set_std01_backup_slave name bs_slave // hack to workaround bug in backup service // use exe_set_std_backup_slave use exe_set_std01_backup_slave - host pd2.std01.ryzomcore.org - cfgAfter MasterBSHost = "pd1.std01.ryzomcore.org:49990"; + host pd2.std01.ryzomcore.local + cfgAfter MasterBSHost = "pd1.std01.ryzomcore.local:49990"; // hack to workaround bug in backup service define exe_set_std01_backup_slave @@ -312,27 +312,27 @@ define shard_std01_lgs cfg L3SlaveLGSPort = 49993; cfg LGSBSPort = 49994; cfg L3LGSBSPort = 49995; - cfg MasterLGSHost = "pd3.std01.ryzomcore.org"; - cfg SlaveLGSHost = "pd4.std01.ryzomcore.org"; - cfg LGSBSHost = "csr.core.ryzomcore.org"; + cfg MasterLGSHost = "pd3.std01.ryzomcore.local"; + cfg SlaveLGSHost = "pd4.std01.ryzomcore.local"; + cfg LGSBSHost = "csr.core.ryzomcore.local"; define shard_exe_set_std01_lgs_primary name lgs_primary use raes use exe_set_std_lgs_master - host pd3.std01.ryzomcore.org + host pd3.std01.ryzomcore.local define shard_exe_set_std01_lgs_secondary name lgs_secondary use raes use exe_set_std_lgs_slave - host pd4.std01.ryzomcore.org + host pd4.std01.ryzomcore.local define shard_exe_set_std01_lgs_bs name lgs_bs use raes use backup_lgs - host csr.core.ryzomcore.org + host csr.core.ryzomcore.local // the std01 las domain ------------- @@ -365,7 +365,7 @@ define shard_std01_las_ras shard std01_las_ras cfg ShardId = 100; use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local // master las ---------------------- @@ -378,7 +378,7 @@ define shard_std01_las_master use las_mainland02 use las_ring01 use las_ring02 - host pd3.std01.ryzomcore.org + host pd3.std01.ryzomcore.local define las_mainland01 cfgAfter StartCommands += {"PDRootDirectory /srv/core/backup01/save_shard_pd/std01_mainland01/pds"}; @@ -415,7 +415,7 @@ define shard_std01_las_slave use las_mainland02_slave use las_ring01_slave use las_ring02_slave - host pd4.std01.ryzomcore.org + host pd4.std01.ryzomcore.local define las_mainland01_slave cfgAfter StartCommands += {"PDRootDirectory /srv/core/backup01/save_shard_pd/std01_mainland01/pds"}; diff --git a/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg b/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg index 351a8614a..c6a336c02 100644 --- a/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg +++ b/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg @@ -41,12 +41,12 @@ StartCommands += // bridge gateway // "moduleManager.createModule StandardGateway gw1", // "gw1.transportAdd L3Client l3client", -// "gw1.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44748)", +// "gw1.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44748)", // ats spm gateway "moduleManager.createModule StandardGateway gw2", "gw2.transportAdd L3Client l3client", - "gw2.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "gw2.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ From c3cf5c7af420f6d5fff717f21153b5ace330fe74 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:16:45 +0100 Subject: [PATCH 130/344] Update default patchman cfg --HG-- branch : develop --- .../patchman_cfg/default/ai_service.cfg | 24 +++---- .../default/dynamic_scenario_service.cfg | 9 +++ .../default/log_analyser_service.cfg | 5 ++ .../server/patchman_cfg/default/ryzom_as.cfg | 2 +- .../patchman_cfg/shard_ctrl_definitions.txt | 66 +++++++++++-------- 5 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg create mode 100644 code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg diff --git a/code/ryzom/server/patchman_cfg/default/ai_service.cfg b/code/ryzom/server/patchman_cfg/default/ai_service.cfg index 72b278cc0..5f3882759 100644 --- a/code/ryzom/server/patchman_cfg/default/ai_service.cfg +++ b/code/ryzom/server/patchman_cfg/default/ai_service.cfg @@ -322,21 +322,21 @@ StartCommandsWhenMirrorReadyRing = "createDynamicAIInstance 10000", "loadPrimitiveFile dummy.primitive", - "loadContinent r2_forest", - "createDynamicAIInstance 10001", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_forest", +// "createDynamicAIInstance 10001", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_lakes", - "createDynamicAIInstance 10003", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_lakes", +// "createDynamicAIInstance 10003", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_jungle", - "createDynamicAIInstance 10002", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_jungle", +// "createDynamicAIInstance 10002", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_roots", - "createDynamicAIInstance 10004", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_roots", +// "createDynamicAIInstance 10004", +// "loadPrimitiveFile dummy.primitive", // "spawnInstances", "updateAI", diff --git a/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg b/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg new file mode 100644 index 000000000..e6d5942ac --- /dev/null +++ b/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg @@ -0,0 +1,9 @@ + +DelayBeforeStartAct = 1; +MaxNpcs = 300; +MaxStaticObjects = 200; + +StartCommands += +{ + "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", +}; diff --git a/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg b/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg new file mode 100644 index 000000000..355984ff5 --- /dev/null +++ b/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg @@ -0,0 +1,5 @@ + +DontUseNS = 1; + +QueryTimeout = 300; +LinePerPage = 50; diff --git a/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg b/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg index 2755403b7..4227bac69 100644 --- a/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg +++ b/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg @@ -1,7 +1,7 @@ DontUseNS = 1; RRDToolPath = "rrdtool"; -RRDVarPath = "../graph_datas"; +RRDVarPath = "../rrd_graphs"; // Variables required to be defined by other cfgs //AESHost="localhost"; diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt index 87bd0ce4d..8deb9f533 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt @@ -26,7 +26,7 @@ define exe_set_mini_ring define exe_set_mini_mainland use raes use ms_mini_mainland - use ais_newbyland + use ais_newbieland use egs_mainland use gpms_mainland use ios_mainland @@ -100,7 +100,7 @@ define exe_set_std_mainland_be03 define exe_set_std_mainland_be03_basics // use ais_matis // use ais_tryker - use ais_newbyland + use ais_newbieland // unifier and co ------------------ @@ -170,12 +170,14 @@ define ais_ring cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Ring use ais data data_r2_desert - data data_r2_forest - data data_r2_jungle - data data_r2_lakes - data data_r2_roots + // data data_r2_forest + // data data_r2_jungle + // data data_r2_lakes + // data data_r2_roots define ais_mainland + name ais + cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais data data_mainland_common_primitives data data_newbieland_primitives @@ -188,8 +190,8 @@ define ais_mini_mainland cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais_mainland -define ais_newbyland - name ais_newbyland +define ais_newbieland + name ais_newbieland cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais data data_mainland_common_primitives @@ -213,36 +215,40 @@ define bms_master use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49990 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49990; cfgAfter L3ListeningPort = 49950; cfgAfter WebPort = 49970; cfgAfter BSReadState = 1; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_master2 use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49994 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49994; cfgAfter L3ListeningPort = 49954; cfgAfter WebPort = 49974; cfgAfter BSReadState = 1; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_slave use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49991 - cfg #include "../live/cfg/backup_module_service_slave.cfg" + //cfg #include "../live/cfg/backup_module_service_slave.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49991; cfgAfter L3ListeningPort = 49951; cfgAfter WebPort = 49971; cfgAfter BSReadState = 0; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_pd_master use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49992 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49992; cfgAfter L3ListeningPort = 49952; cfgAfter WebPort = 49972; @@ -252,7 +258,8 @@ define bms_pd_master define bms_pd_slave use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49993 - cfg #include "../live/cfg/backup_module_service_slave.cfg" + //cfg #include "../live/cfg/backup_module_service_slave.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49993; cfgAfter L3ListeningPort = 49953; cfgAfter WebPort = 49973; @@ -263,6 +270,7 @@ define backup_lgs use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49994 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49994; cfgAfter L3ListeningPort = 49995; cfgAfter WebPort = 49972; @@ -320,7 +328,7 @@ define dss define dss_ring use dss - cfg #include "../live/cfg/dynamic_scenario_service_ring.cfg" + // cfg #include "../live/cfg/dynamic_scenario_service_ring.cfg" // egs ----------------------------- @@ -374,17 +382,17 @@ define egs_mainland define egs_ring use egs data data_mainland_common_primitives - data data_newbieland_primitives - data data_newbieland - data data_indoors - cfg #include "../live/cfg/entities_game_service_ring.cfg" + // data data_newbieland_primitives + // data data_newbieland + // data data_indoors + //cfg #include "../live/cfg/entities_game_service_ring.cfg" // care cfg UsedContinents = cfg { cfg "r2_desert", "10000", - cfg "r2_forest", "10001", - cfg "r2_jungle", "10002", - cfg "r2_lakes", "10003", - cfg "r2_roots", "10004", + // cfg "r2_forest", "10001", + // cfg "r2_jungle", "10002", + // cfg "r2_lakes", "10003", + // cfg "r2_roots", "10004", cfg }; cfgAfter MaxXPGainPerPlayer = 30.0; cfgAfter DeathXPFactor = 0.0; @@ -460,16 +468,16 @@ define gpms_mainland use gpms data data_newbieland data data_indoors - cfg #include "../live/cfg/gpm_service_mainland.cfg" + //cfg #include "../live/cfg/gpm_service_mainland.cfg" define gpms_ring use gpms data data_r2_desert - data data_r2_forest - data data_r2_jungle - data data_r2_lakes - data data_r2_roots - cfg #include "../live/cfg/gpm_service_ring.cfg" + // data data_r2_forest + // data data_r2_jungle + // data data_r2_lakes + // data data_r2_roots + //cfg #include "../live/cfg/gpm_service_ring.cfg" // pdss ---------------------------- @@ -534,7 +542,7 @@ define ios_mainland define ios_ring use ios - cfg #include "../live/cfg/input_output_service_ring.cfg" + //cfg #include "../live/cfg/input_output_service_ring.cfg" // las ----------------------------- From d30cca34f04ef3eee690a38665f80aff5b1601e1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:17:43 +0100 Subject: [PATCH 131/344] Backed out merge changeset: 361eb082ec5e Does not compile. FindLibLZMA missing on Ubunty 12.04 LTS --HG-- branch : develop --- code/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index e0f3fe7ba..071554e06 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -110,10 +110,6 @@ FIND_PACKAGE(Jpeg) IF(WITH_STATIC_LIBXML2) SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) - IF(NOT WIN32 AND NOT APPLE) - FIND_PACKAGE(LibLZMA REQUIRED) - SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) - ENDIF(NOT WIN32 AND NOT APPLE) ENDIF(WITH_STATIC_LIBXML2) IF(WITH_STATIC) From ee92cb070212ae8f918be7e23f1dd11233d35bc9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:21:05 +0100 Subject: [PATCH 132/344] Update default path --HG-- branch : develop --- .../server/patchman_cfg/terminal_mini01/terminal_mini01.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat b/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat index 7f61bfa59..90e11d5d6 100644 --- a/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat +++ b/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat @@ -1,2 +1,2 @@ @echo off -start S:\devw_x86\bin\Release\ryzom_patchman_service.exe --nolog -C. -L. \ No newline at end of file +start R:\build\bin\Release\ryzom_patchman_service.exe --nolog -C. -L. \ No newline at end of file From 91ad193104cae85f99865e1f141c5ff50377396f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:32:18 +0100 Subject: [PATCH 133/344] Fix patchman scripts --HG-- branch : develop --- .../patchman_cfg/admin_install/bin/admin | 6 +- .../admin_install/bin/run_forever | 2 +- .../admin_install/patchman/loop_patchman.sh | 1 + .../patchman/loop_patchman_once.sh | 8 +- .../patchman/loop_special_patchman.sh | 2 +- .../admin_install/patchman/make_next_live.sh | 4 +- .../patchman/patchman_service.default.cfg | 7 -- .../patchman/patchman_service.mini01.cfg | 7 -- .../patchman/patchman_service.std01.cfg | 7 -- .../patchman/patchman_service_base_linux.cfg | 7 +- .../patchman/service_launcher.sh | 74 ++++++++++--------- .../patchman_cfg/default/ai_service.cfg | 6 +- 12 files changed, 62 insertions(+), 69 deletions(-) diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/admin b/code/ryzom/server/patchman_cfg/admin_install/bin/admin index c7cfa2fb6..f48de0d15 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/admin +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/admin @@ -99,14 +99,14 @@ then for f in $DOMAIN_LIST do # see if we're setup to run this domain - if [ -e /srv/core/${f}.screen.rc ] && [ -e /srv/core/bin/${f} ] + if [ -e /srv/core/${f}.screen.rc ] && [ -e /srv/core/bin/domain_${f} ] then # see whether the domain is alredy running - if [ $( screen -list | grep \( | cut -f2 | cut -d. -f2| grep \^$f\$ | wc -l) == 0 ] + if [ $( screen -list | grep \\\.${f} | wc -w ) = 0 ] then # the domain isn't running yet so start it echo '****' starting domain: $f '****' - /srv/core/bin/$f batchstart + /srv/core/bin/domain_$f batchstart else echo '****' Domain is already running: $f '****' fi diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever b/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever index c6f14b074..91a838a02 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever @@ -3,7 +3,7 @@ while true do -if [ "$2" == "" ] +if [ "$2" = "" ] then echo echo USAGE: $0 sleep_time command_line diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh index 73b151c43..af057f2ae 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh @@ -10,6 +10,7 @@ do chmod 775 bin/ps_services 2> /dev/null chmod 775 bin/run_forever 2> /dev/null chmod 775 bin/shard 2> /dev/null + chmod 775 bin/domain_* 2> /dev/null chmod 775 bin/startup 2> /dev/null chmod 775 bin/*.sh 2> /dev/null chmod 775 patchman/*_service 2> /dev/null diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh index 0dd697aa4..f7152cada 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh @@ -3,8 +3,8 @@ CFGFILENAME=patchman_service.${SERVER_TYPE}.cfg echo cfg file: $CFGFILENAME -AESCFGFILENAME=admin_executor_service_default.${SERVER_TYPE}.cfg -echo aes cfg file: $AESCFGFILENAME +#AESCFGFILENAME=admin_executor_service_default.${SERVER_TYPE}.cfg +#echo aes cfg file: $AESCFGFILENAME cd /srv/core/patchman if [ -e $CFGFILENAME ] @@ -15,8 +15,8 @@ if [ -e $CFGFILENAME ] cp $CFGFILENAME patchman_service.cfg # setup the config file for the admin executor service - echo Using aes configuration file: $AESCFGFILENAME - if [ -e $AESCFGFILENAME ] ; then cp $AESCFGFILENAME admin_executor_service_default.cfg ; fi + #echo Using aes configuration file: $AESCFGFILENAME + #if [ -e $AESCFGFILENAME ] ; then cp $AESCFGFILENAME admin_executor_service_default.cfg ; fi # start the patchman service echo Launching patchman... diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh index af1f5b599..6aa9f2ddf 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh @@ -1,6 +1,6 @@ #!/bin/sh -if [ "$1" == "" ] +if [ "$1" = "" ] then echo echo USAGE: $0 command_line diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh index fbaca4ac4..394fc971d 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh @@ -84,7 +84,7 @@ rm -v */*.*launch_ctrl *.*launch_ctrl 2> /dev/null # initialise the state files for the new services to "xxxxx" and remove directories that are no longer of interest for D in $(ls */log.log | sed "s%/.*%%" | sort -u) do - if [ $(grep \"$D\" admin_executor_service.cfg | wc -l) == 1 ] + if [ $(grep \"$D\" admin_executor_service.cfg | wc -l) = 1 ] then printf "xxxxx" > $D/$D.state else @@ -97,7 +97,7 @@ done printf "1" > ./global.launch_ctrl # create a script for accessing the screen for this shard -SCRIPT_FILE=/srv/core/bin/${DOMAIN} +SCRIPT_FILE=/srv/core/bin/domain_${DOMAIN} echo "#!/bin/sh" > $SCRIPT_FILE echo "cd "$(pwd) >> $SCRIPT_FILE echo '/bin/sh /srv/core/bin/ryzom_domain_screen_wrapper.sh $*' >> $SCRIPT_FILE diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg index 184fca55a..7473aa9a0 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg @@ -28,10 +28,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg index 0bd04c5eb..f046815ce 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg @@ -36,10 +36,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg index 8fc5a64c9..23175c08b 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg @@ -36,10 +36,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg index 8aea88a5f..74290a228 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg @@ -14,4 +14,9 @@ DontUseStdIn = 0; // 4 = nothing UseYieldMethod = 0; - +SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; +DeploymentRootDirectory="/srv/core/patchman/"; +MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; +SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; +InstallArchiveDirectory="/srv/core/"; +InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh index 091892af7..435c44bc0 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh @@ -1,25 +1,26 @@ #!/bin/sh -# the object is to make a launcher script that works with a command file to determine when to launch the application that it is responsible for +# the objective is to make a launcher script that works with a command file to determine when to launch the application that it is responsible for DOMAIN=$(pwd |sed "s%/srv/core/%%" | sed "s%/.*%%") NAME_BASE=$(pwd | sed 's/\/srv\/core\///' | sed 's/^.*\///') #if [ _$DOMAIN == _pre_live ] -# then - CTRL_FILE=${NAME_BASE}.launch_ctrl - NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl +# then + CTRL_FILE=${NAME_BASE}.launch_ctrl + NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl #elif [ _$DOMAIN == _pre_pre_live ] -# then -# CTRL_FILE=${NAME_BASE}.launch_ctrl -# NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl +# then +# CTRL_FILE=${NAME_BASE}.launch_ctrl +# NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl #else -# CTRL_FILE=${NAME_BASE}_immediate.launch_ctrl -# NEXT_CTRL_FILE=${NAME_BASE}_waiting.launch_ctrl +# CTRL_FILE=${NAME_BASE}_immediate.launch_ctrl +# NEXT_CTRL_FILE=${NAME_BASE}_waiting.launch_ctrl #fi STATE_FILE=${NAME_BASE}.state START_COUNTER_FILE=${NAME_BASE}.start_count CTRL_CMDLINE=$* +CTRL_COMMAND="" echo echo --------------------------------------------------------------------------------- @@ -36,6 +37,13 @@ echo echo 0 > $START_COUNTER_FILE START_COUNTER=0 +# always give ras a first run +if [ "${NAME_BASE}" = "ras" ] +then + echo Force admin service first startup + printf LAUNCH > $CTRL_FILE +fi + echo Press ENTER to launch program while true do @@ -45,37 +53,37 @@ do then # a control file exists so read it's contents - CTRL_COMMAND=_$(cat $CTRL_FILE)_ + CTRL_COMMAND=$(cat $CTRL_FILE) # do we have a 'launch' command? - if [ $CTRL_COMMAND = _LAUNCH_ ] + if [ "$CTRL_COMMAND" = "LAUNCH" ] then - # update the start counter - START_COUNTER=$(( $START_COUNTER + 1 )) - echo $START_COUNTER > $START_COUNTER_FILE + # update the start counter + START_COUNTER=$(( $START_COUNTER + 1 )) + echo $START_COUNTER > $START_COUNTER_FILE - # big nasty hack to deal with the special cases of ryzom_naming_service and ryzom_admin_service who have badly names cfg files - for f in ryzom_*cfg - do - cp $f $(echo $f | sed "s/ryzom_//") - done + # big nasty hack to deal with the special cases of ryzom_naming_service and ryzom_admin_service who have badly names cfg files + for f in ryzom_*cfg + do + cp $f $(echo $f | sed "s/ryzom_//") + done - # we have a launch command so prepare, launch, wait for exit and do the housekeeping - echo ----------------------------------------------------------------------- - echo Launching ... - echo - printf RUNNING > $STATE_FILE + # we have a launch command so prepare, launch, wait for exit and do the housekeeping + echo ----------------------------------------------------------------------- + echo Launching ... + echo + printf RUNNING > $STATE_FILE - $CTRL_CMDLINE + $CTRL_CMDLINE - echo ----------------------------------------------------------------------- - printf STOPPED > $STATE_FILE + echo ----------------------------------------------------------------------- + printf STOPPED > $STATE_FILE - # consume (remove) the control file to allow start once - rm $CTRL_FILE + # consume (remove) the control file to allow start once + rm $CTRL_FILE - echo Press ENTER to relaunch + echo Press ENTER to relaunch fi fi @@ -87,9 +95,9 @@ do else # give the terminal user a chance to press enter to provoke a re-launch HOLD=`sh -ic '{ read a; echo "ENTER" 1>&3; kill 0; } | { sleep 2; kill 0; }' 3>&1 2>/dev/null` - if [ _${HOLD}_ != _HOLD_ ] - then - printf LAUNCH > $CTRL_FILE + if [ "${HOLD}" = "ENTER" ] + then + printf LAUNCH > $CTRL_FILE fi fi diff --git a/code/ryzom/server/patchman_cfg/default/ai_service.cfg b/code/ryzom/server/patchman_cfg/default/ai_service.cfg index 5f3882759..fdb381b38 100644 --- a/code/ryzom/server/patchman_cfg/default/ai_service.cfg +++ b/code/ryzom/server/patchman_cfg/default/ai_service.cfg @@ -6,7 +6,7 @@ SystemCmd = {}; //NegFiltersDebug += { "LNET", "HNET", "FEVIS"}; //NegFiltersInfo += { "LNET", "HNET", "VISION_DELTA", "FEIMPE", "FEVIS" }; // NegFiltersWarning += { "LNET", "FEHACK", "FERECV"}; -// NegFiltersWarning += { "positional", "faction", "pet" }; +// NegFiltersWarning += { "positional", "faction", "pet" }; ////////////////////////////////////////////////////////////////////////////// //- Basic (specific) heal profile parameters --------------------------------- @@ -49,7 +49,7 @@ DefaultNpcAggroDist = 15; DefaultEscortRange = 10; ////////////////////////////////////////////////////////////////////////////// -// Aggro // +// Aggro // ////////////////////////////////////////////////////////////////////////////// AggroReturnDistCheck = 15.0; AggroReturnDistCheckFauna = 15.0; @@ -318,7 +318,7 @@ StartCommandsWhenMirrorReadyPost = // commands for Ring continents StartCommandsWhenMirrorReadyRing = { - "loadContinent r2_desert", + "loadContinent r2_desert", "createDynamicAIInstance 10000", "loadPrimitiveFile dummy.primitive", From 70ace8b7d4e01059838eb543fee79a633fe94af8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 23:37:39 +0100 Subject: [PATCH 134/344] Print callstack --HG-- branch : develop --- code/web/public_php/login/r2_login.php | 1 + 1 file changed, 1 insertion(+) diff --git a/code/web/public_php/login/r2_login.php b/code/web/public_php/login/r2_login.php index fdce63958..b0a8a2d79 100644 --- a/code/web/public_php/login/r2_login.php +++ b/code/web/public_php/login/r2_login.php @@ -145,6 +145,7 @@ { $logFile = new CWwwLog(); $logFile->logStr("PHP ERROR/$errno $errmsg ($filename:$linenum)"); + $logFile->logStr("PHP CALLSTACK/" . print_r(debug_backtrace(), TRUE)); // Never die after an error } From ef2415257b37621395d104c142ed9f34f47f3c44 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 23:51:42 +0100 Subject: [PATCH 135/344] Fix PHP error "Only variables should be passed by reference" --HG-- branch : develop --- code/web/public_php/tools/nel_message.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/web/public_php/tools/nel_message.php b/code/web/public_php/tools/nel_message.php index c970b9f2c..ee3177f8d 100644 --- a/code/web/public_php/tools/nel_message.php +++ b/code/web/public_php/tools/nel_message.php @@ -86,9 +86,10 @@ } else { - $this->serialUInt32(strlen($val)); + $valLen = strlen($val); + $this->serialUInt32($valLen); $this->Buffer .= $val; - $this->Pos += strlen($val); + $this->Pos += $valLen; debug(sprintf ("write string '%s' %d
\n", $val, $this->Pos)); } } From 2df9cb5f87458ab056d1041406a6e934810bc381 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 8 Nov 2014 00:29:50 +0100 Subject: [PATCH 136/344] Fix PHP error "Only variables should be passed by reference" --HG-- branch : develop --- code/web/public_php/admin/nel/nel_message.php | 5 +++-- code/web/public_php/tools/nel_message.php | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/web/public_php/admin/nel/nel_message.php b/code/web/public_php/admin/nel/nel_message.php index 5e704bff1..42dd91cbe 100644 --- a/code/web/public_php/admin/nel/nel_message.php +++ b/code/web/public_php/admin/nel/nel_message.php @@ -91,9 +91,10 @@ } else { - $this->serialUInt32(strlen($val)); + $valLen = strlen($val); + $this->serialUInt32($valLen); $this->Buffer .= $val; - $this->Pos += strlen($val); + $this->Pos += $valLen; debug(sprintf ("write string '%s' %d
\n", $val, $this->Pos)); } } diff --git a/code/web/public_php/tools/nel_message.php b/code/web/public_php/tools/nel_message.php index ee3177f8d..b696bb151 100644 --- a/code/web/public_php/tools/nel_message.php +++ b/code/web/public_php/tools/nel_message.php @@ -104,7 +104,8 @@ } else { - $this->serialUInt32($val->toInt()); + $intValue = $val->toInt(); + $this->serialUInt32($intValue); debug(sprintf ("write enum '%s' %d
\n", $val->toString(), $this->Pos)); } } From 0c1ff0df2a8686d74774b5274dd76a96bc8d2de4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 10 Nov 2014 23:34:41 +0100 Subject: [PATCH 137/344] ryzomcore/v0.11.0 --HG-- branch : develop --- code/CMakeLists.txt | 4 ++-- code/nel/tools/3d/plugin_max/nel_export/nel_export.rc | 8 ++++---- .../plugin_max/nel_patch_converter/nel_patch_converter.rc | 8 ++++---- code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc | 8 ++++---- .../3d/plugin_max/nel_patch_paint/nel_patch_paint.rc | 8 ++++---- .../plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc | 8 ++++---- code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc | 8 ++++---- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- code/web/public_php/ams/templates/layout.tpl | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 071554e06..372177889 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -2,7 +2,7 @@ # # NeL # Authors: Nevrax and the NeL Community -# Version: 0.10.0 +# Version: 0.11.0 # # Notes: # * Changing install location: add -DCMAKE_INSTALL_PREFIX:PATH=/my/new/path @@ -47,7 +47,7 @@ CHECK_OUT_OF_SOURCE() CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(RyzomCore CXX C) SET(NL_VERSION_MAJOR 0) -SET(NL_VERSION_MINOR 10) +SET(NL_VERSION_MINOR 11) SET(NL_VERSION_PATCH 0) SET(NL_VERSION "${NL_VERSION_MAJOR}.${NL_VERSION_MINOR}.${NL_VERSION_PATCH}") diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc b/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc index 57edca682..d01762618 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc @@ -575,8 +575,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -593,14 +593,14 @@ BEGIN BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "CNelExport\0" VALUE "LegalCopyright", "\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "CNelExport.dlu\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "SpecialBuild", "\0" END END diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc index aa8749a3e..b6eea41a6 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc @@ -85,8 +85,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -103,12 +103,12 @@ BEGIN BEGIN VALUE "Comments", "http://www.ryzomcore.org/" VALUE "FileDescription", "PatchMesh to RykolPatchMesh" - VALUE "FileVersion", "0.10.0" + VALUE "FileVersion", "0.11.0" VALUE "InternalName", "PatchMesh to RykolPatchMesh" VALUE "LegalCopyright", "Copyright, 2000 Nevrax Ltd." VALUE "OriginalFilename", "nel_convert_patch.dlm" VALUE "ProductName", "NeL Patch Converter" - VALUE "ProductVersion", "0.10.0" + VALUE "ProductVersion", "0.11.0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc index adc44260e..243e02da8 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc @@ -514,8 +514,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -533,13 +533,13 @@ BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core" VALUE "FileDescription", "NeL Patch Edit" - VALUE "FileVersion", "0.10.0" + VALUE "FileVersion", "0.11.0" VALUE "InternalName", "neleditpatch" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd. Copyright © 1998 Autodesk Inc." VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF." VALUE "OriginalFilename", "neleditpatch.dlm" VALUE "ProductName", "Ryzom Core" - VALUE "ProductVersion", "0.10.0" + VALUE "ProductVersion", "0.11.0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc index fadbde308..534efb2ac 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc @@ -96,8 +96,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -116,14 +116,14 @@ BEGIN VALUE "Comments", "TECH: cyril.corvazier\0" VALUE "CompanyName", "Ryzom Core\0" VALUE "FileDescription", "NeL Patch Paint\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "mods\0" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "nelpatchpaint.dlm\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "SpecialBuild", "\0" END END diff --git a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc index bf5fdd549..4e70d1afc 100644 --- a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc +++ b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc @@ -125,8 +125,8 @@ IDC_DROPPER_CURSOR CURSOR DISCARDABLE "dropcurs.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -145,13 +145,13 @@ BEGIN VALUE "Comments", "TECH: \0" VALUE "CompanyName", "Ryzom Core\0" VALUE "FileDescription", "Vertex Tree Paint\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "VertexTreePaint\0" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd. Copyright © 1998 Autodesk Inc.\0" VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF.\0" VALUE "OriginalFilename", "nel_vertex_tree_paint.dlm\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc index c6118c2f8..80d1d390d 100644 --- a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc +++ b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc @@ -124,8 +124,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -142,12 +142,12 @@ BEGIN BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "Tile_utility\0" VALUE "LegalCopyright", "\0" VALUE "OriginalFilename", "Tile_utility.dlu\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "FileDescription", "Create material for tiles\0" VALUE "Comments", "TECH: \0" VALUE "LegalTrademarks", "\0" diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index 1c13b7ed1..af714db4d 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.10.0-dev" +#define RYZOM_VERSION "ryzomcore/v0.11.0-dev" #endif // RYZOM_VERSION_H diff --git a/code/web/public_php/ams/templates/layout.tpl b/code/web/public_php/ams/templates/layout.tpl index c949263d1..33dbf3be0 100644 --- a/code/web/public_php/ams/templates/layout.tpl +++ b/code/web/public_php/ams/templates/layout.tpl @@ -167,7 +167,7 @@
- {if $permission > 1}

AMS 0.10.0 Powered by: Charisma

{/if} + {if $permission > 1}

AMS 0.11.0 Powered by: Charisma

{/if}
{/if} From d65a1cbd814c00bbe08ae48e5d24e69738536d33 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 10 Nov 2014 23:41:33 +0100 Subject: [PATCH 139/344] Added tag ryzomcore/v0.11.0 for changeset edaa3624a564 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index c6af6b011..931ad2ca5 100644 --- a/.hgtags +++ b/.hgtags @@ -3,3 +3,4 @@ 00d9b6e29e95f56785fbf85abe60afd34674f402 ryzomcore/v0.9.0 79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1 fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0 +edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0 From f05c52aa0bd40cc97cd19a32700d3854aac954fb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Nov 2014 16:20:14 +0100 Subject: [PATCH 140/344] Remove PIC library --HG-- branch : develop --- code/nel/tools/3d/tile_edit/Browse.cpp | 6 +- code/nel/tools/3d/tile_edit/CMakeLists.txt | 2 +- .../nel/tools/3d/tile_edit/PIC/PIC_System.cpp | 126 ---- code/nel/tools/3d/tile_edit/PIC/Pic_BMP.cpp | 215 ------ code/nel/tools/3d/tile_edit/PIC/Pic_JPG.cpp | 160 ----- .../nel/tools/3d/tile_edit/PIC/Pic_Manage.cpp | 637 ------------------ code/nel/tools/3d/tile_edit/PIC/Pic_TGA.cpp | 215 ------ code/nel/tools/3d/tile_edit/PIC/pic.h | 58 -- code/nel/tools/3d/tile_edit/PIC/pic_private.h | 81 --- code/nel/tools/3d/tile_edit/PIC/readpic.cpp | 84 --- code/nel/tools/3d/tile_edit/PIC/readpic.h | 40 -- code/nel/tools/3d/tile_edit/View.cpp | 45 +- 12 files changed, 42 insertions(+), 1627 deletions(-) delete mode 100644 code/nel/tools/3d/tile_edit/PIC/PIC_System.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/Pic_BMP.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/Pic_JPG.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/Pic_Manage.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/Pic_TGA.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/pic.h delete mode 100644 code/nel/tools/3d/tile_edit/PIC/pic_private.h delete mode 100644 code/nel/tools/3d/tile_edit/PIC/readpic.cpp delete mode 100644 code/nel/tools/3d/tile_edit/PIC/readpic.h diff --git a/code/nel/tools/3d/tile_edit/Browse.cpp b/code/nel/tools/3d/tile_edit/Browse.cpp index 0d71ffad7..7c4f6d745 100644 --- a/code/nel/tools/3d/tile_edit/Browse.cpp +++ b/code/nel/tools/3d/tile_edit/Browse.cpp @@ -885,7 +885,7 @@ void Browse::OnChangeVariety() void Browse::OnBatchLoad () { CFileDialog sFile (true, NULL, NULL, OFN_ENABLESIZING, - "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); + "PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { @@ -1365,7 +1365,7 @@ void Browse::OnExportBorder() { // Select a file CFileDialog sFile (false, NULL, NULL, OFN_ENABLESIZING, - "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); + "PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { // Get the border of the bank @@ -1431,7 +1431,7 @@ void Browse::OnImportBorder() { // Select a file CFileDialog sFile (true, NULL, NULL, OFN_ENABLESIZING, - "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); + "PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { // Get the border of the bank diff --git a/code/nel/tools/3d/tile_edit/CMakeLists.txt b/code/nel/tools/3d/tile_edit/CMakeLists.txt index ea7e1ac77..394359cd0 100644 --- a/code/nel/tools/3d/tile_edit/CMakeLists.txt +++ b/code/nel/tools/3d/tile_edit/CMakeLists.txt @@ -1,4 +1,4 @@ -FILE(GLOB SRC *.cpp *.h PIC/*.cpp PIC/*.h) +FILE(GLOB SRC *.cpp *.h) FILE(GLOB SRC2 cpu.cpp DllEntry.cpp Popup.* thread_win32.* TileCtrl.* TileList.* TileView.*) LIST(REMOVE_ITEM SRC ${SRC2}) diff --git a/code/nel/tools/3d/tile_edit/PIC/PIC_System.cpp b/code/nel/tools/3d/tile_edit/PIC/PIC_System.cpp deleted file mode 100644 index 439de9979..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/PIC_System.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include -#include -#include - -#define PIC_ERRSIZE 256 - -static unsigned long PIC_Sys_MEM_Allocated; -static unsigned long PIC_Sys_MEM_NbAllocs; - -// ---------------------------------------------------------------------------------------------------------------------------------- - -void *Pic_malloc(unsigned long size) -{ - void *mem; - mem=malloc(size); - if (mem) - { - PIC_Sys_MEM_Allocated+=size; - PIC_Sys_MEM_NbAllocs++; - } - return(mem); -} -// ----- -void *Pic_calloc(unsigned long count, unsigned long size) -{ - void *mem; - mem=calloc(count,size); - if (mem) - { - PIC_Sys_MEM_Allocated+=(size*count); - PIC_Sys_MEM_NbAllocs++; - } - return(mem); -} -// ----- -void Pic_free(void *memblock) -{ - unsigned long size; - size=(unsigned long)_msize(memblock); - PIC_Sys_MEM_Allocated-=size; - PIC_Sys_MEM_NbAllocs--; - free(memblock); -} -// ----- -unsigned long Pic__msize(void *memblock) -{ - return(unsigned long)(_msize(memblock)); -} -// ----- -unsigned long PIC_GetMemNbAllocs(void) -{ - return(PIC_Sys_MEM_NbAllocs); -} -// ----- -unsigned long PIC_GetMemAllocated(void) -{ - return(PIC_Sys_MEM_Allocated); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -static char PIC_ErrorFlag; -static char PIC_ErrorString[PIC_ERRSIZE]; -static unsigned char PIC_Sys_FnctActive=0; -static void (*PIC_Sys_Fnct)(void); - -void Pic_SetError(const char *msg, ...) -{ - char curerr[PIC_ERRSIZE],olderr[PIC_ERRSIZE]; - va_list args; - - va_start(args,msg); - vsprintf(curerr,msg,args); - va_end(args); - if ( (strlen(curerr)+strlen(PIC_ErrorString))>PIC_ERRSIZE ) return; - - if (PIC_ErrorFlag) - { - strcpy(olderr,PIC_ErrorString); - sprintf(PIC_ErrorString,"--- [PIC#%03d] :\n%s",PIC_ErrorFlag,curerr); - strcat(PIC_ErrorString,"\n"); - strcat(PIC_ErrorString,olderr); - } - else - { - sprintf(PIC_ErrorString,"--- [PIC#%03d] :\n%s",PIC_ErrorFlag,curerr); - } - PIC_ErrorFlag++; - if (PIC_Sys_FnctActive) PIC_Sys_Fnct(); - return; -} -// ----- -char* PIC_GetError(void) -{ - return(PIC_ErrorString); -} -// ----- -unsigned char PIC_Error(void) -{ - return(PIC_ErrorFlag); -} -// ----- -void PIC_ResetError(void) -{ - strcpy(PIC_ErrorString,""); - PIC_ErrorFlag=0; -} -// ----- -unsigned char PIC_OnErrorCall( void pFnct(void) ) -{ - if (pFnct != NULL) - { - PIC_Sys_Fnct=pFnct; - PIC_Sys_FnctActive=1; - } - else - { - PIC_Sys_FnctActive=0; - } - return(1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - diff --git a/code/nel/tools/3d/tile_edit/PIC/Pic_BMP.cpp b/code/nel/tools/3d/tile_edit/PIC/Pic_BMP.cpp deleted file mode 100644 index 9ea55e029..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/Pic_BMP.cpp +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include -#include - -#include "pic_private.h" -#include "pic.h" - -// ---------------------------------------------------------------------------------------------------------------------------------- - -#pragma pack(1) -typedef struct BMP_HEADER -{ - unsigned short bfType; - unsigned long bfSize; - unsigned short Res1; - unsigned short Res2; - unsigned long bfOffBits; - unsigned long biSize; - unsigned long biWidth; - unsigned long biHeight; - unsigned short biPlanes; - unsigned short biBitCount; - unsigned long biCompression; - unsigned long biSizeImage; - unsigned long biXPelsPerMeter; - unsigned long biYPelsPerMeter; - unsigned long biClrUsed; - unsigned long biClrImportant; -} BMP_HEADER; -#pragma pack() - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long Pic_BMP_Write( const char *FileName, - char *pPal, char *pDatas, - unsigned long w, unsigned long h, unsigned long d) - -{ - FILE *file; - BMP_HEADER bmph; - unsigned long slsize; - unsigned char *scanline; - unsigned long i; - long x,y,rest; - unsigned char r,g,b; - - file=fopen(FileName,"wb"); - if (!file) - { - return(0); - } - memset(&bmph,0,sizeof(BMP_HEADER)); - bmph.bfType=19778; - bmph.bfSize=sizeof(BMP_HEADER); - bmph.bfSize+=w*h*d/8; - if (pPal) - { - bmph.bfSize+=(256*4); - } - bmph.bfOffBits=sizeof(BMP_HEADER); - if (pPal) - { - bmph.bfOffBits+=(256*4); - } - bmph.biSize=40;//sizeof(BMP_HEADER); - bmph.biWidth=w; - bmph.biHeight=h; - bmph.biPlanes=1; - bmph.biBitCount=(unsigned short)d; - bmph.biCompression=0; - bmph.biSizeImage=w*h*d/8; - - fwrite(&bmph,1,sizeof(BMP_HEADER),file); - if (pPal) - { - for(i=0 ; i<256 ; i++) - { - fwrite(&pPal[i*3+0],1,1,file); - fwrite(&pPal[i*3+1],1,1,file); - fwrite(&pPal[i*3+2],1,1,file); - fwrite(&pPal[i*3+2],1,1,file); - } - } - slsize=w*d/8; - scanline=(unsigned char*)Pic_calloc(1,slsize); - if (!scanline) - { - Pic_SetError("BMP_Write, not enough memory for scanline"); - return(0); - } - for(rest=0 ; ((w*d/8)+rest)%4!=0 ; rest++); - for(y=0 ; y<(long)h ; y++) - { - memcpy(scanline,&pDatas[(h-y-1)*slsize],slsize); - if (d==24) - { - for(x=0 ; x<(long)w ; x++) - { - b=scanline[x*3+0]; - g=scanline[x*3+1]; - r=scanline[x*3+2]; - scanline[x*3+0]=b; - scanline[x*3+1]=g; - scanline[x*3+2]=r; - } - } - fwrite(scanline,1,slsize,file); - if (rest) - { - fwrite(scanline,1,rest,file); - } - } - Pic_free(scanline); - fclose(file); - return(1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long Pic_BMP_Read( const char *FileName, - char **ppPal, char **ppDatas, - unsigned long *pWidth, unsigned long *pHeight, - unsigned long *pDepth) -{ - FILE *file; - BMP_HEADER bmph; - char *pPal; - char *pDatas; - unsigned char *scanline; - long w,h,d; - long i,x,y,rest; - unsigned char r,g,b; - unsigned char pad[4]; - - pPal=NULL; - pDatas=NULL; - file=fopen(FileName,"rb"); - if (!file) - { - Pic_SetError("BMP_Read, unable to open %s",FileName); - return(0); - } - fread(&bmph,1,sizeof(BMP_HEADER),file); - *pWidth=w=bmph.biWidth; - *pHeight=h=bmph.biHeight; - *pDepth=d=bmph.biBitCount; - if (d!=8 && d!=24) - { - Pic_SetError("BMP_Read, number of bits per pixel unsupported"); - return(0); - } - if (*pDepth==8) - { - pPal=(char*)Pic_calloc(1,256*3); - if (!pPal) - { - Pic_SetError("BMP_Read, not enough memory for palette"); - return(0); - } - for(i=0 ; i<256 ; i++) - { - fread(&pPal[i*3+2],1,1,file); - fread(&pPal[i*3+1],1,1,file); - fread(&pPal[i*3+0],1,1,file); - fread(&pad[0],1,1,file); - } - } - pDatas=(char*)Pic_calloc(1,w*h*d/8); - if (!pDatas) - { - if (pPal) - { - Pic_free(pPal); - } - Pic_SetError("BMP_Read, not enough memory for datas"); - return(0); - } - scanline=(unsigned char*)Pic_calloc(1,w*h*d/8); - if (!scanline) - { - if (pPal) - { - Pic_free(pPal); - } - Pic_free(pDatas); - Pic_SetError("BMP_Read, not enough memory for scanline"); - return(0); - } - for(rest=0 ; (w+rest)%4!=0 ; rest++); - for(y=0 ; y -#include -#include -#include - -#include -#include "pic_private.h" -#include "pic.h" - -// ---------------------------------------------------------------------------------------------------------------------------------- - -struct my_error_mgr -{ - struct jpeg_error_mgr pub; - jmp_buf setjmp_buffer; -}; -typedef struct my_error_mgr * my_error_ptr; - -// ---------------------------------------------------------------------------------------------------------------------------------- - -static unsigned char error; - -// ---------------------------------------------------------------------------------------------------------------------------------- - -void my_error_exit(j_common_ptr cinfo) -{ - my_error_ptr myerr = (my_error_ptr) cinfo->err; - error=1; - longjmp(myerr->setjmp_buffer, 1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long Pic_JPG_Read(const char *FileName, char **ppPal, char **ppDatas, unsigned long *w, unsigned long *h) -{ - struct jpeg_decompress_struct cinfo; - struct my_error_mgr jerr; - FILE *file; - JSAMPARRAY buffer; - int row_stride,i; - char *pDatas,*pPal; - unsigned long ptr; - - error=0; - ptr=0; - file=fopen(FileName, "rb"); - if (!file) - { - Pic_SetError("JPG_Read, unable to open %s",FileName); - return(0); - } - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_error_exit; - setjmp(jerr.setjmp_buffer); - if (error) - { - Pic_SetError("JPG_Read, internal decompression error"); - jpeg_destroy_decompress(&cinfo); - return(0); - } - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, file); - (void) jpeg_read_header(&cinfo, TRUE); - *w=cinfo.image_width; - *h=cinfo.image_height; - if (!ppPal) - { - pDatas=(char*)Pic_calloc(1,(*w)*(*h)*3); - } - else - { - pDatas=(char*)Pic_calloc(1,(*w)*(*h)); - pPal=(char*)Pic_calloc(1,256*3); - if (!pPal) - { - Pic_SetError("JPG_Read, not enough memory for palette"); - return(0); - } - cinfo.desired_number_of_colors = 256; - cinfo.quantize_colors = TRUE; - cinfo.dither_mode = JDITHER_ORDERED; - } - if (!pDatas) - { - Pic_SetError("JPG_Read, not enough memory for pic"); - return(0); - } - (void) jpeg_start_decompress(&cinfo); - row_stride = cinfo.output_width * cinfo.output_components; - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - while (cinfo.output_scanline < cinfo.output_height) - { - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - memcpy(&pDatas[ptr],buffer[0],row_stride); - ptr+=row_stride; - } - *ppDatas=pDatas; - if (ppPal) - { - for(i=0 ; i<256 ; i++) - { - pPal[i*3+0]=cinfo.colormap[2][i]; - pPal[i*3+1]=cinfo.colormap[1][i]; - pPal[i*3+2]=cinfo.colormap[0][i]; - } - *ppPal=pPal; - } - (void) jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(file); - return(1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long Pic_JPG_Write(const char *FileName, unsigned long Qual, char *pDatas, unsigned long w, unsigned long h) -{ - struct jpeg_compress_struct cinfo; - struct my_error_mgr jerr; - FILE *file; - JSAMPROW row_pointer[1]; - int row_stride; - - error=0; - file=fopen(FileName,"wb"); - if (!file) - { - Pic_SetError("JPG_Write, unable to open %s",FileName); - return(0); - } - jpeg_create_compress(&cinfo); - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_error_exit; - setjmp(jerr.setjmp_buffer); - if (error) - { - Pic_SetError("JPG_Write, internal compression error"); - jpeg_destroy_compress(&cinfo); - return(0); - } - jpeg_stdio_dest(&cinfo, file); - cinfo.image_width = w; - cinfo.image_height = h; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, Qual, TRUE); - jpeg_start_compress(&cinfo, TRUE); - row_stride = w * 3; - while(cinfo.next_scanline -#include "pic_private.h" -#include "pic.h" - -static unsigned long NbPics=0; -static PIC_PICTURE *HeadPic=NULL; - -// ---------------------------------------------------------------------------------------------------------------------------------- - -static PIC_PICTURE *GetPic(unsigned long id) -{ - PIC_PICTURE *pic; - - for(pic=HeadPic ; pic ; pic=pic->Next) - { - if (pic->ID==id) - { - return(pic); - } - } - return(NULL); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long PIC_Load(char* FileName, unsigned char Quantize) -{ - char ext[4]; - unsigned long type; - unsigned long i,taken,id; - PIC_PICTURE *pic; - char *pDatas; - char *pPal; - unsigned long w,h,Depth; - unsigned long ret; - - // --- Init - ret=0; - type=0; - id=0; - taken=0; - w=0; - h=0; - Depth=0; - pic=NULL; - pDatas=NULL; - pPal=NULL; - // --- Get 1st available ID - for(i=1 ; i<=NbPics+1 ; i++) - { - taken=0; - for(pic=HeadPic ; pic ; pic=pic->Next) - { - if (pic->ID==i) - { - taken=1; - break; - } - } - if (!taken) - { - id=i; - break; - } - } - if (!id) - { - Pic_SetError("Load, unable to create ID"); - return(0); - } - // --- Load pic - if (FileName) - { - ext[0]=FileName[strlen(FileName)-3]; - ext[1]=FileName[strlen(FileName)-2]; - ext[2]=FileName[strlen(FileName)-1]; - ext[3]=0; - strupr(ext); - if ( !strcmp(ext,"JPG") ) - { - type=1; - } - else if ( !strcmp(ext,"TGA") ) - { - type=2; - } - else if ( !strcmp(ext,"BMP") ) - { - type=3; - } - - switch(type) - { - // - JPG - case 1: - if (!Quantize) - { - Depth=24; - ret=Pic_JPG_Read(FileName,NULL,&pDatas,&w,&h); - } - else - { - Depth=8; - ret=Pic_JPG_Read(FileName,&pPal,&pDatas,&w,&h); - } - if (!ret) - { - Pic_SetError("Load, unable to load JPG file %s",FileName); - return(0); - } - break; - // - TGA - case 2: - ret=Pic_TGA_Read(FileName,&pPal,&pDatas,&w,&h,&Depth); - if (!ret) - { - Pic_SetError("Load, unable to load TGA file %s",FileName); - return(0); - } - break; - // - BMP - case 3: - ret=Pic_BMP_Read(FileName,&pPal,&pDatas,&w,&h,&Depth); - if (!ret) - { - Pic_SetError("Load, unable to load BMP file %s",FileName); - return(0); - } - break; - // - Unknown - default: - Pic_SetError("Load, unknown extension for %s",FileName); - return(0); - } - } - - // --- Create and place new pic struct - pic=(PIC_PICTURE *)Pic_calloc(1,sizeof(PIC_PICTURE)); - if (!pic) - { - Pic_SetError("Load, not enough memory for internal structure"); - return(0); - } - pic->Next=HeadPic; - HeadPic=pic; - NbPics++; - pic->ID=id; - pic->pDatas=pDatas; - pic->pPal=pPal; - pic->Width=w; - pic->Height=h; - pic->Depth=Depth; - return(id); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long PIC_Create(char* pPal, char* pDatas, unsigned long w, unsigned long h, unsigned long d) -{ - unsigned long i,taken,id; - PIC_PICTURE *pic; - - // --- Init - id=0; - taken=0; - pic=NULL; - // --- Get 1st available ID - for(i=1 ; i<=NbPics+1 ; i++) - { - taken=0; - for(pic=HeadPic ; pic ; pic=pic->Next) - { - if (pic->ID==i) - { - taken=1; - break; - } - } - if (!taken) - { - id=i; - break; - } - } - if (!id) - { - Pic_SetError("Create, unable to create ID"); - return(0); - } - // --- Create pic - if (!pDatas) - { - pDatas=(char *)Pic_calloc(1,w*h*d/8); - if (!pDatas) - { - Pic_SetError("Create, not enough memory for datas"); - return(0); - } - } - if (d==8) - { - if (!pPal) - { - pPal=(char *)Pic_calloc(1,256*3); - if (!pPal) - { - Pic_SetError("Create, not enough memory for palette"); - return(0); - } - } - } - else - { - pPal=NULL; - } - // --- Create and place new pic struct - pic=(PIC_PICTURE *)Pic_calloc(1,sizeof(PIC_PICTURE)); - if (!pic) - { - Pic_SetError("Create, not enough memory for internal structure"); - return(0); - } - pic->Next=HeadPic; - HeadPic=pic; - NbPics++; - pic->ID=id; - pic->pDatas=pDatas; - pic->pPal=pPal; - pic->Width=w; - pic->Height=h; - pic->Depth=d; - return(id); - -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long PIC_GetInfos( unsigned long id, - char **ppPal, char **ppDatas, - unsigned long *pW, unsigned long *pH, unsigned long *pD) -{ - PIC_PICTURE *pic; - - pic=GetPic(id); - if (!pic) - { - Pic_SetError("GetInfos, picture internal structure not found"); - return(0); - } - if (ppPal) - { - *ppPal=pic->pPal; - } - if (ppDatas) - { - *ppDatas=pic->pDatas; - } - if (pW) - { - *pW=pic->Width; - } - if (pH) - { - *pH=pic->Height; - } - if (pD) - { - *pD=pic->Depth; - } - return(id); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -static char* Conv8To24(unsigned long id) -{ - PIC_PICTURE *pic; - char *buf; - unsigned long i; - - pic=GetPic(id); - if (!pic) - { - Pic_SetError("Conv8To24, picture internal structure not found"); - return(NULL); - } - buf=(char *)Pic_malloc(pic->Width*pic->Height*3); - if (!buf) - { - Pic_SetError("Conv8To24, not enough memory for temporary buffer"); - return(NULL); - } - for(i=0 ; iWidth*pic->Height ; i++) - { - buf[i*3+0]=pic->pPal[pic->pDatas[i]*3+0]; - buf[i*3+1]=pic->pPal[pic->pDatas[i]*3+1]; - buf[i*3+2]=pic->pPal[pic->pDatas[i]*3+2]; - } - return(buf); -} - -// ---------------------------------------- -static char* Conv8To16(unsigned long id) -{ - PIC_PICTURE *pic; - unsigned short *buf; - unsigned long i; - unsigned short r,g,b,pix16; - - pic=GetPic(id); - if (!pic) - { - Pic_SetError("Conv8To24, picture internal structure not found"); - return(NULL); - } - buf=(unsigned short*)Pic_malloc(pic->Width*pic->Height*2); - if (!buf) - { - Pic_SetError("Conv8To24, not enough memory for temporary buffer"); - return(NULL); - } - for(i=0 ; iWidth*pic->Height ; i++) - { - b=pic->pPal[pic->pDatas[i]*3+0]; - g=pic->pPal[pic->pDatas[i]*3+1]; - r=pic->pPal[pic->pDatas[i]*3+2]; - r>>=3; - g>>=3; g&=0x3E; - b>>=3; - pix16=(r<<10)+(g<<5)+b; - buf[i]=pix16; - } - return (char*)buf; -} - -// ---------------------------------------- - -static char* Conv16To24(unsigned long id) -{ - PIC_PICTURE *pic; - unsigned short *pDatas; - unsigned char *buf; - unsigned long i; - unsigned short r,g,b; - - pic=GetPic(id); - if (!pic) - { - Pic_SetError("Conv16To24, picture internal structure not found"); - return(NULL); - } - buf=(unsigned char *)Pic_malloc(pic->Width*pic->Height*3); - if (!buf) - { - Pic_SetError("Conv16To24, not enough memory for temporary buffer"); - return(NULL); - } - pDatas=(unsigned short*)pic->pDatas; - for(i=0 ; iWidth*pic->Height ; i++) - { - r=(pDatas[i] & 0x7C00)>>(10-3); - g=(pDatas[i] & 0x03E0)>>(5-3); - b=(pDatas[i] & 0x001F)<<3; - buf[i*3+0]=(unsigned char)r; - buf[i*3+1]=(unsigned char)g; - buf[i*3+2]=(unsigned char)b; - } - return (char*)buf; -} - -// ---------------------------------------- - -static char* Conv24To16(unsigned long id) -{ - PIC_PICTURE *pic; - unsigned short *buf; - unsigned long i; - unsigned short r,g,b; - unsigned short pix16; - - pic=GetPic(id); - if (!pic) - { - Pic_SetError("Conv24To16, picture internal structure not found"); - return(NULL); - } - buf=(unsigned short*)Pic_malloc(pic->Width*pic->Height*2); - if (!buf) - { - Pic_SetError("Conv24To16, not enough memory for temporary buffer"); - return(NULL); - } - for(i=0 ; iWidth*pic->Height ; i++) - { - r=pic->pDatas[i*3+0]; - g=pic->pDatas[i*3+1]; - b=pic->pDatas[i*3+2]; - // r : 5 bits forts (0x7C) - // g : 5 bits (6e zapped) (0x3E) - // b : 5 bits faibles (0x1F) - r>>=3; - g>>=3; g&=0x3E; - b>>=3; - pix16=(r<<10)+(g<<5)+b; - buf[i]=pix16; - } - return (char*)buf; -} - -// ---------------------------------------- - -static char* ConvPic(PIC_PICTURE *pic, unsigned long type, char* pErr) -{ - char *buf; - unsigned long src,dst; - - *pErr=0; - buf=NULL; - src=pic->Depth; - if (type==PIC_TYPE_TGA8 || type==PIC_TYPE_BMP8) - { - dst=8; - } - if (type==PIC_TYPE_TGA16) - { - dst=16; - } - if (type==PIC_TYPE_JPG || type==PIC_TYPE_TGA24 || type==PIC_TYPE_BMP24) - { - dst=24; - } - // --- - if (src==dst) - { - return(NULL); - } - // --- - if (src==8 && dst==24) - { - buf=Conv8To24(pic->ID); - if (!buf) - { - *pErr=1; - } - return(buf); - } - if (src==8 && dst==16) - { - buf=Conv8To16(pic->ID); - if (!buf) - { - *pErr=1; - } - return(buf); - } - // --- - if (src==16 && dst==24) - { - buf=Conv16To24(pic->ID); - if (!buf) - { - *pErr=1; - } - return(buf); - } - // --- - if (src==24 && dst==16) - { - buf=Conv24To16(pic->ID); - if (!buf) - { - *pErr=1; - } - return buf; - } - // --- - if (src==24 && dst==8) - { - Pic_SetError("ConvPic, downsampling 24 to 8 bits unsupported"); - *pErr=1; - return(NULL); - } - Pic_SetError("ConvPic, conversion %d to %d unsupported",src,dst); - *pErr=1; - return(NULL); -} - -// ---------------------------------------- - -unsigned long PIC_Save(unsigned long id, char* FileName, unsigned long type, unsigned long qual) -{ - PIC_PICTURE *pic; - char err; - char *buf; - char *freeit; - unsigned long depth; - - freeit=NULL; - pic=GetPic(id); - if (!pic) - { - Pic_SetError("Save %s, picture internal structure not found",FileName); - return(0); - } - freeit = ConvPic(pic,type,&err); - if (err) - { - Pic_SetError("Save %s, error while converting picture",FileName); - return(0); - } - if (!freeit) - { - buf=pic->pDatas; - } - else - { - buf=freeit; - } - err=0; - switch(type) - { - // --- - case PIC_TYPE_JPG: - if ( !Pic_JPG_Write(FileName,qual,buf,pic->Width,pic->Height) ) - { - if (freeit) - { - Pic_free(buf); - } - Pic_SetError("Save %s, error while saving JPG file",FileName); - err=1; - } - break; - // --- - case PIC_TYPE_TGA8: - case PIC_TYPE_TGA16: - case PIC_TYPE_TGA24: - if (type==PIC_TYPE_TGA8) - { - depth=8; - } - if (type==PIC_TYPE_TGA16) - { - depth=16; - } - if (type==PIC_TYPE_TGA24) - { - depth=24; - } - if ( !Pic_TGA_Write(FileName,pic->pPal,buf,pic->Width,pic->Height,depth) ) - { - if (freeit) - { - Pic_free(freeit); - } - Pic_SetError("Save %s, error while saving TGA file",FileName); - err=1; - } - break; - // --- - case PIC_TYPE_BMP8: - case PIC_TYPE_BMP24: - if (type==PIC_TYPE_BMP8) - { - depth=8; - } - if (type==PIC_TYPE_BMP24) - { - depth=24; - } - if ( !Pic_BMP_Write(FileName,pic->pPal,buf,pic->Width,pic->Height,depth) ) - { - if (freeit) - { - Pic_free(freeit); - } - Pic_SetError("Save %s, error while saving BMP file",FileName); - err=1; - } - break; - // --- - default: - Pic_SetError("Save %s, unknow save format/type",FileName); - err=1; - break; - } - if (freeit) - { - Pic_free(freeit); - } - return(err-1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long PIC_Destroy(unsigned long id) -{ - PIC_PICTURE *prevpic,*pic; - unsigned long found; - - prevpic=NULL; - found=0; - for(pic=HeadPic ; pic ; pic=pic->Next) - { - if (pic->ID==id) - { - found=1; - break; - } - prevpic=pic; - } - if (!found) - { - Pic_SetError("Destroy, picture internal structure not found"); - return(0); - } - if (prevpic) - { - prevpic->Next=pic->Next; - } - if (pic->pDatas) - { - Pic_free(pic->pDatas); - } - if (pic->pPal) - { - Pic_free(pic->pPal); - } - if (pic==HeadPic) - { - HeadPic=pic->Next; - } - Pic_free(pic); - return(1); -} - -// ---------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/code/nel/tools/3d/tile_edit/PIC/Pic_TGA.cpp b/code/nel/tools/3d/tile_edit/PIC/Pic_TGA.cpp deleted file mode 100644 index 6d69b914e..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/Pic_TGA.cpp +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include -#include - -#include "pic_private.h" -#include "pic.h" - -// ---------------------------------------------------------------------------------------------------------------------------------- - -#pragma pack(1) -typedef struct TGA_HEADER -{ - unsigned char LengthID; - unsigned char CMapType; - unsigned char ImageType; - unsigned short Origin; - unsigned short Length; - unsigned char Depth; - unsigned short XOrg; - unsigned short YOrg; - unsigned short Width; - unsigned short Height; - unsigned char ImageDepth; - unsigned char Desc; -} TGA_HEADER; -#pragma pack() - -// ---------------------------------------------------------------------------------------------------------------------------------- - -unsigned long Pic_TGA_Read( const char *FileName, - char **ppPal, char **ppDatas, - unsigned long *pWidth, unsigned long *pHeight, - unsigned long *pDepth) -{ - FILE *file; - TGA_HEADER tgah; - long w,h,d; - unsigned long size; - char *pDatas; - char *pPal; - long x,y; - long slsize; - unsigned char *scanline; - unsigned char r,g,b; - long i; - int upSideDown; - - pDatas=NULL; - pPal=NULL; - file=fopen(FileName,"rb"); - if (!file) - { - Pic_SetError("TGA_Read, unable to open %s",FileName); - return(0); - } - fread(&tgah,1,sizeof(TGA_HEADER),file); - if (tgah.ImageType>3) - { - Pic_SetError("TGA_Read, unsupported TGA format"); - return(0); - } - *pWidth=w=tgah.Width; - *pHeight=h=tgah.Height; - *pDepth=d=tgah.ImageDepth; - upSideDown = ((tgah.Desc & (1 << 5))==0); - - size=tgah.Width*tgah.Height*(tgah.ImageDepth/8); - pDatas=(char*)Pic_malloc(size); - if (!pDatas) - { - Pic_SetError("TGA_Read, not enough memory"); - return(0); - } - if (*pDepth==8) - { - if (!ppPal) - { - Pic_free(pDatas); - Pic_SetError("TGA_Read, need a pointer to palette"); - return(0); - } - pPal=(char*)Pic_calloc(1,256*3); - if (!pPal) - { - Pic_SetError("TGA_Read, not enough memory for palette"); - return(0); - } - if (tgah.ImageType==1) - { - for(i=0 ; i<256*3 ; i+=3) - { - fread(&pPal[i+2],1,1,file); - fread(&pPal[i+1],1,1,file); - fread(&pPal[i+0],1,1,file); - } - } - *ppPal=pPal; - } - - slsize=w*d/8; - scanline=(unsigned char*)Pic_calloc(1,slsize); - if (!scanline) - { - if (pPal) - { - Pic_free(pPal); - } - Pic_free(pDatas); - Pic_SetError("TGA_Read, not enough memory for scanline"); - return(0); - } - for(y=0 ; y8) - { - tgah.CMapType=0; - tgah.ImageType=2; - tgah.Length=0; - tgah.Depth=0; - } - else - { - tgah.CMapType=1; - tgah.ImageType=1; - tgah.Length=256; - tgah.Depth=24; - } - tgah.Origin=0; - tgah.XOrg=0; - tgah.YOrg=0; - tgah.Width=(unsigned short)w; - tgah.Height=(unsigned short)h; - tgah.ImageDepth=(unsigned char)d; - tgah.Desc=0; - fwrite(&tgah,1,sizeof(TGA_HEADER),file); - if (d==8) - { - fwrite(pPal,1,256*3,file); - } - slsize=w*d/8; - scanline=(unsigned char*)Pic_calloc(1,slsize); - if (!scanline) - { - Pic_SetError("TGA_Write, not enough memory for scanline"); - return(0); - } - for(y=0 ; y<(long)h ; y++) - { - memcpy(scanline,&pDatas[(h-y-1)*slsize],slsize); - if (d==24) - { - for(x=0 ; x<(long)w ; x++) - { - r=scanline[x*3+0]; - g=scanline[x*3+1]; - b=scanline[x*3+2]; - scanline[x*3+0]=b; - scanline[x*3+1]=g; - scanline[x*3+2]=r; - } - } - fwrite(scanline,1,slsize,file); - } - Pic_free(scanline); - fclose(file); - return(1); -} diff --git a/code/nel/tools/3d/tile_edit/PIC/pic.h b/code/nel/tools/3d/tile_edit/PIC/pic.h deleted file mode 100644 index ec6582c6b..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/pic.h +++ /dev/null @@ -1,58 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef _PIC_H_ -#define _PIC_H_ - -// ---------------------------------------------------------------------------------------------------------------------------------- - -#define PIC_TYPE_JPG 1 -#define PIC_TYPE_TGA8 2 -#define PIC_TYPE_TGA16 3 -#define PIC_TYPE_TGA24 4 -#define PIC_TYPE_BMP8 5 -#define PIC_TYPE_BMP24 6 - -// ---------------------------------------------------------------------------------------------------------------------------------- - -// -// Basic API -// -extern unsigned long PIC_Load(char* FileName, unsigned char Quantize); - -extern unsigned long PIC_Create(char* pPal, char* pDatas, unsigned long w, unsigned long h, unsigned long d); - -extern unsigned long PIC_Save(unsigned long id, char* FileName, unsigned long type, unsigned long qual); - -extern unsigned long PIC_GetInfos( unsigned long id, - char **ppPal, char **ppDatas, - unsigned long *pW, unsigned long *pH, unsigned long *pD); - - -extern unsigned long PIC_Destroy(unsigned long id); -// -// System -// -extern unsigned long PIC_GetMemNbAllocs(void); -extern unsigned long PIC_GetMemAllocated(void); -extern char* PIC_GetError(void); -extern unsigned char PIC_Error(void); -extern void PIC_ResetError(void); -extern unsigned char PIC_OnErrorCall( void pFnct(void) ); - -// ---------------------------------------------------------------------------------------------------------------------------------- - -#endif diff --git a/code/nel/tools/3d/tile_edit/PIC/pic_private.h b/code/nel/tools/3d/tile_edit/PIC/pic_private.h deleted file mode 100644 index 4a67bbc9c..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/pic_private.h +++ /dev/null @@ -1,81 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef _PIC_PRIVATE_H_ -#define _PIC_PRIVATE_H_ - -// ---------------------------------------------------------------------------------------------------------------------------------- - -typedef struct PIC_PICTURE -{ - unsigned long ID; - unsigned long Width; - unsigned long Height; - unsigned long Depth; - char *pDatas; - char *pPal; - struct PIC_PICTURE *Next; -} PIC_PICTURE; - -// ---------------------------------------------------------------------------------------------------------------------------------- - - -// -// JPG -// - - -extern unsigned long Pic_JPG_Read( const char *FileName, - char **ppPal, char **ppDatas, - unsigned long *w, unsigned long *h); - -extern unsigned long Pic_JPG_Write( const char *FileName, - unsigned long Qual, - char *pDatas, - unsigned long w, unsigned long h); -// -// TGA -// -extern unsigned long Pic_TGA_Read( const char *FileName, - char **ppPal, char **ppDatas, - unsigned long *pWidth, unsigned long *pHeight, - unsigned long *pDepth); -extern unsigned long Pic_TGA_Write( const char *FileName, - char *pPal, char *pDatas, - unsigned long w, unsigned long h, unsigned long d); -// -// BMP -// -extern unsigned long Pic_BMP_Read( const char *FileName, - char **ppPal, char **ppDatas, - unsigned long *pWidth, unsigned long *pHeight, - unsigned long *pDepth); - -extern unsigned long Pic_BMP_Write( const char *FileName, - char *pPal, char *pDatas, - unsigned long w, unsigned long h, unsigned long d); -// -// System -// -extern void* Pic_malloc(unsigned long size); -extern void* Pic_calloc(unsigned long count, unsigned long size); -extern void Pic_free(void *memblock); -extern unsigned long Pic__msize(void *memblock); -extern void Pic_SetError(const char *msg, ...); - -// ---------------------------------------------------------------------------------------------------------------------------------- - -#endif \ No newline at end of file diff --git a/code/nel/tools/3d/tile_edit/PIC/readpic.cpp b/code/nel/tools/3d/tile_edit/PIC/readpic.cpp deleted file mode 100644 index 8afac2b45..000000000 --- a/code/nel/tools/3d/tile_edit/PIC/readpic.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - -#include -#include -#include "readpic.h" -#include "pic.h" -#include - -using namespace std; - -//============================================================ -// Image API. -//============================================================ - - -bool PIC_LoadPic(string path, vector &tampon, uint &Width, uint &Height) -{ - uint32 id; - char *pal, *data; - unsigned long w,h,depth; - uint i; - - - // Loadons l'image. - id= PIC_Load((char*)path.c_str(), 0); - if(id==0) - return false; - PIC_GetInfos( id, &pal, &data, &w, &h, &depth); - Width=w; - Height=h; - - // On traduit en RGBA. - tampon.resize(w*h); - switch(depth) - { - case 8: - for(i=0;i -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef _READPIC_H_ -#define _READPIC_H_ - -#ifdef _MSC_VER -#pragma warning(disable:4786) -#endif - - -#include -#include - -#include -#include - -//============================================================ -// API. -//============================================================ - - -bool PIC_LoadPic(std::string Path, std::vector &Tampon, uint &Width, uint &Height); - - - -#endif \ No newline at end of file diff --git a/code/nel/tools/3d/tile_edit/View.cpp b/code/nel/tools/3d/tile_edit/View.cpp index 2ac9bdeb3..81f5fe784 100644 --- a/code/nel/tools/3d/tile_edit/View.cpp +++ b/code/nel/tools/3d/tile_edit/View.cpp @@ -24,7 +24,7 @@ #include //#include "ListGroup.h" //#include "ViewPopup.h" -#include "pic/readpic.h" +//#include "pic/readpic.h" using namespace std; using namespace NL3D; @@ -74,6 +74,37 @@ void rotateBuffer (uint &Width, uint &Height, std::vector& Tampon Height=tmp; } +static bool loadPic(const string &path, std::vector &tampon, uint &width, uint &height) +{ + try + { + NLMISC::CIFile file; + if (file.open(path.c_str())) + { + NLMISC::CBitmap bitmap; + bitmap.load(file); + width = bitmap.getWidth(); + height = bitmap.getHeight(); + tampon.resize(width * height); + bitmap.convertToType(NLMISC::CBitmap::RGBA); + for (uint y = 0; y < height; ++y) + { + for (uint x = 0; x < width; ++x) + { + NLMISC::CRGBA c = bitmap.getPixelColor(x, y, 0); + c.R = (c.R * c.A) / 255; + c.G = (c.G * c.A) / 255; + c.B = (c.B * c.A) / 255; + tampon[(y * width) + x] = c; + } + } + return true; + } + } + catch (NLMISC::Exception& ) { } + return false; +} + ///////////////////////////////////////////////////////////////////////////// // CTView //Attention : windows veut que le buffer image commence du bas vers le haut @@ -82,7 +113,7 @@ int _LoadBitmap(const std::string& path,LPBITMAPINFO BitmapInfo, std::vector Tampon; uint Width; uint Height; - if (PIC_LoadPic(path, Tampon, Width, Height)) + if (loadPic(path, Tampon, Width, Height)) { BitmapInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); BitmapInfo->bmiHeader.biWidth=Width; @@ -207,7 +238,7 @@ int TileList::setTile128 (int tile, const std::string& name, NL3D::CTile::TBitma vector tampon; uint Width; uint Height; - if (!PIC_LoadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) + if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) { return (int)(MessageBox (NULL, ((tileBank2.getAbsPath ()+troncated)+"\nContinue ?").c_str(), "Can't load bitmap.", MB_YESNO|MB_ICONEXCLAMATION)==IDYES); } @@ -272,7 +303,7 @@ int TileList::setTile256 (int tile, const std::string& name, NL3D::CTile::TBitma vector tampon; uint Width; uint Height; - if (!PIC_LoadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) + if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) { return (int)(MessageBox (NULL, ((tileBank2.getAbsPath ()+troncated)+"\nContinue ?").c_str(), "Can't load bitmap.", MB_YESNO|MB_ICONEXCLAMATION)==IDYES); } @@ -338,7 +369,7 @@ int TileList::setTileTransition (int tile, const std::string& name, NL3D::CTile: vector tampon; uint Width; uint Height; - if (!PIC_LoadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) + if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) { return (int)(MessageBox (NULL, ((tileBank2.getAbsPath ()+troncated)+"\nContinue ?").c_str(), "Can't load bitmap.", MB_YESNO|MB_ICONEXCLAMATION)==IDYES); } @@ -451,7 +482,7 @@ int TileList::setTileTransitionAlpha (int tile, const std::string& name, int rot vector tampon; uint Width; uint Height; - if (!PIC_LoadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) + if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height)) { return MessageBox (NULL, ((tileBank2.getAbsPath ()+troncated)+"\nContinue ?").c_str(), "Can't load bitmap.", MB_YESNO|MB_ICONEXCLAMATION)==IDYES; } @@ -1490,7 +1521,7 @@ LRESULT CTView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { _chdir (LastPath.c_str()); CFileDialog load(true, NULL, LastPath.c_str(), OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, - "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); + "PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); load.m_ofn.lpstrFile = new char[10000]; // buffer contains filenames list load.m_ofn.lpstrFile[0] = 0; // with 10 KB we should be large enough... From 0a765bde8cf12df6ecf49bef97c96df90c52241a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Nov 2014 16:30:14 +0100 Subject: [PATCH 142/344] Fix bug causing patch painter fail to open more than once --HG-- branch : hotfix --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 5bea65771..9df2a53f9 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -463,6 +463,7 @@ bool CDriverGL::unInit() { nlwarning("Can't unregister NLClass"); } + _Registered = 0; // Restaure monitor color parameters if (_NeedToRestaureGammaRamp) From fef6543e0c1c366a89281e8a6258038f6cd32e6f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Nov 2014 16:30:14 +0100 Subject: [PATCH 143/344] Fix bug causing patch painter fail to open more than once --HG-- branch : develop --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 5bea65771..9df2a53f9 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -463,6 +463,7 @@ bool CDriverGL::unInit() { nlwarning("Can't unregister NLClass"); } + _Registered = 0; // Restaure monitor color parameters if (_NeedToRestaureGammaRamp) From 1676b3b46ffb137a686ca204fa00854a23b0e8f2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 24 Nov 2014 14:53:28 +0100 Subject: [PATCH 144/344] Fix #218 erratic mouse behaviour --HG-- branch : hotfix --- code/ryzom/client/src/events_listener.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/ryzom/client/src/events_listener.cpp b/code/ryzom/client/src/events_listener.cpp index 89963a2ab..760a5dc08 100644 --- a/code/ryzom/client/src/events_listener.cpp +++ b/code/ryzom/client/src/events_listener.cpp @@ -184,8 +184,8 @@ void CEventsListener::operator()(const CEvent& event) } // NOTE: No 0, 0 center mouse message in Windows (lower mouse message rate), but safe to assume any movement messages are requeued relative to our new position - // In case free look bugs on other platform, we may need to push in our own message on setMousePos for Windows - if (s_MouseFreeLookWaitCenter) // scX == 0 && scY == 0) + bool outsideBounds = ((abs(scX) > (drW >> 3)) || (abs(scY) > (drH >> 3))); + if (s_MouseFreeLookWaitCenter && !outsideBounds) { // Centered, set last to 0 s_MouseFreeLookLastX = 0; @@ -204,8 +204,7 @@ void CEventsListener::operator()(const CEvent& event) // updateFreeLookPos is called in updateMouseSmoothing per frame // Center cursor - bool outsideBounds = ((abs(scX) > (drW >> 3)) || (abs(scY) > (drH >> 3))); - if (outsideBounds) + if (outsideBounds && !s_MouseFreeLookWaitCenter) { s_MouseFreeLookWaitCenter = true; Driver->setMousePos(0.5f, 0.5f); From 6b1ea30f9c2d047cd3dd163ab0bf9bf2c227556b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 24 Nov 2014 14:57:36 +0100 Subject: [PATCH 145/344] ryzomcore/v0.11.1 --HG-- branch : hotfix --- code/CMakeLists.txt | 4 ++-- .../3d/plugin_max/nel_patch_paint/nel_patch_paint.rc | 8 ++++---- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 372177889..bd36abe61 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -2,7 +2,7 @@ # # NeL # Authors: Nevrax and the NeL Community -# Version: 0.11.0 +# Version: 0.11.1 # # Notes: # * Changing install location: add -DCMAKE_INSTALL_PREFIX:PATH=/my/new/path @@ -48,7 +48,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(RyzomCore CXX C) SET(NL_VERSION_MAJOR 0) SET(NL_VERSION_MINOR 11) -SET(NL_VERSION_PATCH 0) +SET(NL_VERSION_PATCH 1) SET(NL_VERSION "${NL_VERSION_MAJOR}.${NL_VERSION_MINOR}.${NL_VERSION_PATCH}") #----------------------------------------------------------------------------- diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc index 534efb2ac..507d36ab5 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc @@ -96,8 +96,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 11, 0, 0 - PRODUCTVERSION 0, 11, 0, 0 + FILEVERSION 0, 11, 1, 0 + PRODUCTVERSION 0, 11, 1, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -116,14 +116,14 @@ BEGIN VALUE "Comments", "TECH: cyril.corvazier\0" VALUE "CompanyName", "Ryzom Core\0" VALUE "FileDescription", "NeL Patch Paint\0" - VALUE "FileVersion", "0.11.0\0" + VALUE "FileVersion", "0.11.1\0" VALUE "InternalName", "mods\0" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "nelpatchpaint.dlm\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.11.0\0" + VALUE "ProductVersion", "0.11.1\0" VALUE "SpecialBuild", "\0" END END diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index af714db4d..de4524626 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.11.0-dev" +#define RYZOM_VERSION "ryzomcore/v0.11.1" #endif // RYZOM_VERSION_H From 33c1dcc93d3a678f799fd09fc2774e2706f6e6ec Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 24 Nov 2014 15:02:00 +0100 Subject: [PATCH 146/344] Added tag ryzomcore/v0.11.1 for changeset e3fe4855f22c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 931ad2ca5..ac1525929 100644 --- a/.hgtags +++ b/.hgtags @@ -4,3 +4,4 @@ 79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1 fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0 edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0 +e3fe4855f22c3e75722e015dc33c091c340b3ad7 ryzomcore/v0.11.1 From 7bdf719cb99ca2ddde9c96c4071cb0390079661f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 24 Nov 2014 15:04:53 +0100 Subject: [PATCH 147/344] Adjust version --HG-- branch : develop --- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index de4524626..b47cff50b 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.11.1" +#define RYZOM_VERSION "ryzomcore/v0.11.1-dev" #endif // RYZOM_VERSION_H From dfe0b2977aa2952156fe99408bc2a0049f7ea7a3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 24 Nov 2014 16:07:17 +0100 Subject: [PATCH 148/344] Separate version string --HG-- branch : develop --- code/ryzom/common/src/game_share/ryzom_version.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index b47cff50b..f398c989f 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,9 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.11.1-dev" +#define RYZOM_VERSION "ryzomcore/" \ + "v0.11.1" \ + "-dev" #endif // RYZOM_VERSION_H From ff283f5070995bd2a5decfe371b39b04ee0d80b7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Dec 2014 15:16:39 +0100 Subject: [PATCH 149/344] Increase patch painter distance --HG-- branch : develop --- code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp index 3fd00f000..0f615b5ed 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp @@ -4095,7 +4095,7 @@ DWORD WINAPI myThread (LPVOID vData) // Create a Landscape. CLandscapeModel *TheLand= (CLandscapeModel*)CNELU::Scene->createModel(LandscapeModelId); - TheLand->Landscape.setTileNear (1000.f); + TheLand->Landscape.setTileNear (10000.f); TheLand->Landscape.TileBank=bank; // Enbable automatique lighting @@ -4192,7 +4192,7 @@ DWORD WINAPI myThread (LPVOID vData) mat.setPos(P); CNELU::Camera->setTransformMode (ITransformable::DirectMatrix); CNELU::Camera->setMatrix (mat); - CNELU::Camera->setPerspective( 75.f*(float)Pi/180.f/*vp->GetFOV()*/, 1.33f, 0.1f, 1000.f); + CNELU::Camera->setPerspective( 75.f*(float)Pi/180.f/*vp->GetFOV()*/, 1.33f, 0.1f, 10000.f); // Resize the sym vector symVector.resize (pData->VectMesh.size()); From 39c776ec30731e151d3d9231ef227d34c242ad32 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Dec 2014 15:16:39 +0100 Subject: [PATCH 150/344] Add script to orient zone patches automatically --HG-- branch : develop --- .../plugin_max/nel_patch_converter/script.cpp | 30 +++++ .../3d/plugin_max/nel_patch_edit/editpat.h | 1 + .../tools/3d/plugin_max/nel_patch_edit/np.cpp | 89 +++++++++++++++ .../nel_patch_edit/np_epm_selection.cpp | 44 +++++++ .../3d/plugin_max/scripts/nel_orient_zones.ms | 108 ++++++++++++++++++ 5 files changed, 272 insertions(+) create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp index 8acae94bd..80e715f21 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp @@ -338,6 +338,8 @@ get_selected_tile_cf(Value** arg_list, int count) if (tri->rpatch->tileSel[i]) array->append(Integer::intern(i+1)); } + if (os.obj != tri) + delete tri; } } @@ -383,6 +385,8 @@ get_selected_patch_cf(Value** arg_list, int count) if (tri->patch.patchSel[i]) array->append(Integer::intern(i+1)); } + if (os.obj != tri) + delete tri; } } @@ -428,6 +432,8 @@ get_selected_vertex_cf(Value** arg_list, int count) if (tri->patch.vertSel[i]) array->append(Integer::intern(i+1)); } + if (os.obj != tri) + delete tri; } } @@ -617,6 +623,8 @@ set_vertex_count_cf(Value** arg_list, int count) { nRet=tri->patch.numVerts; } + if (os.obj != tri) + delete tri; } return Integer::intern(nRet); @@ -655,6 +663,8 @@ set_vector_count_cf(Value** arg_list, int count) { nRet=tri->patch.numVecs; } + if (os.obj != tri) + delete tri; } return Integer::intern(nRet); @@ -702,6 +712,8 @@ set_vertex_pos_cf(Value** arg_list, int count) node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } + if (os.obj != tri) + delete tri; } } @@ -750,6 +762,8 @@ set_vector_pos_cf(Value** arg_list, int count) node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } + if (os.obj != tri) + delete tri; } } @@ -792,6 +806,8 @@ get_vertex_pos_cf(Value** arg_list, int count) { vRet=new Point3Value (tri->patch.verts[nVertex].p); } + if (os.obj != tri) + delete tri; } } @@ -834,6 +850,8 @@ get_vector_pos_cf(Value** arg_list, int count) { vRet=new Point3Value (tri->patch.vecs[nVertex].p); } + if (os.obj != tri) + delete tri; } } @@ -877,6 +895,8 @@ get_edge_vect1_cf(Value** arg_list, int count) { nVert=tri->patch.edges[nEdge].vec12; } + if (os.obj != tri) + delete tri; } } @@ -919,6 +939,8 @@ get_edge_vect2_cf(Value** arg_list, int count) { nVert=tri->patch.edges[nEdge].vec21; } + if (os.obj != tri) + delete tri; } } @@ -961,6 +983,8 @@ get_edge_vert1_cf(Value** arg_list, int count) { nVert=tri->patch.edges[nEdge].v1; } + if (os.obj != tri) + delete tri; } } @@ -1004,6 +1028,8 @@ get_edge_vert2_cf(Value** arg_list, int count) { nVert=tri->patch.edges[nEdge].v2; } + if (os.obj != tri) + delete tri; } } @@ -1050,6 +1076,8 @@ get_sel_edge_cf(Value** arg_list, int count) array->append(Integer::intern(i+1)); //array->data[j++]=; } + if (os.obj != tri) + delete tri; } } @@ -1158,6 +1186,8 @@ set_tile_steps_cf(Value** arg_list, int count) nTess=5; tri->rpatch->rTess.TileTesselLevel=nTess; tri->rpatch->InvalidateChannels (PART_ALL); + if (os.obj != tri) + delete tri; } if (bRet) { diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h b/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h index d0bfd1773..ec8947571 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h @@ -755,6 +755,7 @@ class EditPatchMod : public Modifier, IPatchOps, IPatchSelect, ISubMtlAPI, Attac TCHAR *GetObjectName() { return GetString(IDS_TH_EDITPATCH); } void ActivateSubobjSel(int level, XFormModes& modes ); int NeedUseSubselButton() { return 0; } + void SelectSubPatch(int index); void SelectSubComponent( HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert ); void ClearSelection(int selLevel); void SelectAll(int selLevel); diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/np.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/np.cpp index 7b1c9c644..133d0b4d6 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/np.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/np.cpp @@ -84,6 +84,31 @@ *> Copyright(c) 1994, All Rights Reserved. **********************************************************************/ #include "stdafx.h" + +#if MAX_VERSION_MAJOR >= 14 +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +// Various MAX and MXS includes +# include +# include +# include +# include +# include +# include +// define the new primitives using macros from SDK +# include +#endif + #include "editpat.h" #include "../nel_patch_lib/vertex_neighborhood.h" @@ -855,3 +880,67 @@ void ResetVert (PatchMesh *patch) patch->computeInteriors(); patch->InvalidateGeomCache (); } + +def_visible_primitive(turn_patch, "RykolTurnPatch"); + +Value *turn_patch_cf (Value** arg_list, int count) +{ + // Make sure we have the correct number of arguments (2) + check_arg_count(RykolTurnPatch, 3, count); + + // Check to see if the arguments match up to what we expect + // We want to use 'TurnAllTexturesOn ' + type_check(arg_list[0], MAXNode, "RykolTurnPatch [Node] [Modifier] [Patch]"); + type_check(arg_list[1], MAXModifier, "RykolTurnPatch [Node] [Modifier] [Patch]"); + type_check(arg_list[2], Integer, "RykolTurnPatch [Node] [Modifier] [Patch]"); + + // Get a good interface pointer + Interface *ip = MAXScript_interface; + + // Get a INode pointer from the argument passed to us + INode *node = arg_list[0]->to_node(); + nlassert (node); + + // Get a Object pointer + ObjectState os = node->EvalWorldState(ip->GetTime()); + + // ok ? + bool bRet=false; + + if (os.obj) + { + // Get class id + if (os.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID)) + { + bRet = true; + RPO *tri = (RPO *)os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); + if (tri) + { + Modifier *mod = arg_list[1]->to_modifier(); + if (mod) + { + EditPatchMod *epmod = (EditPatchMod *)mod; + epmod->ClearSelection(EP_PATCH); + epmod->SelectSubPatch(arg_list[2]->to_int() - 1); + epmod->DoPatchTurn(true); + epmod->ClearSelection(EP_PATCH); + } + else + { + bRet = false; + } + } + // Note that the TriObject should only be deleted + // if the pointer to it is not equal to the object + // pointer that called ConvertToType() + if (os.obj != tri) + delete tri; + + // redraw and update + node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); + ip->RedrawViews(ip->GetTime()); + } + } + + return bRet?&true_value:&false_value; +} \ No newline at end of file diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_selection.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_selection.cpp index 3814a2df9..0b15b63e7 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_selection.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_selection.cpp @@ -236,6 +236,50 @@ void EditPatchMod::SetSelLevel(DWORD level) // ------------------------------------------------------------------------------------------------------------------------------------------------------ +void EditPatchMod::SelectSubPatch(int index) +{ + if (!ip) + return; + TimeValue t = ip->GetTime(); + + ip->ClearCurNamedSelSet(); + + ModContextList mcList; + INodeTab nodes; + ip->GetModContexts(mcList, nodes); + + for (int i = 0; i < mcList.Count(); i++) + { + EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; + + if (!patchData) + return; + + RPatchMesh *rpatch; + PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch); + if (!patch) + return; + + patchData->BeginEdit(t); + if (theHold.Holding()) + theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "SelectSubComponent")); + + patch->patchSel.Set(index); + + patchData->UpdateChanges(patch, rpatch, FALSE); + if (patchData->tempData) + { + patchData->tempData->Invalidate(PART_SELECT); + } + } + PatchSelChanged(); + + UpdateSelectDisplay(); + NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE); +} + +// ------------------------------------------------------------------------------------------------------------------------------------------------------ + // Select a subcomponent within our object(s). WARNING! Because the HitRecord list can // indicate any of the objects contained within the group of patches being edited, we need // to watch for control breaks in the patchData pointer within the HitRecord! diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms b/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms new file mode 100644 index 000000000..fb5ba2862 --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms @@ -0,0 +1,108 @@ + +gc() +nodes = getCurrentSelection() +max select none +clearselection() + +undo off +( + for cnode in nodes do + ( + if (classof cnode) == Editable_Patch or (classof cnode) == RklPatch then + ( + print cnode.name + selectmore cnode + if (classof cnode) == Editable_Patch and (classof cnode) != RklPatch then + ( + modPanel.addModToSelection (NeL_Convert ()) ui:on + ) + modPanel.addModToSelection (NeL_Edit ()) ui:on + setCommandPanelTaskMode #modify + cmod = modpanel.getCurrentObject() + pcount = (GetRykolPatchCount cnode) + print pcount + for p = 1 to pcount do + ( + --print p + vbegin = (NeLGetPatchVertex cnode p 1) + vend = (NeLGetPatchVertex cnode p 2) + vref = (NeLGetPatchVertex cnode p 3) + begin = (GetRykolVertexPos cnode vbegin) + end = (GetRykolVertexPos cnode vend) + ref = (GetRykolVertexPos cnode vref) + normal = (cross (end - begin) (ref - begin)) + normal = (normalize normal) + + rotnormal = (normal * (rotateZMatrix -90)) + if (normal.z > 0.9) then + ( + -- print "x normal" + rotnormal = (normal * (rotateXMatrix -90)) + ) + -- print rotnormal + + -- print normal + -- print rotnormal + -- print begin + -- print end + dir = (normalize (end - begin)) + -- print dir + score1 = (dot dir rotnormal) + + RykolTurnPatch cnode cmod (p) + vbegin = (NeLGetPatchVertex cnode p 1) + vend = (NeLGetPatchVertex cnode p 2) + begin = (GetRykolVertexPos cnode vbegin) + end = (GetRykolVertexPos cnode vend) + dir = (normalize (end - begin)) + score2 = (dot dir rotnormal) + + RykolTurnPatch cnode cmod (p) + vbegin = (NeLGetPatchVertex cnode p 1) + vend = (NeLGetPatchVertex cnode p 2) + begin = (GetRykolVertexPos cnode vbegin) + end = (GetRykolVertexPos cnode vend) + dir = (normalize (end - begin)) + score3 = (dot dir rotnormal) + + RykolTurnPatch cnode cmod (p) + vbegin = (NeLGetPatchVertex cnode p 1) + vend = (NeLGetPatchVertex cnode p 2) + begin = (GetRykolVertexPos cnode vbegin) + end = (GetRykolVertexPos cnode vend) + dir = (normalize (end - begin)) + score4 = (dot dir rotnormal) + + -- print score1 + -- print score2 + -- print score3 + -- print score4 + + if (score1 > score2 and score1 > score3 and score1 > score4) then + ( + -- print "score 1" + RykolTurnPatch cnode cmod (p) + ) + else if (score2 > score3 and score2 > score4) then + ( + -- print "score 2" + RykolTurnPatch cnode cmod (p) + RykolTurnPatch cnode cmod (p) + ) + else if (score3 > score4) then + ( + -- print "score 3" + RykolTurnPatch cnode cmod (p) + RykolTurnPatch cnode cmod (p) + RykolTurnPatch cnode cmod (p) + ) + else + ( + -- print "score 4" + ) + ) + maxOps.CollapseNode cnode off + max select none + ) + ) +) From 59a5cb7e6b8fa865880ae9add66dca3c97da3487 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Dec 2014 13:21:12 +0100 Subject: [PATCH 151/344] Fix crash with patch mesh attach --HG-- branch : hotfix --- code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_attach.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_attach.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_attach.cpp index 64a3296f0..d2843df1c 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_attach.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_attach.cpp @@ -37,7 +37,6 @@ int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPat nodes.DisposeTemporary(); return 0; } - patchData->BeginEdit(ip->GetTime()); // If the mesh isn't yet cached, this will cause it to get cached. RPatchMesh *rpatch; @@ -49,6 +48,7 @@ int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPat } patchData->RecordTopologyTags(patch); RecordTopologyTags(); + patchData->BeginEdit(ip->GetTime()); // Transform the shape for attachment: // If reorienting, just translate to align pivots From 90f1234ed028d0b6a5f6ad4377b4728e2b26af50 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Dec 2014 13:21:45 +0100 Subject: [PATCH 152/344] Add key in patch painter to reset a patch mesh --HG-- branch : develop --- .../3d/plugin_max/nel_patch_paint/keys.cfg | 1 + .../3d/plugin_max/nel_patch_paint/paint.cpp | 34 +++++++++++++++++-- .../plugin_max/nel_patch_paint/paint_ui.cpp | 2 ++ .../3d/plugin_max/nel_patch_paint/paint_ui.h | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/keys.cfg b/code/nel/tools/3d/plugin_max/nel_patch_paint/keys.cfg index a94996500..4f1013dae 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/keys.cfg +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/keys.cfg @@ -176,6 +176,7 @@ LockBorders = KeyL; ZoomIn = Key1; ZoomOut = Key2; GetState = Key3; +ResetPatch = KeyF10; /*************** *This is the the light settings diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp index 0f615b5ed..fb99978da 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp @@ -145,7 +145,7 @@ std::vector symVector; // Painter modes enum TModePaint { ModeTile, ModeColor, ModeDisplace}; -enum TModeMouse { ModePaint, ModeSelect, ModePick, ModeFill, ModeGetState }; +enum TModeMouse { ModePaint, ModeSelect, ModePick, ModeFill, ModeGetState, ModeResetPatch }; /*-------------------------------------------------------------------*/ @@ -2585,6 +2585,13 @@ void mainproc(CScene& scene, CEventListenerAsync& AsyncListener, CEvent3dMouseLi // Set mode modeSelect=ModeGetState; + // Mode reset zone + if (AsyncListener.isKeyDown ((TKey)PainterKeys[ResetPatch])) + { + // Set mode + modeSelect=ModeResetPatch; + } + // Mode picking if (AsyncListener.isKeyDown ((TKey)PainterKeys[Fill0])) { @@ -2891,6 +2898,8 @@ void mainproc(CScene& scene, CEventListenerAsync& AsyncListener, CEvent3dMouseLi SetCursor (bankCont->HFill); else if (pData->pobj->TileTrick) SetCursor (bankCont->HTrick); + else if (modeSelect==ModeResetPatch) + SetCursor (LoadCursor (NULL, IDC_NO)); else SetCursor (LoadCursor (NULL, IDC_ARROW)); @@ -3140,9 +3149,30 @@ private: _FillTile.fillColor (mesh1, patch, _VectMesh, maxToNel (color1), (uint16)(256.f*opa1), PaintColor); else if (nModeTexture==ModeDisplace) - // Fill this patch with the current color + // Fill this patch with the current displace _FillTile.fillDisplace (mesh1, patch, _VectMesh, bank); } + else if (modeSelect==ModeResetPatch) + { + int np = _VectMesh[mesh1].PMesh->numPatches; + for (int pp = 0; pp < np; ++pp) + { + // Fill default tile + _FillTile.fillTile (mesh1, pp, _VectMesh, -1, 0, 0, true, bank); + + // Fill default color + _FillTile.fillColor (mesh1, pp, _VectMesh, CRGBA(255, 255, 255), 256, PaintColor); + + // Backup current displace, fill default, restore + int bkdt = _Pobj->DisplaceTile; + int bkdts = _Pobj->DisplaceTileSet; + _Pobj->DisplaceTile = 0; + _Pobj->DisplaceTileSet = -1; + _FillTile.fillDisplace (mesh1, pp, _VectMesh, bank); + _Pobj->DisplaceTile = bkdt; + _Pobj->DisplaceTileSet = bkdts; + } + } } } // Pick with right mouse diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp index 1c756e0c8..b8503c137 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp @@ -43,6 +43,7 @@ uint PainterKeys[KeyCounter]= Key1, Key2, KeyI, + KeyF10, }; // Keys @@ -77,6 +78,7 @@ const char* PainterKeysName[KeyCounter]= "ZoomIn", "ZoomOut", "GetState", + "ResetPatch", }; // Light settings diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.h b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.h index aa56b06ba..13d1708ef 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.h +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.h @@ -122,6 +122,7 @@ enum PainterKeysType ZoomIn, ZoomOut, GetState, + ResetPatch, KeyCounter }; From 07286c14d19d846891d8f05ea893a93fb526ac17 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Dec 2014 13:28:30 +0100 Subject: [PATCH 153/344] Adjust patch orientation script --HG-- branch : develop --- .../3d/plugin_max/scripts/nel_orient_zones.ms | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms b/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms index fb5ba2862..26fd67171 100644 --- a/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms +++ b/code/nel/tools/3d/plugin_max/scripts/nel_orient_zones.ms @@ -33,13 +33,19 @@ undo off normal = (cross (end - begin) (ref - begin)) normal = (normalize normal) - rotnormal = (normal * (rotateZMatrix -90)) + rotnormal = (point3 0 0 0) if (normal.z > 0.9) then ( - -- print "x normal" + --print "x normal" rotnormal = (normal * (rotateXMatrix -90)) ) - -- print rotnormal + else + ( + normal.z = 0 + normal = (normalize normal) + rotnormal = (normal * (rotateZMatrix -90)) + ) + --print rotnormal -- print normal -- print rotnormal @@ -106,3 +112,13 @@ undo off ) ) ) + +max select none +clearselection() +undo off +( + for cnode in nodes do + ( + selectmore cnode + ) +) From a79e1411939e2bf123942d150299734d7dac8a23 Mon Sep 17 00:00:00 2001 From: botanicvelious Date: Sun, 7 Dec 2014 05:01:05 -0800 Subject: [PATCH 154/344] Update with added Domain_Auto_Add settings --HG-- branch : develop --- code/web/private_php/setup/sql/nel_ams_lib_00007.sql | 2 ++ code/web/public_php/setup/database.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 code/web/private_php/setup/sql/nel_ams_lib_00007.sql diff --git a/code/web/private_php/setup/sql/nel_ams_lib_00007.sql b/code/web/private_php/setup/sql/nel_ams_lib_00007.sql new file mode 100644 index 000000000..748793e66 --- /dev/null +++ b/code/web/private_php/setup/sql/nel_ams_lib_00007.sql @@ -0,0 +1,2 @@ +INSERT INTO `settings` (`idSettings`, `Setting`, `Value`) VALUES +(2, 'Domain_Auto_Add', '1'); \ No newline at end of file diff --git a/code/web/public_php/setup/database.php b/code/web/public_php/setup/database.php index 3e195f2b8..6137cb00f 100644 --- a/code/web/public_php/setup/database.php +++ b/code/web/public_php/setup/database.php @@ -6,7 +6,7 @@ $db_nel_tool = 2; // Support $db_nel_ams = 2; -$db_nel_ams_lib = 6; +$db_nel_ams_lib = 7; // Domain $db_ring_domain = 1; From 1df52a45ad68db3ecfd49d2a98fabbac35500495 Mon Sep 17 00:00:00 2001 From: botanicvelious Date: Sun, 7 Dec 2014 06:42:57 -0800 Subject: [PATCH 155/344] add some additional checking for database errors --HG-- branch : develop --- code/web/private_php/ams/autoload/ticket_user.php | 14 ++++++++++++-- code/web/public_php/setup/install.php | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/code/web/private_php/ams/autoload/ticket_user.php b/code/web/private_php/ams/autoload/ticket_user.php index 6de69ccdd..a52ffaec8 100644 --- a/code/web/private_php/ams/autoload/ticket_user.php +++ b/code/web/private_php/ams/autoload/ticket_user.php @@ -20,8 +20,18 @@ class Ticket_User{ * @param $permission the permission that will be given to the user. 1=user, 2=mod, 3=admin */ public static function createTicketUser( $extern_id, $permission) { - $dbl = new DBLayer("lib"); - $dbl->insert("ticket_user",array('TUserId' => $extern_id, 'Permission' => $permission, 'ExternId' => $extern_id)); + try { + //make connection with and put into db + $dbl = new DBLayer("lib"); + $dbl->insert("ticket_user",array('TUserId' => $extern_id, 'Permission' => $permission, 'ExternId' => $extern_id)); + } + catch (PDOException $e) { + //oh noooz... + //error_log(print_r($e, true)); + //print_r($e); + echo "Problem creating user in database!"; + } + } diff --git a/code/web/public_php/setup/install.php b/code/web/public_php/setup/install.php index 49fc0b3a7..438a5c332 100644 --- a/code/web/public_php/setup/install.php +++ b/code/web/public_php/setup/install.php @@ -42,6 +42,20 @@ require_once('setup/version.php'); $continue = false; } } + + if ($continue) { + try { + if (!in_array("mysql",PDO::getAvailableDrivers(),TRUE)) + { + throw new PDOException ("Cannot work without a proper database setting up"); + } + } + catch (PDOException $pdoEx) + { + printalert("danger", "PHP PDO seems to be missing the mysql driver"); + $continue = false; + } + } // Validate basics if ($continue) { From 56339c6f936d1b07076fec86966e72cee7eb085a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 9 Dec 2014 23:06:07 +0100 Subject: [PATCH 156/344] Handle window close message in painter --HG-- branch : develop --- code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp index fb99978da..73bb142b1 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp @@ -3043,7 +3043,7 @@ private: // Callback on mouse events virtual void operator ()(const CEvent& event) { - if (event==EventDestroyWindowId) + if (event==EventDestroyWindowId || event==EventCloseWindowId) { WindowActive=false; } @@ -4287,6 +4287,7 @@ DWORD WINAPI myThread (LPVOID vData) CNELU::EventServer.addListener (EventMouseUpId, &listener); CNELU::EventServer.addListener (EventMouseDblClkId, &listener); CNELU::EventServer.addListener (EventDestroyWindowId, &listener); + CNELU::EventServer.addListener (EventCloseWindowId, &listener); CNELU::EventServer.addListener (EventKeyDownId, &listener); // Camera position @@ -4356,6 +4357,7 @@ DWORD WINAPI myThread (LPVOID vData) CNELU::EventServer.removeListener (EventMouseDblClkId, &listener); CNELU::EventServer.removeListener (EventKeyDownId, &listener); CNELU::EventServer.removeListener (EventDestroyWindowId, &listener); + CNELU::EventServer.removeListener (EventCloseWindowId, &listener); // End. //======== From 6db29c375aacac39509ee393846367016e587110 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 9 Dec 2014 23:06:07 +0100 Subject: [PATCH 157/344] Add script to generate zone names --HG-- branch : develop --- .../3d/plugin_max/scripts/nel_zone_namer.ms | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_zone_namer.ms diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_zone_namer.ms b/code/nel/tools/3d/plugin_max/scripts/nel_zone_namer.ms new file mode 100644 index 000000000..e651dd76a --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_zone_namer.ms @@ -0,0 +1,68 @@ +-- This script sets proper centered zone positions and generates their names +-- Use after cutting the zone into 160m by 160m pieces + +cell_size = 160.0 +offset_x = 7680 / 2 +offset_y = -(20480 + (5120 / 2)) + +alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +-- http://proofofprogress.blogspot.be/2011/03/solution-align-pivot-to-world-without.html +Function alignPivotToWorld &theObject = ( + --VLM = Visible Local Matrix. + --The matrix/pivot you see when selecting object and "Local" axis is selected as viewable. + VLM = theObject.Transform; + IP_LocalRot = theObject.objectOffsetRot; --Rotation to be used later. + IP_LOCAL = theObject.objectOffsetPos; --Invisible Pivot Local coordinates + --In relation to VLM matrix. + IP_WORLD = IP_LOCAL * VLM; --World Coordinates of Invisible Pivot. [Local To World Transform] + VLM_0 = matrix3 1; --Reset Visible Local matrix coordinates. + + NEW_IP_LOCAL = IP_WORLD * inverse(VLM_0); --[World To local Transform] + + theObject.Transform = VLM_0; + theObject.objectOffsetPos = NEW_IP_LOCAL; + + --Now Handle Rotation: + --Since rotation of visible local matrix has been zeroed out, + --You must add that loss to the invisible pivot rotation. + GeomWorldRot = VLM.RotationPart + IP_LocalRot; + theObject.objectOffsetRot = GeomWorldRot; +) + +-- Convert a coordinate in a name +-- name = coordToName #(x, y) +fn coordToName coord = +( + up = floor(coord[1] / 26) + 1 + down = floor(coord[1] - ((up-1) * 26)) + 1 + return (((-coord[2] + 1) as integer) as string) + "_" + alphabet[up] + alphabet[down] +) + +fn realCoordToName coord = +( + return coordToName(#(((coord[1] + offset_x) / cell_size) + 0.5, ((coord[2] + offset_y) / cell_size) + 0.5)) +) + +fn roundedCoord coord = +( + return #(ceil(coord[1] / cell_size) * cell_size - (cell_size / 2), ceil(coord[2] / cell_size) * cell_size - (cell_size / 2)) +) + +max select none +clearselection() + +for node in geometry do +( + if (classof node) == RklPatch or (classof node) == Editable_Patch then + ( + newcoords = roundedCoord(#(node.center.x, node.center.y)) + newname = realCoordToName(newcoords) + node.name = newname + alignPivotToWorld &node + node.pivot.x = newcoords[1] + node.pivot.y = newcoords[2] + resetxform node + maxOps.CollapseNode node off + ) +) From 58590a9e7e1912b7bc33a48fd5cfbb56463c16e7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 9 Dec 2014 23:06:08 +0100 Subject: [PATCH 158/344] Fix offscreen rendering mode --HG-- branch : develop --- .../3d/driver/opengl/driver_opengl_window.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 9df2a53f9..8307f885e 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -627,9 +627,11 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re // Offscreen mode ? if (_CurrentMode.OffScreen) { -#if 0 if (!createWindow(mode)) return false; + HWND tmpHWND = _win; + int width = mode.Width; + int height = mode.Height; // resize the window RECT rc; @@ -908,7 +910,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re _hDC = NULL; return false; } -#endif } else { @@ -1437,8 +1438,17 @@ bool CDriverGL::createWindow(const GfxMode &mode) #ifdef NL_OS_WINDOWS // create the OpenGL window - window = CreateWindowW(L"NLClass", L"NeL Window", WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, - CW_USEDEFAULT, CW_USEDEFAULT, mode.Width, mode.Height, HWND_DESKTOP, NULL, GetModuleHandle(NULL), NULL); + DWORD dwStyle = WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS; + int pos = CW_USEDEFAULT; + HWND hwndParent = HWND_DESKTOP; + if (mode.OffScreen) + { + dwStyle &= ~WS_VISIBLE; + pos = 0; + hwndParent = NULL; + } + window = CreateWindowW(L"NLClass", L"NeL Window", dwStyle, + pos, pos, mode.Width, mode.Height, hwndParent, NULL, GetModuleHandle(NULL), NULL); if (window == EmptyWindow) { From 4c4b96bcfd6720d22c210aaf150f073891e35597 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 9 Dec 2014 23:06:08 +0100 Subject: [PATCH 159/344] Fix NeLLigoMakeSnapShot --HG-- branch : develop --- code/nel/tools/3d/ligo/plugin_max/script.cpp | 33 +++++++++++--------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/code/nel/tools/3d/ligo/plugin_max/script.cpp b/code/nel/tools/3d/ligo/plugin_max/script.cpp index 41740bcbe..8a88136c5 100644 --- a/code/nel/tools/3d/ligo/plugin_max/script.cpp +++ b/code/nel/tools/3d/ligo/plugin_max/script.cpp @@ -1739,14 +1739,14 @@ bool MakeSnapShot (NLMISC::CBitmap &snapshot, const NL3D::CTileBank &tileBank, c float posY = config.CellSize * (float)ymin; // Use NELU - if (CNELU::init (oversampledWidth, oversampledHeight, CViewport(), 32, true, NULL, true)) + if (CNELU::init (oversampledWidth, oversampledHeight, CViewport(), 32, true, NULL, false, true)) // FIXME: OpenGL not working correctly, offscreen not available in Direct3D { // Setup the camera CNELU::Camera->setTransformMode (ITransformable::DirectMatrix); CMatrix view; view.setPos (CVector (width/2 + posX, height/2 + posY, width)); view.setRot (CVector::I, -CVector::K, CVector::J); - CNELU::Camera->setFrustum (width, height, 0.1f, 1000.f, false); + CNELU::Camera->setFrustum (width, height, 0.1f, 10000.f, false); CNELU::Camera->setMatrix (view); // Create a Landscape. @@ -1766,12 +1766,17 @@ bool MakeSnapShot (NLMISC::CBitmap &snapshot, const NL3D::CTileBank &tileBank, c theLand->enableAdditive (true); theLand->Landscape.setRefineMode (true); + // theLand->Landscape.setupStaticLight(CRGBA(255, 255, 255), CRGBA(0, 0, 0), 1.0f); + // theLand->Landscape.setThreshold(0.0005); + // Enbable automatique lighting #ifndef NL_DEBUG - theLand->Landscape.enableAutomaticLighting (true); - theLand->Landscape.setupAutomaticLightDir (CVector (0, 0, -1)); + // theLand->Landscape.enableAutomaticLighting (true); + // theLand->Landscape.setupAutomaticLightDir (CVector (0, 0, -1)); #endif // NL_DEBUG + // theLand->Landscape.updateLightingAll(); + // Clear the backbuffer and the alpha CNELU::clearBuffers(CRGBA(255,0,255,0)); @@ -1851,7 +1856,7 @@ bool MakeSnapShot (NLMISC::CBitmap &snapshot, const NL3D::CTileBank &tileBank, c Value* make_snapshot_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (7) - check_arg_count(check_zone_with_template, 7, count); + check_arg_count(NeLLigoMakeSnapShot, 7, count); // Check to see if the arguments match up to what we expect char *message = "NeLLigoMakeSnapShot [Object] [Snapshot filename] [xMin] [xMax] [yMin] [yMax] [Error in dialog]"; @@ -1903,11 +1908,11 @@ Value* make_snapshot_cf (Value** arg_list, int count) else { // Build a filename - char drive[512]; - char path[512]; - char name[512]; - char ext[512]; - _splitpath (fileName.c_str(), drive, path, name, ext); + char drivetga[512]; + char pathtga[512]; + char nametga[512]; + char exttga[512]; + _splitpath (fileName.c_str(), drivetga, pathtga, nametga, exttga); // Build the zone CZone zone; @@ -1970,7 +1975,7 @@ Value* make_snapshot_cf (Value** arg_list, int count) { // Build the snap shot filename char outputFilenameSnapShot[512]; - _makepath (outputFilenameSnapShot, drive, path, name, ".tga"); + _makepath (outputFilenameSnapShot, drivetga, pathtga, nametga, ".tga"); // Output the snap shot COFile outputSnapShot; @@ -2011,10 +2016,10 @@ Value* make_snapshot_cf (Value** arg_list, int count) // Write the zone COFile outputLigoZone; - _makepath (outputFilenameSnapShot, drive, path, name, ".ligozone"); + _makepath (outputFilenameSnapShot, drivetga, pathtga, nametga, ".ligozone"); // Catch exception - try + /*try { // Open the selected zone file if (outputLigoZone.open (outputFilenameSnapShot)) @@ -2043,7 +2048,7 @@ Value* make_snapshot_cf (Value** arg_list, int count) char tmp[512]; smprintf (tmp, 512, "Error while loading the file %s : %s", fileName, e.what()); CMaxToLigo::errorMessage (tmp, "NeL Ligo export zone", *MAXScript_interface, errorInDialog); - } + }*/ } else { From da166c81db73e95b7561b0604a732026c22ec59c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 9 Dec 2014 23:06:08 +0100 Subject: [PATCH 160/344] Add zone snapshot script example --HG-- branch : develop --- .../plugin_max/scripts/nel_zone_snapshot.ms | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_zone_snapshot.ms diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_zone_snapshot.ms b/code/nel/tools/3d/plugin_max/scripts/nel_zone_snapshot.ms new file mode 100644 index 000000000..edab4f35d --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_zone_snapshot.ms @@ -0,0 +1,162 @@ +-- Use to take the snapshots of a large manually created zone + +from_x = 160 +size_x = 7680-320 +from_y = -25600+160 +size_y = 5120-320 + +targetdir = "W:/database/landscape/ligo/asteroids/max" +snapshotdir = "W:/database/landscape/ligo/asteroids/zonebitmaps" +zonename = "anne" +resumeonly = true + +cell_size = 160.0 + +alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +fn lowercase instring = -- beginning of function definition +( + local upper, lower, outstring -- declare variables as local + upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- set variables to literals + lower="abcdefghijklmnopqrstuvwxyz" + outstring=copy instring + for i=1 to outstring.count do + ( + j=findString upper outstring[i] + if (j != undefined) do outstring[i]=lower[j] + ) + return outstring -- value of outstring will be returned as function result +) + +fn existFile fname = (getfiles fname).count != 0 + +-- Convert a coordinate in a name +-- name = coordToName #(x, y) +fn coordToName coord = +( + up = floor(coord[1] / 26) + 1 + down = floor(coord[1] - ((up-1) * 26)) + 1 + return (((-coord[2] + 1) as integer) as string) + "_" + alphabet[up] + alphabet[down] +) + +fn roundedCoord coord = +( + return #(ceil(coord[1] / cell_size) * cell_size - (cell_size / 2), ceil(coord[2] / cell_size) * cell_size - (cell_size / 2)) +) + +fn coordId coord = +( + coordr = (roundedCoord coord) + return #(((coordr[1]) / cell_size) + 0.5, ((coordr[2]) / cell_size) + 0.5) +) + +from_coord = (coordId #(from_x, from_y)) +to_coord = (coordId #(from_x + size_x, from_y + size_y)) + +print from_coord +print to_coord + +print (coordToName from_coord) + +undo off +( + for x=from_coord[1] to to_coord[1] do + ( + for y=from_coord[2] to to_coord[2] do + ( + ny=y+1 + sy=y-1 + ex=x+1 + wx=x-1 + zc = coordToName #(x, y) + zn = coordToName #(x, ny) + zne = coordToName #(ex, ny) + ze = coordToName #(ex, y) + zse = coordToName #(ex, sy) + zs = coordToName #(x, sy) + zsw = coordToName #(wx, sy) + zw = coordToName #(wx, y) + znw = coordToName #(wx, ny) + maxc = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zc) + ".max" + csnapfile = snapshotdir + "/" + zonename + "-" + (lowercase zc) + ".tga" + if existFile maxc and (not resumeonly or not (existFile csnapfile)) then + ( + print zc + resetMAXFile #noprompt + gc() + mergeMAXFile maxc #(zc) + ccenter = getnodebyname zc + maxn = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zn) + ".max" + if existFile maxn then + ( + mergeMAXFile maxn #(zn) + cnode = getnodebyname zn + cnode.position.y = cnode.position.y + 160 + NeLAttachPatchMesh cnode ccenter + ) + maxne = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zne) + ".max" + if existFile maxne then + ( + mergeMAXFile maxne #(zne) + cnode = getnodebyname zne + cnode.position.x = cnode.position.x + 160 + cnode.position.y = cnode.position.y + 160 + NeLAttachPatchMesh cnode ccenter + ) + maxe = targetdir + "/zonematerial-" + zonename + "-" + (lowercase ze) + ".max" + if existFile maxe then + ( + mergeMAXFile maxe #(ze) + cnode = getnodebyname ze + cnode.position.x = cnode.position.x + 160 + NeLAttachPatchMesh cnode ccenter + ) + maxse = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zse) + ".max" + if existFile maxse then + ( + mergeMAXFile maxse #(zse) + cnode = getnodebyname zse + cnode.position.x = cnode.position.x + 160 + cnode.position.y = cnode.position.y - 160 + NeLAttachPatchMesh cnode ccenter + ) + maxs = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zs) + ".max" + if existFile maxs then + ( + mergeMAXFile maxs #(zs) + cnode = getnodebyname zs + cnode.position.y = cnode.position.y - 160 + NeLAttachPatchMesh cnode ccenter + ) + maxsw = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zsw) + ".max" + if existFile maxsw then + ( + mergeMAXFile maxsw #(zsw) + cnode = getnodebyname zsw + cnode.position.x = cnode.position.x - 160 + cnode.position.y = cnode.position.y - 160 + --NeLAttachPatchMesh cnode ccenter + ) + maxw = targetdir + "/zonematerial-" + zonename + "-" + (lowercase zw) + ".max" + if existFile maxw then + ( + mergeMAXFile maxw #(zw) + cnode = getnodebyname zw + cnode.position.x = cnode.position.x - 160 + NeLAttachPatchMesh cnode ccenter + ) + maxnw = targetdir + "/zonematerial-" + zonename + "-" + (lowercase znw) + ".max" + if existFile maxnw then + ( + mergeMAXFile maxnw #(znw) + cnode = getnodebyname znw + cnode.position.x = cnode.position.x - 160 + cnode.position.y = cnode.position.y + 160 + NeLAttachPatchMesh cnode ccenter + ) + NeLWeldPatchMesh ccenter 1.0 + NeLLigoMakeSnapShot ccenter csnapfile 0 1 0 1 false + ) + ) + ) +) From f411d2b2302dc44d5558c2346ece42ba55f60bfb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 01:22:18 +0100 Subject: [PATCH 161/344] Fix choppy sky animation --HG-- branch : develop --- code/ryzom/client/src/main_loop_debug.cpp | 3 +++ code/ryzom/client/src/sky.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp index 19ea38414..992325c54 100644 --- a/code/ryzom/client/src/main_loop_debug.cpp +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -371,6 +371,9 @@ void displayDebug() // Current GameCycle TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick()); line += lineStep; + // Smoothed Client Date + TextContext->printfAt(1.f, line, "Smoothed Client Date : %u %f", SmoothedClientDate.Day, SmoothedClientDate.Hour); + line += lineStep; // Packet Loss TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f); line += lineStep; diff --git a/code/ryzom/client/src/sky.cpp b/code/ryzom/client/src/sky.cpp index d5a9216ce..855ab3387 100644 --- a/code/ryzom/client/src/sky.cpp +++ b/code/ryzom/client/src/sky.cpp @@ -235,7 +235,7 @@ uint CSky::setup(const CClientDate &date, const CClientDate &animationDate, floa // animate objects if (_PlayListManager) { - double globalDate = ((double) _NumHourInDay * date.Day + (double) date.Hour) / _NumHourInDay; + double globalDate = (double)date.Hour / (double)_NumHourInDay; //nlinfo("global date = %f", (float) globalDate); _PlayListManager->animate(_AnimLengthInSeconds * globalDate); } From 44286f7adeefcd18af42bfbebda6b0c2b925c308 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 01:22:18 +0100 Subject: [PATCH 162/344] Add sky batch script --HG-- branch : develop --- code/nel/tools/build_gamedata/sky_dev.bat | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 code/nel/tools/build_gamedata/sky_dev.bat diff --git a/code/nel/tools/build_gamedata/sky_dev.bat b/code/nel/tools/build_gamedata/sky_dev.bat new file mode 100644 index 000000000..590400640 --- /dev/null +++ b/code/nel/tools/build_gamedata/sky_dev.bat @@ -0,0 +1,11 @@ +title Ryzom Core: 1_export.py (LEVELDESIGN) +1_export.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +title Ryzom Core: 2_build.py (LEVELDESIGN) +2_build.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +title Ryzom Core: 3_install.py (LEVELDESIGN) +3_install.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +title Ryzom Core: b1_client_dev.py (LEVELDESIGN) +b1_client_dev.py +title Ryzom Core: b2_shard_data.py (LEVELDESIGN) +b2_shard_data.py +title Ryzom Core: Ready From c3df884b133a9785246b9ed30c4c9f343aad4f97 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 01:22:19 +0100 Subject: [PATCH 163/344] Allow different light cycle for different continents [breaks packed sheets] --HG-- branch : develop --- code/ryzom/client/src/client_sheets/continent_sheet.cpp | 5 +++++ code/ryzom/client/src/client_sheets/continent_sheet.h | 5 ++++- code/ryzom/client/src/continent.cpp | 5 +++++ code/ryzom/client/src/continent_manager.cpp | 2 +- code/ryzom/client/src/init_main_loop.cpp | 2 +- .../client/src/interface_v3/action_handler_debug.cpp | 2 +- code/ryzom/client/src/weather.cpp | 9 +++++++-- code/ryzom/client/src/weather.h | 3 ++- 8 files changed, 26 insertions(+), 7 deletions(-) diff --git a/code/ryzom/client/src/client_sheets/continent_sheet.cpp b/code/ryzom/client/src/client_sheets/continent_sheet.cpp index 17868866c..6cd46b15c 100644 --- a/code/ryzom/client/src/client_sheets/continent_sheet.cpp +++ b/code/ryzom/client/src/client_sheets/continent_sheet.cpp @@ -300,6 +300,9 @@ void CContinentParameters::build(const NLGEORGES::UFormElm &item) if(readSeasontype() != CEntitySheet::LIGHT_CYCLE) { diff --git a/code/ryzom/client/src/weather.h b/code/ryzom/client/src/weather.h index 954b7f2c8..02a70a5a2 100644 --- a/code/ryzom/client/src/weather.h +++ b/code/ryzom/client/src/weather.h @@ -20,6 +20,7 @@ #define CL_WORLD_LIGHT_CYCLE_H +#include #include "game_share/season.h" struct CLightCycleDesc; @@ -47,7 +48,7 @@ extern EGSPD::CSeason::TSeason StartupSeason; extern CWeatherFunctionParamsSheet *WeatherFunctionParams; // load the world light cycle from a sheet -void loadWorldLightCycle(); +void loadWorldLightCycle(NLMISC::CSheetId lightCycleSheet); // load the weather function params void loadWeatherFunctionParams(); From 0c77c91e95585f5def67fec4e65a44d22de79d06 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 01:22:19 +0100 Subject: [PATCH 164/344] Adjust sky batch --HG-- branch : develop --- code/nel/tools/build_gamedata/sky_dev.bat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/nel/tools/build_gamedata/sky_dev.bat b/code/nel/tools/build_gamedata/sky_dev.bat index 590400640..ac80d591e 100644 --- a/code/nel/tools/build_gamedata/sky_dev.bat +++ b/code/nel/tools/build_gamedata/sky_dev.bat @@ -1,9 +1,9 @@ title Ryzom Core: 1_export.py (LEVELDESIGN) -1_export.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +1_export.py -ipj common/sky common/sfx common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share title Ryzom Core: 2_build.py (LEVELDESIGN) -2_build.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +2_build.py -ipj common/sky common/sfx common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share title Ryzom Core: 3_install.py (LEVELDESIGN) -3_install.py -ipj common/sky common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share +3_install.py -ipj common/sky common/sfx common/gamedev common/data_common common/data_shard common/leveldesign common/exedll common/cfg shard/data_shard shard/data_language shard/data_leveldesign shard/data_game_share title Ryzom Core: b1_client_dev.py (LEVELDESIGN) b1_client_dev.py title Ryzom Core: b2_shard_data.py (LEVELDESIGN) From eb2f4555b182bd4a4335f95b9b7d1ceea5bd5317 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 21:17:13 +0100 Subject: [PATCH 165/344] Also export non-root shapes --HG-- branch : develop --- .../generators/max_exporter_scripts/shape.ms | 66 +++++++++---------- .../processes/shape/maxscript/shape_export.ms | 66 +++++++++---------- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms index d8d6c8d9d..2a52947ec 100755 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms @@ -187,6 +187,8 @@ fn haveCoarseMesh node = return false ) +fn getRoot node = if isvalidnode node.parent then getRoot node.parent else node + fn runNelMaxExportSub inputMaxFile retryCount = ( tagThisFile = false @@ -273,55 +275,51 @@ fn runNelMaxExportSub inputMaxFile retryCount = -- For each node for node in array_node do ( - -- It is root ? - if (node.parent == undefined) then + -- Is not a skeleton ? + if (((substring node.name 1 3) != "Bip") and ((substring (getRoot node).name 1 3) != "Bip")) then ( - -- Is not a skeleton ? - if (node.name != "Bip01") then + -- Can be exported ? + if (isToBeExported node == true) then ( - -- Can be exported ? - if (isToBeExported node == true) then + -- Not a lod ? + if ((isLod node) == false) then ( - -- Not a lod ? - if ((isLod node) == false) then + -- Output directory + if (haveCoarseMesh node) == true then + output = ("%OutputDirectoryWithCoarseMesh%/" + (node.name) + ".shape") + else + output = ("%OutputDirectoryWithoutCoarseMesh%/" + (node.name) + ".shape") + + -- Compare file date + if (NeLTestFileDate output inputMaxFile) == true then ( - -- Output directory - if (haveCoarseMesh node) == true then - output = ("%OutputDirectoryWithCoarseMesh%/" + (node.name) + ".shape") - else - output = ("%OutputDirectoryWithoutCoarseMesh%/" + (node.name) + ".shape") - - -- Compare file date - if (NeLTestFileDate output inputMaxFile) == true then + try ( - try + -- Export the shape + if (NelExportShapeEx node output %ShapeExportOptShadow% %ShapeExportOptExportLighting% "%OutputDirectoryLightmap%" %ShapeExportOptLightingLimit% %ShapeExportOptLumelSize% %ShapeExportOptOversampling% true false %ShapeExportOptLightmapLog%) == true then ( - -- Export the shape - if (NelExportShapeEx node output %ShapeExportOptShadow% %ShapeExportOptExportLighting% "%OutputDirectoryLightmap%" %ShapeExportOptLightingLimit% %ShapeExportOptLumelSize% %ShapeExportOptOversampling% true false %ShapeExportOptLightmapLog%) == true then - ( - nlerror("OK "+output) - exported = exported +1 - ) - else - ( - -- Error - nlerror("ERROR exporting shape " + node.name + " in file " + inputMaxFile) - tagThisFile = false - ) + nlerror("OK "+output) + exported = exported +1 ) - catch + else ( -- Error - nlerror("ERROR fatal error exporting shape " + node.name + " in file " + inputMaxFile) + nlerror("ERROR exporting shape " + node.name + " in file " + inputMaxFile) tagThisFile = false ) ) - else + catch ( - nlerror("SKIPPED " + output) - exported = exported + 1 + -- Error + nlerror("ERROR fatal error exporting shape " + node.name + " in file " + inputMaxFile) + tagThisFile = false ) ) + else + ( + nlerror("SKIPPED " + output) + exported = exported + 1 + ) ) ) ) diff --git a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms index 16c6dcec9..5bece0c50 100755 --- a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms +++ b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms @@ -253,6 +253,8 @@ fn haveCoarseMesh node = return false ) +fn getRoot node = if isvalidnode node.parent then getRoot node.parent else node + fn runNelMaxExportSub inputMaxFile retryCount = ( tagThisFile = false @@ -339,55 +341,51 @@ fn runNelMaxExportSub inputMaxFile retryCount = -- For each node for node in array_node do ( - -- It is root ? - if (node.parent == undefined) then + -- Is not a skeleton ? + if (((substring node.name 1 3) != "Bip") and ((substring (getRoot node).name 1 3) != "Bip")) then ( - -- Is not a skeleton ? - if (node.name != "Bip01") then + -- Can be exported ? + if (isToBeExported node == true) then ( - -- Can be exported ? - if (isToBeExported node == true) then + -- Not a lod ? + if ((isLod node) == false) then ( - -- Not a lod ? - if ((isLod node) == false) then + -- Output directory + if (haveCoarseMesh node) == true then + output = ("%OutputDirectoryWithCoarseMesh%/" + (node.name) + ".shape") + else + output = ("%OutputDirectoryWithoutCoarseMesh%/" + (node.name) + ".shape") + + -- Compare file date + if (NeLTestFileDate output inputMaxFile) == true then ( - -- Output directory - if (haveCoarseMesh node) == true then - output = ("%OutputDirectoryWithCoarseMesh%/" + (node.name) + ".shape") - else - output = ("%OutputDirectoryWithoutCoarseMesh%/" + (node.name) + ".shape") - - -- Compare file date - if (NeLTestFileDate output inputMaxFile) == true then + try ( - try + -- Export the shape + if (NelExportShapeEx node output %ShapeExportOptShadow% %ShapeExportOptExportLighting% "%OutputDirectoryLightmap%" %ShapeExportOptLightingLimit% %ShapeExportOptLumelSize% %ShapeExportOptOversampling% true false %ShapeExportOptLightmapLog%) == true then ( - -- Export the shape - if (NelExportShapeEx node output %ShapeExportOptShadow% %ShapeExportOptExportLighting% "%OutputDirectoryLightmap%" %ShapeExportOptLightingLimit% %ShapeExportOptLumelSize% %ShapeExportOptOversampling% true false %ShapeExportOptLightmapLog%) == true then - ( - nlerror("OK "+output) - exported = exported +1 - ) - else - ( - -- Error - nlerror("ERROR exporting shape " + node.name + " in file " + inputMaxFile) - tagThisFile = false - ) + nlerror("OK "+output) + exported = exported +1 ) - catch + else ( -- Error - nlerror("ERROR fatal error exporting shape " + node.name + " in file " + inputMaxFile) + nlerror("ERROR exporting shape " + node.name + " in file " + inputMaxFile) tagThisFile = false ) ) - else + catch ( - nlerror("SKIPPED " + output) - exported = exported + 1 + -- Error + nlerror("ERROR fatal error exporting shape " + node.name + " in file " + inputMaxFile) + tagThisFile = false ) ) + else + ( + nlerror("SKIPPED " + output) + exported = exported + 1 + ) ) ) ) From 93d5ffddb6bbe9469a265db944dc03da1bd6028f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Dec 2014 21:17:13 +0100 Subject: [PATCH 166/344] Override sun direction from sky dome [breaks packed sheets] --HG-- branch : develop --- .../client/src/client_sheets/sky_sheet.cpp | 5 +++ .../client/src/client_sheets/sky_sheet.h | 3 ++ code/ryzom/client/src/light_cycle_manager.cpp | 10 +++++- code/ryzom/client/src/sky.cpp | 35 +++++++++++++++++++ code/ryzom/client/src/sky.h | 4 +++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/client_sheets/sky_sheet.cpp b/code/ryzom/client/src/client_sheets/sky_sheet.cpp index 4d3c35caf..e47aac582 100644 --- a/code/ryzom/client/src/client_sheets/sky_sheet.cpp +++ b/code/ryzom/client/src/client_sheets/sky_sheet.cpp @@ -24,6 +24,7 @@ CSkySheet::CSkySheet() Type = SKY; WaterEnvMapCameraHeight = 0.f; WaterEnvMapAlpha = 255; + SunClipZ = -1.0f; } // ***************************************************************************************************** @@ -53,6 +54,8 @@ void CSkySheet::build(const NLGEORGES::UFormElm &item, const std::string &prefix item.getValueByName(FogColorBitmap, (prefix + "FogColorBitmap").c_str()); item.getValueByName(WaterEnvMapCameraHeight, (prefix + "WaterEnvMapCameraHeight").c_str()); item.getValueByName(WaterEnvMapAlpha, (prefix + "WaterEnvMapAlpha").c_str()); + item.getValueByName(SunSource, (prefix + "SunSource").c_str()); + item.getValueByName(SunClipZ, (prefix + "SunClipZ").c_str()); } // ***************************************************************************************************** @@ -67,6 +70,8 @@ void CSkySheet::serial(class NLMISC::IStream &f) throw(NLMISC::EStream) f.serial(FogColorBitmap); f.serial(WaterEnvMapCameraHeight); f.serial(WaterEnvMapAlpha); + f.serial(SunSource); + f.serial(SunClipZ); } // ***************************************************************************************************** diff --git a/code/ryzom/client/src/client_sheets/sky_sheet.h b/code/ryzom/client/src/client_sheets/sky_sheet.h index 3ec207f27..319992847 100644 --- a/code/ryzom/client/src/client_sheets/sky_sheet.h +++ b/code/ryzom/client/src/client_sheets/sky_sheet.h @@ -39,6 +39,9 @@ public: // Water env map (computed from sky scene) float WaterEnvMapCameraHeight; uint8 WaterEnvMapAlpha; + // Sun direction override + std::string SunSource; + float SunClipZ; public: // ctor CSkySheet(); diff --git a/code/ryzom/client/src/light_cycle_manager.cpp b/code/ryzom/client/src/light_cycle_manager.cpp index 1f7175dba..2bf664130 100644 --- a/code/ryzom/client/src/light_cycle_manager.cpp +++ b/code/ryzom/client/src/light_cycle_manager.cpp @@ -477,7 +477,15 @@ void CLightCycleManager::setDirLight(const CDirLightSetup &setup0, const CDirLig scene.setSunAmbient (resultSetup.Ambiant); scene.setSunDiffuse (resultSetup.Diffuse); scene.setSunSpecular (resultSetup.Specular); - scene.setSunDirection(resultSetup.Direction); + CSky &sky = ContinentMngr.cur()->CurrentSky; + if (sky.overrideSunDirection()) + { + scene.setSunDirection(sky.calculateSunDirection()); + } + else + { + scene.setSunDirection(resultSetup.Direction); + } } //----------------------------------------------- diff --git a/code/ryzom/client/src/sky.cpp b/code/ryzom/client/src/sky.cpp index 855ab3387..d086bad60 100644 --- a/code/ryzom/client/src/sky.cpp +++ b/code/ryzom/client/src/sky.cpp @@ -48,6 +48,8 @@ CSky::CSky() _FogColor = NULL; _WaterEnvMapCameraHeight = 0.f; _WaterEnvMapAlpha = 255; + _SunSource = -1; + _SunClipZ = -1.0f; } // ************************************************************************************************* @@ -217,6 +219,39 @@ void CSky::init(UDriver *drv, const CSkySheet &sheet, bool forceFallbackVersion _NumHourInDay = numHourInDay; _WaterEnvMapCameraHeight = sheet.WaterEnvMapCameraHeight; _WaterEnvMapAlpha= sheet.WaterEnvMapAlpha; + // + // Find sun source + std::string sunSource = NLMISC::toLower(sheet.SunSource); + _SunSource = -1; + if (sunSource.size()) + { + uint numObjects = (uint)_Objects.size(); + for (uint k = 0; k < numObjects; ++k) + { + if (NLMISC::toLower(_Objects[k].Name) == sunSource) + { + nldebug("Found sun source: '%s'", sunSource.c_str()); + _SunSource = k; + } + } + } + _SunClipZ = sheet.SunClipZ; +} + +// ************************************************************************************************* +bool CSky::overrideSunDirection() const +{ + return (_SunSource >= 0) + && (_Objects[_SunSource].Instance.getLastClippedState()); +} + +// ************************************************************************************************* +NLMISC::CVector CSky::calculateSunDirection() const +{ + CVector sunPos = _Objects[_SunSource].Instance.getLastWorldMatrixComputed().getPos(); + CVector baseDir = (-sunPos).normed(); + baseDir.z = std::max(_SunClipZ, baseDir.z); + return baseDir.normed(); } // ************************************************************************************************* diff --git a/code/ryzom/client/src/sky.h b/code/ryzom/client/src/sky.h index 9c9f56d1f..07797c3e4 100644 --- a/code/ryzom/client/src/sky.h +++ b/code/ryzom/client/src/sky.h @@ -63,6 +63,8 @@ public: NLMISC::CRGBA computeFogColor(const CClientDate &date, float weatherLevel) const; float getWaterEnvMapCameraHeight() const { return _WaterEnvMapCameraHeight; } uint8 getWaterEnvMapAlpha() const { return _WaterEnvMapAlpha; } + bool overrideSunDirection() const; + NLMISC::CVector calculateSunDirection() const; private: std::vector _Objects; // all the object in the sky std::vector _Bitmaps; // all the bitmaps for the color lookups @@ -80,6 +82,8 @@ private: NLMISC::CBitmap *_FogColor; float _WaterEnvMapCameraHeight; uint8 _WaterEnvMapAlpha; + sint _SunSource; + float _SunClipZ; }; From 4d67a41f9473986952f306d195ef9ad915eb4336 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 21 Dec 2014 22:55:27 +0100 Subject: [PATCH 167/344] CCtrlTextbutton checkcoords should call it's text's checkcoords method. Fix #219. --HG-- branch : hotfix --- code/nel/include/nel/gui/ctrl_text_button.h | 1 + code/nel/src/gui/ctrl_text_button.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index d2b49ffa9..4f5251a8b 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -51,6 +51,7 @@ namespace NLGUI // Init part virtual bool parse (xmlNodePtr cur,CInterfaceGroup * parentGroup); + virtual void checkCoords(); virtual void updateCoords(); virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index cdf9ea0d2..2fb19a9fc 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -868,6 +868,15 @@ namespace NLGUI } } + // *************************************************************************** + void CCtrlTextButton::checkCoords() + { + if( _ViewText != NULL ) + _ViewText->checkCoords(); + + CCtrlBaseButton::checkCoords(); + } + // *************************************************************************** void CCtrlTextButton::updateCoords() From f189a98422e7f99601b5d0e56d83c619a3d5878d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 22 Dec 2014 01:26:04 +0100 Subject: [PATCH 168/344] Ported changeset 9878ab4: CCtrlTextbutton checkcoords should call it's text's checkcoords method. Fix #219. --HG-- branch : develop --- code/nel/include/nel/gui/ctrl_text_button.h | 1 + code/nel/src/gui/ctrl_text_button.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index d2b49ffa9..4f5251a8b 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -51,6 +51,7 @@ namespace NLGUI // Init part virtual bool parse (xmlNodePtr cur,CInterfaceGroup * parentGroup); + virtual void checkCoords(); virtual void updateCoords(); virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index cdf9ea0d2..2fb19a9fc 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -868,6 +868,15 @@ namespace NLGUI } } + // *************************************************************************** + void CCtrlTextButton::checkCoords() + { + if( _ViewText != NULL ) + _ViewText->checkCoords(); + + CCtrlBaseButton::checkCoords(); + } + // *************************************************************************** void CCtrlTextButton::updateCoords() From a43fb4dba84cb6e81d69001c675fb7a8d11345c3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 14:08:29 +0100 Subject: [PATCH 169/344] Move to hotfix: 287c1142e5ea --HG-- branch : develop --- code/nel/include/nel/gui/ctrl_text_button.h | 1 - code/nel/src/gui/ctrl_text_button.cpp | 9 --------- 2 files changed, 10 deletions(-) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index 4f5251a8b..d2b49ffa9 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -51,7 +51,6 @@ namespace NLGUI // Init part virtual bool parse (xmlNodePtr cur,CInterfaceGroup * parentGroup); - virtual void checkCoords(); virtual void updateCoords(); virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index 2fb19a9fc..cdf9ea0d2 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -868,15 +868,6 @@ namespace NLGUI } } - // *************************************************************************** - void CCtrlTextButton::checkCoords() - { - if( _ViewText != NULL ) - _ViewText->checkCoords(); - - CCtrlBaseButton::checkCoords(); - } - // *************************************************************************** void CCtrlTextButton::updateCoords() From b9d372b14434c32758bd0ea524b3f55e58bb3a45 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 14:08:54 +0100 Subject: [PATCH 170/344] Backed out changeset: 3694176c26bf --HG-- branch : develop --- .../client/src/client_sheets/sky_sheet.cpp | 5 --- .../client/src/client_sheets/sky_sheet.h | 3 -- code/ryzom/client/src/light_cycle_manager.cpp | 10 +----- code/ryzom/client/src/sky.cpp | 35 ------------------- code/ryzom/client/src/sky.h | 4 --- 5 files changed, 1 insertion(+), 56 deletions(-) diff --git a/code/ryzom/client/src/client_sheets/sky_sheet.cpp b/code/ryzom/client/src/client_sheets/sky_sheet.cpp index e47aac582..4d3c35caf 100644 --- a/code/ryzom/client/src/client_sheets/sky_sheet.cpp +++ b/code/ryzom/client/src/client_sheets/sky_sheet.cpp @@ -24,7 +24,6 @@ CSkySheet::CSkySheet() Type = SKY; WaterEnvMapCameraHeight = 0.f; WaterEnvMapAlpha = 255; - SunClipZ = -1.0f; } // ***************************************************************************************************** @@ -54,8 +53,6 @@ void CSkySheet::build(const NLGEORGES::UFormElm &item, const std::string &prefix item.getValueByName(FogColorBitmap, (prefix + "FogColorBitmap").c_str()); item.getValueByName(WaterEnvMapCameraHeight, (prefix + "WaterEnvMapCameraHeight").c_str()); item.getValueByName(WaterEnvMapAlpha, (prefix + "WaterEnvMapAlpha").c_str()); - item.getValueByName(SunSource, (prefix + "SunSource").c_str()); - item.getValueByName(SunClipZ, (prefix + "SunClipZ").c_str()); } // ***************************************************************************************************** @@ -70,8 +67,6 @@ void CSkySheet::serial(class NLMISC::IStream &f) throw(NLMISC::EStream) f.serial(FogColorBitmap); f.serial(WaterEnvMapCameraHeight); f.serial(WaterEnvMapAlpha); - f.serial(SunSource); - f.serial(SunClipZ); } // ***************************************************************************************************** diff --git a/code/ryzom/client/src/client_sheets/sky_sheet.h b/code/ryzom/client/src/client_sheets/sky_sheet.h index 319992847..3ec207f27 100644 --- a/code/ryzom/client/src/client_sheets/sky_sheet.h +++ b/code/ryzom/client/src/client_sheets/sky_sheet.h @@ -39,9 +39,6 @@ public: // Water env map (computed from sky scene) float WaterEnvMapCameraHeight; uint8 WaterEnvMapAlpha; - // Sun direction override - std::string SunSource; - float SunClipZ; public: // ctor CSkySheet(); diff --git a/code/ryzom/client/src/light_cycle_manager.cpp b/code/ryzom/client/src/light_cycle_manager.cpp index 2bf664130..1f7175dba 100644 --- a/code/ryzom/client/src/light_cycle_manager.cpp +++ b/code/ryzom/client/src/light_cycle_manager.cpp @@ -477,15 +477,7 @@ void CLightCycleManager::setDirLight(const CDirLightSetup &setup0, const CDirLig scene.setSunAmbient (resultSetup.Ambiant); scene.setSunDiffuse (resultSetup.Diffuse); scene.setSunSpecular (resultSetup.Specular); - CSky &sky = ContinentMngr.cur()->CurrentSky; - if (sky.overrideSunDirection()) - { - scene.setSunDirection(sky.calculateSunDirection()); - } - else - { - scene.setSunDirection(resultSetup.Direction); - } + scene.setSunDirection(resultSetup.Direction); } //----------------------------------------------- diff --git a/code/ryzom/client/src/sky.cpp b/code/ryzom/client/src/sky.cpp index d086bad60..855ab3387 100644 --- a/code/ryzom/client/src/sky.cpp +++ b/code/ryzom/client/src/sky.cpp @@ -48,8 +48,6 @@ CSky::CSky() _FogColor = NULL; _WaterEnvMapCameraHeight = 0.f; _WaterEnvMapAlpha = 255; - _SunSource = -1; - _SunClipZ = -1.0f; } // ************************************************************************************************* @@ -219,39 +217,6 @@ void CSky::init(UDriver *drv, const CSkySheet &sheet, bool forceFallbackVersion _NumHourInDay = numHourInDay; _WaterEnvMapCameraHeight = sheet.WaterEnvMapCameraHeight; _WaterEnvMapAlpha= sheet.WaterEnvMapAlpha; - // - // Find sun source - std::string sunSource = NLMISC::toLower(sheet.SunSource); - _SunSource = -1; - if (sunSource.size()) - { - uint numObjects = (uint)_Objects.size(); - for (uint k = 0; k < numObjects; ++k) - { - if (NLMISC::toLower(_Objects[k].Name) == sunSource) - { - nldebug("Found sun source: '%s'", sunSource.c_str()); - _SunSource = k; - } - } - } - _SunClipZ = sheet.SunClipZ; -} - -// ************************************************************************************************* -bool CSky::overrideSunDirection() const -{ - return (_SunSource >= 0) - && (_Objects[_SunSource].Instance.getLastClippedState()); -} - -// ************************************************************************************************* -NLMISC::CVector CSky::calculateSunDirection() const -{ - CVector sunPos = _Objects[_SunSource].Instance.getLastWorldMatrixComputed().getPos(); - CVector baseDir = (-sunPos).normed(); - baseDir.z = std::max(_SunClipZ, baseDir.z); - return baseDir.normed(); } // ************************************************************************************************* diff --git a/code/ryzom/client/src/sky.h b/code/ryzom/client/src/sky.h index 07797c3e4..9c9f56d1f 100644 --- a/code/ryzom/client/src/sky.h +++ b/code/ryzom/client/src/sky.h @@ -63,8 +63,6 @@ public: NLMISC::CRGBA computeFogColor(const CClientDate &date, float weatherLevel) const; float getWaterEnvMapCameraHeight() const { return _WaterEnvMapCameraHeight; } uint8 getWaterEnvMapAlpha() const { return _WaterEnvMapAlpha; } - bool overrideSunDirection() const; - NLMISC::CVector calculateSunDirection() const; private: std::vector _Objects; // all the object in the sky std::vector _Bitmaps; // all the bitmaps for the color lookups @@ -82,8 +80,6 @@ private: NLMISC::CBitmap *_FogColor; float _WaterEnvMapCameraHeight; uint8 _WaterEnvMapAlpha; - sint _SunSource; - float _SunClipZ; }; From 11ae94ab212c6c4b49e757506889b113b7cf9f46 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 14:10:37 +0100 Subject: [PATCH 171/344] Move to feature-light_cycle: c5207e1f862a --HG-- branch : develop --- code/ryzom/client/src/client_sheets/continent_sheet.cpp | 5 ----- code/ryzom/client/src/client_sheets/continent_sheet.h | 5 +---- code/ryzom/client/src/continent.cpp | 5 ----- code/ryzom/client/src/continent_manager.cpp | 2 +- code/ryzom/client/src/init_main_loop.cpp | 2 +- .../client/src/interface_v3/action_handler_debug.cpp | 2 +- code/ryzom/client/src/weather.cpp | 9 ++------- code/ryzom/client/src/weather.h | 3 +-- 8 files changed, 7 insertions(+), 26 deletions(-) diff --git a/code/ryzom/client/src/client_sheets/continent_sheet.cpp b/code/ryzom/client/src/client_sheets/continent_sheet.cpp index 6cd46b15c..17868866c 100644 --- a/code/ryzom/client/src/client_sheets/continent_sheet.cpp +++ b/code/ryzom/client/src/client_sheets/continent_sheet.cpp @@ -300,9 +300,6 @@ void CContinentParameters::build(const NLGEORGES::UFormElm &item) if(readSeasontype() != CEntitySheet::LIGHT_CYCLE) { diff --git a/code/ryzom/client/src/weather.h b/code/ryzom/client/src/weather.h index 02a70a5a2..954b7f2c8 100644 --- a/code/ryzom/client/src/weather.h +++ b/code/ryzom/client/src/weather.h @@ -20,7 +20,6 @@ #define CL_WORLD_LIGHT_CYCLE_H -#include #include "game_share/season.h" struct CLightCycleDesc; @@ -48,7 +47,7 @@ extern EGSPD::CSeason::TSeason StartupSeason; extern CWeatherFunctionParamsSheet *WeatherFunctionParams; // load the world light cycle from a sheet -void loadWorldLightCycle(NLMISC::CSheetId lightCycleSheet); +void loadWorldLightCycle(); // load the weather function params void loadWeatherFunctionParams(); From f9c81f37404ee482c7a5da381cc6b5ca8f951b6f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 14:21:01 +0100 Subject: [PATCH 172/344] ryzomcore/v0.11.2 --HG-- branch : hotfix --- code/CMakeLists.txt | 4 ++-- code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc | 8 ++++---- code/ryzom/common/src/game_share/ryzom_version.h | 5 ++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index bd36abe61..0f9a72ac6 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -2,7 +2,7 @@ # # NeL # Authors: Nevrax and the NeL Community -# Version: 0.11.1 +# Version: 0.11.2 # # Notes: # * Changing install location: add -DCMAKE_INSTALL_PREFIX:PATH=/my/new/path @@ -48,7 +48,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(RyzomCore CXX C) SET(NL_VERSION_MAJOR 0) SET(NL_VERSION_MINOR 11) -SET(NL_VERSION_PATCH 1) +SET(NL_VERSION_PATCH 2) SET(NL_VERSION "${NL_VERSION_MAJOR}.${NL_VERSION_MINOR}.${NL_VERSION_PATCH}") #----------------------------------------------------------------------------- diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc index 243e02da8..6de328356 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc @@ -514,8 +514,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 11, 0, 0 - PRODUCTVERSION 0, 11, 0, 0 + FILEVERSION 0, 11, 2, 0 + PRODUCTVERSION 0, 11, 2, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -533,13 +533,13 @@ BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core" VALUE "FileDescription", "NeL Patch Edit" - VALUE "FileVersion", "0.11.0" + VALUE "FileVersion", "0.11.2" VALUE "InternalName", "neleditpatch" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd. Copyright © 1998 Autodesk Inc." VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF." VALUE "OriginalFilename", "neleditpatch.dlm" VALUE "ProductName", "Ryzom Core" - VALUE "ProductVersion", "0.11.0" + VALUE "ProductVersion", "0.11.2" END END BLOCK "VarFileInfo" diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index de4524626..915f9ed1c 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,10 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.11.1" +#define RYZOM_VERSION "ryzomcore" \ + "/" \ + "v0.11.2" \ + "" #endif // RYZOM_VERSION_H From 0d1c319b2fa3bda0bfe5c61cb1e854ec3f7f6e05 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 14:22:12 +0100 Subject: [PATCH 173/344] Added tag ryzomcore/v0.11.2 for changeset 9e583b717fd6 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index ac1525929..80061a2ee 100644 --- a/.hgtags +++ b/.hgtags @@ -5,3 +5,4 @@ fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0 edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0 e3fe4855f22c3e75722e015dc33c091c340b3ad7 ryzomcore/v0.11.1 +9e583b717fd63be0be9fd60b99087abf1691ea49 ryzomcore/v0.11.2 From bb8eb7dcecd2ba502ac5f076d9451d62e0b76bff Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 22 Dec 2014 16:39:54 +0100 Subject: [PATCH 174/344] Fix mirror type sizes --HG-- branch : hotfix --- code/ryzom/common/src/game_share/ryzom_mirror_properties.h | 2 +- code/ryzom/server/data_shard/mirror_sheets/fe_temp.dataset | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h index 55d8b9bbb..134ebe38b 100644 --- a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h +++ b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h @@ -138,7 +138,7 @@ void initRyzomVisualPropertyIndices( CMirroredDataSet& dataset ); #define TYPE_BOT_TRADE_SELECTOR2 uint64 #define TYPE_EVENT_FACTION_ID uint32 -#define TYPE_PVP_MODE uint32 +#define TYPE_PVP_MODE uint16 #define TYPE_PVP_CLAN uint32 #define TYPE_FUEL bool diff --git a/code/ryzom/server/data_shard/mirror_sheets/fe_temp.dataset b/code/ryzom/server/data_shard/mirror_sheets/fe_temp.dataset index f88263c27..b891b6252 100644 --- a/code/ryzom/server/data_shard/mirror_sheets/fe_temp.dataset +++ b/code/ryzom/server/data_shard/mirror_sheets/fe_temp.dataset @@ -292,14 +292,14 @@ - + - + From 3bfcd8644daf84ff8c6c8e545b95b8c7455b4f75 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 26 Dec 2014 13:12:56 +0100 Subject: [PATCH 175/344] Changed: Minor changes --HG-- branch : develop --- code/ryzom/server/src/CMakeLists.txt | 1 - .../src/entities_game_service/admin.cpp | 15 +- .../entities_game_service/database_plr.cpp | 20 +- .../src/entities_game_service/database_plr.h | 47 ++- .../guild_manager/guild_member_module.cpp | 5 +- .../mission_client_callbacks.cpp | 1 + .../mission_manager/mission_action.cpp | 18 +- .../mission_manager/mission_step_template.cpp | 1 - .../phrase_manager/faber_action.cpp | 2 +- .../character_version_adapter.cpp | 4 +- .../src/input_output_service/chat_manager.cpp | 269 +++++++++--------- .../src/input_output_service/chat_manager.h | 18 +- .../src/server_share/continent_container.h | 2 +- .../server/src/server_share/mysql_wrapper.cpp | 2 +- .../nel_database_mapping.cpp | 23 +- .../nel_database_mapping.h | 16 +- code/ryzom/tools/client/CMakeLists.txt | 15 +- .../screenshot_islands.cpp | 3 +- code/ryzom/tools/leveldesign/CMakeLists.txt | 1 - code/ryzom/tools/server/CMakeLists.txt | 1 - .../brick_param_extractor.cpp | 2 +- 21 files changed, 254 insertions(+), 212 deletions(-) diff --git a/code/ryzom/server/src/CMakeLists.txt b/code/ryzom/server/src/CMakeLists.txt index 29c11be09..08731a4ca 100644 --- a/code/ryzom/server/src/CMakeLists.txt +++ b/code/ryzom/server/src/CMakeLists.txt @@ -1,4 +1,3 @@ - # Supporting modules and libraries. # Need servershare for build packed collision tool # Need aishare for build wmap tool diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index 20941e77f..080dc16bb 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -4821,9 +4821,9 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSlotCount(); ++ i) { const CGameItemPtr itemPtr = inventory->getItem(i); - if( itemPtr != NULL ) + if ( itemPtr != NULL ) { - if( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) + if ( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) { numberItem += itemPtr->getStackSize(); } @@ -4841,9 +4841,9 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSlotCount(); ++ i) { const CGameItemPtr itemPtr = inventory->getItem(i); - if( itemPtr != NULL ) + if ( itemPtr != NULL ) { - if( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) + if ( (itemPtr->getSheetId() == sheetId) && (itemPtr->quality() == quality) ) { numberItem -= inventory->deleteStackItem(i, quantity); if(numberItem == 0) @@ -5053,7 +5053,8 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getType()) + + if (creature == NULL || creatureSheetId == CSheetId::Unknown || creatureSheetId != creature->getType()) { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=bad_sheet", getSalt()); @@ -5686,7 +5687,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getHomeMainlandSessionId(), value)); - if (entityBase == 0) + if (entityBase == NULL) { // try to find the bot name vector aliases; @@ -5711,7 +5712,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getState().X + sint32 (cos (entityBase->getState ().Heading) * 2000); y = entityBase->getState().Y + sint32 (sin (entityBase->getState ().Heading) * 2000); diff --git a/code/ryzom/server/src/entities_game_service/database_plr.cpp b/code/ryzom/server/src/entities_game_service/database_plr.cpp index 7cf0d2108..4b5fa84fd 100644 --- a/code/ryzom/server/src/entities_game_service/database_plr.cpp +++ b/code/ryzom/server/src/entities_game_service/database_plr.cpp @@ -1,3 +1,18 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . ///////////////////////////////////////////////////////////////// // WARNING : this is a generated file, don't change it ! @@ -347,7 +362,7 @@ void CBankAccessor_PLR::TUSER::init(ICDBStructNode *parent) node = parent->getNode( ICDBStructNode::CTextId("IS_INVISIBLE"), false ); nlassert(node != NULL); _IS_INVISIBLE = node; - + node = parent->getNode( ICDBStructNode::CTextId("COUNTER"), false ); nlassert(node != NULL); _COUNTER = node; @@ -3124,11 +3139,10 @@ void CBankAccessor_PLR::TPACK_ANIMAL::TBEAST::init(ICDBStructNode *parent, uint node = parent->getNode( ICDBStructNode::CTextId("DESPAWN"), false ); nlassert(node != NULL); _DESPAWN = node; - + node = parent->getNode( ICDBStructNode::CTextId("NAME"), false ); nlassert(node != NULL); _NAME = node; - // branch init diff --git a/code/ryzom/server/src/entities_game_service/database_plr.h b/code/ryzom/server/src/entities_game_service/database_plr.h index 38a394c88..67e0f7798 100644 --- a/code/ryzom/server/src/entities_game_service/database_plr.h +++ b/code/ryzom/server/src/entities_game_service/database_plr.h @@ -1,3 +1,18 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . #ifndef INCLUDED_DATABASE_PLR_H @@ -941,8 +956,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C void setIS_INVISIBLE(CCDBSynchronised &dbGroup, bool value, bool forceSending = false) { - - _setProp(dbGroup, _IS_INVISIBLE, value, forceSending); } @@ -958,7 +971,7 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C { return _IS_INVISIBLE; } - + void setCOUNTER(CCDBSynchronised &dbGroup, uint8 value, bool forceSending = false) { @@ -1300,13 +1313,14 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C { return _DODGE; } - TBRICK_TICK_RANGE &getBRICK_TICK_RANGE() + + TBRICK_TICK_RANGE &getBRICK_TICK_RANGE() { return _BRICK_TICK_RANGE; } - + }; - + class TTARGET { public: @@ -3457,8 +3471,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C void setMONEY(CCDBSynchronised &dbGroup, uint64 value, bool forceSending = false) { - - _setProp(dbGroup, _MONEY, value, forceSending); } @@ -4560,8 +4572,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C void setMONEY(CCDBSynchronised &dbGroup, uint64 value, bool forceSending = false) { - - _setProp(dbGroup, _MONEY, value, forceSending); } @@ -4572,14 +4582,12 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C return value; } - + ICDBStructNode *getMONEYCDBNode() { return _MONEY; } - }; - private: ICDBStructNode *_BranchNode; @@ -4602,11 +4610,8 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C return _BranchNode; } - void setMONEY(CCDBSynchronised &dbGroup, uint64 value, bool forceSending = false) { - - _setProp(dbGroup, _MONEY, value, forceSending); } @@ -6000,8 +6005,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C void setMONEY_SHEET(CCDBSynchronised &dbGroup, NLMISC::CSheetId value, bool forceSending = false) { - - _setProp(dbGroup, _MONEY_SHEET, value, forceSending); } @@ -8858,7 +8861,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C ICDBStructNode *_HUNGER; ICDBStructNode *_DESPAWN; ICDBStructNode *_NAME; - public: void init(ICDBStructNode *parent, uint index); @@ -9047,11 +9049,9 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C { return _DESPAWN; } - + void setNAME(CCDBSynchronised &dbGroup, uint32 value, bool forceSending = false) { - - _setProp(dbGroup, _NAME, value, forceSending); } @@ -9062,12 +9062,11 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C return value; } - + ICDBStructNode *getNAMECDBNode() { return _NAME; } - }; diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp index 03a105445..c04347c08 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp @@ -559,7 +559,8 @@ void CGuildMemberModule::kickMember( uint16 index,uint8 session )const } // if the user is online reset its guild id CGuildMemberModule * module = NULL; - if ( member->getReferencingModule( module ) ) + + if (member->getReferencingModule(module)) { module->clearOnlineGuildProperties(); } @@ -568,7 +569,7 @@ void CGuildMemberModule::kickMember( uint16 index,uint8 session )const params[0].setEIdAIAlias( proxy.getId(), CAIAliasTranslator::getInstance()->getAIAlias(proxy.getId()) ); params[1].StringId = CEntityIdTranslator::getInstance()->getEntityNameStringId(member->getIngameEId()); sendMessageToGuildMembers("GUILD_KICK_MEMBER",params); - + guild->deleteMember( member ); } diff --git a/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp b/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp index 7cc0bf32a..98d784e11 100644 --- a/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp @@ -236,6 +236,7 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser MISLOG("user:%s cbClientGroupAbandonMission : Invalid team", userId.toString().c_str()); return; } + if ( team->getLeader() != userId ) { CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), "REQ_LEADER_TO_ABANDON_MISSION" ); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp index 941b31afa..d967e6971 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp @@ -767,7 +767,7 @@ class CMissionActionRecvItem : public IMissionAction freeSlotcount -= invTemp->getUsedSlotCount(); maxBulk -= invTemp->getInventoryBulk(); } - + if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) ) { fail = false; @@ -862,7 +862,7 @@ class CMissionActionRecvItem : public IMissionAction } params[2].Int = _Item.getQuality(); } - + params[0].SheetId = _SheetId; params[1].Int = _Quantity; PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_ITEM", params); @@ -1050,7 +1050,7 @@ class CMissionActionRecvNamedItem : public IMissionAction sint16 neededSlotCount = (sint16) ceil( (float)_Quantity / itemTmp->getMaxStackSize() ); uint32 neededBulk = _Quantity * itemTmp->getStackBulk(); itemTmp.deleteItem(); - + bool fail = true; for ( uint i = 0; i < entities.size(); i++ ) { @@ -1067,15 +1067,15 @@ class CMissionActionRecvNamedItem : public IMissionAction freeSlotcount -= invTemp->getUsedSlotCount(); maxBulk -= invTemp->getInventoryBulk(); } - + if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) ) { fail = false; break; } } - } + if( fail ) { CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() ); @@ -1274,7 +1274,6 @@ class CMissionActionDestroyItem : // If the "guild" parameter is not set, we destroy the items for the users if (!_Guild) { - for ( uint i = 0; i < entities.size(); i++ ) { CCharacter * user = PlayerManager.getChar( entities[i] ); @@ -1303,7 +1302,6 @@ class CMissionActionDestroyItem : PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params); } } - } // We destroy the item in the guild else @@ -1909,7 +1907,6 @@ class CMissionActionRecvMoney : public IMissionAction // If the guild parameter is not set we just divide the money and give it to each entity if (!_Guild) { - uint amount = _Amount / (uint)entities.size(); if ( amount == 0 || _Amount % entities.size() ) amount++; @@ -1924,7 +1921,6 @@ class CMissionActionRecvMoney : public IMissionAction PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_MONEY",params); } } - } // Else we give the money to the guild else @@ -2026,7 +2022,6 @@ class CMissionActionRecvFame : public IMissionAction // If there is no "guild" parameter we give the fame to every user if (!_Guild) { - for ( uint i = 0; i < entities.size(); i++ ) { CEntityId eid = TheDataset.getEntityId(entities[i]); @@ -2037,12 +2032,10 @@ class CMissionActionRecvFame : public IMissionAction if (character) character->sendEventForMissionAvailabilityCheck(); } - } // Else we just give it to the guild else { - if (entities.size() == 0) return; @@ -2072,7 +2065,6 @@ class CMissionActionRecvFame : public IMissionAction if (character) character->sendEventForMissionAvailabilityCheck(); } - } }; diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp index 7e99059b9..1caefb340 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_template.cpp @@ -170,7 +170,6 @@ uint32 IMissionStepTemplate::sendStepText(CCharacter * user,const std::vectorgetLowerRmQuality(),(uint16)phrase->getRecommendedSkill()) * successFactor) ); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp index 1cf7940c6..adc281dda 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_version_adapter.cpp @@ -652,7 +652,9 @@ void CCharacterVersionAdapter::adaptToVersion11(CCharacter &character) const case EGSPD::CPeople::Zorai : mission = CAIAliasTranslator::getInstance()->getMissionUniqueIdFromName( "ZORAI_NEWB_WELCOME_SHENG_WO_1" ); CAIAliasTranslator::getInstance()->getNPCAliasesFromName("welcomer_sheng_wo_1", bots); - break; + break; + default: + break; } } // other give him a rite intro mission diff --git a/code/ryzom/server/src/input_output_service/chat_manager.cpp b/code/ryzom/server/src/input_output_service/chat_manager.cpp index fbc38ead5..aedfa063f 100644 --- a/code/ryzom/server/src/input_output_service/chat_manager.cpp +++ b/code/ryzom/server/src/input_output_service/chat_manager.cpp @@ -94,21 +94,21 @@ void CChatManager::onServiceDown(const std::string &serviceShortName) switch (cg.Type) { - case CChatGroup::universe: - case CChatGroup::say: - case CChatGroup::shout: - continue; - case CChatGroup::team: - case CChatGroup::guild: - case CChatGroup::civilization: - case CChatGroup::territory: - case CChatGroup::tell: - case CChatGroup::arround: - case CChatGroup::system: - case CChatGroup::region: - case CChatGroup::dyn_chat: - groupToRemove.push_back(gid); - break; + case CChatGroup::universe: + case CChatGroup::say: + case CChatGroup::shout: + continue; + case CChatGroup::team: + case CChatGroup::guild: + case CChatGroup::civilization: + case CChatGroup::territory: + case CChatGroup::tell: + case CChatGroup::arround: + case CChatGroup::system: + case CChatGroup::region: + case CChatGroup::dyn_chat: + groupToRemove.push_back(gid); + break; } } @@ -121,7 +121,7 @@ void CChatManager::onServiceDown(const std::string &serviceShortName) // clear muted players table _MutedUsers.clear(); - + // clear the dyn chats _DynChat.removeAllChannels(); } @@ -151,9 +151,11 @@ bool CChatManager::checkClient( const TDataSetRow& id ) void CChatManager::addClient( const TDataSetRow& id ) { if (VerboseChatManagement) - nldebug("IOSCM: addClient : adding client %s:%x into chat manager and universe group.", + { + nldebug("IOSCM: addClient : adding client %s:%x into chat manager and universe group.", TheDataset.getEntityId(id).toString().c_str(), id.getIndex()); + } if(id.getIndex() == 0xffffff) { @@ -197,10 +199,11 @@ void CChatManager::addClient( const TDataSetRow& id ) void CChatManager::removeClient( const TDataSetRow& id ) { if (VerboseChatManagement) - nldebug("IOSCM: removeClient : removing the client %s:%x from chat manager !", + { + nldebug("IOSCM: removeClient : removing the client %s:%x from chat manager !", TheDataset.getEntityId(id).toString().c_str(), id.getIndex()); - + } TClientInfoCont::iterator itCl = _Clients.find( id ); if( itCl != _Clients.end() ) @@ -214,7 +217,7 @@ void CChatManager::removeClient( const TDataSetRow& id ) } else { - nlwarning("CChatManager::removeClient : The client %s:%x is unknown !", + nlwarning("CChatManager::removeClient : The client %s:%x is unknown !", TheDataset.getEntityId(id).toString().c_str(), id.getIndex()); } @@ -233,7 +236,7 @@ CChatClient& CChatManager::getClient( const TDataSetRow& id ) TClientInfoCont::iterator itCl = _Clients.find( id ); if( itCl != _Clients.end() ) { - return *(itCl->second); + return *(itCl->second); } else { @@ -259,15 +262,15 @@ void CChatManager::addGroup( TGroupId gId, CChatGroup::TGroupType gType, const s { if (!groupName.empty()) nldebug("IOSCM: addGroup : adding %s named chat group %s as '%s'", - CChatGroup::groupTypeToString(gType).c_str(), + CChatGroup::groupTypeToString(gType).c_str(), gId.toString().c_str(), groupName.c_str()); else nldebug("IOSCM: addGroup : adding %s anonymous chat group %s", - CChatGroup::groupTypeToString(gType).c_str(), + CChatGroup::groupTypeToString(gType).c_str(), gId.toString().c_str()); } - + map< TGroupId, CChatGroup >::iterator itGrp = _Groups.find( gId ); if( itGrp == _Groups.end() ) { @@ -290,7 +293,7 @@ void CChatManager::addGroup( TGroupId gId, CChatGroup::TGroupType gType, const s { nlwarning("CChatManager::addGroup : the group %s already exists", gId.toString().c_str()); } - + } // addGroup // @@ -302,8 +305,10 @@ void CChatManager::addGroup( TGroupId gId, CChatGroup::TGroupType gType, const s void CChatManager::removeGroup( TGroupId gId ) { if (VerboseChatManagement) + { nldebug("IOSCM: removeGroup : removing group %s", gId.toString().c_str()); + } map< TGroupId, CChatGroup >::iterator itGrp = _Groups.find( gId ); if( itGrp != _Groups.end() ) @@ -338,10 +343,12 @@ void CChatManager::removeGroup( TGroupId gId ) void CChatManager::addToGroup( TGroupId gId, const TDataSetRow &charId ) { if (VerboseChatManagement) + { nldebug("IOSCM: addtoGroup : adding player %s:%x to group %s", TheDataset.getEntityId(charId).toString().c_str(), charId.getIndex(), gId.toString().c_str()); + } map< TGroupId, CChatGroup >::iterator itGrp = _Groups.find( gId ); if( itGrp != _Groups.end() ) @@ -372,7 +379,7 @@ void CChatManager::addToGroup( TGroupId gId, const TDataSetRow &charId ) } else { - nlwarning("CChatManager::addToGroup : client %s:%x is unknown", + nlwarning("CChatManager::addToGroup : client %s:%x is unknown", TheDataset.getEntityId(charId).toString().c_str(), charId.getIndex()); // remove it from the group (don't leave bad client...) @@ -396,10 +403,12 @@ void CChatManager::addToGroup( TGroupId gId, const TDataSetRow &charId ) void CChatManager::removeFromGroup( TGroupId gId, const TDataSetRow &charId ) { if (VerboseChatManagement) + { nldebug("IOSCM: removeFromGroup : removing player %s:%x from group %s", TheDataset.getEntityId(charId).toString().c_str(), - charId.getIndex(), + charId.getIndex(), gId.toString().c_str()); + } map< TGroupId, CChatGroup >::iterator itGrp = _Groups.find( gId ); if( itGrp != _Groups.end() ) @@ -443,7 +452,7 @@ void CChatManager::removeFromGroup( TGroupId gId, const TDataSetRow &charId ) } // removeFromGroup // - + //----------------------------------------------- @@ -486,7 +495,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) } // CEntityId eid = TheDataset.getEntityId(sender); - // Get the char info + // Get the char info //WARNING: can be NULL CCharacterInfos *ci = IOS->getCharInfos(eid); @@ -525,7 +534,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // clean up container _DestUsers.clear(); - + switch( itCl->second->getChatMode() ) { // dynamic group @@ -533,7 +542,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) case CChatGroup::say : { CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -566,7 +575,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // so even after teleporting in a remote region the previous around people were still receiving // the messages. - TGroupId grpId = itCl->second->getRegionChatGroup(); + TGroupId grpId = itCl->second->getRegionChatGroup(); _DestUsers.push_back(grpId); _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); @@ -599,7 +608,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // } // } - TGroupId grpId = CEntityId(RYZOMID::chatGroup,0); + TGroupId grpId = CEntityId(RYZOMID::chatGroup, 0); _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); _DestUsers.push_back(grpId); @@ -621,15 +630,15 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) TGroupId grpId = itCl->second->getGuildChatGroup(); _DestUsers.push_back(grpId); - _Log.displayNL("'%s' (%s) : \t\"%s\"", - senderName.c_str(), - groupNames[itCl->second->getChatMode()], + _Log.displayNL("'%s' (%s) : \t\"%s\"", + senderName.c_str(), + groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); chatInGroup( grpId, ucstr, sender ); } break; case CChatGroup::dyn_chat: - { + { TChanID chanID = itCl->second->getDynChatChan(); CDynChatSession *session = _DynChat.getSession(chanID, sender); if (session) // player must have a session in that channel @@ -650,7 +659,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) if (!session->getChan()->getDontBroadcastPlayerInputs()) { - // add msg to the historic + // add msg to the historic CDynChatChan::CHistoricEntry entry; entry.String = ucstr; if (ci != NULL) @@ -671,15 +680,15 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) ucstring tmp("{no_bubble}"); if (ucstr.find(tmp) == ucstring::npos) { - tmp += ucstr; + tmp += ucstr; content.swap(tmp); } else { content = ucstr; } - } - + } + // broadcast to other client in the channel CDynChatSession *dcc = session->getChan()->getFirstSession(); @@ -687,7 +696,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) { sendChat(itCl->second->getChatMode(), dcc->getClient()->getID(), content, sender, chanID); dcc = dcc->getNextChannelSession(); // next session in this channel - } + } } else { @@ -702,11 +711,11 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) TPlayerInputForward pif; pif.ChanID = chanID; pif.Sender = sender; - pif.Content = ucstr; + pif.Content = ucstr; CMessage msgout( "DYN_CHAT:FORWARD"); msgout.serial(pif); - + CUnifiedNetwork::getInstance()->send(serviceId, msgout); } if (session->getChan()->getUnifiedChannel()) @@ -716,19 +725,19 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) IChatUnifierClient::getInstance()->sendUnifiedDynChat(session->getChan()->getID(), senderName, ucstr); } } - } + } } break; // static group default : nlwarning(" client %u chat in %s ! don't know how to handle it.", - sender.getIndex(), + sender.getIndex(), groupNames[itCl->second->getChatMode()]); /* { TGroupId grpId = itCl->second.getChatGroup(); _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second.getChatMode()], ucstr.toString().c_str() ); - + chatInGroup( grpId, ucstr, sender ); } */ } @@ -736,8 +745,8 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // log chat to PDS system // IOSPD::logChat(ucstr, itCl->second->getId(), _DestUsers); log_Chat_Chat(CChatGroup::groupTypeToString(itCl->second->getChatMode()), - TheDataset.getEntityId(sender), - ucstr.toUtf8(), + TheDataset.getEntityId(sender), + ucstr.toUtf8(), _DestUsers); } @@ -770,7 +779,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD CMirrorPropValueRO instanceId( TheDataset, *itM, DSPropertyAI_INSTANCE ); // check the ai instance for region chat - if (chatGrp.Type != CChatGroup::region + if (chatGrp.Type != CChatGroup::region || instanceId == senderInstanceId) { // check homeSessionId for universe @@ -795,7 +804,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD _DestUsers.push_back(TheDataset.getEntityId(*itM)); } } - } + } if (chatGrp.Type == CChatGroup::guild) { @@ -855,7 +864,7 @@ void CChatManager::farChatInGroup(TGroupId &grpId, uint32 homeSessionId, const u continue; } sendFarChat( itGrp->second.Type, *itM, text, senderName ); - } + } } else { @@ -885,7 +894,7 @@ void CChatManager::chat2( const TDataSetRow& sender, const std::string &phraseId case CChatGroup::shout : { CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -900,7 +909,7 @@ void CChatManager::chat2( const TDataSetRow& sender, const std::string &phraseId chatInGroup2( grpId, phraseId, sender ); } break; - + case CChatGroup::universe: { @@ -937,7 +946,7 @@ void CChatManager::chat2( const TDataSetRow& sender, const std::string &phraseId { nlwarning(" client %s:%x chat in mode %u ! don't know how to handle it.", TheDataset.getEntityId(sender).toString().c_str(), - sender.getIndex(), + sender.getIndex(), itCl->second->getChatMode()); } } @@ -973,7 +982,7 @@ void CChatManager::chatParam( const TDataSetRow& sender, const std::string &phra case CChatGroup::shout : { CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -988,7 +997,7 @@ void CChatManager::chatParam( const TDataSetRow& sender, const std::string &phra chatParamInGroup( grpId, phraseId, params, sender ); } break; - + case CChatGroup::universe: { @@ -1025,7 +1034,7 @@ void CChatManager::chatParam( const TDataSetRow& sender, const std::string &phra { nlwarning(" client %s:%x chat in mode %u ! don't know how to handle it.", TheDataset.getEntityId(sender).toString().c_str(), - sender.getIndex(), + sender.getIndex(), itCl->second->getChatMode()); } } @@ -1049,7 +1058,7 @@ void CChatManager::chat2Ex( const TDataSetRow& sender, uint32 phraseId) CEntityId eid = TheDataset.getEntityId(sender); if(_MutedUsers.find( eid ) != _MutedUsers.end()) { - nldebug("IOSCM: chat2Ex The player %s:%x is muted", + nldebug("IOSCM: chat2Ex The player %s:%x is muted", TheDataset.getEntityId(sender).toString().c_str(), sender.getIndex()); return; @@ -1061,7 +1070,7 @@ void CChatManager::chat2Ex( const TDataSetRow& sender, uint32 phraseId) case CChatGroup::shout : { CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -1076,7 +1085,7 @@ void CChatManager::chat2Ex( const TDataSetRow& sender, uint32 phraseId) chatInGroup2Ex( grpId, phraseId, sender ); } break; - + case CChatGroup::universe: { CEntityId eid = TheDataset.getEntityId(sender); @@ -1098,21 +1107,21 @@ void CChatManager::chat2Ex( const TDataSetRow& sender, uint32 phraseId) chatInGroup2Ex( grpId, phraseId, sender ); } break; - + case CChatGroup::guild: { TGroupId grpId = itCl->second->getGuildChatGroup(); chatInGroup2Ex( grpId, phraseId, sender ); } break; - - + + // static group default : { nlwarning(" client %s:%x chat in mode %u ! don't know how to handle it.", TheDataset.getEntityId(sender).toString().c_str(), - sender.getIndex(), + sender.getIndex(), itCl->second->getChatMode()); // TGroupId grpId = (*itCl).second.getChatGroup(); // chatInGroup2( grpId, phraseId, sender ); @@ -1141,7 +1150,7 @@ void CChatManager::chatInGroup2Ex( TGroupId& grpId, uint32 phraseId, const TData { CMirrorPropValueRO instanceId( TheDataset, *itM, DSPropertyAI_INSTANCE ); - if (chatGrp.Type != CChatGroup::region + if (chatGrp.Type != CChatGroup::region || instanceId == senderInstanceId) { const CEntityId &eid = TheDataset.getEntityId(*itM); @@ -1184,14 +1193,14 @@ void CChatManager::chatInGroup2( TGroupId& grpId, const std::string & phraseId, CMirrorPropValueRO instanceId( TheDataset, *itM, DSPropertyAI_INSTANCE ); // check the ai instance for region chat - if (chatGrp.Type != CChatGroup::region + if (chatGrp.Type != CChatGroup::region || instanceId == senderInstanceId) { const CEntityId &eid = TheDataset.getEntityId(*itM); if (eid.getType() == RYZOMID::player && std::find( excluded.begin(), excluded.end(), *itM ) == excluded.end() ) sendChat2( (*itGrp ).second.Type, *itM, phraseId, sender ); } - } + } if (chatGrp.Type == CChatGroup::guild) { CCharacterInfos *charInfos = IOS->getCharInfos(TheDataset.getEntityId(sender)); @@ -1232,7 +1241,7 @@ void CChatManager::chatParamInGroup( TGroupId& grpId, const std::string & phrase if (eid.getType() == RYZOMID::player && std::find( excluded.begin(), excluded.end(), *itM ) == excluded.end() ) sendChat2( (*itGrp ).second.Type, *itM, phraseId, sender ); } - } + } if (chatGrp.Type == CChatGroup::guild) { CCharacterInfos *charInfos = IOS->getCharInfos(TheDataset.getEntityId(sender)); @@ -1278,10 +1287,10 @@ void CChatManager::sendEmoteTextToAudience( const TDataSetRow& sender,const std TChanID oldChan = itCl->second->getDynChatChan(); itCl->second->setChatMode(CChatGroup::say); itCl->second->updateAudience(); - + // get audience around the emoting player CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -1329,10 +1338,10 @@ void CChatManager::sendEmoteCustomTextToAll( const TDataSetRow& sender, const uc TChanID oldChan = itCl->second->getDynChatChan(); itCl->second->setChatMode(CChatGroup::say); itCl->second->updateAudience(); - + // get audience around the emoting player CChatGroup::TMemberCont::iterator itA; - for( itA = itCl->second->getAudience().Members.begin(); + for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) { @@ -1347,7 +1356,7 @@ void CChatManager::sendEmoteCustomTextToAll( const TDataSetRow& sender, const uc TheDataset.getEntityId(sender).toString().c_str(), sender.getIndex()); } - + } @@ -1386,7 +1395,7 @@ void CChatManager::sendEmoteCustomTextToAll( const TDataSetRow& sender, const uc // bms.serial( index ); // bms.serial( infos->Str ); // } -// +// //// nldebug(" sending association [%s,%d] to %s",infos->Str.c_str(),index,receiver.toString().c_str()); // msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); // sendMessageViaMirror(frontendId, msgout); @@ -1406,7 +1415,7 @@ void CChatManager::sendEmoteCustomTextToAll( const TDataSetRow& sender, const uc // //----------------------------------------------- void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataSetRow &receiver, const ucstring& ucstr, const TDataSetRow &sender, TChanID chanID, const ucstring &senderName) -{ +{ //if( receiver != sender ) { CCharacterInfos * charInfos = NULL; @@ -1440,14 +1449,14 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS } uint32 senderNameIndex; - // if the sender exists + // if the sender exists if( charInfos ) { senderNameIndex = charInfos->NameIndex; } else { - // if no sender, we use a special name + // if no sender, we use a special name ucstring senderName(""); senderNameIndex = SM->storeString( senderName ); } @@ -1466,14 +1475,14 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:CHAT", bms ); - + CChatMsg chatMsg; chatMsg.CompressedIndex = sender.getCompressedIndex(); chatMsg.SenderNameId = senderNameIndex; chatMsg.ChatMode = (uint8) senderChatMode; if (senderChatMode == CChatGroup::dyn_chat) - { - chatMsg.DynChatChanID = chanID; + { + chatMsg.DynChatChanID = chanID; } chatMsg.Content = ucstr; bms.serial( chatMsg ); @@ -1483,7 +1492,7 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS chatMsg.Sender, receiver.toString().c_str(), chatMsg.ChatMode); - */ + */ msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror(TServiceId(receiverInfos->EntityId.getDynamicId()), msgout); } @@ -1500,7 +1509,7 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS nlwarning(" The character %s:%x is unknown, no chat msg sent", TheDataset.getEntityId(receiver).toString().c_str(), receiver.getIndex()); - } + } } } // sendChat // @@ -1526,14 +1535,14 @@ void CChatManager::sendFarChat( CChatGroup::TGroupType senderChatMode, const TDa msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:CHAT", bms ); - + CChatMsg chatMsg; chatMsg.CompressedIndex = 0xFFFFF; chatMsg.SenderNameId = senderNameIndex; chatMsg.ChatMode = (uint8) senderChatMode; if (senderChatMode == CChatGroup::dyn_chat) - { - chatMsg.DynChatChanID = chanID; + { + chatMsg.DynChatChanID = chanID; } chatMsg.Content = ucstr; bms.serial( chatMsg ); @@ -1554,7 +1563,7 @@ void CChatManager::sendFarChat( CChatGroup::TGroupType senderChatMode, const TDa nlwarning(" The character %s:%x is unknown, no chat msg sent", TheDataset.getEntityId(receiver).toString().c_str(), receiver.getIndex()); - } + } } @@ -1584,7 +1593,7 @@ void CChatManager::sendChatParam( CChatGroup::TGroupType senderChatMode, const T { TVectorParamCheck params2; params2.resize( params.size() + 1); - // send the chat phrase to the client + // send the chat phrase to the client params2[0].Type = STRING_MANAGER::bot; params2[0].setEId( TheDataset.getEntityId(sender) ); uint32 first = 0, last = (uint32)params.size(); @@ -1643,7 +1652,7 @@ void CChatManager::sendChat2Ex( CChatGroup::TGroupType senderChatMode, const TDa msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:CHAT2", bms ); - + CChatMsg2 chatMsg; chatMsg.CompressedIndex = sender.getCompressedIndex(); chatMsg.SenderNameId = charInfos ? charInfos->NameIndex : 0; // empty string if there is no sender @@ -1651,7 +1660,7 @@ void CChatManager::sendChat2Ex( CChatGroup::TGroupType senderChatMode, const TDa chatMsg.PhraseId = phraseId; chatMsg.CustomTxt = customTxt; bms.serial( chatMsg ); - + msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); CUnifiedNetwork::getInstance()->send(TServiceId(receiverInfos->EntityId.getDynamicId()), msgout); } @@ -1677,9 +1686,9 @@ void CChatManager::sendChat2Ex( CChatGroup::TGroupType senderChatMode, const TDa // //----------------------------------------------- void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSetRow &receiver, const ucstring& ucstr ) -{ +{ TDataSetRow senderFake = TDataSetRow::createFromRawIndex( INVALID_DATASET_ROW ); - + CCharacterInfos * receiverInfos = IOS->getCharInfos( TheDataset.getEntityId(receiver) ); CCharacterInfos * senderInfos = IOS->getCharInfos( TheDataset.getEntityId(sender) ); if( receiverInfos ) @@ -1698,7 +1707,7 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe { return; } - + // send the string to FE CMessage msgout( "IMPULS_CH_ID" ); uint8 channel = 1; @@ -1707,7 +1716,7 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:CHAT", bms ); - + CChatMsg chatMsg; chatMsg.CompressedIndex = senderFake.getCompressedIndex(); chatMsg.SenderNameId = 0; @@ -1785,7 +1794,7 @@ void CChatManager::tell2( const TDataSetRow& sender, const TDataSetRow& receiver TheDataset.getEntityId(receiver).toString().c_str() ); return; } - + // check if the sender is CSR or is not in the ignore list of the receiver if(senderInfos->HavePrivilege || !itCl->second->isInIgnoreList(sender) ) { @@ -1802,10 +1811,10 @@ void CChatManager::tell2( const TDataSetRow& sender, const TDataSetRow& receiver msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:TELL2", bms); - + bms.serial( senderInfos->NameIndex ); bms.serial( id); - + msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); CUnifiedNetwork::getInstance()->send(TServiceId(receiverInfos->EntityId.getDynamicId()), msgout); } @@ -1938,8 +1947,8 @@ void CChatManager::tell( const TDataSetRow& sender, const string& receiverIn, co */ _Log.displayNL("'%s' to '%s' (%s) : \t\"%s\"", senderName.c_str(), receiverName.c_str(), "tell", ucstr.toString().c_str() ); - - + + // if the client doesn't know this dynamic string(name of sender), we send it to him // send the string to FE CMessage msgout( "IMPULS_CH_ID" ); @@ -1948,12 +1957,12 @@ void CChatManager::tell( const TDataSetRow& sender, const string& receiverIn, co msgout.serial( channel ); CBitMemStream bms; GenericXmlMsgHeaderMngr.pushNameToStream( "STRING:TELL", bms); - + TDataSetIndex dsi = senderInfos->DataSetIndex.getCompressedIndex(); bms.serial( dsi ); bms.serial( senderInfos->NameIndex ); bms.serial( const_cast(ucstr) ); - + msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror(TServiceId(receiverInfos->EntityId.getDynamicId()), msgout); @@ -2088,8 +2097,8 @@ void CChatManager::farTell( const NLMISC::CEntityId &senderCharId, const ucstrin string receiverName = receiverInfos->Name.toString(); _Log.displayNL("'%s' to '%s' (%s) : \t\"%s\"", senderName.toUtf8().c_str(), receiverName.c_str(), "tell", ucstr.toString().c_str() ); - - + + // if the client doesn't know this dynamic string(name of sender), we send it to him // send the string to FE CMessage msgout( "IMPULS_CH_ID" ); @@ -2103,7 +2112,7 @@ void CChatManager::farTell( const NLMISC::CEntityId &senderCharId, const ucstrin ftm.SenderName = senderName; ftm.Text = ucstr; ftm.serial(bms); - + msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror(TServiceId(receiverInfos->EntityId.getDynamicId()), msgout); @@ -2134,19 +2143,19 @@ void CChatManager::displayChatClients(NLMISC::CLog &log) if (ci != NULL) { if (ci->EntityId.getType() == RYZOMID::player) - log.displayNL("'%s' %s:%x %s mode '%s'", - ci->Name.toString().c_str(), - ci->EntityId.toString().c_str(), - im->first.getIndex(), - im->second->isMuted()?"(muted)":"", + log.displayNL("'%s' %s:%x %s mode '%s'", + ci->Name.toString().c_str(), + ci->EntityId.toString().c_str(), + im->first.getIndex(), + im->second->isMuted()?"(muted)":"", CChatGroup::groupTypeToString(im->second->getChatMode()).c_str() ); } else { - log.displayNL("*no name* %s:%x %s mode '%s'", - ci->EntityId.toString().c_str(), - im->first.getIndex(), - im->second->isMuted()?"(muted)":"", + log.displayNL("*no name* %s:%x %s mode '%s'", + ci->EntityId.toString().c_str(), + im->first.getIndex(), + im->second->isMuted()?"(muted)":"", CChatGroup::groupTypeToString(im->second->getChatMode()).c_str() ); } } @@ -2157,17 +2166,17 @@ void CChatManager::displayChatGroup(NLMISC::CLog &log, TGroupId gid, CChatGroup { if (chatGroup.GroupName == CStringMapper::emptyId()) { - log.displayNL("Group : anonym (%s), %s : %u clients :", + log.displayNL("Group : anonym (%s), %s : %u clients :", gid.toString().c_str(), - CChatGroup::groupTypeToString(chatGroup.Type).c_str(), + CChatGroup::groupTypeToString(chatGroup.Type).c_str(), chatGroup.Members.size()); } else { - log.displayNL("Group : '%s' (%s), %s : %u clients :", + log.displayNL("Group : '%s' (%s), %s : %u clients :", CStringMapper::unmap(chatGroup.GroupName).c_str(), - gid.toString().c_str(), - CChatGroup::groupTypeToString(chatGroup.Type).c_str(), + gid.toString().c_str(), + CChatGroup::groupTypeToString(chatGroup.Type).c_str(), chatGroup.Members.size()); } @@ -2179,12 +2188,12 @@ void CChatManager::displayChatGroup(NLMISC::CLog &log, TGroupId gid, CChatGroup { CCharacterInfos *ci = IOS->getCharInfos(TheDataset.getEntityId(*first)); if (ci != NULL) - log.displayNL(" '%s' %s:%x", - ci->Name.toString().c_str(), + log.displayNL(" '%s' %s:%x", + ci->Name.toString().c_str(), ci->EntityId.toString().c_str(), first->getIndex()); else - log.displayNL(" *unknow* %s:%x", + log.displayNL(" *unknow* %s:%x", eid.toString().c_str(), first->getIndex()); } @@ -2262,13 +2271,13 @@ void CChatManager::displayChatAudience(NLMISC::CLog &log, const CEntityId &eid, { CCharacterInfos *ci = IOS->getCharInfos(TheDataset.getEntityId(*first)); if (ci != NULL) - log.displayNL(" '%s' %s:%x", - ci->Name.toString().c_str(), + log.displayNL(" '%s' %s:%x", + ci->Name.toString().c_str(), TheDataset.getEntityId(*first).toString().c_str(), first->getIndex()); - + else - log.displayNL(" *unknow* %s:%x", + log.displayNL(" *unknow* %s:%x", TheDataset.getEntityId(*first).toString().c_str(), first->getIndex()); } @@ -2301,9 +2310,9 @@ ucstring CChatManager::filterClientInputColorCode(ucstring &text) { ucstring result; result.reserve(text.size()); - + ucstring::size_type pos = 0; - + for (; pos < text.size(); ++pos) { if (text[pos] == '@' && pos < text.size()-1 && text[pos+1] == '{') @@ -2316,7 +2325,7 @@ ucstring CChatManager::filterClientInputColorCode(ucstring &text) result += text[pos]; } } - + return result; } @@ -2340,7 +2349,7 @@ ucstring CChatManager::filterClientInput(ucstring &text) bool lastIsWhite = false; for (; pos < text.size(); ++pos) { - bool currentIsWhite = (text[pos] == ' ' || text[pos] == '\t'); + bool currentIsWhite = (text[pos] == ' ' || text[pos] == '\t'); if (!(lastIsWhite && currentIsWhite)) { // any double white skipped @@ -2353,7 +2362,7 @@ ucstring CChatManager::filterClientInput(ucstring &text) hasBrackets = (text[pos-1] == '>') && (text[pos-5] == '<'); } - // Filter out '&' at the first non-whitespace position to remove + // Filter out '&' at the first non-whitespace position to remove // system color code (like '&SYS&' ) bool disallowAmpersand = (result.size() == 0) || hasBrackets; if (disallowAmpersand) diff --git a/code/ryzom/server/src/input_output_service/chat_manager.h b/code/ryzom/server/src/input_output_service/chat_manager.h index 9e2d20e8c..544dbfa2c 100644 --- a/code/ryzom/server/src/input_output_service/chat_manager.h +++ b/code/ryzom/server/src/input_output_service/chat_manager.h @@ -42,14 +42,14 @@ - + /** * CChatManager * \author Stephane Coutelas * \author Nevrax France * \date 2002 */ -class CChatManager +class CChatManager { public : @@ -72,7 +72,7 @@ public : */ void init( /*const std::string& staticDBFileName, const std::string& dynDBFileName*/ ); - /** A service has gone down + /** A service has gone down */ void onServiceDown(const std::string &serviceShortName); @@ -80,7 +80,7 @@ public : * Reset ChatLog management */ void resetChatLog(); - + /** * Check if the client is already registered in the chat manager. */ @@ -102,7 +102,7 @@ public : * \param id is the client character id */ CChatClient& getClient( const TDataSetRow& id ); //throw (EChatClient); - + /** * Return a reference on the static database */ @@ -195,7 +195,7 @@ public : void chat2( const TDataSetRow& sender, const std::string &phraseId ); - + /** * Transmit a chat message * \param sender is the id of the talking char @@ -334,7 +334,7 @@ public : private : - + typedef std::map< TDataSetRow, CChatClient*> TClientInfoCont; /// client infos TClientInfoCont _Clients; @@ -377,7 +377,7 @@ protected: friend void cbNpcTellEx( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ); friend void cbDynChatServiceChat( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ); friend void cbDynChatServiceTell( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ); - + public: /** * Send a chat message @@ -389,7 +389,7 @@ public: * \param senderName Can be used to replace the sender name with a specific string */ void sendChat( CChatGroup::TGroupType senderChatMode, const TDataSetRow &receiver, const ucstring& ucstr, const TDataSetRow &sender = TDataSetRow(), TChanID chanID = NLMISC::CEntityId::Unknown, const ucstring &senderName = ucstring()); - + /** * Send a far chat message diff --git a/code/ryzom/server/src/server_share/continent_container.h b/code/ryzom/server/src/server_share/continent_container.h index 7edfb0c96..6e65b3dc4 100644 --- a/code/ryzom/server/src/server_share/continent_container.h +++ b/code/ryzom/server/src/server_share/continent_container.h @@ -162,7 +162,7 @@ public: /// Init whole continent container void init(uint gridWidth, uint gridHeight, double primitiveMaxSize, uint nbWorldImages, const std::string &packedSheetsDirectory, double cellSize=0.0, bool loadPacsPrims = true); - + /// Build sheets void buildSheets(const std::string &packedSheetsDirectory); diff --git a/code/ryzom/server/src/server_share/mysql_wrapper.cpp b/code/ryzom/server/src/server_share/mysql_wrapper.cpp index 5b993b56e..3bb343314 100644 --- a/code/ryzom/server/src/server_share/mysql_wrapper.cpp +++ b/code/ryzom/server/src/server_share/mysql_wrapper.cpp @@ -116,7 +116,7 @@ namespace MSW if (MSWAutoReconnect) { addOption(MYSQL_OPT_RECONNECT, "1"); - } + } return _connect(); } diff --git a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.cpp b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.cpp index 9e81798dc..238b2b49e 100644 --- a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.cpp +++ b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.cpp @@ -1,3 +1,18 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . ///////////////////////////////////////////////////////////////// // WARNING : this is a generated file, don't change it ! @@ -303,7 +318,7 @@ namespace RSMGR } else if (cmd == NOPE::cc_instance_count) { - return _ObjectCache.size(); + return (uint32)_ObjectCache.size(); } // default return value @@ -321,7 +336,7 @@ namespace RSMGR TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end()); for (; first != last; ++first) { - nbReleased += first->second.size(); + nbReleased += (uint32)first->second.size(); } nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased); @@ -781,7 +796,7 @@ namespace RSMGR } else if (cmd == NOPE::cc_instance_count) { - return _ObjectCache.size(); + return (uint32)_ObjectCache.size(); } // default return value @@ -799,7 +814,7 @@ namespace RSMGR TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end()); for (; first != last; ++first) { - nbReleased += first->second.size(); + nbReleased += (uint32)first->second.size(); } nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased); diff --git a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h index 50ef8e823..685386bfc 100644 --- a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h +++ b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h @@ -1,3 +1,18 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . ///////////////////////////////////////////////////////////////// // WARNING : this is a generated file, don't change it ! @@ -661,7 +676,6 @@ namespace RSMGR setPersistentState(NOPE::os_dirty); _DomainId = value; - } } diff --git a/code/ryzom/tools/client/CMakeLists.txt b/code/ryzom/tools/client/CMakeLists.txt index aabc3142c..0c42233cb 100644 --- a/code/ryzom/tools/client/CMakeLists.txt +++ b/code/ryzom/tools/client/CMakeLists.txt @@ -1,10 +1,9 @@ - IF(WITH_RYZOM_CLIENT) - ADD_SUBDIRECTORY( client_patcher ) - - IF( WITH_QT ) - ADD_SUBDIRECTORY( client_config_qt ) - ENDIF( WITH_QT ) -ENDIF(WITH_RYZOM_CLIENT) + ADD_SUBDIRECTORY(client_patcher) + + IF(WITH_QT) + ADD_SUBDIRECTORY(client_config_qt) + ENDIF() +ENDIF() -ADD_SUBDIRECTORY( r2_islands_textures ) +ADD_SUBDIRECTORY(r2_islands_textures) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index 4f167ea9c..69f701054 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -1540,7 +1540,6 @@ void CScreenshotIslands::buildIslandsTextures() CIFile proxFS(proxFileName.c_str()); proxBitmap.load(proxFS); - // resize proximity bitmap CBitmap tempBitmap; int newWidth = islandBitmap.getWidth(); @@ -1568,7 +1567,7 @@ void CScreenshotIslands::buildIslandsTextures() // swap them proxBitmap.resize(newWidth, newHeight, proxBitmap.PixelFormat); proxBitmap.swap(tempBitmap); - + //proxBitmap.resample(newWidth, newHeight); diff --git a/code/ryzom/tools/leveldesign/CMakeLists.txt b/code/ryzom/tools/leveldesign/CMakeLists.txt index 9a56a2fac..399a71deb 100644 --- a/code/ryzom/tools/leveldesign/CMakeLists.txt +++ b/code/ryzom/tools/leveldesign/CMakeLists.txt @@ -1,4 +1,3 @@ - ADD_SUBDIRECTORY(uni_conv) ADD_SUBDIRECTORY(csv_transform) ADD_SUBDIRECTORY(icon_search) diff --git a/code/ryzom/tools/server/CMakeLists.txt b/code/ryzom/tools/server/CMakeLists.txt index 982c47718..1f215ae94 100644 --- a/code/ryzom/tools/server/CMakeLists.txt +++ b/code/ryzom/tools/server/CMakeLists.txt @@ -1,4 +1,3 @@ - IF(WITH_LIGO) ADD_SUBDIRECTORY(ai_build_wmap) ENDIF(WITH_LIGO) diff --git a/code/ryzom/tools/server/brick_param_extractor/brick_param_extractor.cpp b/code/ryzom/tools/server/brick_param_extractor/brick_param_extractor.cpp index 1a4257a99..170aa0c90 100644 --- a/code/ryzom/tools/server/brick_param_extractor/brick_param_extractor.cpp +++ b/code/ryzom/tools/server/brick_param_extractor/brick_param_extractor.cpp @@ -508,7 +508,7 @@ void COutputFile::generateOutput() const } outbuff+="#endif\n\n"; - + // read in the previous version of the output file char *inbuff=NULL; FILE *inf=fopen(_FileName.c_str(),"rb"); From 6596af9682b2c50e5c59f82d90e48a7b166f996a Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 26 Dec 2014 13:38:02 +0100 Subject: [PATCH 176/344] Changed: Minor changes --HG-- branch : develop --- code/nel/include/nel/3d/driver.h | 3 +-- code/nel/include/nel/misc/p_thread.h | 6 ++--- .../nel/samples/3d/nel_qt/qtcolorpicker_cpp.h | 4 ++-- .../3d/driver/direct3d/driver_direct3d.cpp | 3 --- .../src/3d/driver/opengl/driver_opengl.cpp | 2 +- .../driver/opengl/driver_opengl_material.cpp | 2 +- .../3d/driver/opengl/driver_opengl_states.cpp | 4 ++-- code/nel/src/3d/meshvp_wind_tree.cpp | 3 +-- code/nel/src/3d/scene.cpp | 4 +--- code/nel/src/3d/shadow_map_manager.cpp | 2 +- code/nel/src/3d/transform.cpp | 2 +- code/nel/src/georges/form_dfn.cpp | 2 +- code/nel/src/misc/p_thread.cpp | 4 ++-- code/nel/src/misc/sheet_id.cpp | 12 +++++----- code/nel/src/misc/win_thread.cpp | 2 +- .../src/sound/driver/dsound/source_dsound.h | 4 ++-- .../nel/src/sound/driver/fmod/source_fmod.cpp | 2 +- .../nel/src/sound/driver/openal/buffer_al.cpp | 4 ++-- code/nel/src/sound/simple_source.cpp | 2 +- code/nel/tools/CMakeLists.txt | 1 - code/ryzom/client/src/actions.h | 2 +- code/ryzom/client/src/cdb_synchronised.cpp | 2 +- code/ryzom/client/src/character_cl.cpp | 2 +- code/ryzom/client/src/client.cpp | 1 - code/ryzom/client/src/client_chat_manager.cpp | 4 ---- code/ryzom/client/src/entities.cpp | 2 +- code/ryzom/client/src/entity_cl.cpp | 5 ++-- code/ryzom/client/src/far_tp.cpp | 1 - code/ryzom/client/src/init.cpp | 6 ++--- .../src/interface_v3/action_handler_game.cpp | 3 ++- .../src/interface_v3/action_handler_help.cpp | 2 +- .../src/interface_v3/action_handler_misc.cpp | 2 +- .../interface_v3/action_handler_phrase.cpp | 3 +-- .../client/src/interface_v3/chat_displayer.h | 1 - .../src/interface_v3/chat_text_manager.cpp | 3 +-- .../interface_v3/group_in_scene_user_info.cpp | 9 +++---- .../client/src/interface_v3/group_map.cpp | 2 +- .../client/src/interface_v3/group_skills.cpp | 2 +- .../client/src/interface_v3/guild_manager.cpp | 5 ++-- .../src/interface_v3/interface_manager.cpp | 2 -- .../src/interface_v3/interface_observer.h | 2 +- .../src/interface_v3/people_interraction.cpp | 1 - .../client/src/interface_v3/people_list.cpp | 2 +- .../src/interface_v3/sphrase_manager.cpp | 24 +++++++++---------- code/ryzom/client/src/sound_manager.cpp | 8 +++---- code/ryzom/client/src/user_entity.cpp | 2 +- code/ryzom/common/data_common/r2/r2_misc.lua | 2 +- .../world_editor_classes.xml | 10 ++++---- 48 files changed, 78 insertions(+), 100 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 8738a7dda..39cafc2de 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -493,7 +493,7 @@ public: * * NB: you must setupViewMatrix() BEFORE setupModelMatrix(), or else undefined results. */ - virtual void setupViewMatrix(const CMatrix &mtx)=0; + virtual void setupViewMatrix(const CMatrix &mtx) = 0; /** setup the view matrix (inverse of camera matrix). * Extended: give a cameraPos (mtx.Pos() is not taken into account but for getViewMatrix()), @@ -1422,7 +1422,6 @@ protected: private: bool _StaticMemoryToVRAM; - }; // -------------------------------------------------- diff --git a/code/nel/include/nel/misc/p_thread.h b/code/nel/include/nel/misc/p_thread.h index 4f0a9aa63..01f476d7b 100644 --- a/code/nel/include/nel/misc/p_thread.h +++ b/code/nel/include/nel/misc/p_thread.h @@ -39,9 +39,9 @@ class CPThread : public IThread public: enum TThreadState { - ThreadStateNone, - ThreadStateRunning, - ThreadStateFinished, + ThreadStateNone, + ThreadStateRunning, + ThreadStateFinished, }; /// Constructor diff --git a/code/nel/samples/3d/nel_qt/qtcolorpicker_cpp.h b/code/nel/samples/3d/nel_qt/qtcolorpicker_cpp.h index 0701a803f..2386ff939 100644 --- a/code/nel/samples/3d/nel_qt/qtcolorpicker_cpp.h +++ b/code/nel/samples/3d/nel_qt/qtcolorpicker_cpp.h @@ -543,14 +543,14 @@ ColorPickerPopup::ColorPickerPopup(int width, bool withColorDialog, setMouseTracking(true); cols = width; - if (withColorDialog) + if (withColorDialog) { moreButton = new ColorPickerButton(this); moreButton->setFixedWidth(24); moreButton->setFixedHeight(21); moreButton->setFrameRect(QRect(2, 2, 20, 17)); connect(moreButton, SIGNAL(clicked()), SLOT(getColorFromDialog())); - } + } else { moreButton = 0; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 916cafe49..2ce747105 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1509,9 +1509,6 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r } } - -// _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶meters, &_DeviceInterface); - // Check some caps D3DCAPS9 caps; if (_DeviceInterface->GetDeviceCaps(&caps) == D3D_OK) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index ce60d7f42..d129f3aa2 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -2178,7 +2178,7 @@ void CDriverGL::flush() // *************************************************************************** void CDriverGL::setSwapVBLInterval(uint interval) { - H_AUTO_OGL(CDriverGL_setSwapVBLInterval) + H_AUTO_OGL(CDriverGL_setSwapVBLInterval); if (!_Initialized) return; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp index 986dd6303..95c8e61f2 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp @@ -403,7 +403,7 @@ bool CDriverGL::setupMaterial(CMaterial& mat) // Must setup textures each frame. (need to test if touched). // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader != CMaterial::Water + if (matShader != CMaterial::Water && ((matShader != CMaterial::Program) || (_LastSetuppedPP->features().MaterialFlags & CProgramFeatures::TextureStages)) ) { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp index 60a0609dc..9bf53592f 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp @@ -767,7 +767,7 @@ void CDriverGLStates::setTextureMode(TTextureMode texMode) { glDisable(GL_TEXTURE_2D); } - else if(oldTexMode == TextureRect) + else if (oldTexMode == TextureRect) { #ifndef USE_OPENGLES if(_TextureRectangleSupported) @@ -780,7 +780,7 @@ void CDriverGLStates::setTextureMode(TTextureMode texMode) glDisable(GL_TEXTURE_2D); } } - else if(oldTexMode == TextureCubeMap) + else if (oldTexMode == TextureCubeMap) { if(_TextureCubeMapSupported) { diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 0d2e91363..1e3d215a3 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -392,7 +392,6 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m sint numPls= renderTrav->getNumVPLights()-1; clamp(numPls, 0, CRenderTrav::MaxVPLight-1); - // Enable normalize only if requested by user. Because lighting don't manage correct "scale lighting" uint idVP= (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; // correct VP id for correct unmber of pls. @@ -523,7 +522,7 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase idVP = numPls*4 + idVP; // re-activate VP if idVP different from last setup - if(idVP != _LastMBRIdVP) + if (idVP != _LastMBRIdVP) { _LastMBRIdVP= idVP; driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index 67465eb8c..7c552efd4 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -158,7 +158,7 @@ CScene::CScene(bool bSmallScene) : LightTrav(bSmallScene) _MaxSkeletonsInNotCLodForm= 20; - _FilterRenderFlags= std::numeric_limits::max(); + _FilterRenderFlags = std::numeric_limits::max(); _NextRenderProfile= false; @@ -592,11 +592,9 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, boo // nlassert(CurrentCamera); - // update models. updateModels(); - // Use the camera to setup Clip / Render pass. float left, right, bottom, top, znear, zfar; CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar); diff --git a/code/nel/src/3d/shadow_map_manager.cpp b/code/nel/src/3d/shadow_map_manager.cpp index 383a28184..0c9f7ba8b 100644 --- a/code/nel/src/3d/shadow_map_manager.cpp +++ b/code/nel/src/3d/shadow_map_manager.cpp @@ -244,7 +244,7 @@ void CShadowMapManager::addShadowReceiver(CTransform *model) void CShadowMapManager::renderGenerate(CScene *scene) { H_AUTO( NL3D_ShadowManager_Generate ); - + // Each frame, do a small garbage collector for unused free textures. garbageShadowTextures(scene); diff --git a/code/nel/src/3d/transform.cpp b/code/nel/src/3d/transform.cpp index c12754c57..0ec65360d 100644 --- a/code/nel/src/3d/transform.cpp +++ b/code/nel/src/3d/transform.cpp @@ -113,7 +113,7 @@ CTransform::CTransform() _StateFlags= IsOpaque | IsUserLightable; // By default, always allow rendering of Transform Models. - _RenderFilterType= std::numeric_limits::max(); + _RenderFilterType = std::numeric_limits::max(); // By default, don't suport fast intersection detection _SupportFastIntersect= false; diff --git a/code/nel/src/georges/form_dfn.cpp b/code/nel/src/georges/form_dfn.cpp index d4a16bb50..16ee74d5b 100644 --- a/code/nel/src/georges/form_dfn.cpp +++ b/code/nel/src/georges/form_dfn.cpp @@ -707,7 +707,7 @@ bool CFormDfn::getEntryIndexByName (uint &entry, const std::string &name) const } entryIndex++; } - entry=std::numeric_limits::max(); + entry = std::numeric_limits::max(); return false; } diff --git a/code/nel/src/misc/p_thread.cpp b/code/nel/src/misc/p_thread.cpp index a24029b3c..e71f56611 100644 --- a/code/nel/src/misc/p_thread.cpp +++ b/code/nel/src/misc/p_thread.cpp @@ -17,8 +17,8 @@ #include "stdmisc.h" -#include -#include +#include "nel/misc/types_nl.h" +#include "nel/misc/debug.h" #ifdef NL_OS_UNIX diff --git a/code/nel/src/misc/sheet_id.cpp b/code/nel/src/misc/sheet_id.cpp index 83dd4be89..690d09ab1 100644 --- a/code/nel/src/misc/sheet_id.cpp +++ b/code/nel/src/misc/sheet_id.cpp @@ -217,7 +217,7 @@ bool CSheetId::buildSheetId(const std::string& sheetName) return true; } } - + #ifdef NL_TEMP_YUBO_NO_SOUND_SHEET_ID if (a_NoSoundSheetId && sheetName.find(".sound") != std::string::npos) { @@ -236,7 +236,7 @@ bool CSheetId::buildSheetId(const std::string& sheetName) return true; } #endif - + return false; } @@ -417,10 +417,10 @@ void CSheetId::initWithoutSheet() nlassert(_DontHaveSheetKnowledge); return; } - + _Initialised = true; _DontHaveSheetKnowledge = true; - + // Initialize id 0,0 as unknown.unknown CSheetId unknownunknown = CSheetId("unknown.unknown"); nlassert(unknownunknown == CSheetId::Unknown); @@ -525,7 +525,7 @@ bool CSheetId::operator < (const CSheetId& sheetRef ) const string CSheetId::toString(bool ifNotFoundUseNumericId) const { if (!_Initialised) init(false); - + if (_DontHaveSheetKnowledge) { // FIXME: When someone punches in a fake sheet id this will @@ -564,7 +564,7 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const void CSheetId::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { nlassert(!_DontHaveSheetKnowledge); - + f.serial( _Id.Id ); #ifdef NL_DEBUG_SHEET_ID diff --git a/code/nel/src/misc/win_thread.cpp b/code/nel/src/misc/win_thread.cpp index f556779ba..4178b7a58 100644 --- a/code/nel/src/misc/win_thread.cpp +++ b/code/nel/src/misc/win_thread.cpp @@ -198,7 +198,7 @@ void CWinThread::start () { if (isRunning()) throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen"); - + // ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId); ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId); // nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name()); diff --git a/code/nel/src/sound/driver/dsound/source_dsound.h b/code/nel/src/sound/driver/dsound/source_dsound.h index 81174c1a0..1aa2d5625 100644 --- a/code/nel/src/sound/driver/dsound/source_dsound.h +++ b/code/nel/src/sound/driver/dsound/source_dsound.h @@ -80,7 +80,7 @@ enum TSourceDSoundEndState class CSourceDSound : public ISource { friend class CSoundDriverDSound; - + public: /// Constructor CSourceDSound(uint sourcename = 0); @@ -446,7 +446,7 @@ private: // Set the 'used' state of the source. Managed by the driver. void setUsed(bool v) { _IsUsed = v; } - + // Return the 'used' state of the source bool isUsed() { return _IsUsed; } */ diff --git a/code/nel/src/sound/driver/fmod/source_fmod.cpp b/code/nel/src/sound/driver/fmod/source_fmod.cpp index c5c6e8266..6026ce2f5 100644 --- a/code/nel/src/sound/driver/fmod/source_fmod.cpp +++ b/code/nel/src/sound/driver/fmod/source_fmod.cpp @@ -419,7 +419,7 @@ void CSourceFMod::setMinMaxDistances( float mindist, float maxdist, bool /* defe nlwarning("SOUND_DEV (FMod): Ridiculously high max distance set on source"); maxdist = maxSqrt; } - + _MinDist= mindist; _MaxDist= maxdist; if(_FModChannel!=-1) diff --git a/code/nel/src/sound/driver/openal/buffer_al.cpp b/code/nel/src/sound/driver/openal/buffer_al.cpp index b63e39fa2..352128c3e 100644 --- a/code/nel/src/sound/driver/openal/buffer_al.cpp +++ b/code/nel/src/sound/driver/openal/buffer_al.cpp @@ -121,7 +121,7 @@ bool CBufferAL::unlock(uint size) // Error handling if (alGetError() == AL_NO_ERROR) _IsLoaded = true; // ->lock() set it to false - + return _IsLoaded; } @@ -162,7 +162,7 @@ bool CBufferAL::fill(const uint8 *src, uint size) // Error handling _IsLoaded = (alGetError() == AL_NO_ERROR); - + return _IsLoaded; } diff --git a/code/nel/src/sound/simple_source.cpp b/code/nel/src/sound/simple_source.cpp index 2c9dda86c..9b9ee5950 100644 --- a/code/nel/src/sound/simple_source.cpp +++ b/code/nel/src/sound/simple_source.cpp @@ -176,7 +176,7 @@ void CSimpleSource::play() // and play the sound bool play = pSource->play(); - + #ifdef NL_DEBUG nlassert(play); #else diff --git a/code/nel/tools/CMakeLists.txt b/code/nel/tools/CMakeLists.txt index 2c1f641a0..0e1c5709d 100644 --- a/code/nel/tools/CMakeLists.txt +++ b/code/nel/tools/CMakeLists.txt @@ -1,4 +1,3 @@ - # Don't add other subdirectories if only max plugins are selected. IF(WITH_NEL_TOOLS) ADD_SUBDIRECTORY(misc) diff --git a/code/ryzom/client/src/actions.h b/code/ryzom/client/src/actions.h index e9b9d53e0..cdc3f200a 100644 --- a/code/ryzom/client/src/actions.h +++ b/code/ryzom/client/src/actions.h @@ -30,8 +30,8 @@ /////////// // CLASS // class CCombo; -class CActionsManager; class CAction; +class CActionsManager; /** * The goal of CCombo is to gather together Inputs that will validate an Action. diff --git a/code/ryzom/client/src/cdb_synchronised.cpp b/code/ryzom/client/src/cdb_synchronised.cpp index 45c57dd55..2ad3022cf 100644 --- a/code/ryzom/client/src/cdb_synchronised.cpp +++ b/code/ryzom/client/src/cdb_synchronised.cpp @@ -41,7 +41,7 @@ #include -#include "../../common/src/game_share/ryzom_database_banks.h" +#include "game_share/ryzom_database_banks.h" //////////////// diff --git a/code/ryzom/client/src/character_cl.cpp b/code/ryzom/client/src/character_cl.cpp index 23fdb78e2..89c9b805b 100644 --- a/code/ryzom/client/src/character_cl.cpp +++ b/code/ryzom/client/src/character_cl.cpp @@ -4537,7 +4537,7 @@ void CCharacterCL::applyBehaviourFlyingHPs(const CBehaviourContext &bc, const MB { if(behaviour.DeltaHP != 0) { - CRGBA deltaHPColor( 0, 0, 0 ); + CRGBA deltaHPColor(0, 0, 0); // if it's a hit if( behaviour.DeltaHP < 0 ) { diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index 19af0545d..fb6e2dca5 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -26,7 +26,6 @@ #include "nel/misc/types_nl.h" #ifdef NL_OS_WINDOWS -#include #include #else #include diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp index 09f874b96..bac2abf1e 100644 --- a/code/ryzom/client/src/client_chat_manager.cpp +++ b/code/ryzom/client/src/client_chat_manager.cpp @@ -969,8 +969,6 @@ void CClientChatManager::buildTellSentence(const ucstring &sender, const ucstrin name = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(name), bWoman); } } - - } else { @@ -1052,8 +1050,6 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde senderName = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(senderName), bWoman); } } - - } switch(type) diff --git a/code/ryzom/client/src/entities.cpp b/code/ryzom/client/src/entities.cpp index 7bc478ce7..516232108 100644 --- a/code/ryzom/client/src/entities.cpp +++ b/code/ryzom/client/src/entities.cpp @@ -426,7 +426,7 @@ void CEntityManager::initialize(uint nbMaxEntity) _Entities.resize(_NbMaxEntity, 0); _EntityGroundFXHandle.resize(_NbMaxEntity); } - + ICDBNode::CTextId textId; // Add an observer on the mission database diff --git a/code/ryzom/client/src/entity_cl.cpp b/code/ryzom/client/src/entity_cl.cpp index 0063c93f4..6a14d6400 100644 --- a/code/ryzom/client/src/entity_cl.cpp +++ b/code/ryzom/client/src/entity_cl.cpp @@ -2296,6 +2296,7 @@ void CEntityCL::onStringAvailable(uint /* stringId */, const ucstring &value) } ucstring replacement(STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw, womanTitle)); + // Sometimes translation contains another title { ucstring::size_type pos = replacement.find('$'); @@ -2308,7 +2309,7 @@ void CEntityCL::onStringAvailable(uint /* stringId */, const ucstring &value) replacement = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw, womanTitle); } } - + _Tags = STRING_MANAGER::CStringManagerClient::getTitleInfos(_TitleRaw, womanTitle); if (!replacement.empty() || !ClientCfg.DebugStringManager) @@ -2949,7 +2950,7 @@ void CEntityCL::dataSetId(CLFECOMMON::TClientDataSetIndex dataSet) { _DataSetId = dataSet; - if (_Primitive && _Primitive->UserData == UserDataEntity) + if (_Primitive && _Primitive->UserData == UserDataEntity) _Primitive->UserData |= (((uint64)_DataSetId)<<16); // additionaly, on a UID change, must check the IsInTeam and IsAniml flags diff --git a/code/ryzom/client/src/far_tp.cpp b/code/ryzom/client/src/far_tp.cpp index 4f48d2ff5..5b9b0c836 100644 --- a/code/ryzom/client/src/far_tp.cpp +++ b/code/ryzom/client/src/far_tp.cpp @@ -188,7 +188,6 @@ const std::string& CLoginStateMachine::toString(CLoginStateMachine::TEvent event _CurrentState = stateId; \ break; \ } \ - extern std::string LoginLogin, LoginPassword; extern bool noUserChar; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 1644f7e2d..4de65491a 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -759,7 +759,7 @@ void prelogInit() NLMISC::CTime::probeTimerInfo(timerInfo); if (timerInfo.RequiresSingleCore) // TODO: Also have a FV configuration value to force single core. setCPUMask(); - + FPU_CHECKER_ONCE NLMISC::TTime initStart = ryzomGetLocalTime (); @@ -949,7 +949,7 @@ void prelogInit() Driver->setSwapVBLInterval(1); else Driver->setSwapVBLInterval(0); - + if (StereoDisplay) // VR_CONFIG // VR_DRIVER { // override mode TODO @@ -1077,7 +1077,7 @@ void prelogInit() // Set the monitor color properties CMonitorColorProperties monitorColor; - for ( uint i=0; i<3; i++) + for (uint i=0; i<3; i++) { monitorColor.Contrast[i] = ClientCfg.Contrast; monitorColor.Luminosity[i] = ClientCfg.Luminosity; diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp index 63d2c93b7..b76bbce21 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp @@ -1950,13 +1950,14 @@ public: womanTitle = pChar->getGender() == GSGENDER::female; STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(copyInout), womanTitle); - + // Sometimes translation contains another title ucstring::size_type pos = copyInout.find('$'); if (pos != ucstring::npos) { copyInout = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(copyInout), womanTitle); } + CStringPostProcessRemoveTitle::cbIDStringReceived(copyInout); inout = copyInout; } diff --git a/code/ryzom/client/src/interface_v3/action_handler_help.cpp b/code/ryzom/client/src/interface_v3/action_handler_help.cpp index e519bb2d0..a8d1059ea 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_help.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_help.cpp @@ -3613,7 +3613,7 @@ public: uint8 index; fromString(Params, index); --index; // Param is 1-based so subtract 1 - if ( index >= MAX_INVENTORY_ANIMAL) + if (index >= MAX_INVENTORY_ANIMAL) { return; } diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 688c27635..4e8966e16 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -520,7 +520,7 @@ CCameraBackup setupCameraForScreenshot(UScene &scene, uint left, uint right, uin // Build a viewport CViewport viewport; NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver(); - viewport.init (0, 0, (float)(right-left)/Driver->getWindowWidth(),(float)(bottom-top)/Driver->getWindowHeight()); + viewport.init (0, 0, (float)(right-left)/Driver->getWindowWidth(), (float)(bottom-top)/Driver->getWindowHeight()); // Activate all this scene.getCam().setFrustum (frustumPart); diff --git a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp index efd19fe45..67f798cb8 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp @@ -777,7 +777,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P sint32 dstPhraseId= pCSDst->getSPhraseId(); sint32 dstMacroId= pCSDst->getMacroId(); - if ((src.empty()) && (CHandlerPhraseMemoryCopy::haveLastPhraseElement)) + if (src.empty() && (CHandlerPhraseMemoryCopy::haveLastPhraseElement)) { // get the slot ids from save srcIsMacro= CHandlerPhraseMemoryCopy::isMacro; @@ -1600,7 +1600,6 @@ public: } } }; - REGISTER_ACTION_HANDLER(CHandlerPhraseSelectMemory2, "phrase_select_memory_2"); // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/chat_displayer.h b/code/ryzom/client/src/interface_v3/chat_displayer.h index e84179f94..e2afc7207 100644 --- a/code/ryzom/client/src/interface_v3/chat_displayer.h +++ b/code/ryzom/client/src/interface_v3/chat_displayer.h @@ -30,7 +30,6 @@ #undef LOG_WARNING #endif - /** * class used to display console text commands in the chat window * \author Nicolas Brigand diff --git a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp index faaf86092..83ef7474e 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -47,7 +47,6 @@ CChatTextManager::~CChatTextManager() _TextShadowed = NULL; delete _ShowTimestamps; _ShowTimestamps = NULL; - } //================================================================================= uint CChatTextManager::getTextFontSize() const @@ -96,6 +95,7 @@ bool CChatTextManager::showTimestamps() const } return _ShowTimestamps->getValueBool(); } + //================================================================================= static CInterfaceGroup *parseCommandTag(ucstring &line) { @@ -186,7 +186,6 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA msg = cur_time + msg; } - vt->setTextFormatTaged(msg); vt->setColor(NLMISC::CRGBA::White); } diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp index 76d97c519..53cddc93b 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp @@ -198,7 +198,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity) ucstring theTribeName; ucstring entityName = entity->getDisplayName(); ucstring entityTitle = entity->getTitle(); - + // For some NPC's the name is empty and only a title is given, // in that case, treat the title as the name. if (entityName.empty()) @@ -652,7 +652,6 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity) if (pPlayer == NULL) needPvPLogo = false; - if (pPlayer != NULL && needPvPLogo) { if (pvpFactionLogo) @@ -756,7 +755,6 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity) view = leftGroup->getView ("win_jauge_bot"); if (view) leftGroup->delView (view); - } // Delete remaining strings @@ -771,8 +769,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity) CViewBase *win_mid = leftGroup->getView ("win_mid"); if (win_mid) { - win_mid->setH (win_mid->getH() - spaceBar/2 ); - + win_mid->setH (win_mid->getH() - spaceBar/2); } // Set player name @@ -963,7 +960,7 @@ void CGroupInSceneUserInfo::updateDynamicData () if (pPlayer != NULL) if (pPlayer->isAFK()) - entityName += CI18N::get("uiAFK"); + entityName += CI18N::get("uiAFK"); _Name->setText(entityName); // Title color get the PVP color diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 558ab960c..371673a00 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -3213,7 +3213,7 @@ class CAHValidateUserLandMarkName : public IActionHandler CGroupEditBox *eb = dynamic_cast(ig->getGroup("eb")); if (!eb) return; ig->setActive(false); - + CGroupContainer *gc = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(WIN_LANDMARK_NAME)); if (!gc) return; // Retrieve ComboBox to get the position(ordered landmark type) of the selected item diff --git a/code/ryzom/client/src/interface_v3/group_skills.cpp b/code/ryzom/client/src/interface_v3/group_skills.cpp index e414ab4e4..b5e5c5d34 100644 --- a/code/ryzom/client/src/interface_v3/group_skills.cpp +++ b/code/ryzom/client/src/interface_v3/group_skills.cpp @@ -87,7 +87,7 @@ bool CGroupSkills::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) string sTmp; ICDBNode::CTextId textId; - + for (uint k = 0; k < SKILLS::NUM_SKILLS; ++k) { sTmp = string(DB_SKILLS)+":"+NLMISC::toString((sint32)k)+":BaseSKILL"; diff --git a/code/ryzom/client/src/interface_v3/guild_manager.cpp b/code/ryzom/client/src/interface_v3/guild_manager.cpp index 9edf86c56..2e0e4e3e7 100644 --- a/code/ryzom/client/src/interface_v3/guild_manager.cpp +++ b/code/ryzom/client/src/interface_v3/guild_manager.cpp @@ -378,13 +378,13 @@ void CGuildManager::update() // Online status not changed for this member continue; } - + if ( (*it).second.Online != ccs_offline && _GuildMembers[i].Online != ccs_offline) { // Not from offline, or to offline, so don't show anything continue; } - + ucstring msg = (_GuildMembers[i].Online != ccs_offline) ? onlineMessage : offlineMessage; strFindReplace(msg, "%s", _GuildMembers[i].Name); string cat = getStringCategory(msg, msg); @@ -398,7 +398,6 @@ void CGuildManager::update() bool dummy; PeopleInterraction.ChatInput.Guild.displayMessage(msg, col, 2, &dummy); break; - } } diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index b89566ecd..541cb853a 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -3982,5 +3982,3 @@ bool CInterfaceManager::parseTokens(ucstring& ucstr) ucstr = str; return true;; } - - diff --git a/code/ryzom/client/src/interface_v3/interface_observer.h b/code/ryzom/client/src/interface_v3/interface_observer.h index 4261f10a4..6da93637e 100644 --- a/code/ryzom/client/src/interface_v3/interface_observer.h +++ b/code/ryzom/client/src/interface_v3/interface_observer.h @@ -119,7 +119,7 @@ public: char * end = ptr.getDatas() + strlen( ptr.getDatas() ); char * dataTok = strtok( ptr.getDatas()," ,"); NLMISC::ICDBNode::CTextId textId; - + while(dataTok) { std::string data (dataTok); diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp index 332bcac57..c2eb972dd 100644 --- a/code/ryzom/client/src/interface_v3/people_interraction.cpp +++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp @@ -2193,7 +2193,6 @@ class CHandlerTellContact : public IActionHandler CInterfaceGroup *ig = pCaller->getParent(); if (!ig) return; CGroupContainer *gc = static_cast< CGroupContainer* >( ig->getEnclosingContainer() ); - if (!gc) return; CPeopleList *list; uint peopleIndex; diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index a2ee04808..4dc451ea3 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -895,7 +895,7 @@ class CHandlerContactEntry : public IActionHandler // it is simpler to keep it as it and to just use this action handler to manage user input. if (!pCaller || !pCaller->getParent()) return; CGroupContainer *gc = static_cast< CGroupContainer* >( pCaller->getParent()->getEnclosingContainer() ); - + // title gives the name of the player ucstring playerName = gc->getUCTitle(); diff --git a/code/ryzom/client/src/interface_v3/sphrase_manager.cpp b/code/ryzom/client/src/interface_v3/sphrase_manager.cpp index 790657e2e..d214d1150 100644 --- a/code/ryzom/client/src/interface_v3/sphrase_manager.cpp +++ b/code/ryzom/client/src/interface_v3/sphrase_manager.cpp @@ -474,16 +474,16 @@ void CSPhraseManager::memorizePhrase(uint32 memoryLine, uint32 memorySlot, ui } } -void CSPhraseManager::selectMemoryLineDBalt(sint32 memoryLine) +// *************************************************************************** +void CSPhraseManager::selectMemoryLineDB(sint32 memoryLine) { if(memoryLine<0) memoryLine= -1; - - if(_SelectedMemoryDBalt!=memoryLine) + + if(_SelectedMemoryDB!=memoryLine) { - _SelectedMemoryDBalt= memoryLine; + _SelectedMemoryDB= memoryLine; // since memory selection changes then must update all the DB and the Ctrl states - updateMemoryDBAll(); updateAllMemoryCtrlState(); updateAllMemoryCtrlRegenTickRange(); @@ -492,14 +492,14 @@ void CSPhraseManager::selectMemoryLineDBalt(sint32 memoryLine) } } -// *************************************************************************** -void CSPhraseManager::selectMemoryLineDB(sint32 memoryLine) +void CSPhraseManager::selectMemoryLineDBalt(sint32 memoryLine) { if(memoryLine<0) memoryLine= -1; - if(_SelectedMemoryDB!=memoryLine) + + if(_SelectedMemoryDBalt!=memoryLine) { - _SelectedMemoryDB= memoryLine; + _SelectedMemoryDBalt= memoryLine; // since memory selection changes then must update all the DB and the Ctrl states updateMemoryDBAll(); updateAllMemoryCtrlState(); @@ -573,7 +573,7 @@ void CSPhraseManager::updateMemoryDBSlot(uint32 memorySlot) _MemoryDbLeaves[memorySlot]->setValue32(0); else _MemoryDbLeaves[memorySlot]->setValue32(slot.Id); - + CMemorySlot &slotAlt= _Memories[_SelectedMemoryDBalt].Slot[memorySlot]; if(!slotAlt.isPhrase()) @@ -1126,7 +1126,7 @@ void CSPhraseManager::buildPhraseDesc(ucstring &text, const CSPhraseCom &phrase, uint32 totalActionMalus= 0; CCDBNodeLeaf *actMalus = _TotalMalusEquipLeaf ? &*_TotalMalusEquipLeaf : &*(_TotalMalusEquipLeaf = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:TOTAL_MALUS_EQUIP", false)); - + // root brick must not be Power or aura, because Action malus don't apply to them // (ie leave 0 ActionMalus for Aura or Powers if(actMalus && !rootBrick->isSpecialPower()) @@ -4519,7 +4519,7 @@ uint32 CSPhraseManager::getTotalActionMalus(const CSPhraseCom &phrase) const if (!rootBrick) nlerror("Invalid root sbrick in sphrase_com '%s'", phrase.Name.toUtf8().c_str()); else if (actMalus && !rootBrick->isSpecialPower()) - totalActionMalus = actMalus->getValue32(); + totalActionMalus = actMalus->getValue32(); } return totalActionMalus; } diff --git a/code/ryzom/client/src/sound_manager.cpp b/code/ryzom/client/src/sound_manager.cpp index f87c6cdee..4a981366d 100644 --- a/code/ryzom/client/src/sound_manager.cpp +++ b/code/ryzom/client/src/sound_manager.cpp @@ -106,11 +106,11 @@ enum TFilterMapping // constructor //----------------------------------------------- CSoundManager::CSoundManager(IProgressCallback * /* progressCallBack */) -: _AudioMixer(NULL), +: _AudioMixer(NULL), _GroupControllerEffects(NULL), - _GroupControllerEffectsGame(NULL), - _EnvSoundRoot(NULL), - _Sources(NULL), + _GroupControllerEffectsGame(NULL), + _EnvSoundRoot(NULL), + _Sources(NULL), _UserEntitySoundLevel(1.0f) { _EnableBackgroundMusicAtTime= 0; diff --git a/code/ryzom/client/src/user_entity.cpp b/code/ryzom/client/src/user_entity.cpp index bb632cf4e..62d45f330 100644 --- a/code/ryzom/client/src/user_entity.cpp +++ b/code/ryzom/client/src/user_entity.cpp @@ -518,7 +518,7 @@ void CUserEntity::updateVisualPropertyName(const NLMISC::TGameCycle &gameCycle, html->browse("home"); } } -*/ +*/ }// updateVisualPropertyName // //----------------------------------------------- diff --git a/code/ryzom/common/data_common/r2/r2_misc.lua b/code/ryzom/common/data_common/r2/r2_misc.lua index 827e91579..d85744bd0 100644 --- a/code/ryzom/common/data_common/r2/r2_misc.lua +++ b/code/ryzom/common/data_common/r2/r2_misc.lua @@ -187,7 +187,7 @@ end function strify(str) return [["]] .. tostring(str) .. [["]] end - + ------------------------------------------------------------------------------------------------- -- enclose a string by double quotes function strifyXml(str) diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml index de424f76f..d9aae794a 100644 --- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml +++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml @@ -1112,7 +1112,7 @@ - + @@ -1126,7 +1126,7 @@ - + @@ -5023,13 +5023,13 @@ - + - + - + From f745f82455943a46b1b18ed0d1881f01b650679c Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 26 Dec 2014 13:43:20 +0100 Subject: [PATCH 177/344] Changed: Give priority to Luabind library filenames with specific Lua version --HG-- branch : develop --- code/CMakeModules/FindLuabind.cmake | 42 ++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/code/CMakeModules/FindLuabind.cmake b/code/CMakeModules/FindLuabind.cmake index 14f67ce44..73255077a 100644 --- a/code/CMakeModules/FindLuabind.cmake +++ b/code/CMakeModules/FindLuabind.cmake @@ -69,14 +69,48 @@ FIND_PATH(LUABIND_INCLUDE_DIR /opt/include ) -SET(LIBRARY_NAME_RELEASE luabind libluabind) -SET(LIBRARY_NAME_DEBUG luabind_d luabindd libluabind_d libluabindd) +SET(LIBRARY_NAME_RELEASE) +SET(LIBRARY_NAME_DEBUG) + +IF(WITH_LUA52) + IF(WITH_STLPORT) + LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua52) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_stlport_lua52d) + ENDIF(WITH_STLPORT) + + LIST(APPEND LIBRARY_NAME_RELEASE luabind_lua52) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_lua52d) +ENDIF() + +IF(WITH_LUA51) + IF(WITH_STLPORT) + LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua51) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_stlport_lua51d) + ENDIF(WITH_STLPORT) + + LIST(APPEND LIBRARY_NAME_RELEASE luabind_lua51) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_lua51d) +ENDIF() + +IF(WITH_LUA50) + IF(WITH_STLPORT) + LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport_lua50) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_stlport_lua50d) + ENDIF(WITH_STLPORT) + + LIST(APPEND LIBRARY_NAME_RELEASE luabind_lua50) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_lua50d) +ENDIF() IF(WITH_STLPORT) - SET(LIBRARY_NAME_RELEASE luabind_stlport ${LIBRARY_NAME_RELEASE}) - SET(LIBRARY_NAME_DEBUG luabind_stlportd ${LIBRARY_NAME_DEBUG}) + LIST(APPEND LIBRARY_NAME_RELEASE luabind_stlport) + LIST(APPEND LIBRARY_NAME_DEBUG luabind_stlportd) ENDIF(WITH_STLPORT) +# generic libraries names +LIST(APPEND LIBRARY_NAME_RELEASE luabind libluabind) +LIST(APPEND LIBRARY_NAME_DEBUG luabind_d luabindd libluabind_d libluabindd) + FIND_LIBRARY(LUABIND_LIBRARY_RELEASE NAMES ${LIBRARY_NAME_RELEASE} PATHS From ec12e6a75e6267baa0d5ca7343a97fc292e08bdb Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 26 Dec 2014 13:44:03 +0100 Subject: [PATCH 178/344] Changed: Allow to enable UAC for Windows client --HG-- branch : develop --- code/CMakeModules/nel.cmake | 1 + code/ryzom/client/src/CMakeLists.txt | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 0474c7d7b..b18b8f279 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -360,6 +360,7 @@ MACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) ### OPTION(WITH_LUA51 "Build Ryzom Core using Lua 5.1" ON ) OPTION(WITH_LUA52 "Build Ryzom Core using Lua 5.2" OFF) + OPTION(WITH_RYZOM_CLIENT_UAC "Ask to run as Administrator" OFF) ENDMACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) MACRO(NL_SETUP_SNOWBALLS_DEFAULT_OPTIONS) diff --git a/code/ryzom/client/src/CMakeLists.txt b/code/ryzom/client/src/CMakeLists.txt index c20d9d0dc..d06af95c8 100644 --- a/code/ryzom/client/src/CMakeLists.txt +++ b/code/ryzom/client/src/CMakeLists.txt @@ -121,6 +121,14 @@ NL_ADD_RUNTIME_FLAGS(ryzom_client) NL_ADD_LIB_SUFFIX(ryzom_client) +IF(WITH_RYZOM_CLIENT_UAC) + IF(CMAKE_GENERATOR MATCHES "Visual Studio") + SET_PROPERTY(TARGET ryzom_client PROPERTY LINK_FLAGS_RELEASE "/level='requireAdministrator'") + ELSEIF(CMAKE_GENERATOR MATCHES "NMake Makefiles") + SET_PROPERTY(TARGET ryzom_client PROPERTY LINK_FLAGS_RELEASE "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"") + ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio") +ENDIF(WITH_RYZOM_CLIENT_UAC) + IF(WITH_PCH AND (NOT MINGW OR NOT WITH_SYMBOLS)) ADD_NATIVE_PRECOMPILED_HEADER(ryzom_client ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) ENDIF(WITH_PCH AND (NOT MINGW OR NOT WITH_SYMBOLS)) From 4fc639671c29ae08c4de85e3e6bec26ff911a54b Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 26 Dec 2014 13:44:35 +0100 Subject: [PATCH 179/344] Changed: Check for string length --HG-- branch : develop --- code/ryzom/common/src/game_share/crypt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp index 9a46281f7..1750d5d20 100644 --- a/code/ryzom/common/src/game_share/crypt.cpp +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -520,7 +520,7 @@ char * rz_crypt(register const char *key, register const char *setting, char *bu return buff; #endif - if (setting[0] == '$' && setting[1] == '6') { + if (strlen(setting) >= 2 && setting[0] == '$' && setting[1] == '6') { return __crypt_sha512(key, setting, buf); } From fbea1d2173b5ab3fa3c7d91bf824940e249bc66d Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 9 Jan 2015 12:59:53 +0200 Subject: [PATCH 180/344] CGroupEditBox: ignore enter key when ctrl is pressed (ctrl+m combo) (issue #225) --HG-- branch : fix-issue-225 --- code/nel/src/gui/group_editbox.cpp | 11 ++++++----- code/nel/src/gui/widget_manager.cpp | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 92ae46703..565cc1549 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -999,7 +999,8 @@ namespace NLGUI break; // OTHER default: - if ((rEDK.getChar() == KeyRETURN) && !_WantReturn) + bool isKeyRETURN = !rEDK.getKeyCtrl() && rEDK.getChar() == KeyRETURN; + if (isKeyRETURN && !_WantReturn) { // update historic. if(_MaxHistoric) @@ -1030,9 +1031,9 @@ namespace NLGUI // If the char is not alphanumeric -> return. // if(!isalnum(ec.Char)) // return - if( (rEDK.getChar()>=32) || (rEDK.getChar() == KeyRETURN) ) + if( (rEDK.getChar()>=32) || isKeyRETURN ) { - if (rEDK.getChar() == KeyRETURN) + if (isKeyRETURN) { ucstring copyStr= _InputString; if ((uint) std::count(copyStr.begin(), copyStr.end(), '\n') >= _MaxNumReturn) @@ -1049,7 +1050,7 @@ namespace NLGUI cutSelection(); } - ucchar c = (rEDK.getChar() == KeyRETURN)?'\n':rEDK.getChar(); + ucchar c = isKeyRETURN ? '\n' : rEDK.getChar(); if (isFiltered(c)) return; switch(_EntryType) { @@ -1128,7 +1129,7 @@ namespace NLGUI ++ _CursorPos; triggerOnChangeAH(); } - if (rEDK.getChar() == KeyRETURN) + if (isKeyRETURN) { CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams); } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 81fbaf28b..2ac06f797 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2207,7 +2207,7 @@ namespace NLGUI } // Manage complex "Enter" - if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN) + if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN && !eventDesc.getKeyCtrl() ) { // If the top window has Enter AH CInterfaceGroup *tw= getTopWindow(); From 85f63b7db32576839899c137a8663159ec1e8240 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 9 Jan 2015 13:11:20 +0200 Subject: [PATCH 181/344] Fix html submit button value that is included with form data (issue #226) --HG-- branch : fix-issue-226 --- code/nel/include/nel/gui/ctrl_base.h | 8 ++++ code/nel/include/nel/gui/group_html.h | 6 ++- code/nel/src/gui/ctrl_base_button.cpp | 5 +++ code/nel/src/gui/group_html.cpp | 37 ++++++++++++++++--- .../src/interface_v3/action_handler_help.cpp | 7 +++- 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/code/nel/include/nel/gui/ctrl_base.h b/code/nel/include/nel/gui/ctrl_base.h index 71e6cad56..3b522e114 100644 --- a/code/nel/include/nel/gui/ctrl_base.h +++ b/code/nel/include/nel/gui/ctrl_base.h @@ -50,6 +50,8 @@ namespace NLGUI // see interface.txt for meaning of auto _ToolTipParentPosRef= Hotspot_TTAuto; _ToolTipPosRef= Hotspot_TTAuto; + _EventX = 0; + _EventY = 0; resizer = false; } @@ -70,6 +72,9 @@ namespace NLGUI bool handleEvent (const NLGUI::CEventDescriptor &event); + sint32 getEventX() { return _EventX; } + sint32 getEventY() { return _EventY; } + virtual CCtrlBase *getSubCtrl (sint32 /* x */, sint32 /* y */) { return this; } /// Debug @@ -181,6 +186,9 @@ namespace NLGUI static std::map< std::string, std::map< std::string, std::string > > AHCache; bool resizer; + + sint32 _EventX; + sint32 _EventY; }; } diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 21d609af3..333800760 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -107,7 +107,7 @@ namespace NLGUI void refresh(); // submit form - void submitForm (uint formId, const char *submitButtonName); + void submitForm (uint formId, const char *submitButtonType, const char *submitButtonName, const char *submitButtonValue, sint32 x, sint32 y); // Browse error void browseError (const char *msg); @@ -328,7 +328,11 @@ namespace NLGUI bool _BrowseNextTime; bool _PostNextTime; uint _PostFormId; + std::string _PostFormSubmitType; std::string _PostFormSubmitButton; + std::string _PostFormSubmitValue; + sint32 _PostFormSubmitX; + sint32 _PostFormSubmitY; // Browsing.. bool _Browsing; diff --git a/code/nel/src/gui/ctrl_base_button.cpp b/code/nel/src/gui/ctrl_base_button.cpp index 4f118cd51..673ea906d 100644 --- a/code/nel/src/gui/ctrl_base_button.cpp +++ b/code/nel/src/gui/ctrl_base_button.cpp @@ -701,6 +701,11 @@ namespace NLGUI //pIM->submitEvent ("button_click:"+getId()); } */ + + // top-right corner is EventX=0, EventY=0 + _EventX = eventDesc.getX() - _XReal; + _EventY = (_YReal + _HReal) - eventDesc.getY(); + runLeftClickAction(); if (CWidgetManager::getInstance()->getCapturePointerLeft() == NULL) return true; // event handler may release cpature from this object (if it is removed for example) diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index dd7eebdef..656e36ca8 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1217,7 +1217,7 @@ namespace NLGUI normal = value[MY_HTML_INPUT_SRC]; // Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name" - string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name; + string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image"; // Add the ctrl button addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over, @@ -1241,7 +1241,15 @@ namespace NLGUI text = value[MY_HTML_INPUT_VALUE]; // Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name" - string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name; + string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit"; + if (text.size() > 0) + { + // escape AH param separator + string tmp = text; + while(NLMISC::strFindReplace(tmp, "|", "|")) + ; + param = param + "|submit_button_value=" + tmp; + } // Add the ctrl button if (!_Paragraph) @@ -3638,14 +3646,18 @@ namespace NLGUI // *************************************************************************** - void CGroupHTML::submitForm (uint formId, const char *submitButtonName) + void CGroupHTML::submitForm (uint formId, const char *submitButtonType, const char *submitButtonName, const char *submitButtonValue, sint32 x, sint32 y) { // Form id valid ? if (formId < _Forms.size()) { _PostNextTime = true; _PostFormId = formId; + _PostFormSubmitType = submitButtonType; _PostFormSubmitButton = submitButtonName; + _PostFormSubmitValue = submitButtonValue; + _PostFormSubmitX = x; + _PostFormSubmitY = y; } } @@ -3918,9 +3930,22 @@ namespace NLGUI } } - // Add the button coordinates - HTParseFormInput(formfields, (_PostFormSubmitButton + "_x=0").c_str()); - HTParseFormInput(formfields, (_PostFormSubmitButton + "_y=0").c_str()); + if (_PostFormSubmitType == "image") + { + // Add the button coordinates + if (_PostFormSubmitButton.find_first_of("[") == string::npos) + { + HTParseFormInput(formfields, (_PostFormSubmitButton + "_x=" + NLMISC::toString(_PostFormSubmitX)).c_str()); + HTParseFormInput(formfields, (_PostFormSubmitButton + "_y=" + NLMISC::toString(_PostFormSubmitY)).c_str()); + } + else + { + HTParseFormInput(formfields, (_PostFormSubmitButton + "=" + NLMISC::toString(_PostFormSubmitX)).c_str()); + HTParseFormInput(formfields, (_PostFormSubmitButton + "=" + NLMISC::toString(_PostFormSubmitY)).c_str()); + } + } + else + HTParseFormInput(formfields, (_PostFormSubmitButton + "=" + _PostFormSubmitValue).c_str()); // Add custom params addHTTPPostParams(formfields, _TrustedDomain); diff --git a/code/ryzom/client/src/interface_v3/action_handler_help.cpp b/code/ryzom/client/src/interface_v3/action_handler_help.cpp index a8d1059ea..ed2b34ce3 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_help.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_help.cpp @@ -1117,6 +1117,11 @@ class CHandlerHTMLSubmitForm : public IActionHandler fromString(getParam (sParams, "form"), form); string submit_button = getParam (sParams, "submit_button"); + string type = getParam (sParams, "submit_button_type"); + string value = getParam (sParams, "submit_button_value"); + + sint32 x = pCaller->getEventX(); + sint32 y = pCaller->getEventY(); CInterfaceElement *element = CWidgetManager::getInstance()->getElementFromId(container); { @@ -1125,7 +1130,7 @@ class CHandlerHTMLSubmitForm : public IActionHandler if (groupHtml) { // Submit the form the url - groupHtml->submitForm (form, submit_button.c_str ()); + groupHtml->submitForm (form, type.c_str(), submit_button.c_str(), value.c_str(), x, y); } } } From 0f22ea7777a3d9acf5161c4f774dc7d6d312970b Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 18:41:18 +0100 Subject: [PATCH 182/344] Changed: More aliases for OpenGL ES functions and defines to simplify code --HG-- branch : develop --- .../src/3d/driver/opengl/driver_opengl.cpp | 8 --- .../opengl/driver_opengl_extension_def.h | 43 +++++++++++++++ .../3d/driver/opengl/driver_opengl_matrix.cpp | 8 --- .../3d/driver/opengl/driver_opengl_states.cpp | 29 ---------- .../driver/opengl/driver_opengl_texture.cpp | 54 ++----------------- .../driver_opengl_vertex_buffer_hard.cpp | 49 +++-------------- 6 files changed, 53 insertions(+), 138 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index d129f3aa2..35cf9c094 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -435,11 +435,7 @@ bool CDriverGL::setupDisplay() glViewport(0,0,_CurrentMode.Width,_CurrentMode.Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); -#ifdef USE_OPENGLES - glOrthof(0.f,_CurrentMode.Width,_CurrentMode.Height,0.f,-1.0f,1.0f); -#else glOrtho(0,_CurrentMode.Width,_CurrentMode.Height,0,-1.0f,1.0f); -#endif glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #ifndef USE_OPENGLES @@ -725,11 +721,7 @@ bool CDriverGL::activeFrameBufferObject(ITexture * tex) } else { -#ifdef USE_OPENGLES - nglBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); -#else nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -#endif return true; } } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h index 41d2c1366..31ca00961 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension_def.h @@ -40,6 +40,24 @@ extern "C" { #define GL_ADD_SIGNED_EXT GL_ADD_SIGNED #define GL_INTERPOLATE_EXT GL_INTERPOLATE #define GL_BUMP_ENVMAP_ATI GL_INTERPOLATE +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES +#define GL_RENDERBUFFER_EXT GL_RENDERBUFFER_OES +#define GL_DEPTH24_STENCIL8_EXT GL_DEPTH24_STENCIL8_OES +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES +#define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT_OES +#define GL_STENCIL_ATTACHMENT_EXT GL_STENCIL_ATTACHMENT_OES +#define GL_ARRAY_BUFFER_ARB GL_ARRAY_BUFFER +#define GL_TEXTURE0_ARB GL_TEXTURE0 + +#define GL_ALPHA8 GL_ALPHA +#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE_ALPHA +#define GL_LUMINANCE8 GL_LUMINANCE +#define GL_RGBA8 GL_RGBA +#define GL_RGB8 GL_RGB + +#define GL_STATIC_DRAW_ARB GL_STATIC_DRAW +#define GL_DYNAMIC_DRAW_ARB GL_DYNAMIC_DRAW #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES @@ -48,6 +66,31 @@ extern "C" { #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES +#define nglGenRenderbuffersEXT nglGenRenderbuffersOES +#define nglBindRenderbufferEXT nglBindRenderbufferOES +#define nglDeleteRenderbuffersEXT nglDeleteRenderbuffersOES +#define nglRenderbufferStorageEXT nglRenderbufferStorageOES +#define nglGenFramebuffersEXT nglGenFramebuffersOES +#define nglBindFramebufferEXT nglBindFramebufferOES +#define nglFramebufferTexture2DEXT nglFramebufferTexture2DOES +#define nglFramebufferRenderbufferEXT nglFramebufferRenderbufferOES +#define nglCheckFramebufferStatusEXT nglCheckFramebufferStatusOES +#define nglDeleteBuffersARB glDeleteBuffers +#define nglIsBufferARB glIsBuffer +#define nglDeleteRenderbuffersEXT nglDeleteRenderbuffersOES +#define nglBindFramebufferEXT nglBindFramebufferOES +#define nglDeleteFramebuffersEXT nglDeleteFramebuffersOES +#define nglUnmapBufferARB nglUnmapBufferOES +#define nglActiveTextureARB glActiveTexture +#define nglClientActiveTextureARB glClientActiveTexture +#define nglBindBufferARB glBindBuffer +#define nglGenBuffersARB glGenBuffers +#define nglBufferDataARB glBufferData + +#define glFrustum glFrustumf +#define glOrtho glOrthof +#define glDepthRange glDepthRangef + #else #if defined(NL_OS_MAC) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp index 855c10c21..41575024c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_matrix.cpp @@ -37,19 +37,11 @@ void CDriverGL::setFrustum(float left, float right, float bottom, float top, flo if (perspective) { -#ifdef USE_OPENGLES - glFrustumf(left,right,bottom,top,znear,zfar); -#else glFrustum(left,right,bottom,top,znear,zfar); -#endif } else { -#ifdef USE_OPENGLES - glOrthof(left,right,bottom,top,znear,zfar); -#else glOrtho(left,right,bottom,top,znear,zfar); -#endif } _ProjMatDirty = true; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp index 9bf53592f..8ec7a6bc8 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_states.cpp @@ -155,11 +155,7 @@ void CDriverGLStates::forceDefaults(uint nbStages) for(stage=0;stage_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID); @@ -1259,11 +1255,7 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff } if (glGetError() != GL_NO_ERROR) { -#ifdef USE_OPENGLES - glDeleteBuffers(1, &vertexBufferID); -#else nglDeleteBuffersARB(1, &vertexBufferID); -#endif return NULL; } @@ -1306,13 +1298,10 @@ void CVertexArrayRangeARB::updateLostBuffers() { nlassert((*it)->_VertexObjectId); GLuint id = (GLuint) (*it)->_VertexObjectId; -#ifdef USE_OPENGLES - nlassert(glIsBuffer(id)); - glDeleteBuffers(1, &id); -#else + nlassert(nglIsBufferARB(id)); nglDeleteBuffersARB(1, &id); -#endif + (*it)->_VertexObjectId = 0; (*it)->VB->setLocation(CVertexBuffer::NotResident); } @@ -1361,13 +1350,8 @@ CVertexBufferHardARB::~CVertexBufferHardARB() if (_VertexObjectId) { GLuint id = (GLuint) _VertexObjectId; -#ifdef USE_OPENGLES - nlassert(glIsBuffer(id)); - glDeleteBuffers(1, &id); -#else nlassert(nglIsBufferARB(id)); nglDeleteBuffersARB(1, &id); -#endif } if (_VertexArrayRange) { @@ -1412,12 +1396,7 @@ void *CVertexBufferHardARB::lock() } // recreate a vb GLuint vertexBufferID; - -#ifdef USE_OPENGLES - glGenBuffers(1, &vertexBufferID); -#else nglGenBuffersARB(1, &vertexBufferID); -#endif if (glGetError() != GL_NO_ERROR) { @@ -1436,35 +1415,23 @@ void *CVertexBufferHardARB::lock() break; case CVertexBuffer::StaticPreferred: if (_Driver->getStaticMemoryToVRAM()) -#ifdef USE_OPENGLES - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); -#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STATIC_DRAW_ARB); -#endif else -#ifdef USE_OPENGLES glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); -#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); -#endif break; // case CVertexBuffer::AGPPreferred: default: -#ifdef USE_OPENGLES - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); -#else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); -#endif + break; } if (glGetError() != GL_NO_ERROR) { _Driver->incrementResetCounter(); -#ifdef USE_OPENGLES - glDeleteBuffers(1, &vertexBufferID); -#else + nglDeleteBuffersARB(1, &vertexBufferID); -#endif + return &_DummyVB[0];; } _VertexObjectId = vertexBufferID; @@ -1567,12 +1534,10 @@ void CVertexBufferHardARB::unlock() #ifdef USE_OPENGLES if (_Driver->_Extensions.OESMapBuffer) +#endif { - unmapOk = nglUnmapBufferOES(GL_ARRAY_BUFFER); + unmapOk = nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB); } -#else - unmapOk = nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB); -#endif #ifdef NL_DEBUG _Unmapping = false; From 2869d5f1ac39479719760c0b33545d88c72cd4ba Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 18:41:54 +0100 Subject: [PATCH 183/344] Fixed: OpenGL ES driver compilation --HG-- branch : develop --- .../driver/opengl/driver_opengl_texture.cpp | 61 ------------------- .../driver_opengl_vertex_buffer_hard.cpp | 6 +- .../3d/driver/opengl/driver_opengl_window.cpp | 4 ++ 3 files changed, 8 insertions(+), 63 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 696d30635..3aa1f7e25 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -93,19 +93,6 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL() { _Driver->_TextureUsed[TextureUsedIdx] = NULL; } - -#ifdef USE_OPENGLES - if (InitFBO) - { - nglDeleteFramebuffersOES(1, &FBOId); - if(AttachDepthStencil) - { - nglDeleteRenderbuffersOES(1, &DepthFBOId); - if(!UsePackedDepthStencil) - nglDeleteRenderbuffersOES(1, &StencilFBOId); - } - } -#endif } CDepthStencilFBO::CDepthStencilFBO(CDriverGL *driver, uint width, uint height) @@ -175,53 +162,6 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D(); } -#ifdef USE_OPENGLES - // generate IDs - nglGenFramebuffersOES(1, &FBOId); - if(AttachDepthStencil) - { - nglGenRenderbuffersOES(1, &DepthFBOId); - if(UsePackedDepthStencil) - StencilFBOId = DepthFBOId; - else - nglGenRenderbuffersOES(1, &StencilFBOId); - } - - //nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId); - - // initialize FBO - nglBindFramebufferOES(GL_FRAMEBUFFER_OES, FBOId); - nglFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, TextureMode, ID, 0); - - // attach depth/stencil render to FBO - // note: for some still unkown reason it's impossible to add - // a stencil buffer as shown in the respective docs (see - // opengl.org extension registry). Until a safe approach to add - // them is found, there will be no attached stencil for the time - // being, aside of using packed depth+stencil buffers. - if(AttachDepthStencil) - { - if(UsePackedDepthStencil) - { - //nldebug("3D: using packed depth stencil"); - nglBindRenderbufferOES(GL_RENDERBUFFER_OES, StencilFBOId); - nglRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, tex->getWidth(), tex->getHeight()); - } - else - { - nglBindRenderbufferOES(GL_RENDERBUFFER_OES, DepthFBOId); - nglRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT24_OES, tex->getWidth(), tex->getHeight()); - /* - nglBindRenderbufferEXT(GL_RENDERBUFFER_OES, StencilFBOId); - nglRenderbufferStorageEXT(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_EXT, tex->getWidth(), tex->getHeight()); - */ - } - nglFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, DepthFBOId); - nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); - nglFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, StencilFBOId); - nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); - } -#else // generate IDs nglGenFramebuffersEXT(1, &FBOId); @@ -253,7 +193,6 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) GL_RENDERBUFFER_EXT, DepthStencilFBO->StencilFBOId); nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); } -#endif // check status GLenum status = (GLenum) nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp index 3a75afe8d..6ed74f78e 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp @@ -1225,7 +1225,8 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff { case CVertexBuffer::AGPVolatile: #ifdef USE_OPENGLES - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STREAM_DRAW); + // TODO: GL_STREAM_DRAW doesn't exist in OpenGL ES 1.x + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); #else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STREAM_DRAW_ARB); #endif @@ -1408,7 +1409,8 @@ void *CVertexBufferHardARB::lock() { case CVertexBuffer::AGPVolatile: #ifdef USE_OPENGLES - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STREAM_DRAW); + // TODO: GL_STREAM_DRAW doesn't exist in OpenGL ES 1.x + glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); #else nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STREAM_DRAW_ARB); #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 8307f885e..172b0e451 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -633,6 +633,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re int width = mode.Width; int height = mode.Height; +#ifdef USE_OPENGLES + // TODO: implement for OpenGL ES 1.x +#else // resize the window RECT rc; SetRect (&rc, 0, 0, width, height); @@ -910,6 +913,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re _hDC = NULL; return false; } +#endif } else { From 99c88bd515e917dafb46b79235a9453dc154e47e Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 18:45:14 +0100 Subject: [PATCH 184/344] Changed: Minor changes --HG-- branch : develop --- code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp | 2 +- .../nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp | 1 - code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 4 ++-- code/ryzom/server/src/ai_service/ai_vector_mirror.h | 2 +- code/ryzom/server/src/dynamic_scenario_service/service.cpp | 2 -- .../src/entities_game_service/progression/progression_pve.h | 1 - .../server/src/shard_unifier_service/nel_database_mapping.h | 2 +- 7 files changed, 5 insertions(+), 9 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 3aa1f7e25..7b49e20a0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -164,7 +164,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) // generate IDs nglGenFramebuffersEXT(1, &FBOId); - + //nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId); // initialize FBO diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 5470ec5c5..22bc5ff5a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -453,7 +453,6 @@ bool CDriverGL::setupEXTVertexShader(const CVPParser::TProgram &program, GLuint // clear last error GLenum glError = glGetError(); - //variants[EVSSecondaryColorVariant] = nglGenSymbolsEXT(GL_VECTOR_EXT, GL_VARIANT_EXT, GL_NORMALIZED_RANGE_EXT, 1); //variants[EVSSecondaryColorVariant] = nglGenSymbolsEXT(GL_VECTOR_EXT, GL_VARIANT_EXT, GL_NORMALIZED_RANGE_EXT, 1); // allocate the symbols diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 172b0e451..4db3f550b 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -627,8 +627,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re // Offscreen mode ? if (_CurrentMode.OffScreen) { - if (!createWindow(mode)) - return false; + if (!createWindow(mode)) return false; + HWND tmpHWND = _win; int width = mode.Width; int height = mode.Height; diff --git a/code/ryzom/server/src/ai_service/ai_vector_mirror.h b/code/ryzom/server/src/ai_service/ai_vector_mirror.h index 0464de4fb..da229b4c3 100644 --- a/code/ryzom/server/src/ai_service/ai_vector_mirror.h +++ b/code/ryzom/server/src/ai_service/ai_vector_mirror.h @@ -95,7 +95,7 @@ public: // Methods. inline double distTo(const CAIVectorMirror &dest) const; inline double distSqTo(const CAIVectorMirror &dest) const; inline double quickDistTo(const CAIVectorMirror &dest) const; - + protected: inline void setX(const CAICoord &x) { _x=x; } inline void setY(const CAICoord &y) { _y=y; } diff --git a/code/ryzom/server/src/dynamic_scenario_service/service.cpp b/code/ryzom/server/src/dynamic_scenario_service/service.cpp index 342a05c23..07c454566 100644 --- a/code/ryzom/server/src/dynamic_scenario_service/service.cpp +++ b/code/ryzom/server/src/dynamic_scenario_service/service.cpp @@ -56,8 +56,6 @@ namespace R2 // The ligo config NLLIGO::CLigoConfig* LigoConfigPtr; CR2LigoConfig R2LigoConfig; - - } diff --git a/code/ryzom/server/src/entities_game_service/progression/progression_pve.h b/code/ryzom/server/src/entities_game_service/progression/progression_pve.h index 11d538ea4..2c9e9aba2 100644 --- a/code/ryzom/server/src/entities_game_service/progression/progression_pve.h +++ b/code/ryzom/server/src/entities_game_service/progression/progression_pve.h @@ -279,7 +279,6 @@ struct CCreatureTakenDamage { if ( PlayerInflictedDamage[i].TotalDamage > maxDmg ) { - nlinfo("set damage by player"); maxDmg = PlayerInflictedDamage[i].TotalDamage; index = (sint16)i; } diff --git a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h index 685386bfc..c33e4fe15 100644 --- a/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h +++ b/code/ryzom/server/src/shard_unifier_service/nel_database_mapping.h @@ -625,7 +625,7 @@ namespace RSMGR }; - ///////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// // WARNING : this is a generated file, don't change it ! ///////////////////////////////////////////////////////////////// class CNelPermission From 5b9ac59f495da17e9973eb7faeac646d2aa8a5b4 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 19:53:27 +0100 Subject: [PATCH 185/344] Fixed: OpenGL driver compilation --HG-- branch : develop --- .../src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp index 6ed74f78e..25c7da614 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_buffer_hard.cpp @@ -1419,7 +1419,6 @@ void *CVertexBufferHardARB::lock() if (_Driver->getStaticMemoryToVRAM()) nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STATIC_DRAW_ARB); else - glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB); break; // case CVertexBuffer::AGPPreferred: From e8ff07fe7dff49a57c5ce810652baf0c950fe6c3 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 19:55:05 +0100 Subject: [PATCH 186/344] Fixed: Removed raw mouse mode for OS X too --HG-- branch : develop --- .../driver/opengl/mac/cocoa_event_emitter.cpp | 67 ++----------------- .../driver/opengl/mac/cocoa_event_emitter.h | 4 -- .../src/3d/driver/opengl/unix_event_emitter.h | 1 - 3 files changed, 5 insertions(+), 67 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index d290e0cee..6206d94c3 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -270,28 +270,14 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) return false; } - // first event about mouse movement after setting to emulateRawMode - if(_setToEmulateRawMode && - (event.type == NSMouseMoved || - event.type == NSLeftMouseDragged || - event.type == NSRightMouseDragged)) - { - // do not report because it reflects wrapping pointer to 0.5/0.5 - _setToEmulateRawMode = false; - return false; - } - // convert the modifiers for nel to pass them with the events - NLMISC::TKeyButton modifiers = - modifierFlagsToNelKeyButton([event modifierFlags]); + NLMISC::TKeyButton modifiers = modifierFlagsToNelKeyButton([event modifierFlags]); switch(event.type) { case NSLeftMouseDown: { - server->postEvent(new NLMISC::CEventMouseDown( - mousePos.x, mousePos.y, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + server->postEvent(new NLMISC::CEventMouseDown(mousePos.x, mousePos.y, (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); } break; case NSLeftMouseUp: @@ -319,15 +305,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) { NLMISC::CEvent* nelEvent; - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove( - mousePos.x, mousePos.y, (NLMISC::TMouseButton)modifiers, this); + nelEvent = new NLMISC::CEventMouseMove(mousePos.x, mousePos.y, (NLMISC::TMouseButton)modifiers, this); server->postEvent(nelEvent); break; @@ -336,15 +314,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) { NLMISC::CEvent* nelEvent; - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mousePos.x, mousePos.y, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); + nelEvent = new NLMISC::CEventMouseMove(mousePos.x, mousePos.y, (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); server->postEvent(nelEvent); break; @@ -353,15 +323,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) { NLMISC::CEvent* nelEvent; - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mousePos.x, mousePos.y, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); + nelEvent = new NLMISC::CEventMouseMove(mousePos.x, mousePos.y, (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); server->postEvent(nelEvent); break; @@ -434,12 +396,6 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) } } - if(_emulateRawMode && _driver && (event.type == NSMouseMoved || - event.type == NSLeftMouseDragged || event.type == NSRightMouseDragged)) - { - _driver->setMousePos(0.5, 0.5); - } - return true; } @@ -492,17 +448,4 @@ void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) _server = &server; } -void CCocoaEventEmitter::emulateMouseRawMode(bool enable) -{ - _emulateRawMode = enable; - - if(_emulateRawMode) - { - _setToEmulateRawMode = true; - - if(_driver) - _driver->setMousePos(0.5, 0.5); - } -} - } diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h index aa7d591fd..960614ef4 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h @@ -31,8 +31,6 @@ namespace NLMISC class CCocoaEventEmitter : public IEventEmitter { - bool _emulateRawMode; - bool _setToEmulateRawMode; bool _eventLoop; NL3D::IDriver* _driver; CocoaOpenGLView* _glView; @@ -42,8 +40,6 @@ class CCocoaEventEmitter : public IEventEmitter public: CCocoaEventEmitter() : - _emulateRawMode(false), - _setToEmulateRawMode(false), _driver(NULL), _glView(nil), _server(NULL) { } diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.h b/code/nel/src/3d/driver/opengl/unix_event_emitter.h index 7eeef970e..493c4ad35 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.h @@ -100,7 +100,6 @@ private: std::map _PressedKeys; XIM _im; XIC _ic; - bool _emulateRawMode; NL3D::IDriver* _driver; CUnixEventServer _InternalServer; ucstring _CopiedString; From fad0e9af4edc609fd62b5f308b9988311d9f87e1 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 10 Jan 2015 20:33:02 +0100 Subject: [PATCH 187/344] Fixed: Compilation with OS X SDK 10.10 --HG-- branch : develop --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 4db3f550b..5c6cecab9 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1483,7 +1483,7 @@ bool CDriverGL::createWindow(const GfxMode &mode) [[CocoaApplicationDelegate alloc] initWithDriver:this]; // set the application delegate, this will handle window/app close events - [NSApp setDelegate:appDelegate]; + [NSApp setDelegate:(id)appDelegate]; // bind the close button of the window to applicationShouldTerminate id closeButton = [cocoa_window standardWindowButton:NSWindowCloseButton]; From 3bca3f41cc3b7ab30a1790a88bce955cdb520c78 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 14:56:51 +0100 Subject: [PATCH 188/344] Changed: Typo --HG-- branch : develop --- code/nel/include/nel/misc/path.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/include/nel/misc/path.h b/code/nel/include/nel/misc/path.h index f3120c907..d8c24758c 100644 --- a/code/nel/include/nel/misc/path.h +++ b/code/nel/include/nel/misc/path.h @@ -343,7 +343,7 @@ public: /** Adds a search path. * The path is a directory "c:/temp" all files in the directory will be included (and recursively if asked) * - * Alternative directories are not pre-cached (instead of non Alternative files) and will used when a file is not found in the standard directories. + * Alternative directories are not pre-cached (instead of non Alternative files) and will be used when a file is not found in the standard directories. * For example, local data will be in the cached directories and server repository files will be in the Alternative files. If a new file is not * found in the local data, we'll try to find it on the repository. * From acf677e63570f82fdc1f8d91ac3d26ec54befa8d Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 14:57:40 +0100 Subject: [PATCH 189/344] Changed: Don't use replaceApplicationDirToken anymore --HG-- branch : develop --- code/ryzom/client/src/init.cpp | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 4de65491a..704260a64 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -554,27 +554,6 @@ void checkDriverDepth () } } -static std::string replaceApplicationDirToken(const std::string &dir) -{ - -#ifdef NL_OS_MAC - // if client_default.cfg is not in current directory, and it's not an absolute path, use application default directory - if (!CFile::isExists("client_default.cfg") && dir.size()>0 && dir[0]!='/') - { - return getAppBundlePath() + "/Contents/Resources/" + dir; - } -#else - static const std::string token = ""; - std::string::size_type pos = dir.find(token); - if (pos != std::string::npos) - return dir.substr(0, pos) + getAppBundlePath() + dir.substr(pos + token.length()); -#endif - -// preDataPath = getAppBundlePath() + "/Contents/Resources/" + preDataPath; - - return dir; -} - void listStereoDisplayDevices(std::vector &devices) { bool cache = VRDeviceCache.empty(); @@ -678,7 +657,7 @@ void addSearchPaths(IProgressCallback &progress) progress.progress ((float)i/(float)ClientCfg.DataPath.size()); progress.pushCropedValues ((float)i/(float)ClientCfg.DataPath.size(), (float)(i+1)/(float)ClientCfg.DataPath.size()); - CPath::addSearchPath(replaceApplicationDirToken(ClientCfg.DataPath[i]), true, false, &progress); + CPath::addSearchPath(ClientCfg.DataPath[i], true, false, &progress); progress.popCropedValues (); } @@ -690,13 +669,12 @@ void addSearchPaths(IProgressCallback &progress) progress.progress ((float)i/(float)ClientCfg.DataPathNoRecurse.size()); progress.pushCropedValues ((float)i/(float)ClientCfg.DataPathNoRecurse.size(), (float)(i+1)/(float)ClientCfg.DataPathNoRecurse.size()); - CPath::addSearchPath(replaceApplicationDirToken(ClientCfg.DataPathNoRecurse[i]), false, false, &progress); + CPath::addSearchPath(ClientCfg.DataPathNoRecurse[i], false, false, &progress); progress.popCropedValues (); } } - void addPreDataPaths(NLMISC::IProgressCallback &progress) { NLMISC::TTime initPaths = ryzomGetLocalTime (); @@ -706,7 +684,7 @@ void addPreDataPaths(NLMISC::IProgressCallback &progress) progress.progress ((float)i/(float)ClientCfg.PreDataPath.size()); progress.pushCropedValues ((float)i/(float)ClientCfg.PreDataPath.size(), (float)(i+1)/(float)ClientCfg.PreDataPath.size()); - CPath::addSearchPath(replaceApplicationDirToken(ClientCfg.PreDataPath[i]), true, false, &progress); + CPath::addSearchPath(ClientCfg.PreDataPath[i], true, false, &progress); progress.popCropedValues (); } @@ -719,7 +697,7 @@ static void addPackedSheetUpdatePaths(NLMISC::IProgressCallback &progress) { progress.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size()); progress.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size()); - CPath::addSearchPath(replaceApplicationDirToken(ClientCfg.UpdatePackedSheetPath[i]), true, false, &progress); + CPath::addSearchPath(ClientCfg.UpdatePackedSheetPath[i], true, false, &progress); progress.popCropedValues(); } } From 3367eb3205ba4f99a0f6011a86e2b8fecdcbff75 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 14:59:15 +0100 Subject: [PATCH 190/344] Changed: Append getAppBundlePath() to search paths under OS X --HG-- branch : develop --- code/ryzom/client/src/init.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 704260a64..07ac27b62 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -664,6 +664,7 @@ void addSearchPaths(IProgressCallback &progress) CPath::loadRemappedFiles("remap_files.csv"); } + for (uint i = 0; i < ClientCfg.DataPathNoRecurse.size(); i++) { progress.progress ((float)i/(float)ClientCfg.DataPathNoRecurse.size()); @@ -673,6 +674,17 @@ void addSearchPaths(IProgressCallback &progress) progress.popCropedValues (); } + + // add in last position, a specific possibly read only directory + std::string defaultDirectory; + +#ifdef NL_OS_MAC + defaultDirectory = getAppBundlePath() + "/Contents/Resources/data"; +#elif defined(NL_OS_UNIX) && defined(RYZOM_SHARE_PREFIX) + defaultDirectory = std::string(RYZOM_SHARE_PREFIX) + "/data"; +#endif + + if (!defaultDirectory.empty()) CPath::addSearchPath(defaultDirectory, true, false); } void addPreDataPaths(NLMISC::IProgressCallback &progress) From 08c557ae76d1110b39edc24ac1c33018a5ae1676 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 15:06:02 +0100 Subject: [PATCH 191/344] Changed: Allow to use a readable and writable data path for IG patch (usefull when data are read only) --HG-- branch : develop --- code/ryzom/client/src/login_patch.cpp | 107 +++++++++++++++++++------- code/ryzom/client/src/login_patch.h | 5 +- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index 5b9a83c83..297f7fddf 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -207,9 +207,23 @@ CPatchManager::CPatchManager() : State("t_state"), DataScanState("t_data_scan_st // **************************************************************************** void CPatchManager::setClientRootPath(const std::string& clientRootPath) { - ClientRootPath = clientRootPath; - ClientPatchPath = ClientRootPath + "unpack/"; - ClientDataPath = ClientRootPath + "data/"; + ClientRootPath = CPath::standardizePath(clientRootPath); + ClientPatchPath = CPath::standardizePath(ClientRootPath + "unpack"); + ReadableClientDataPath = CPath::standardizePath(ClientRootPath + "data"); + + std::string writableTest = ReadableClientDataPath + "writableTest"; + + // if succeeded to create a delete a temporary file in data directory + if (CFile::createEmptyFile(writableTest) && CFile::deleteFile(writableTest)) + { + // use it to patch data files + WritableClientDataPath = ReadableClientDataPath; + } + else + { + // use system user profile to patch data files + WritableClientDataPath = CPath::standardizePath(CPath::getApplicationDirectory("Ryzom") + "data"); + } } // **************************************************************************** @@ -253,7 +267,7 @@ void CPatchManager::init(const std::vector& patchURIs, const std::s DisplayedServerPath = ServerPath; NLMISC::CFile::createDirectory(ClientPatchPath); - NLMISC::CFile::createDirectory(ClientDataPath); + NLMISC::CFile::createDirectory(WritableClientDataPath); // try to read the version file from the server (that will replace the version number) @@ -787,7 +801,7 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool if (!result) { -//:TODO: handle exception? + // TODO: handle exception? string err = toString("Error unpacking %s", rFilename.c_str()); if (useBatchFile) @@ -913,7 +927,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool throw NLMISC::EWriteError(UpdateBatchFilename.c_str()); } } - } // **************************************************************************** @@ -1616,9 +1629,25 @@ void CPatchManager::getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn, // Only look in data path if the file should not be unpack (otherwise it should only remains in the "unpack" directory) if (!needUnpack) { - if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientDataPath + rFilename)) sFilePath = ClientDataPath + rFilename; + if (sFilePath.empty()) + { + if (NLMISC::CFile::fileExists(WritableClientDataPath + rFilename)) + { + // if file exists in writable directory, use it + sFilePath = WritableClientDataPath + rFilename; + } + else if (NLMISC::CFile::fileExists(ReadableClientDataPath + rFilename)) + { + // if file exists in readable directory, use it + sFilePath = ReadableClientDataPath + rFilename; + } + } + } + + if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + rFilename)) + { + sFilePath = ClientPatchPath + rFilename; } - if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + rFilename)) sFilePath = ClientPatchPath + rFilename; // following lines removed by Sadge to ensure that the correct file is patched // string sFilePath = CPath::lookup(rFilename, false, false); @@ -2039,7 +2068,8 @@ uint CPatchManager::applyScanDataResult() if(ScanDataThread) return 0; - uint numError= 0; + uint numError= 0; + { TSyncDataScanState::CAccessor ac(&DataScanState); CDataScanState &val= ac.value(); @@ -2057,7 +2087,8 @@ uint CPatchManager::applyScanDataResult() // get file path // following lines added by Sadge to ensure that the correct file gets patched string sFilePath; - if (NLMISC::CFile::fileExists(ClientDataPath + ftp.FileName)) sFilePath = ClientDataPath + ftp.FileName; + if (NLMISC::CFile::fileExists(WritableClientDataPath + ftp.FileName)) sFilePath = WritableClientDataPath + ftp.FileName; + if (sFilePath.empty() && NLMISC::CFile::fileExists(ReadableClientDataPath + ftp.FileName)) sFilePath = ReadableClientDataPath + ftp.FileName; if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + ftp.FileName)) sFilePath = ClientPatchPath + ftp.FileName; // following lines removed by Sadge to ensure that the correct file gets patched @@ -2768,15 +2799,31 @@ public: void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) { CPatchManager *pPM = CPatchManager::getInstance(); - // Source File Name + + // Source File Name (in writable or readable directory) string SourceName; + + // Destination File Name (in writable directory) + string DestinationName; + if (rFTP.ExtractPath.empty()) { + DestinationName = pPM->WritableClientDataPath + rFTP.FileName; + if (rFTP.LocalFileExists) { // following lines added by Sadge to ensure that the correct file gets patched SourceName.clear(); - if (NLMISC::CFile::fileExists(pPM->ClientDataPath + rFTP.FileName)) SourceName = pPM->ClientDataPath + rFTP.FileName; + + if (NLMISC::CFile::fileExists(pPM->WritableClientDataPath + rFTP.FileName)) + { + SourceName = pPM->WritableClientDataPath + rFTP.FileName; + } + else if (NLMISC::CFile::fileExists(pPM->ReadableClientDataPath + rFTP.FileName)) + { + SourceName = pPM->ReadableClientDataPath + rFTP.FileName; + } + // version from previous download if (SourceName.empty()) throw Exception (std::string("ERROR: Failed to find file: ")+rFTP.FileName); @@ -2788,12 +2835,13 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) // note : if file was background downloaded, we have : // rFTP.LocalFileExists = false // rFTP.SrcFileName = "unpack/filename.bnp.tmp" - SourceName = pPM->ClientDataPath + rFTP.FileName; + SourceName = DestinationName; } } else { SourceName = pPM->ClientPatchPath + rFTP.FileName; + DestinationName = SourceName; } if (rFTP.LocalFileToDelete) @@ -2838,7 +2886,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) for (uint i=0; ideleteFile(SourceName, false, false); // File can exists if bad BNP loading if (_CommitPatch) { - pPM->renameFile(OutFilename+".tmp", SourceName); + pPM->renameFile(OutFilename+".tmp", DestinationName); } } } - if (usePatchFile && !rFTP.Patches.empty()) + if (usePatchFile) { uint32 currentPatchedSize = 0; for (uint32 j = 0; j < rFTP.Patches.size(); ++j) @@ -2987,21 +3035,14 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) SourceNameXD = SourceNameXD.substr(0, SourceNameXD.rfind('.')); SourceNameXD += "_.ref"; - std::string refPath; - if (_CommitPatch) - { - refPath = pPM->ClientDataPath; - } - else + if (!_CommitPatch) { // works - refPath = pPM->ClientPatchPath; std::string tmpRefFile = SourceNameXD + ".tmp"; if (!NLMISC::CFile::fileExists(pPM->ClientPatchPath + tmpRefFile)) { // Not found in the patch directory -> version in data directory should be good, or would have been // detected by the check thread else. - refPath = pPM->ClientDataPath; } else { @@ -3018,7 +3059,14 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) // if (SourceNameXDFull.empty()) // SourceNameXDFull = pPM->ClientDataPath + SourceNameXD; // SourceNameXD = SourceNameXDFull; - SourceNameXD = pPM->ClientDataPath + SourceNameXD; + if (CFile::fileExists(pPM->WritableClientDataPath + SourceNameXD)) + { + SourceNameXD = pPM->WritableClientDataPath + SourceNameXD; + } + else if (CFile::fileExists(pPM->ReadableClientDataPath + SourceNameXD)) + { + SourceNameXD = pPM->ReadableClientDataPath + SourceNameXD; + } } PatchName = pPM->ClientPatchPath + PatchName; @@ -3042,7 +3090,8 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) PatchSizeProgress += rFTP.PatcheSizes[j]; currentPatchedSize += rFTP.PatcheSizes[j]; } - if (tmpSourceName != SourceName) + + if (tmpSourceName != DestinationName) { pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading if (!_CommitPatch) @@ -3052,7 +3101,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) } else { - pPM->renameFile(tmpSourceName, SourceName); + pPM->renameFile(tmpSourceName, DestinationName); } } } @@ -3060,9 +3109,10 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP) { PatchSizeProgress += totalPatchSize; } + // If all patches applied with success so file size should be ok // We just have to change file date to match the last patch applied - pPM->applyDate(SourceName, rFTP.LastFileDate); + pPM->applyDate(DestinationName, rFTP.LastFileDate); //progress.progress(1.f); } @@ -3413,6 +3463,7 @@ bool CPatchManager::extract(const std::string& patchPath, string err = toString("Can't open file '%s' for writing: code=%d %s (error code 29)", updateBatchFilename.c_str(), errno, strerror(errno)); throw Exception (err); } + fprintf(fp, "@echo off\n"); fprintf(fp, "ping 127.0.0.1 -n 7 -w 1000 > nul\n"); // wait diff --git a/code/ryzom/client/src/login_patch.h b/code/ryzom/client/src/login_patch.h index de7351775..cd4fad0ff 100644 --- a/code/ryzom/client/src/login_patch.h +++ b/code/ryzom/client/src/login_patch.h @@ -447,8 +447,9 @@ private: std::string UpdateBatchFilename; // Where the client get all delta and desc file - std::string ClientPatchPath; - std::string ClientDataPath; + std::string ClientPatchPath; // Temporary path + std::string ReadableClientDataPath; // Where original data can be found + std::string WritableClientDataPath; // Where data can be written /// Output useful information for debugging in the log file bool VerboseLog; From 8fc8c3aa3993666fb3d956732f487d0d6978e9fa Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 18:01:32 +0100 Subject: [PATCH 192/344] Changed: Use defined directories prefixed by a default directory --HG-- branch : develop --- code/ryzom/client/src/init.cpp | 54 ++++++++++++++++++++++++--- code/ryzom/client/src/login_patch.cpp | 27 +++++++------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 07ac27b62..765e2fcd6 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -675,22 +675,39 @@ void addSearchPaths(IProgressCallback &progress) progress.popCropedValues (); } - // add in last position, a specific possibly read only directory std::string defaultDirectory; #ifdef NL_OS_MAC - defaultDirectory = getAppBundlePath() + "/Contents/Resources/data"; + defaultDirectory = CPath::standardizePath(getAppBundlePath() + "/Contents/Resources"); #elif defined(NL_OS_UNIX) && defined(RYZOM_SHARE_PREFIX) - defaultDirectory = std::string(RYZOM_SHARE_PREFIX) + "/data"; + defaultDirectory = CPath::standardizePath(std::string(RYZOM_SHARE_PREFIX)); #endif - if (!defaultDirectory.empty()) CPath::addSearchPath(defaultDirectory, true, false); + // add in last position, a specific possibly read only directory + if (!defaultDirectory.empty()) + { + for (uint i = 0; i < ClientCfg.DataPath.size(); i++) + { + // don't prepend default directory if path is absolute + if (!ClientCfg.PreDataPath[i].empty() && ClientCfg.PreDataPath[i][0] != '/') + { + progress.progress ((float)i/(float)ClientCfg.DataPath.size()); + progress.pushCropedValues ((float)i/(float)ClientCfg.DataPath.size(), (float)(i+1)/(float)ClientCfg.DataPath.size()); + + CPath::addSearchPath(defaultDirectory + ClientCfg.DataPath[i], true, false, &progress); + + progress.popCropedValues (); + } + } + } } void addPreDataPaths(NLMISC::IProgressCallback &progress) { NLMISC::TTime initPaths = ryzomGetLocalTime (); - H_AUTO(InitRZAddSearchPaths) + + H_AUTO(InitRZAddSearchPaths); + for (uint i = 0; i < ClientCfg.PreDataPath.size(); i++) { progress.progress ((float)i/(float)ClientCfg.PreDataPath.size()); @@ -700,7 +717,34 @@ void addPreDataPaths(NLMISC::IProgressCallback &progress) progress.popCropedValues (); } + //nlinfo ("PROFILE: %d seconds for Add search paths Predata", (uint32)(ryzomGetLocalTime ()-initPaths)/1000); + + std::string defaultDirectory; + +#ifdef NL_OS_MAC + defaultDirectory = CPath::standardizePath(getAppBundlePath() + "/Contents/Resources"); +#elif defined(NL_OS_UNIX) && defined(RYZOM_SHARE_PREFIX) + defaultDirectory = CPath::standardizePath(std::string(RYZOM_SHARE_PREFIX)); +#endif + + // add in last position, a specific possibly read only directory + if (!defaultDirectory.empty()) + { + for (uint i = 0; i < ClientCfg.PreDataPath.size(); i++) + { + // don't prepend default directory if path is absolute + if (!ClientCfg.PreDataPath[i].empty() && ClientCfg.PreDataPath[i][0] != '/') + { + progress.progress ((float)i/(float)ClientCfg.PreDataPath.size()); + progress.pushCropedValues ((float)i/(float)ClientCfg.PreDataPath.size(), (float)(i+1)/(float)ClientCfg.PreDataPath.size()); + + CPath::addSearchPath(defaultDirectory + ClientCfg.PreDataPath[i], true, false, &progress); + + progress.popCropedValues (); + } + } + } } static void addPackedSheetUpdatePaths(NLMISC::IProgressCallback &progress) diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index 297f7fddf..2a08262f0 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -26,6 +26,10 @@ #include #endif +#ifdef NL_OS_MAC + #include "app_bundle_utils.h" +#endif + #include #include @@ -209,21 +213,16 @@ void CPatchManager::setClientRootPath(const std::string& clientRootPath) { ClientRootPath = CPath::standardizePath(clientRootPath); ClientPatchPath = CPath::standardizePath(ClientRootPath + "unpack"); - ReadableClientDataPath = CPath::standardizePath(ClientRootPath + "data"); - - std::string writableTest = ReadableClientDataPath + "writableTest"; + + WritableClientDataPath = CPath::standardizePath(ClientRootPath + "data"); - // if succeeded to create a delete a temporary file in data directory - if (CFile::createEmptyFile(writableTest) && CFile::deleteFile(writableTest)) - { - // use it to patch data files - WritableClientDataPath = ReadableClientDataPath; - } - else - { - // use system user profile to patch data files - WritableClientDataPath = CPath::standardizePath(CPath::getApplicationDirectory("Ryzom") + "data"); - } +#ifdef NL_OS_MAC + ReadableClientDataPath = CPath::standardizePath(getAppBundlePath() + "/Contents/Resources/data"); +#elif defined(NL_OS_UNIX) && defined(RYZOM_SHARE_PREFIX) + ReadableClientDataPath = CPath::standardizePath(std::string(RYZOM_SHARE_PREFIX) + "/data"); +#else + ReadableClientDataPath = WritableClientDataPath; +#endif } // **************************************************************************** From bc78734602970200531be773191ee6d5e9241683 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 11 Jan 2015 18:27:06 +0100 Subject: [PATCH 193/344] Changed: Fixed a wrong copy-paste --HG-- branch : develop --- code/ryzom/client/src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 765e2fcd6..c6b74ebd2 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -689,7 +689,7 @@ void addSearchPaths(IProgressCallback &progress) for (uint i = 0; i < ClientCfg.DataPath.size(); i++) { // don't prepend default directory if path is absolute - if (!ClientCfg.PreDataPath[i].empty() && ClientCfg.PreDataPath[i][0] != '/') + if (!ClientCfg.DataPath[i].empty() && ClientCfg.DataPath[i][0] != '/') { progress.progress ((float)i/(float)ClientCfg.DataPath.size()); progress.pushCropedValues ((float)i/(float)ClientCfg.DataPath.size(), (float)(i+1)/(float)ClientCfg.DataPath.size()); From 1ab170b7d86580415f3864e92deba18a64a07c12 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 13 Jan 2015 13:21:56 +0100 Subject: [PATCH 194/344] Unhide layers in max export --HG-- branch : develop --- .../generators/max_exporter_scripts/clod.ms | 1 + .../generators/max_exporter_scripts/ig.ms | 1 + .../generators/max_exporter_scripts/shape.ms | 1 + .../generators/max_exporter_scripts/veget.ms | 1 + .../export_header.ms | 10 ++++++++++ .../export_header.ms | 10 ++++++++++ .../build_gamedata/processes/anim/1_export.py | 2 +- .../processes/anim/maxscript/anim_export.ms | 10 ++++++++++ .../processes/clodbank/1_export.py | 2 +- .../processes/clodbank/maxscript/clod_export.ms | 11 +++++++++++ .../processes/ig/maxscript/ig_export.ms | 11 +++++++++++ .../processes/ligo/maxscript/nel_ligo_export.ms | 17 +++++++++++++++++ .../processes/pacs_prim/1_export.py | 9 ++++++++- .../pacs_prim/maxscript/pacs_prim_export.ms | 10 ++++++++++ .../build_gamedata/processes/rbank/1_export.py | 2 +- .../processes/rbank/maxscript/cmb_export.ms | 10 ++++++++++ .../processes/shape/maxscript/shape_export.ms | 11 +++++++++++ .../build_gamedata/processes/skel/1_export.py | 2 +- .../processes/skel/maxscript/skel_export.ms | 10 ++++++++++ .../build_gamedata/processes/swt/1_export.py | 2 +- .../processes/swt/maxscript/swt_export.ms | 10 ++++++++++ .../build_gamedata/processes/veget/1_export.py | 2 +- .../processes/veget/maxscript/veget_export.ms | 11 +++++++++++ .../build_gamedata/processes/zone/1_export.py | 2 +- .../processes/zone/maxscript/zone_export.ms | 10 ++++++++++ 25 files changed, 160 insertions(+), 8 deletions(-) diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/clod.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/clod.ms index 68c8455d6..1a947f7d6 100755 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/clod.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/clod.ms @@ -49,6 +49,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/ig.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/ig.ms index df0ecf7fc..43a05abcc 100755 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/ig.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/ig.ms @@ -54,6 +54,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms index 2a52947ec..cfb51d0e0 100755 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms @@ -194,6 +194,7 @@ fn runNelMaxExportSub inputMaxFile retryCount = tagThisFile = false -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/veget.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/veget.ms index 22c49013a..614a9a94f 100755 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/veget.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/veget.ms @@ -39,6 +39,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/generators/simple_max_exporter_template/export_header.ms b/code/nel/tools/build_gamedata/generators/simple_max_exporter_template/export_header.ms index 2d5e5434f..f06bab786 100755 --- a/code/nel/tools/build_gamedata/generators/simple_max_exporter_template/export_header.ms +++ b/code/nel/tools/build_gamedata/generators/simple_max_exporter_template/export_header.ms @@ -13,6 +13,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_header.ms b/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_header.ms index 03bfea443..a7b97a064 100755 --- a/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_header.ms +++ b/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_header.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/anim/1_export.py b/code/nel/tools/build_gamedata/processes/anim/1_export.py index 4c51fc261..1745c45a9 100755 --- a/code/nel/tools/build_gamedata/processes/anim/1_export.py +++ b/code/nel/tools/build_gamedata/processes/anim/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export anim -# \date 2011-09-21-20-51-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export anim diff --git a/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms b/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms index 7121e16d5..fc1eda5f9 100755 --- a/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms +++ b/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/clodbank/1_export.py b/code/nel/tools/build_gamedata/processes/clodbank/1_export.py index 64cd875df..c73a86ac7 100755 --- a/code/nel/tools/build_gamedata/processes/clodbank/1_export.py +++ b/code/nel/tools/build_gamedata/processes/clodbank/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export clodbank -# \date 2011-09-21-20-51-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export clodbank diff --git a/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms b/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms index a8693dc8a..02856d2c7 100755 --- a/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms +++ b/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( @@ -115,6 +125,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms b/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms index 65cb38c4a..e91732391 100755 --- a/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms +++ b/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( @@ -120,6 +130,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/processes/ligo/maxscript/nel_ligo_export.ms b/code/nel/tools/build_gamedata/processes/ligo/maxscript/nel_ligo_export.ms index 933468459..07d032809 100755 --- a/code/nel/tools/build_gamedata/processes/ligo/maxscript/nel_ligo_export.ms +++ b/code/nel/tools/build_gamedata/processes/ligo/maxscript/nel_ligo_export.ms @@ -17,6 +17,16 @@ NEL3D_APPDATA_IGNAME = 1423062564 -- string : name of the Instance Group tagThisFile = true +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( @@ -307,6 +317,10 @@ fn buildTransitionMatrixObj mt transitionZone cellSize = -- Export instance groups from the current loaded zone fn exportInstanceGroupFromZone inputFile outputPath igName transitionZone cellSize = ( + -- Unhide category + unhidelayers() + unhidecategory() + -- Unhide max unhide all @@ -501,6 +515,7 @@ try objXRefMgr.UpdateAllRecords() -- Unhide category + unhidelayers() unhidecategory() DeleteDebugMarkersFn () @@ -648,6 +663,7 @@ try objXRefMgr.UpdateAllRecords() -- Unhide category + unhidelayers() unhidecategory() DeleteDebugMarkersFn () @@ -863,6 +879,7 @@ try objXRefMgr.UpdateAllRecords() -- Unhide category + unhidelayers() unhidecategory() DeleteDebugMarkersFn () diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py b/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py index 4fb464704..cfb46635f 100755 --- a/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py +++ b/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export pacs_prim -# \date 2013-07-24-14-21-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export pacs_prim @@ -130,6 +130,13 @@ if MaxAvailable: +# Remove bad file from previous script version +listPath = ExportBuildDirectory + "/" + PacsPrimExportDirectory + "/landscape_col_prim_pacs_list.txt" +if os.path.isfile(listPath): + os.remove(listPath) + + + log.close() if os.path.isfile("log.log"): os.remove("log.log") diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim/maxscript/pacs_prim_export.ms b/code/nel/tools/build_gamedata/processes/pacs_prim/maxscript/pacs_prim_export.ms index 750af80d9..d0d7c7ce4 100755 --- a/code/nel/tools/build_gamedata/processes/pacs_prim/maxscript/pacs_prim_export.ms +++ b/code/nel/tools/build_gamedata/processes/pacs_prim/maxscript/pacs_prim_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/rbank/1_export.py b/code/nel/tools/build_gamedata/processes/rbank/1_export.py index 4b5667961..65c14c907 100755 --- a/code/nel/tools/build_gamedata/processes/rbank/1_export.py +++ b/code/nel/tools/build_gamedata/processes/rbank/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export rbank -# \date 2011-09-21-20-51-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export rbank diff --git a/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms b/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms index 59b444db3..4949f7c60 100755 --- a/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms +++ b/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms index 5bece0c50..f97419aa7 100755 --- a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms +++ b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( @@ -260,6 +270,7 @@ fn runNelMaxExportSub inputMaxFile retryCount = tagThisFile = false -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/processes/skel/1_export.py b/code/nel/tools/build_gamedata/processes/skel/1_export.py index 5f065fe5d..dcf336dbd 100755 --- a/code/nel/tools/build_gamedata/processes/skel/1_export.py +++ b/code/nel/tools/build_gamedata/processes/skel/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export skel -# \date 2011-09-28-07-42-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export skel diff --git a/code/nel/tools/build_gamedata/processes/skel/maxscript/skel_export.ms b/code/nel/tools/build_gamedata/processes/skel/maxscript/skel_export.ms index 7fd2af0fb..74440350b 100755 --- a/code/nel/tools/build_gamedata/processes/skel/maxscript/skel_export.ms +++ b/code/nel/tools/build_gamedata/processes/skel/maxscript/skel_export.ms @@ -13,6 +13,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/swt/1_export.py b/code/nel/tools/build_gamedata/processes/swt/1_export.py index 0803f1246..820950fe5 100755 --- a/code/nel/tools/build_gamedata/processes/swt/1_export.py +++ b/code/nel/tools/build_gamedata/processes/swt/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export swt -# \date 2011-09-28-07-42-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export swt diff --git a/code/nel/tools/build_gamedata/processes/swt/maxscript/swt_export.ms b/code/nel/tools/build_gamedata/processes/swt/maxscript/swt_export.ms index ea6ff95c3..99d684ea3 100755 --- a/code/nel/tools/build_gamedata/processes/swt/maxscript/swt_export.ms +++ b/code/nel/tools/build_gamedata/processes/swt/maxscript/swt_export.ms @@ -13,6 +13,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( diff --git a/code/nel/tools/build_gamedata/processes/veget/1_export.py b/code/nel/tools/build_gamedata/processes/veget/1_export.py index b2f8a7c57..ae8b835a3 100755 --- a/code/nel/tools/build_gamedata/processes/veget/1_export.py +++ b/code/nel/tools/build_gamedata/processes/veget/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export veget -# \date 2011-09-21-20-51-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export veget diff --git a/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms b/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms index cbc2f2177..1b8154530 100755 --- a/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms +++ b/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms @@ -16,6 +16,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( @@ -105,6 +115,7 @@ fn runNelMaxExport inputMaxFile = tagThisFile = true -- Unhide category + unhidelayers() unhidecategory() -- Unhide diff --git a/code/nel/tools/build_gamedata/processes/zone/1_export.py b/code/nel/tools/build_gamedata/processes/zone/1_export.py index 94a90900c..acffe9abb 100755 --- a/code/nel/tools/build_gamedata/processes/zone/1_export.py +++ b/code/nel/tools/build_gamedata/processes/zone/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export zone -# \date 2011-09-28-07-42-GMT +# \date 2015-01-06-16-31-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export zone diff --git a/code/nel/tools/build_gamedata/processes/zone/maxscript/zone_export.ms b/code/nel/tools/build_gamedata/processes/zone/maxscript/zone_export.ms index 3a0ebf8fe..6c4e0c8a0 100755 --- a/code/nel/tools/build_gamedata/processes/zone/maxscript/zone_export.ms +++ b/code/nel/tools/build_gamedata/processes/zone/maxscript/zone_export.ms @@ -13,6 +13,16 @@ nlErrorStream = openFile nlErrorFilename mode:"a" if nlErrorStream == undefined then nlErrorStream = createFile nlErrorFilename +-- Unhide layers +fn unhidelayers = +( + for i = 0 to (LayerManager.count - 1) do + ( + layer = (LayerManager.getLayer i) + layer.ishidden = false + ) +) + -- Unhide category fn unhidecategory = ( From dade81e02e52e5b2ee3d196fba89ea6f7b19853b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 13 Jan 2015 13:21:56 +0100 Subject: [PATCH 195/344] Lightmap debug message --HG-- branch : develop --- code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp index d6bdbb690..d82e2a394 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp @@ -2144,6 +2144,8 @@ void appendLightmapLog (COFile &outputLog, const char *lightmapName, const vecto bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshBaseBuild *pZeMeshBaseBuild, INode& ZeNode, TimeValue tvTime, uint firstMaterial, bool outputLightmapLog) { + nldebug("Calculate LM: '%s'", ZeNode.GetName()); + DWORD t = timeGetTime(); uint32 i, j; From 704610668d75aabf72f8d4d5f2f2fcb58df31133 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 13:47:19 +0100 Subject: [PATCH 196/344] Changed: Replaced ~0 by corresponding std::numeric_limits::max() --HG-- branch : develop --- code/ryzom/server/src/ai_service/ai.cpp | 4 +- code/ryzom/server/src/ai_service/ai.h | 6 +- .../src/ai_service/ai_generic_fight.cpp | 2 +- .../server/src/ai_service/ai_grp_fauna.cpp | 14 ++-- .../server/src/ai_service/child_container.h | 2 +- code/ryzom/server/src/ai_service/commands.cpp | 2 +- .../server/src/ai_service/continent_inline.h | 2 +- .../server/src/ai_service/family_behavior.h | 2 +- code/ryzom/server/src/ai_service/nf_helpers.h | 2 +- .../server/src/ai_service/path_behaviors.h | 14 ++-- .../server/src/ai_service/state_instance.h | 2 +- .../stat_user_file_list_builders.cpp | 2 +- .../ryzom_welcome_service.cpp | 2 +- .../server_share/logger_service_client.cpp | 4 +- .../server/src/server_share/msg_ai_service.h | 4 +- .../src/server_share/pet_interface_msg.h | 2 +- .../server/src/server_share/r2_vision.cpp | 64 +++++++++---------- .../ryzom/server/src/server_share/r2_vision.h | 8 +-- .../src/server_share/used_continent.cpp | 4 +- .../server/src/server_share/used_continent.h | 4 +- .../shard_unifier_service/character_sync.cpp | 2 +- .../src/tick_service/range_mirror_manager.cpp | 2 +- .../src/tick_service/range_mirror_manager.h | 2 +- .../server/src/tick_service/tick_service.cpp | 6 +- .../server/src/tick_service/tick_service.h | 2 +- .../tools/leveldesign/mp_generator/utils.h | 16 ++--- .../tools/patch_gen/patch_gen_common.cpp | 2 +- .../ai_build_wmap/build_proximity_maps.cpp | 8 +-- .../packed_world_builder.cpp | 2 +- 29 files changed, 94 insertions(+), 94 deletions(-) diff --git a/code/ryzom/server/src/ai_service/ai.cpp b/code/ryzom/server/src/ai_service/ai.cpp index 587e5ac0c..49144fa9d 100644 --- a/code/ryzom/server/src/ai_service/ai.cpp +++ b/code/ryzom/server/src/ai_service/ai.cpp @@ -224,7 +224,7 @@ uint32 CAIS::getEmotNumber(const std::string &name) { std::map::iterator it(_EmotNames.find(name)); if (it==_EmotNames.end()) - return ~0; + return std::numeric_limits::max(); return it->second; } @@ -280,7 +280,7 @@ uint32 CAIS::createAIInstance(const std::string &continentName, uint32 instanceN continue; nlwarning("CAIS::createAIInstance: instance number %u is already in use, can't create new instance.", instanceNumber); - return ~0; + return std::numeric_limits::max(); } CAIInstance *aii = _AIInstances.addChild(new CAIInstance(this)); diff --git a/code/ryzom/server/src/ai_service/ai.h b/code/ryzom/server/src/ai_service/ai.h index 4f9a7d802..57ff524ec 100644 --- a/code/ryzom/server/src/ai_service/ai.h +++ b/code/ryzom/server/src/ai_service/ai.h @@ -104,7 +104,7 @@ public: // classic init(), update() and release() /** create an AI instance, return the instance index in the AIList - * Return ~0 if the instance number is already in use. + * Return std::numeric_limits::max() if the instance number is already in use. */ uint32 createAIInstance(const std::string &continentName, uint32 instanceNumber); /** destroy an AI Instance (useful for ring creation / destruction of session) @@ -205,7 +205,7 @@ public: /// Time warp managment. This method is called when time as warped more than 600ms bool advanceUserTimer(uint32 nbTicks); - /// Retreive emot number given it's name, return ~0 if not found + /// Retreive emot number given it's name, return std::numeric_limits::max() if not found uint32 getEmotNumber(const std::string &name); CCont &AIList () { return _AIInstances; } @@ -243,7 +243,7 @@ public: class CCounter { public: - CCounter(const uint32 max=~0):_Total(0),_Max(max) + CCounter(const uint32 max=std::numeric_limits::max()):_Total(0),_Max(max) {} virtual ~CCounter() {} diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp b/code/ryzom/server/src/ai_service/ai_generic_fight.cpp index a19f747c3..f4c9a5cb0 100644 --- a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp +++ b/code/ryzom/server/src/ai_service/ai_generic_fight.cpp @@ -571,7 +571,7 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) ennemy=entity; } } - entity->_ChooseLastTime=~0; + entity->_ChooseLastTime = std::numeric_limits::max(); } if (fleeEnnemy==NULL && !spawnBot->getUnreachableTarget().isNULL()) diff --git a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp b/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp index 2bab5200d..6cd657ff2 100644 --- a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp +++ b/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp @@ -220,7 +220,7 @@ void CSpawnGroupFauna::update() getPersistent().updateStateInstance(); - if (_CurrentCycle==~0) + if (_CurrentCycle==std::numeric_limits::max()) return; // Respawn @@ -606,9 +606,9 @@ CGrpFauna::CGrpFauna(CMgrFauna* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MA // state - _CurPopulation = ~0u; + _CurPopulation = std::numeric_limits::max(); - _CurrentCycle = ~0; + _CurrentCycle = std::numeric_limits::max(); // default values. setTimer(EAT_TIME, refTimer(EAT_TIME)); @@ -699,9 +699,9 @@ CAliasTreeOwner* CGrpFauna::createChild(IAliasCont* cont, CAIAliasDescriptionNod CAIPlaceXYRFauna *faunaPlace = new CAIPlaceXYRFauna(this, aliasTree); child = faunaPlace; uint placeIndex = faunaPlace->setupFromOldName(name); - nlassert(placeIndex!=~0); + nlassert(placeIndex!=std::numeric_limits::max()); - if (placeIndex!=~0) + if (placeIndex!=std::numeric_limits::max()) cont->addAliasChild(child, placeIndex); return child; @@ -769,7 +769,7 @@ bool CGrpFauna::spawn() return false; setStartState(getStartState()); // stateInstance. - return spawnPop(~0); + return spawnPop(std::numeric_limits::max()); } bool CGrpFauna::timeAllowSpawn(uint32 popVersion) const @@ -841,7 +841,7 @@ bool CGrpFauna::spawnPop(uint popVersion) } // check the validity of the input parameter - if (popVersion!=~0 && popVersion>=_Populations.size()) + if (popVersion!=std::numeric_limits::max() && popVersion>=_Populations.size()) { nlwarning("CGrpFauna::spawn(idx) FAILED for group %s because idx (%d) >= _Populations.size() (%d)",this->CGroup::getFullName().c_str(),popVersion,_Populations.size()); return false; diff --git a/code/ryzom/server/src/ai_service/child_container.h b/code/ryzom/server/src/ai_service/child_container.h index ab98d93af..0b5c79c4e 100644 --- a/code/ryzom/server/src/ai_service/child_container.h +++ b/code/ryzom/server/src/ai_service/child_container.h @@ -495,7 +495,7 @@ uint32 CAliasCont::getChildIndexByAlias(uint32 alias) const if (child!=NULL && child->getAlias()==alias) return (uint32)i; } - return ~0; + return std::numeric_limits::max(); } template diff --git a/code/ryzom/server/src/ai_service/commands.cpp b/code/ryzom/server/src/ai_service/commands.cpp index d257d0492..b51c7615b 100644 --- a/code/ryzom/server/src/ai_service/commands.cpp +++ b/code/ryzom/server/src/ai_service/commands.cpp @@ -577,7 +577,7 @@ NLMISC_COMMAND(createStaticAIInstance, "Create a new static AIInstance for a giv CUsedContinent &uc = CUsedContinent::instance(); const uint32 in = uc.getInstanceForContinent(args[0]); - if (in == ~0) + if (in == std::numeric_limits::max()) { nlwarning("The continent '%s' is unknow or not active. Can't create instance, FATAL", args[0].c_str()); nlassert(in != ~0); diff --git a/code/ryzom/server/src/ai_service/continent_inline.h b/code/ryzom/server/src/ai_service/continent_inline.h index 49c21248e..4ddf09c18 100644 --- a/code/ryzom/server/src/ai_service/continent_inline.h +++ b/code/ryzom/server/src/ai_service/continent_inline.h @@ -695,7 +695,7 @@ static CAIVector randomPos(double dispersionRadius) { return CAIVector(0., 0.); } - uint32 const maxLimit=((uint32)~0U)>>1; + uint32 const maxLimit=(std::numeric_limits::max())>>1; double rval = (double)CAIS::rand32(maxLimit)/(double)maxLimit; // [0-1[ double r = dispersionRadius*sqrt(rval); rval = (double)CAIS::rand32(maxLimit)/(double)maxLimit; // [0-1[ diff --git a/code/ryzom/server/src/ai_service/family_behavior.h b/code/ryzom/server/src/ai_service/family_behavior.h index 893282ae0..52d534e1c 100644 --- a/code/ryzom/server/src/ai_service/family_behavior.h +++ b/code/ryzom/server/src/ai_service/family_behavior.h @@ -210,7 +210,7 @@ class CFamilyBehavior void spawnBoss(NLMISC::TStringId outpostName); - uint32 energyScale (uint32 levelIndex=~0) const; + uint32 energyScale (uint32 levelIndex=std::numeric_limits::max()) const; void setModifier (const float &value, const uint32 &index) { diff --git a/code/ryzom/server/src/ai_service/nf_helpers.h b/code/ryzom/server/src/ai_service/nf_helpers.h index 2b8ead4e6..dc9c7c345 100644 --- a/code/ryzom/server/src/ai_service/nf_helpers.h +++ b/code/ryzom/server/src/ai_service/nf_helpers.h @@ -161,7 +161,7 @@ public: if (_value==-1) // not for affectation. return; - if (_index==~0) // all indexs ? + if (_index==std::numeric_limits::max()) // all indexs ? { for (uint32 nrjIndex=0;nrjIndex<4;nrjIndex++) fb->setModifier (_value, nrjIndex); diff --git a/code/ryzom/server/src/ai_service/path_behaviors.h b/code/ryzom/server/src/ai_service/path_behaviors.h index 8c509ae9d..6684b2db3 100644 --- a/code/ryzom/server/src/ai_service/path_behaviors.h +++ b/code/ryzom/server/src/ai_service/path_behaviors.h @@ -168,11 +168,11 @@ public: // - This method adds the new object to the top of the CFollowPath singleton's context stack // parameters: // - contextName : an arbitrary string naming the context - // - maxSearchDepth : the value that the path finder search depth should be limitted to (default to ~0u meaning no limit) + // - maxSearchDepth : the value that the path finder search depth should be limitted to (default to std::numeric_limits::max() meaning no limit) // - forceMaxDepth : set this flag true to override previous limit with larger value // example: - // - ... Before we begin ... CFollowPath::_MaxSearchDepth = ~0u - // - CFollowPathContext context1("tata") : CFollowPath::_MaxSearchDepth => ~0u + // - ... Before we begin ... CFollowPath::_MaxSearchDepth = std::numeric_limits::max() + // - CFollowPathContext context1("tata") : CFollowPath::_MaxSearchDepth => std::numeric_limits::max() // - CFollowPathContext context2("tete",456) : CFollowPath::_MaxSearchDepth => 456 // - CFollowPathContext context3("titi",123) : CFollowPath::_MaxSearchDepth => 123 // - CFollowPathContext context4("toto",456) : CFollowPath::_MaxSearchDepth => 123 @@ -182,9 +182,9 @@ public: // - CFollowPathContext context5.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 123 // - CFollowPathContext context4.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 123 // - CFollowPathContext context3.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 456 - // - CFollowPathContext context2.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => ~0u - // - CFollowPathContext context1.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => ~0u - CFollowPathContext(const char* contextName, uint32 maxSearchDepth=~0u, bool forceMaxDepth=false); + // - CFollowPathContext context2.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => std::numeric_limits::max() + // - CFollowPathContext context1.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => std::numeric_limits::max() + CFollowPathContext(const char* contextName, uint32 maxSearchDepth=std::numeric_limits::max(), bool forceMaxDepth=false); // dtor // - This method removes the destroyed object from the CFollowPath singleton's context stack @@ -270,7 +270,7 @@ private: friend class CFollowPathContext; CFollowPathContext* _TopFollowPathContext; public: - uint32 getMaxSearchDepth() const { return (_TopFollowPathContext==NULL)? ~0u: _TopFollowPathContext->getMaxSearchDepth(); } + uint32 getMaxSearchDepth() const { return (_TopFollowPathContext==NULL)? std::numeric_limits::max(): _TopFollowPathContext->getMaxSearchDepth(); } const char* getContextName() const; }; diff --git a/code/ryzom/server/src/ai_service/state_instance.h b/code/ryzom/server/src/ai_service/state_instance.h index 94755c143..3ad6e6d55 100644 --- a/code/ryzom/server/src/ai_service/state_instance.h +++ b/code/ryzom/server/src/ai_service/state_instance.h @@ -185,7 +185,7 @@ protected: CAITimerExtended _StateTimeout; /// current state (index into manager's state vector) CAIState* _state; - /// variable set to request a state change (~0 otherwise) + /// variable set to request a state change (std::numeric_limits::max() otherwise) CAIState* _NextState; /// timer for timing punctual states diff --git a/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp b/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp index 8f4f1e07f..d5d6570a4 100644 --- a/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp +++ b/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp @@ -522,7 +522,7 @@ FILE_LIST_BUILDER(NewestFile,"remove all but the latest file for each account (a uint32 accountId= accountIds[i]; uint32& bestTime= bestTimes[accountId]; uint32 timeStamp= fdc[i].FileTimeStamp; - if (bestTime!=timeStamp || bestTime==~0u) + if (bestTime!=timeStamp || bestTime==std::numeric_limits::max()) { fdc.removeFile(i); continue; diff --git a/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp b/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp index 1656f34c1..98ae3a893 100644 --- a/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp +++ b/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp @@ -912,7 +912,7 @@ void cbLSChooseShard (CMessage &msgin, const std::string &serviceName, TServiceI } - string ret = lsChooseShard(userName, cookie, userPriv, userExtended, WS::TUserRole::ur_player, 0xffffffff, ~0); + string ret = lsChooseShard(userName, cookie, userPriv, userExtended, WS::TUserRole::ur_player, 0xffffffff, std::numeric_limits::max()); if (!ret.empty()) { diff --git a/code/ryzom/server/src/server_share/logger_service_client.cpp b/code/ryzom/server/src/server_share/logger_service_client.cpp index e8174e0cd..d94834d12 100644 --- a/code/ryzom/server/src/server_share/logger_service_client.cpp +++ b/code/ryzom/server/src/server_share/logger_service_client.cpp @@ -238,8 +238,8 @@ namespace LGS // create the log context closing _LogInfos.push_back(TLogInfo()); _LogInfos.back().setLogName(contextName); - // tag as 'closing' with ~0 - _LogInfos.back().setTimeStamp(~0); + // tag as 'closing' with std::numeric_limits::max() + _LogInfos.back().setTimeStamp(std::numeric_limits::max()); } --_NbOpenContext; if (VerboseLogger) diff --git a/code/ryzom/server/src/server_share/msg_ai_service.h b/code/ryzom/server/src/server_share/msg_ai_service.h index bd4115f4a..13c6a3423 100644 --- a/code/ryzom/server/src/server_share/msg_ai_service.h +++ b/code/ryzom/server/src/server_share/msg_ai_service.h @@ -88,7 +88,7 @@ public: virtual void description () { className ("CUserEventMsg"); - property ("InstanceNumber", PropUInt32, uint32(~0), InstanceNumber); + property ("InstanceNumber", PropUInt32, std::numeric_limits::max(), InstanceNumber); property ("GrpAlias", PropUInt32, uint32(0xffffffff), GrpAlias); property ("EventId", PropUInt8, uint8(0xff), EventId); propertyCont ("Params", PropString, Params); @@ -133,7 +133,7 @@ public: virtual void description () { className ("CSetEscortTeamId"); - property ("InstanceNumber", PropUInt32, uint32(~0), InstanceNumber); + property ("InstanceNumber", PropUInt32, std::numeric_limits::max(), InstanceNumber); propertyCont ("Groups", PropUInt32, Groups); property ("TeamId", PropUInt16, CTEAM::InvalidTeamId, TeamId); } diff --git a/code/ryzom/server/src/server_share/pet_interface_msg.h b/code/ryzom/server/src/server_share/pet_interface_msg.h index d2f9e64a2..9aa914226 100644 --- a/code/ryzom/server/src/server_share/pet_interface_msg.h +++ b/code/ryzom/server/src/server_share/pet_interface_msg.h @@ -47,7 +47,7 @@ public: virtual void description () { className ("CPetSpawnMsg"); - property ("AIInstanceId", PropUInt32, (uint32)~0, AIInstanceId); + property ("AIInstanceId", PropUInt32, std::numeric_limits::max(), AIInstanceId); property ("SpawnMode", PropUInt16, (uint16)NEAR_PLAYER, SpawnMode); property ("CharacterMirrorRow", PropDataSetRow, TDataSetRow(), CharacterMirrorRow); property ("PetSheetId", PropSheetId, NLMISC::CSheetId::Unknown, PetSheetId); diff --git a/code/ryzom/server/src/server_share/r2_vision.cpp b/code/ryzom/server/src/server_share/r2_vision.cpp index 7433e9026..dd4b2a25d 100644 --- a/code/ryzom/server/src/server_share/r2_vision.cpp +++ b/code/ryzom/server/src/server_share/r2_vision.cpp @@ -147,8 +147,8 @@ namespace R2_VISION void CUniverse::createInstance(uint32 aiInstance, uint32 groupId) { - // just ignore attempts to create the ~0u instance - if (aiInstance==~0u) + // just ignore attempts to create the std::numeric_limits::max() instance + if (aiInstance==std::numeric_limits::max()) { return; } @@ -172,8 +172,8 @@ namespace R2_VISION void CUniverse::removeInstance(uint32 aiInstance) { - // just ignore attempts to remove the ~0u instance - if (aiInstance==~0u) + // just ignore attempts to remove the std::numeric_limits::max() instance + if (aiInstance==std::numeric_limits::max()) { return; } @@ -227,7 +227,7 @@ namespace R2_VISION SUniverseEntity& theEntity= _Entities[row]; // if the entity was already allocated then remove it - if (theEntity.AIInstance == ~0u) { return; } + if (theEntity.AIInstance == std::numeric_limits::max()) { return; } if ( theEntity.ViewerRecord) { @@ -325,8 +325,8 @@ namespace R2_VISION BOMB_IF(row>=_Entities.size(),NLMISC::toString("Ignoring attempt to set entity position with invalid row value: %d",row),return); // ensure that the new AIInstance exists - BOMB_IF(aiInstance!=~0u && (aiInstance>=_Instances.size() || _Instances[aiInstance]==NULL), - NLMISC::toString("ERROR: Failed to add entity %d to un-initialised instance: %d",row,aiInstance),aiInstance=~0u); + BOMB_IF(aiInstance!=std::numeric_limits::max() && (aiInstance>=_Instances.size() || _Instances[aiInstance]==NULL), + NLMISC::toString("ERROR: Failed to add entity %d to un-initialised instance: %d",row,aiInstance),aiInstance=std::numeric_limits::max()); // delegate to workhorse routine (converting y coordinate to +ve axis) _teleportEntity(dataSetRow,aiInstance,x,-y,invisibilityLevel); @@ -429,7 +429,7 @@ namespace R2_VISION SUniverseEntity& theEntity= _Entities[row]; // if the entity was already allocated then remove it - if (theEntity.AIInstance!=~0u) + if (theEntity.AIInstance!=std::numeric_limits::max()) { _removeEntity(dataSetRow); } @@ -455,7 +455,7 @@ namespace R2_VISION { // detach the entity from the instance it's currently in _Instances[theEntity.AIInstance]->removeEntity(theEntity); - theEntity.AIInstance= ~0u; + theEntity.AIInstance= std::numeric_limits::max(); theEntity.ViewerRecord= NULL; } } @@ -466,8 +466,8 @@ namespace R2_VISION SUniverseEntity& theEntity= _Entities[dataSetRow.getIndex()]; #ifdef NL_DEBUG - nlassert(theEntity.AIInstance==~0u || theEntity.AIInstance<_Instances.size()); - nlassert(theEntity.AIInstance==~0u || _Instances[theEntity.AIInstance]!=NULL); + nlassert(theEntity.AIInstance==std::numeric_limits::max() || theEntity.AIInstance<_Instances.size()); + nlassert(theEntity.AIInstance==std::numeric_limits::max() || _Instances[theEntity.AIInstance]!=NULL); #endif // if the entity is a viewer then move the view coordinates @@ -477,7 +477,7 @@ namespace R2_VISION } // if the entity is not currently in an AIInstance then stop here - if (theEntity.AIInstance==~0u) + if (theEntity.AIInstance==std::numeric_limits::max()) return; // set the instance entity record position @@ -498,10 +498,10 @@ namespace R2_VISION // set the new AIInstance value for the entity theEntity.AIInstance= aiInstance; - // if the aiInstance is set to ~0u (a reserved value) then we stop here - if (aiInstance==~0u) + // if the aiInstance is set to std::numeric_limits::max() (a reserved value) then we stop here + if (aiInstance==std::numeric_limits::max()) { - // clear out the vision for an entity in aiInstance ~0u + // clear out the vision for an entity in aiInstance std::numeric_limits::max() if (getEntity(dataSetRow)->ViewerRecord!=NULL) { TVision emptyVision(2); @@ -785,7 +785,7 @@ namespace R2_VISION // locate the old vision group (the one we're allocated to before isolation) uint32 visionId= viewerRecord->VisionId; NLMISC::CSmartPtr& oldVisionGroup= _VisionGroups[visionId]; - BOMB_IF(visionId>=_VisionGroups.size() ||oldVisionGroup==NULL,"Trying to remove entity from vision group with unknown vision id",viewerRecord->VisionId=~0u;return); + BOMB_IF(visionId>=_VisionGroups.size() ||oldVisionGroup==NULL,"Trying to remove entity from vision group with unknown vision id",viewerRecord->VisionId=std::numeric_limits::max();return); // if we're the only viewer then already isolated so just return if (oldVisionGroup->numViewers()==1) @@ -830,7 +830,7 @@ namespace R2_VISION if (viewerRecord!=NULL) { uint32 visionId= viewerRecord->VisionId; - BOMB_IF(visionId>=_VisionGroups.size() ||_VisionGroups[visionId]==NULL,"Trying to remove entity with unknown vision id",viewerRecord->VisionId=~0u;return); + BOMB_IF(visionId>=_VisionGroups.size() ||_VisionGroups[visionId]==NULL,"Trying to remove entity with unknown vision id",viewerRecord->VisionId=std::numeric_limits::max();return); _VisionGroups[visionId]->removeViewer(viewerRecord); } @@ -847,8 +847,8 @@ namespace R2_VISION _Entities.pop_back(); // invalidate the InstanceIndex value for the entity we just removed - entity.InstanceIndex=~0u; - entity.AIInstance=~0u; + entity.InstanceIndex=std::numeric_limits::max(); + entity.AIInstance=std::numeric_limits::max(); } void CInstance::release() @@ -899,11 +899,11 @@ namespace R2_VISION CVisionGroup::CVisionGroup() { - _XMin=~0u; + _XMin=std::numeric_limits::max(); _XMax=0; - _YMin=~0u; + _YMin=std::numeric_limits::max(); _YMax=0; - _VisionId=~0u; + _VisionId=std::numeric_limits::max(); // setup the dummy entry in the vision buffer _Vision.reserve(AllocatedVisionVectorSize); vectAppend(_Vision).DataSetRow= ZeroDataSetRow; @@ -923,8 +923,8 @@ namespace R2_VISION // ensure that the viewer wasn't aleady attached to another vision group #ifdef NL_DEBUG nlassert(viewer!=NULL); - nlassert(viewer->VisionId==~0u); - nlassert(viewer->VisionIndex==~0u); + nlassert(viewer->VisionId==std::numeric_limits::max()); + nlassert(viewer->VisionIndex==std::numeric_limits::max()); #endif TEST(("add viewer %d to grp %d",viewer->getViewerId().getIndex(),_VisionId)); @@ -961,8 +961,8 @@ namespace R2_VISION // pop the back entry off the vector and flag oursleves as unused _Viewers.pop_back(); - viewer->VisionId= ~0u; - viewer->VisionIndex= ~0u; + viewer->VisionId= std::numeric_limits::max(); + viewer->VisionIndex= std::numeric_limits::max(); // NOTE: after this the boundary may be out of date - this will be recalculated at the next // vision update so we don't take time to do it here @@ -1171,8 +1171,8 @@ namespace R2_VISION return; // calculate the bouding box for our viewers - uint32 xmin= ~0u; - uint32 ymin= ~0u; + uint32 xmin= std::numeric_limits::max(); + uint32 ymin= std::numeric_limits::max(); uint32 xmax= 0; uint32 ymax= 0; for (uint32 i=(uint32)_Viewers.size();i--;) @@ -1247,7 +1247,7 @@ namespace R2_VISION // reset the vision vector and add in the dummy entry with DataSetRow=0 _Vision.resize(AllocatedVisionVectorSize); _Vision[0].DataSetRow= ZeroDataSetRow; - _Vision[0].VisionSlot= ~0u; + _Vision[0].VisionSlot= std::numeric_limits::max(); // setup a vision slot iterator for filling in the vision buffer (=1 to skip passed the dummy entry) uint32 nextVisionSlot=1; @@ -1380,8 +1380,8 @@ namespace R2_VISION CViewer::CViewer() { - VisionId=~0u; - VisionIndex=~0u; + VisionId=std::numeric_limits::max(); + VisionIndex=std::numeric_limits::max(); _VisionResetCount= 0; } @@ -1399,7 +1399,7 @@ namespace R2_VISION // setup the dummy entry with DataSetRow=0 _Vision[0].DataSetRow= ZeroDataSetRow; - _Vision[0].VisionSlot= ~0u; + _Vision[0].VisionSlot= std::numeric_limits::max(); // setup the vision slots in reverse order from 254..0 (because they're popped from the back) _FreeVisionSlots.clear(); diff --git a/code/ryzom/server/src/server_share/r2_vision.h b/code/ryzom/server/src/server_share/r2_vision.h index 9bf3f7689..9872e606a 100644 --- a/code/ryzom/server/src/server_share/r2_vision.h +++ b/code/ryzom/server/src/server_share/r2_vision.h @@ -140,7 +140,7 @@ namespace R2_VISION // ctor SViewedEntity() { - VisionSlot=~0u; + VisionSlot=std::numeric_limits::max(); } }; @@ -196,15 +196,15 @@ namespace R2_VISION struct SUniverseEntity { TDataSetRow DataSetRow; // the complete data set row for the entity - uint32 AIInstance; // the id of the instance that we're currently in (~0u by default) + uint32 AIInstance; // the id of the instance that we're currently in (std::numeric_limits::max() by default) mutable uint32 InstanceIndex; // the index within the instance's _Entities vector NLMISC::CSmartPtr ViewerRecord; // pointer to the CViewer record for viewers (or NULL) // ctor SUniverseEntity() { - AIInstance=~0u; - InstanceIndex=~0u; + AIInstance=std::numeric_limits::max(); + InstanceIndex=std::numeric_limits::max(); } }; diff --git a/code/ryzom/server/src/server_share/used_continent.cpp b/code/ryzom/server/src/server_share/used_continent.cpp index 01ab2beda..075f16c14 100644 --- a/code/ryzom/server/src/server_share/used_continent.cpp +++ b/code/ryzom/server/src/server_share/used_continent.cpp @@ -105,7 +105,7 @@ uint32 CUsedContinent::getInstanceForContinent(const std::string &continentName) if (it != _Continents.end()) return it->ContinentInstance; else - return ~0; + return std::numeric_limits::max(); } uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEnum) const @@ -115,7 +115,7 @@ uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEn if (it != _Continents.end()) return it->ContinentInstance; else - return ~0; + return std::numeric_limits::max(); } const std::string &CUsedContinent::getContinentForInstance(uint32 instanceNumber) const diff --git a/code/ryzom/server/src/server_share/used_continent.h b/code/ryzom/server/src/server_share/used_continent.h index 150b6342c..85f002e40 100644 --- a/code/ryzom/server/src/server_share/used_continent.h +++ b/code/ryzom/server/src/server_share/used_continent.h @@ -60,12 +60,12 @@ public: bool isContinentUsed(const std::string &continentName) const; /** Return the static instance number associated with a continent name. - * If the continent name is unknow, return ~0 + * If the continent name is unknow, return std::numeric_limits::max() */ uint32 getInstanceForContinent(const std::string &continentName) const; /** Return the static instance number associated with a continent enum value - * If the continent name is unknow, return ~0 + * If the continent name is unknow, return std::numeric_limits::max() */ uint32 getInstanceForContinent(CONTINENT::TContinent continentEnum) const; diff --git a/code/ryzom/server/src/shard_unifier_service/character_sync.cpp b/code/ryzom/server/src/shard_unifier_service/character_sync.cpp index 3b1a8b995..29b404567 100644 --- a/code/ryzom/server/src/shard_unifier_service/character_sync.cpp +++ b/code/ryzom/server/src/shard_unifier_service/character_sync.cpp @@ -365,7 +365,7 @@ namespace CHARSYNC for (; first != last; ++first) { // default to no limit - uint32 limit=~0u; + uint32 limit=std::numeric_limits::max(); // if there's a limit in the limis map then use it instead... if (limitsMap.find(first->first)!=limitsMap.end()) diff --git a/code/ryzom/server/src/tick_service/range_mirror_manager.cpp b/code/ryzom/server/src/tick_service/range_mirror_manager.cpp index f988ac054..2c92c738f 100644 --- a/code/ryzom/server/src/tick_service/range_mirror_manager.cpp +++ b/code/ryzom/server/src/tick_service/range_mirror_manager.cpp @@ -472,7 +472,7 @@ void CRangeList::acquireFirstRow() */ bool CRangeList::acquireRange( NLNET::TServiceId ownerServiceId, NLNET::TServiceId mirrorServiceId, sint32 nbRows, TDataSetIndex *first, TDataSetIndex *last ) { - TDataSetIndex prevlast(~0); + TDataSetIndex prevlast(std::numeric_limits::max()); TRangeList::iterator irl = _RangeList.begin(); // Find a compatible range diff --git a/code/ryzom/server/src/tick_service/range_mirror_manager.h b/code/ryzom/server/src/tick_service/range_mirror_manager.h index 6615a1c6a..0bde600e4 100644 --- a/code/ryzom/server/src/tick_service/range_mirror_manager.h +++ b/code/ryzom/server/src/tick_service/range_mirror_manager.h @@ -46,7 +46,7 @@ class CRangeList public: /// Default constructor - CRangeList() : _TotalMaxRows(~0) { acquireFirstRow(); } + CRangeList() : _TotalMaxRows(std::numeric_limits::max()) { acquireFirstRow(); } /// Constructor CRangeList( sint32 totalMaxRows ) : _TotalMaxRows( totalMaxRows ) { acquireFirstRow(); } diff --git a/code/ryzom/server/src/tick_service/tick_service.cpp b/code/ryzom/server/src/tick_service/tick_service.cpp index 95f609571..4a64fdd7c 100644 --- a/code/ryzom/server/src/tick_service/tick_service.cpp +++ b/code/ryzom/server/src/tick_service/tick_service.cpp @@ -825,7 +825,7 @@ bool CTickService::loadGameCycle() /* * */ -CTickServiceGameCycleTimeMeasure::CTickServiceGameCycleTimeMeasure() : HistoryMain( CTickService::getInstance()->getServiceId(), NLNET::TServiceId(~0), false ) {} +CTickServiceGameCycleTimeMeasure::CTickServiceGameCycleTimeMeasure() : HistoryMain( CTickService::getInstance()->getServiceId(), NLNET::TServiceId(std::numeric_limits::max()), false ) {} /* @@ -904,7 +904,7 @@ void CTickServiceGameCycleTimeMeasure::displayStat( NLMISC::CLog *log, TTimeMeas uint divideBy = (HistoryMain.NbMeasures==0) ? 0 : ((stat==MHTSum) ? HistoryMain.NbMeasures : 1); HistoryMain.Stats[stat].displayStat( log, TickServiceTimeMeasureTypeToCString, divideBy ); { - CMirrorTimeMeasure gatheredStats [NbTimeMeasureHistoryStats] = { 0, ~0, 0 }; + CMirrorTimeMeasure gatheredStats [NbTimeMeasureHistoryStats] = { 0, std::numeric_limits::max(), 0 }; for ( std::vector::const_iterator ihm=HistoryByMirror.begin(); ihm!=HistoryByMirror.end(); ++ihm ) { log->displayRawNL( "\tMS-%hu, %u measures:", (*ihm).ServiceId.get(), (*ihm).NbMeasures ); @@ -921,7 +921,7 @@ void CTickServiceGameCycleTimeMeasure::displayStat( NLMISC::CLog *log, TTimeMeas } } { - CServiceTimeMeasure gatheredStats [NbTimeMeasureHistoryStats] = { 0, ~0, 0 }; + CServiceTimeMeasure gatheredStats [NbTimeMeasureHistoryStats] = { 0, std::numeric_limits::max(), 0 }; for ( std::vector::const_iterator ihs=HistoryByService.begin(); ihs!=HistoryByService.end(); ++ihs ) { log->displayRawNL( "\t%s (on MS-%hu), %u measures:", CUnifiedNetwork::getInstance()->getServiceUnifiedName( (*ihs).ServiceId ).c_str(), (*ihs).ParentServiceId.get(), (*ihs).NbMeasures ); diff --git a/code/ryzom/server/src/tick_service/tick_service.h b/code/ryzom/server/src/tick_service/tick_service.h index 5b07793a3..9abe079bc 100644 --- a/code/ryzom/server/src/tick_service/tick_service.h +++ b/code/ryzom/server/src/tick_service/tick_service.h @@ -113,7 +113,7 @@ public: NbMeasures = 0; Stats.resize( NbTimeMeasureHistoryStats ); Stats[MHTSum] = 0; - Stats[MHTMin] = ~0; + Stats[MHTMin] = std::numeric_limits::max(); Stats[MHTMax] = 0; } } diff --git a/code/ryzom/tools/leveldesign/mp_generator/utils.h b/code/ryzom/tools/leveldesign/mp_generator/utils.h index 63148f61f..01bb25fe7 100644 --- a/code/ryzom/tools/leveldesign/mp_generator/utils.h +++ b/code/ryzom/tools/leveldesign/mp_generator/utils.h @@ -55,17 +55,17 @@ public: * Display the item as a row of a HTML table. * If (key!=previousKey) and (name==previousName), the row will not be displayed entirely to save space * - * \param keyColumn If not ~0, column used for sorting => this column displays only the field matching the key + * \param keyColumn If not std::numeric_limits::max(), column used for sorting => this column displays only the field matching the key * \param key The key used for sorting (see keyColumn) * \param previousKey Previous key - * \param nameColumn If not ~0, column used for the unique name (column must have exaclty one element) + * \param nameColumn If not std::numeric_limits::max(), column used for the unique name (column must have exaclty one element) * \param previousName Previous name */ - std::string toHTMLRow( uint32 keyColumn=~0, const string& key=string(), const string& previousKey=string(), - uint32 nameColumn=~0, const string& previousName=string() ) const + std::string toHTMLRow( uint32 keyColumn=std::numeric_limits::max(), const string& key=string(), const string& previousKey=string(), + uint32 nameColumn=std::numeric_limits::max(), const string& previousName=string() ) const { std::string s = ""; - bool lightMode = (nameColumn == ~0) ? false : ((key != previousKey) && (Fields[nameColumn][0] == previousName)); + bool lightMode = (nameColumn == std::numeric_limits::max()) ? false : ((key != previousKey) && (Fields[nameColumn][0] == previousName)); for ( uint32 c=0; c!=NC; ++c ) { s += ""; @@ -86,11 +86,11 @@ public: /// - std::string toCSVLine( char columnSeparator=',', string internalSeparator=" - ", uint32 keyColumn=~0, const string& key=string(), const string& previousKey=string(), - uint32 nameColumn=~0, const string& previousName=string() ) const + std::string toCSVLine( char columnSeparator=',', string internalSeparator=" - ", uint32 keyColumn=std::numeric_limits::max(), const string& key=string(), const string& previousKey=string(), + uint32 nameColumn=std::numeric_limits::max(), const string& previousName=string() ) const { std::string s; - bool lightMode = (nameColumn == ~0) ? false : ((key != previousKey) && (Fields[nameColumn][0] == previousName)); + bool lightMode = (nameColumn == std::numeric_limits::max()) ? false : ((key != previousKey) && (Fields[nameColumn][0] == previousName)); for ( uint32 c=0; c!=NC; ++c ) { if ( c == keyColumn ) diff --git a/code/ryzom/tools/patch_gen/patch_gen_common.cpp b/code/ryzom/tools/patch_gen/patch_gen_common.cpp index 3d28a2439..7f63177ac 100644 --- a/code/ryzom/tools/patch_gen/patch_gen_common.cpp +++ b/code/ryzom/tools/patch_gen/patch_gen_common.cpp @@ -149,7 +149,7 @@ CPackageDescription::CPackageDescription() void CPackageDescription::clear() { - _NextVersionNumber= ~0u; + _NextVersionNumber= std::numeric_limits::max(); _VersionNumberReserved = false; _Categories.clear(); _IndexFileName.clear(); diff --git a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp index a15f8c6d3..f194f996e 100644 --- a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp +++ b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp @@ -237,8 +237,8 @@ CProximityZone::CProximityZone(uint32 scanWidth,uint32 scanHeight,sint32 xOffset _MaxOffset = scanWidth * scanHeight -1; - _XMin = ~0u; - _YMin = ~0u; + _XMin = std::numeric_limits::max(); + _YMin = std::numeric_limits::max(); _XMax = 0; _YMax = 0; } @@ -386,7 +386,7 @@ void CProximityMapBuffer::load(const std::string& name) } } // setup the next pixel in the output buffers... - _Buffer[y*_ScanWidth+x]= (isAccessible? 0: (TBufferEntry)~0u); + _Buffer[y*_ScanWidth+x]= (isAccessible? 0: (TBufferEntry)std::numeric_limits::max()); } } } @@ -471,7 +471,7 @@ void CProximityMapBuffer::_prepareBufferForZoneProximityMap(const CProximityZone uint32 zoneWidth= zone.getZoneWidth(); uint32 zoneHeight= zone.getZoneHeight(); zoneBuffer.clear(); - zoneBuffer.resize(zoneWidth*zoneHeight,(TBufferEntry)~0u); + zoneBuffer.resize(zoneWidth*zoneHeight,(TBufferEntry)std::numeric_limits::max()); // setup the buffer's accessible points and prime vects[0] with the set of accessible points in the zone buffer for (uint32 i=0;i &islands, float camSpeed texturedMaterial.setDoubleSided(true); texturedMaterial.setZFunc(CMaterial::lessequal); // - uint currWorldIndex = ~0; + uint currWorldIndex = std::numeric_limits::max(); bool newPosWanted = true; // std::vector zones; From 303f7d2e790c19a5f571fb938c3aa7130d78ae8a Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 14:11:07 +0100 Subject: [PATCH 197/344] Changed: Minor changes --HG-- branch : develop --- code/nel/include/nel/net/service.h | 10 +-- code/nel/src/3d/landscape.cpp | 1 - code/nel/src/3d/landscapevb_allocator.cpp | 1 - code/ryzom/client/src/CMakeLists.txt | 1 - code/ryzom/client/src/commands.cpp | 1 - code/ryzom/client/src/connection.cpp | 2 +- code/ryzom/client/src/init.cpp | 3 +- .../src/interface_v3/action_handler_item.cpp | 23 ++++--- .../interface_v3/bot_chat_page_mission.cpp | 1 - .../src/interface_v3/bot_chat_page_trade.cpp | 3 - .../client/src/interface_v3/chat_window.cpp | 2 +- .../client/src/interface_v3/dbctrl_sheet.cpp | 1 - .../dbgroup_list_sheet_text_share.cpp | 1 - .../interface_v3/dbgroup_list_sheet_trade.cpp | 1 - .../client/src/interface_v3/skill_manager.cpp | 2 - .../client/src/interface_v3/view_radar.cpp | 2 +- code/ryzom/client/src/misc.h | 1 + code/ryzom/client/src/player_cl.cpp | 2 +- code/ryzom/client/src/r2/editor.cpp | 4 +- code/ryzom/client/src/time_client.h | 2 +- .../server/src/ai_service/ai_bot_npc.cpp | 4 +- .../src/ai_service/generic_logic_action.cpp | 4 +- .../entities_game_service/dyn_chat_egs.cpp | 2 +- .../pvp_manager/pvp_manager_2.cpp | 7 ++- .../shop_type/character_shopping_list.cpp | 6 +- .../georges_editor_qt/src/configuration.cpp | 25 +++++--- .../georges_editor_qt/src/formdelegate.cpp | 3 +- .../src/georges_treeview_dialog.cpp | 3 +- .../src/georgesform_model.cpp | 62 +++++++++++-------- .../georges_editor_qt/src/main_window.cpp | 3 +- .../georges_editor_qt/src/new_dialog.cpp | 3 +- .../src/objectviewer_dialog.cpp | 6 +- .../georges_editor_qt/src/qt_displayer.cpp | 37 ++++++----- .../world_editor/land_export_lib/export.cpp | 4 +- code/ryzom/tools/translation_tools/main.cpp | 15 ++--- 35 files changed, 132 insertions(+), 116 deletions(-) diff --git a/code/nel/include/nel/net/service.h b/code/nel/include/nel/net/service.h index c74688799..8c7a52c63 100644 --- a/code/nel/include/nel/net/service.h +++ b/code/nel/include/nel/net/service.h @@ -218,13 +218,13 @@ public: static bool isServiceInitialized() { return _Instance != NULL; } /// Returns the current service short name (ie: TS) - const std::string &getServiceShortName () const { return _ShortName; }; + const std::string &getServiceShortName () const { return _ShortName; } /// Returns the current service long name (ie: test_serivce) - const std::string &getServiceLongName () const { return _LongName; }; + const std::string &getServiceLongName () const { return _LongName; } /// Returns the current service alias name setted by AES - const std::string &getServiceAliasName () const { return _AliasName; }; + const std::string &getServiceAliasName () const { return _AliasName; } /// Returns the current service unified name that is alias/short-id or short-id if alias is empty std::string getServiceUnifiedName () const; @@ -242,10 +242,10 @@ public: uint32 getLaunchingDate () const; /// Return true if this service don't use the NS (naming service) - bool getDontUseNS() const { return _DontUseNS; }; + bool getDontUseNS() const { return _DontUseNS; } /// Return true if this service don't use the AES (admin executor service) - bool getDontUseAES() const { return _DontUseAES; }; + bool getDontUseAES() const { return _DontUseAES; } /// Returns arguments of the program pass from the user to the program using parameters (ie: "myprog param1 param2") const NLMISC::CVectorSString &getArgs () const { return _Args; } diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index 154f6f847..ccdeabc34 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -583,7 +583,6 @@ void CLandscape::setDriver(IDriver *drv) // Does the driver has sufficient requirements for Vegetable??? // only if VP supported by GPU, and Only if max vertices allowed. _DriverOkForVegetable = _VertexShaderOk && (_Driver->getMaxVerticesByVertexBufferHard()>=(uint)NL3D_LANDSCAPE_VEGETABLE_MAX_AGP_VERTEX_MAX); - } } diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index 2c30cc19b..51714b88d 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -611,7 +611,6 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr nlverify(_Driver->compileVertexProgram(_VertexProgram[1])); } } - } diff --git a/code/ryzom/client/src/CMakeLists.txt b/code/ryzom/client/src/CMakeLists.txt index d06af95c8..a2f89420b 100644 --- a/code/ryzom/client/src/CMakeLists.txt +++ b/code/ryzom/client/src/CMakeLists.txt @@ -1,4 +1,3 @@ - # Need clientsheets lib for sheets packer tool ADD_SUBDIRECTORY(client_sheets) diff --git a/code/ryzom/client/src/commands.cpp b/code/ryzom/client/src/commands.cpp index ad8a328ba..90287955d 100644 --- a/code/ryzom/client/src/commands.cpp +++ b/code/ryzom/client/src/commands.cpp @@ -3890,7 +3890,6 @@ NLMISC_COMMAND(displayInventoryCounter, "display the Inventory counter to compar NLMISC_COMMAND(displayActionCounter, "display the action counters", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); CSPhraseManager *pPM= CSPhraseManager::getInstance(); diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 8b07cc7f2..92ecff0ac 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -31,7 +31,7 @@ // 3D Interface. #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" -#include +#include "nel/3d/stereo_display.h" // Game Share //#include "game_share/gd_time.h" // \todo GUIGUI : TO DELETE/CHANGE #include "game_share/gender.h" diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index c6b74ebd2..ed7943b8f 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -788,7 +788,7 @@ void prelogInit() #ifdef NL_OS_WINDOWS _control87 (_EM_INVALID|_EM_DENORMAL/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM); #endif // NL_OS_WINDOWS - + CTime::CTimerInfo timerInfo; NLMISC::CTime::probeTimerInfo(timerInfo); if (timerInfo.RequiresSingleCore) // TODO: Also have a FV configuration value to force single core. @@ -930,7 +930,6 @@ void prelogInit() switch(ClientCfg.Driver3D) { #ifdef NL_OS_WINDOWS - case CClientConfig::Direct3D: driver = UDriver::Direct3d; break; diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp index 24f59cecc..f6dec2d1f 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp @@ -815,7 +815,6 @@ public: CurrentStackDst= NULL; validateStackItem(pCSSrc, pCSDst, val, CurrentStackMode); } - }; REGISTER_ACTION_HANDLER( CHandlerStackOk, "stack_item"); @@ -826,17 +825,17 @@ class CPlayerTradePutBagItemToExchange : public IActionHandler public: virtual void execute (CCtrlBase *pCaller, const string &/* Params */) { - CInterfaceManager *im = CInterfaceManager::getInstance(); - CDBCtrlSheet *src = dynamic_cast(pCaller); - CDBCtrlSheet *dest = dynamic_cast(CWidgetManager::getInstance()->getCtrlLaunchingModal()); - if (src->getSheetId() == 0) - { - putExchangedItemToInventory(dest); - } - else - { - putInventoryItemToExchange(src, dest); - } + CInterfaceManager *im = CInterfaceManager::getInstance(); + CDBCtrlSheet *src = dynamic_cast(pCaller); + CDBCtrlSheet *dest = dynamic_cast(CWidgetManager::getInstance()->getCtrlLaunchingModal()); + if (src->getSheetId() == 0) + { + putExchangedItemToInventory(dest); + } + else + { + putInventoryItemToExchange(src, dest); + } } }; REGISTER_ACTION_HANDLER(CPlayerTradePutBagItemToExchange, "put_bag_item_to_exchange"); diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_mission.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_mission.cpp index bb16353f5..caa90cdda 100644 --- a/code/ryzom/client/src/interface_v3/bot_chat_page_mission.cpp +++ b/code/ryzom/client/src/interface_v3/bot_chat_page_mission.cpp @@ -53,7 +53,6 @@ void CBotChatPageMission::init() NLGUI::CDBManager::getInstance()->addBranchObserver("SERVER:CHOOSE_MISSIONS", &_MissionPagesObs); } - // *************************************************************************************** void CBotChatPageMission::begin() { diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp index 17aaead48..966a3886a 100644 --- a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp +++ b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp @@ -1808,7 +1808,6 @@ void CBotChatPageTrade::giveFocusToMaxEBChangeBuyFilterDialog() setFocusOnEditBox(ig->getGroup("edit_max:eb")); } - // *************************************************************************** void CBotChatPageTrade::startChangeBuyFilterMPDialog() { @@ -1822,7 +1821,6 @@ void CBotChatPageTrade::startChangeBuyFilterMPDialog() CWidgetManager::getInstance()->enableModalWindow(NULL, ig); } - // *************************************************************************** void CBotChatPageTrade::confirmChangeBuyFilterMPDialog(uint ft) { @@ -1840,7 +1838,6 @@ void CBotChatPageTrade::confirmChangeBuyFilterMPDialog(uint ft) CWidgetManager::getInstance()->disableModalWindow(); } - // *************************************************************************** void CBotChatPageTrade::resetItemPartAndTypeFilters() { diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index e74392432..7dcf13eeb 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -601,7 +601,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC if (pos == ucstring::npos || (colonpos < pos)) { // No timestamp, so put it right after the color and add a space - pos = newmsg.find(ucstring("}"));; + pos = newmsg.find(ucstring("}")); prefix += " "; } newmsg = newmsg.substr(0, pos + 1) + prefix + newmsg.substr(pos + 1); diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 293582f52..91bb94a23 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -1741,7 +1741,6 @@ void CDBCtrlSheet::resetCharBitmaps() _CharBitmaps.clear(); } - // *************************************************************************** void CDBCtrlSheet::setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar, bool topDown) { diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp index fcef370e0..112ec3e9e 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp @@ -175,7 +175,6 @@ void CDBGroupListSheetTextShare::CSheetChildShare::init(CDBGroupListSheetText *p pNL = NLGUI::CDBManager::getInstance()->getDbProp(sTmp, false); nlassert(pNL != NULL); CurrentWanted.link ( sTmp.c_str() ); - } diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp index 0028ad964..d4fc5da86 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp @@ -728,7 +728,6 @@ void CDBGroupListSheetTrade::sort() } } - bool CDBGroupListSheetTrade::needCheckAllItems() { if (_LastFamePriceFactor != _FamePriceFactorLeaf->getValue16()) diff --git a/code/ryzom/client/src/interface_v3/skill_manager.cpp b/code/ryzom/client/src/interface_v3/skill_manager.cpp index e71225cc2..d8656d925 100644 --- a/code/ryzom/client/src/interface_v3/skill_manager.cpp +++ b/code/ryzom/client/src/interface_v3/skill_manager.cpp @@ -159,10 +159,8 @@ void CSkillManager::initInGame() _TrackSkillChange= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:TRACK_SKILL_CHANGE", true); // Add a branch observer on skill value change NLGUI::CDBManager::getInstance()->addBranchObserver( "SERVER:CHARACTER_INFO:SKILLS", &_SkillChangeObs ); - } - // *************************************************************************** void CSkillManager::uninitInGame() { diff --git a/code/ryzom/client/src/interface_v3/view_radar.cpp b/code/ryzom/client/src/interface_v3/view_radar.cpp index 8c8cd1de8..5ebb7fd64 100644 --- a/code/ryzom/client/src/interface_v3/view_radar.cpp +++ b/code/ryzom/client/src/interface_v3/view_radar.cpp @@ -177,7 +177,7 @@ void CViewRadar::draw () // Select the icon to display and draw it uint spotId = CNPCIconCache::getInstance().getNPCIcon(entity).getSpotId(); CRadarSpotDesc spotDesc = _SpotDescriptions[spotId]; - + if (!_MissionIconsObs._displayMissionSpots) spotDesc = _SpotDescriptions[0]; diff --git a/code/ryzom/client/src/misc.h b/code/ryzom/client/src/misc.h index d74010c03..463f02b66 100644 --- a/code/ryzom/client/src/misc.h +++ b/code/ryzom/client/src/misc.h @@ -225,6 +225,7 @@ uint getCurrentColorDepth(); // get maximized bool isWindowMaximized(); +// get all supported video modes sint getRyzomModes(std::vector &videoModes, std::vector &stringModeList); #endif // CL_MISC_H diff --git a/code/ryzom/client/src/player_cl.cpp b/code/ryzom/client/src/player_cl.cpp index 4166dbec8..a050ac197 100644 --- a/code/ryzom/client/src/player_cl.cpp +++ b/code/ryzom/client/src/player_cl.cpp @@ -673,7 +673,7 @@ void CPlayerCL::updateVisualPropertyVpa(const NLMISC::TGameCycle &/* gameCycle * } // update title when gender changed - const ucstring replacement(STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw,_Gender == GSGENDER::female)); + const ucstring replacement(STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw, _Gender == GSGENDER::female)); if (!replacement.empty() || !ClientCfg.DebugStringManager) { // Get extended name diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp index 2bceb4200..aa5995b05 100644 --- a/code/ryzom/client/src/r2/editor.cpp +++ b/code/ryzom/client/src/r2/editor.cpp @@ -5293,10 +5293,8 @@ void CEditor::onTestModeDisconnected(TSessionId sessionId, uint32 lastAct, TSce //H_AUTO(R2_CEditor_onTestModeDisconnected) CHECK_EDITOR _DMC->CDynamicMapClient::onTestModeDisconnected(sessionId, lastAct, sessionType); - } - // ********************************************************************************************************* void CEditor::nodeInserted(const std::string& instanceId, const std::string& attrName, sint32 position, const std::string& key, CObject* value) { @@ -6611,7 +6609,7 @@ NLMISC::CVectorD getVectorD(const CObject *obj) CObject *buildVector(const NLMISC::CVectorD &vector, const std::string &instanceId /*= ""*/) { CObject *table; - if (instanceId.empty() ) + if (instanceId.empty()) { table = getEditor().getDMC().newComponent("Position"); table->set("x", vector.x); diff --git a/code/ryzom/client/src/time_client.h b/code/ryzom/client/src/time_client.h index 9243a908d..b3327ee76 100644 --- a/code/ryzom/client/src/time_client.h +++ b/code/ryzom/client/src/time_client.h @@ -48,7 +48,7 @@ extern sint64 DT64; // Diff time with current and last frame in ms. extern float DT; // Diff time with current and last frame in sec. extern TTime TSend; // Next Time to send motions. extern TTime DTSend; // Delta of time to generate the next time to send motions. - extern double TimeInSec; // Time for the current frame in second. +extern double TimeInSec; // Time for the current frame in second. extern double FirstTimeInSec; // Game local origin time diff --git a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp b/code/ryzom/server/src/ai_service/ai_bot_npc.cpp index cb183850e..24de0feaf 100644 --- a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp +++ b/code/ryzom/server/src/ai_service/ai_bot_npc.cpp @@ -875,9 +875,9 @@ Colors are something like that: 2: VERT CITRON VERT CITRON GREEN 3: VERT VERT TURQUOISE 4: BLEU BLEU BLUE -5: ROUGE fonce ROUGE (tout court) CRIMSON +5: ROUGE dark ROUGE (normal) CRIMSON 6: BLANC JAUNE WHITE -7: NOIR BLEU tres fonce BLACK +7: NOIR BLEU very dark BLACK 3D column is (probably) used for equipment */ diff --git a/code/ryzom/server/src/ai_service/generic_logic_action.cpp b/code/ryzom/server/src/ai_service/generic_logic_action.cpp index afd0f9b3c..aaa113b30 100644 --- a/code/ryzom/server/src/ai_service/generic_logic_action.cpp +++ b/code/ryzom/server/src/ai_service/generic_logic_action.cpp @@ -1407,8 +1407,8 @@ public: return false; } - // check if its a number or a var. - //TODO: et les variables negatives? + // check if it's a number or a var. + //TODO: and negative values ? if ((str[0]<='9' && str[0]>='0')||(str[0]=='-')) // its a number { var.Type = constant; diff --git a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp index 90d41820f..98ec86a75 100644 --- a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp +++ b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp @@ -507,7 +507,7 @@ void CDynChatEGS::iosSetHideBubble(TChanID chan, bool hideBubble) void CDynChatEGS::iosSetUniversalChannel(TChanID chan, bool universalChannel) { CMessage msg("DYN_CHAT:SET_UNIVERSAL_CHANNEL"); - msg.serial(chan); + msg.serial(chan); msg.serial(universalChannel); sendMessageViaMirror( "IOS", msg); } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp index 6beb7b1b2..7f42a671c 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp @@ -211,13 +211,16 @@ std::vector CPVPManager2::getCharacterChannels(CCharacter * user) result.clear(); // Add lang channel, should be first. - if (!user->getLangChannel().empty()) { + if (!user->getLangChannel().empty()) + { TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(user->getLangChannel()); if (it != _ExtraFactionChannel.end()) { result.push_back((*it).second); } - } else { + } + else + { TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("en"); if (it != _ExtraFactionChannel.end()) { diff --git a/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp b/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp index d23945d25..e024334c2 100644 --- a/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp +++ b/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp @@ -460,9 +460,9 @@ void CCharacterShoppingList::initPageToUpdate( uint32 nbSlotPerPage ) void CCharacterShoppingList::fillTradePage( uint16 session ) { /* -- Ajout de TRADING:*:PRICE_RETIRE (utile que si SELLER_TYPE == User ou ResaleAndUser). Note: Prix UNITAIRE (si MP, Ammo etc..) -- Si SELLER_TYPE==User seulement: Si PRICE==-1, alors cela veut dire " Item Sold " (pour afficher la liste des items vendus les plus récents) -- Note: TRADING:*:PRICE reste un Prix UNITAIRE (si MP, Ammo etc..) (cela devait déja être le cas) +- Added TRADING:*:PRICE_RETIRE (only useful if SELLER_TYPE == User or ResaleAndUser). Note: UNIT price (if Raw Mats, Ammo, etc..) +- If SELLER_TYPE==User only: if PRICE==-1, then it means " Item Sold " (to display list of more recent sold items) +- Note: TRADING:*:PRICE is wtill a UNIT price (if Raw Mats, Ammo, etc..) (it should already be the case) */ // get page to update if any diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/configuration.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/configuration.cpp index 6af950eae..cd937688a 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/configuration.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/configuration.cpp @@ -53,7 +53,8 @@ namespace NLQT { { // load config QFile file(NLQT_CONFIG_FILE); - if (!file.exists()) { + if (!file.exists()) + { file.open( QIODevice::WriteOnly | QIODevice::Text ); file.write("GraphicsDrivers = { \"OpenGL\", \"Direct3D\" };"); file.write("\nSearchPaths = {\"\"};"); @@ -64,9 +65,12 @@ namespace NLQT { file.close(); } - try { + try + { ConfigFile.load(NLQT_CONFIG_FILE); - } catch(...) { + } + catch(...) + { } addLeveldesignPath(); @@ -213,16 +217,17 @@ namespace NLQT { uint listsize = tmpList->size(); for (uint i = 0; i < listsize; ++i) { - if(_progressCB) { - _progressCB->DisplayString = tmpList->at(i); - CPath::addSearchPath(tmpList->at(i), true, false, _progressCB); + if(_progressCB) + { + _progressCB->DisplayString = tmpList->at(i); + CPath::addSearchPath(tmpList->at(i), true, false, _progressCB); } else { - CProgressDialog pcb; - pcb.DisplayString = tmpList->at(i); - pcb.show(); - CPath::addSearchPath(tmpList->at(i), true, false, &pcb); + CProgressDialog pcb; + pcb.DisplayString = tmpList->at(i); + pcb.show(); + CPath::addSearchPath(tmpList->at(i), true, false, &pcb); } } if (!list) diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/formdelegate.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/formdelegate.cpp index bb91f8b62..25b8a1490 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/formdelegate.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/formdelegate.cpp @@ -60,7 +60,8 @@ namespace NLQT CFormItem* curItem = m->getItem(mp->mapToSource(index)); NLGEORGES::UFormElm *curElm = curItem->getFormElm(); - if (!curElm) { + if (!curElm) + { // TODO: create new Element return 0; } diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/georges_treeview_dialog.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/georges_treeview_dialog.cpp index b5ab13ba3..f06bb537e 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/georges_treeview_dialog.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/georges_treeview_dialog.cpp @@ -377,7 +377,8 @@ namespace NLQT nlinfo("CGeorgesTreeViewDialog::filterRows"); CGeorgesFormProxyModel * mp = dynamic_cast(_ui.treeView->model()); CGeorgesFormModel *m = dynamic_cast(mp->sourceModel()); - if (m) { + if (m) + { m->setShowParents(_ui.checkBoxParent->isChecked()); m->setShowDefaults(_ui.checkBoxDefaults->isChecked()); } diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/georgesform_model.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/georgesform_model.cpp index 89cba843c..98c7b59e2 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/georgesform_model.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/georgesform_model.cpp @@ -352,7 +352,8 @@ namespace NLQT /******************************************************************************/ - void CGeorgesFormModel::loadFormData(UFormElm *root, CFormItem *parent) { + void CGeorgesFormModel::loadFormData(UFormElm *root, CFormItem *parent) + { if (!root) return; @@ -390,7 +391,8 @@ namespace NLQT elmtType = "Array"; if (elmt->isStruct()) elmtType = "Struct"; - if (elmt->isAtom()) { + if (elmt->isAtom()) + { elmtType = "Atom"; uint numDefinitions = 0; const UType *type = elmt->getType(); @@ -433,7 +435,8 @@ namespace NLQT tmpValue = v.c_str(); if (type->getType() == UType::SignedInt) { - if (QString("%1").arg(value.c_str()).toDouble() == tmpValue.toDouble()) { + if (QString("%1").arg(value.c_str()).toDouble() == tmpValue.toDouble()) + { value = l; break; } @@ -482,7 +485,8 @@ namespace NLQT } columnData << QString(elmName.c_str()) << QString(value.c_str()) << "" << elmtType; parent->appendChild(new CFormItem(elmt, columnData, parent, *whereV, *whereN)); - //if (parents.last()->childCount() > 0) { + //if (parents.last()->childCount() > 0) + //{ // parents << parents.last()->child(parents.last()->childCount()-1); //} loadFormData(elmt, parent->child(parent->childCount()-1)); @@ -549,7 +553,8 @@ namespace NLQT { if (elmt->isArray()) elmtType = "Array"; - if (elmt->isStruct()) { + if (elmt->isStruct()) + { elmtType = "Struct"; } if (elmt->isAtom()) @@ -593,28 +598,35 @@ namespace NLQT CFormItem *fi_dep = new CFormItem(_rootElm, QList() << "dependencies", _rootItem); _rootItem->appendChild(fi_dep); - if (!dfns.isEmpty()) { - CFormItem *fi_dfn = new CFormItem(_rootElm, QList() << "dfn", fi_dep); - fi_dep->appendChild(fi_dfn); - foreach(QString str, dfns) { - fi_dfn->appendChild(new CFormItem(_rootElm, QList() << str, fi_dfn)); - } - } - if (!typs.isEmpty()) { - CFormItem *fi_typ = new CFormItem(_rootElm, QList() << "typ", fi_dep); - fi_dep->appendChild(fi_typ); - foreach(QString str, typs) { - fi_typ->appendChild(new CFormItem(_rootElm, QList() << str, fi_typ)); - } - } - if (!_dependencies.isEmpty()) { - CFormItem *fi_other = new CFormItem(_rootElm, QList() << "other", fi_dep); - fi_dep->appendChild(fi_other); - foreach(QStringList list, _dependencies) { - foreach(QString str, list) { - fi_other->appendChild(new CFormItem(_rootElm, QList() << str, fi_other)); + if (!dfns.isEmpty()) + { + CFormItem *fi_dfn = new CFormItem(_rootElm, QList() << "dfn", fi_dep); + fi_dep->appendChild(fi_dfn); + foreach(QString str, dfns) + { + fi_dfn->appendChild(new CFormItem(_rootElm, QList() << str, fi_dfn)); + } } + if (!typs.isEmpty()) + { + CFormItem *fi_typ = new CFormItem(_rootElm, QList() << "typ", fi_dep); + fi_dep->appendChild(fi_typ); + foreach(QString str, typs) + { + fi_typ->appendChild(new CFormItem(_rootElm, QList() << str, fi_typ)); + } } + if (!_dependencies.isEmpty()) + { + CFormItem *fi_other = new CFormItem(_rootElm, QList() << "other", fi_dep); + fi_dep->appendChild(fi_other); + foreach(QStringList list, _dependencies) + { + foreach(QString str, list) + { + fi_other->appendChild(new CFormItem(_rootElm, QList() << str, fi_other)); + } + } }*/ } diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/main_window.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/main_window.cpp index ef40f4dbc..8dbc2c18b 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/main_window.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/main_window.cpp @@ -338,7 +338,8 @@ namespace NLQT _aboutQtAction->setStatusTip(tr("Show the Qt library's About box")); connect(_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - for (int i = 0; i < MaxRecentFiles; ++i) { + for (int i = 0; i < MaxRecentFiles; ++i) + { recentFileActs[i] = new QAction(this); recentFileActs[i]->setVisible(false); connect(recentFileActs[i], SIGNAL(triggered()), diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/new_dialog.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/new_dialog.cpp index 499b06d94..f0a1fe351 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/new_dialog.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/new_dialog.cpp @@ -333,7 +333,8 @@ namespace NLQT return -1; } - void CGeorgesNewDialog::validateParentCombo() { + void CGeorgesNewDialog::validateParentCombo() + { // TODO: clear if no valid text //if (!_filelist.contains(_ui.parentLineEdit->text())) // _ui.parentLineEdit->clear(); diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/objectviewer_dialog.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/objectviewer_dialog.cpp index a47395cf6..e3c3d24e2 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/objectviewer_dialog.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/objectviewer_dialog.cpp @@ -77,7 +77,8 @@ namespace NLQT } } - void CObjectViewerDialog::topLevelChanged ( bool topLevel ) { + void CObjectViewerDialog::topLevelChanged ( bool topLevel ) + { //nldebug("topLevel:%d",topLevel); //_georges->init(); } @@ -100,7 +101,8 @@ namespace NLQT { //nldebug("%d %d",_nlw->width(), _nlw->height()); QDockWidget::resizeEvent(resizeEvent); - if (Modules::objViewInt()) { + if (Modules::objViewInt()) + { if (Modules::objViewInt()->getDriver()) Modules::objViewInt()->setSizeViewport(resizeEvent->size().width(), resizeEvent->size().height()); } diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/qt_displayer.cpp b/code/ryzom/tools/leveldesign/georges_editor_qt/src/qt_displayer.cpp index 07b338009..7c94e4fb0 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/qt_displayer.cpp +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/qt_displayer.cpp @@ -39,8 +39,8 @@ namespace NLQT ; } - CQtDisplayer::~CQtDisplayer() { - ; + CQtDisplayer::~CQtDisplayer() + { } void CQtDisplayer::setParam (QPlainTextEdit *dlgDebug, bool eraseLastLog) @@ -59,7 +59,8 @@ namespace NLQT QTextCharFormat format; - if (args.Date != 0 && !_Raw) { + if (args.Date != 0 && !_Raw) + { str += dateToHumanString(args.Date); needSpace = true; } @@ -76,27 +77,31 @@ namespace NLQT } // Write thread identifier - /*if ( args.ThreadId != 0 && !_Raw) { - if (needSpace) { str += " "; needSpace = false; } - str += NLMISC::toString(args.ThreadId); - needSpace = true; + /*if ( args.ThreadId != 0 && !_Raw) + { + if (needSpace) { str += " "; needSpace = false; } + str += NLMISC::toString(args.ThreadId); + needSpace = true; }*/ - /*if (!args.ProcessName.empty() && !_Raw) { - if (needSpace) { str += " "; needSpace = false; } - str += args.ProcessName; - needSpace = true; + /*if (!args.ProcessName.empty() && !_Raw) + { + if (needSpace) { str += " "; needSpace = false; } + str += args.ProcessName; + needSpace = true; }*/ - //if (args.FileName != NULL && !_Raw) { + //if (args.FileName != NULL && !_Raw) + //{ // if (needSpace) { str += " "; needSpace = false; } // str += NLMISC::CFile::getFilename(args.FileName); // needSpace = true; //} - /*if (args.Line != -1 && !_Raw) { - if (needSpace) { str += " "; needSpace = false; } - str += NLMISC::toString(args.Line); - needSpace = true; + /*if (args.Line != -1 && !_Raw) + { + if (needSpace) { str += " "; needSpace = false; } + str += NLMISC::toString(args.Line); + needSpace = true; }*/ if (args.FuncName != NULL && !_Raw) diff --git a/code/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp b/code/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp index e99b0eceb..279578293 100644 --- a/code/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp +++ b/code/ryzom/tools/leveldesign/world_editor/land_export_lib/export.cpp @@ -2595,8 +2595,8 @@ void CExport::transformAdditionnalIG (const std::string &name, const NLMISC::CMa inStream.close(); if (_ExportCB != NULL) { - _ExportCB->dispWarning("Error while reading " + igName); - _ExportCB->dispWarning(e.what()); + _ExportCB->dispWarning("Error while reading " + igName); + _ExportCB->dispWarning(e.what()); } } } diff --git a/code/ryzom/tools/translation_tools/main.cpp b/code/ryzom/tools/translation_tools/main.cpp index 9eba8c8da..9997342fe 100644 --- a/code/ryzom/tools/translation_tools/main.cpp +++ b/code/ryzom/tools/translation_tools/main.cpp @@ -96,13 +96,14 @@ const std::string historyDir("history/"); string diffVersion; #ifndef NL_OS_WINDOWS -char* itoa(int val, char *buffer, int base){ - static char buf[32] = {0}; - int i = 30; - for(; val && i ; --i, val /= base) - buf[i] = "0123456789abcdef"[val % base]; - return &buf[i+1]; -} +char* itoa(int val, char *buffer, int base) +{ + static char buf[32] = {0}; + int i = 30; + for(; val && i ; --i, val /= base) + buf[i] = "0123456789abcdef"[val % base]; + return &buf[i+1]; +} #endif // NL_OS_WINDOWS #ifdef NL_DEBUG From 5ee28644914902c1d1e175c4422faf7fc18eb030 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 15:08:13 +0100 Subject: [PATCH 198/344] Fixed: Compilation --HG-- branch : develop --- .../server/src/ryzom_welcome_service/ryzom_welcome_service.cpp | 1 + code/ryzom/server/src/server_share/pet_interface_msg.h | 1 + code/ryzom/server/src/tick_service/range_mirror_manager.h | 1 + 3 files changed, 3 insertions(+) diff --git a/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp b/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp index 98ae3a893..1de6677cb 100644 --- a/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp +++ b/code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service.cpp @@ -21,6 +21,7 @@ #include #include +#include #include "nel/misc/debug.h" #include "nel/misc/config_file.h" diff --git a/code/ryzom/server/src/server_share/pet_interface_msg.h b/code/ryzom/server/src/server_share/pet_interface_msg.h index 9aa914226..f404a76ef 100644 --- a/code/ryzom/server/src/server_share/pet_interface_msg.h +++ b/code/ryzom/server/src/server_share/pet_interface_msg.h @@ -25,6 +25,7 @@ #include "game_share/synchronised_message.h" #include "game_share/mirror.h" +#include // Pet interface message class for AIS / EGS communication diff --git a/code/ryzom/server/src/tick_service/range_mirror_manager.h b/code/ryzom/server/src/tick_service/range_mirror_manager.h index 0bde600e4..ed12f706b 100644 --- a/code/ryzom/server/src/tick_service/range_mirror_manager.h +++ b/code/ryzom/server/src/tick_service/range_mirror_manager.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace NLNET { From b70e8d3e7bb41582c278245a8a939d4ee534f68a Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 15:15:07 +0100 Subject: [PATCH 199/344] Fixed: Compilation --HG-- branch : develop --- .../src/pd_support_service/stat_user_file_list_builders.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp b/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp index d5d6570a4..45c172384 100644 --- a/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp +++ b/code/ryzom/server/src/pd_support_service/stat_user_file_list_builders.cpp @@ -20,6 +20,7 @@ //------------------------------------------------------------------------------------------------- #include +#include #include "game_share/utils.h" #include "stat_file_list_builder_factory.h" #include "stat_globals.h" From 3aa448ba24a2590fa93e228457be49a6d6edbc86 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 19:47:14 +0100 Subject: [PATCH 200/344] Changed: Replaced atoi and atof by NLMISC::fromString --HG-- branch : develop --- code/nel/src/3d/water_pool_manager.cpp | 8 ++--- code/nel/src/misc/sstring.cpp | 4 ++- code/nel/src/sound/sound_animation.cpp | 5 ++- .../nelns/login_service/connection_client.cpp | 2 +- .../Configuration.cpp | 2 +- .../nel_launcher_windows_ext/nel_launcher.cpp | 2 +- code/ryzom/client/src/3d_notes.cpp | 7 ++-- .../src/interfaces_manager/interf_script.cpp | 8 +++-- code/ryzom/client/src/scene_parser.cpp | 4 +-- code/ryzom/common/src/game_share/fame.cpp | 3 +- .../src/game_share/persistent_data_inline.h | 14 ++++++-- .../src/admin_modules/aes_client_module.cpp | 8 +++-- code/ryzom/server/src/ags_test/commands.cpp | 32 +++++++++++++------ .../server/src/ai_data_service/pacs_scan.cpp | 28 ++++++++++------ code/ryzom/server/src/ai_service/commands.cpp | 9 +++--- .../src/ai_service/generic_logic_action.cpp | 3 +- .../pvp_faction_reward_manager.cpp | 30 ++++++++++------- .../ryzom/server/src/gpm_service/commands.cpp | 4 +-- .../georges_convert/type_unit_double.cpp | 2 +- .../tools/leveldesign/prim_export/main.cpp | 4 +-- .../tools/make_anim_melee_impact/main.cpp | 2 +- 21 files changed, 116 insertions(+), 65 deletions(-) diff --git a/code/nel/src/3d/water_pool_manager.cpp b/code/nel/src/3d/water_pool_manager.cpp index b38068852..c377ff1f3 100644 --- a/code/nel/src/3d/water_pool_manager.cpp +++ b/code/nel/src/3d/water_pool_manager.cpp @@ -44,19 +44,19 @@ NLMISC_COMMAND(setWaterPool, "Setup a pool of water in the water pool manager", } if (numArgs == 3) { - whmb.FilterWeight = ::atof(args[2].c_str()); + NLMISC::fromString(args[2], whmb.FilterWeight); } if (numArgs == 4) { - whmb.UnitSize = ::atof(args[3].c_str()); + NLMISC::fromString(args[3], whmb.UnitSize); } if (numArgs == 5) { - whmb.WaveIntensity = ::atof(args[4].c_str()); + NLMISC::fromString(args[4], whmb.WaveIntensity); } if (numArgs == 4) { - whmb.WavePeriod = ::atof(args[5].c_str()); + NLMISC::fromString(args[5], whmb.WavePeriod); } // create the water pool GetWaterPoolManager().createWaterPool(whmb); diff --git a/code/nel/src/misc/sstring.cpp b/code/nel/src/misc/sstring.cpp index fe9332328..833553f21 100644 --- a/code/nel/src/misc/sstring.cpp +++ b/code/nel/src/misc/sstring.cpp @@ -1731,7 +1731,9 @@ namespace NLMISC double CSString::atof() const { - return ::atof(c_str()); + double val; + NLMISC::fromString(*this, val); + return val; } bool CSString::readFromFile(const CSString& fileName) diff --git a/code/nel/src/sound/sound_animation.cpp b/code/nel/src/sound/sound_animation.cpp index 5a6f1c256..1d1f9093a 100644 --- a/code/nel/src/sound/sound_animation.cpp +++ b/code/nel/src/sound/sound_animation.cpp @@ -176,7 +176,10 @@ void CSoundAnimation::load() throw NLMISC::Exception("Invalid sound animation marker"); } - marker->setTime((float) atof(time)); + float val; + NLMISC::fromString(time, val); + + marker->setTime(val); xmlFree ((void*)time); diff --git a/code/nelns/login_service/connection_client.cpp b/code/nelns/login_service/connection_client.cpp index 8ff713ec2..ebdef1b9a 100644 --- a/code/nelns/login_service/connection_client.cpp +++ b/code/nelns/login_service/connection_client.cpp @@ -126,7 +126,7 @@ retry: // now the user is on the database - uid = atoi(row[0]); + NLMISC::fromString(row[0], uid); if(cpassword != row[2]) { diff --git a/code/nelns/login_system/nel_launcher_windows_ext/Configuration.cpp b/code/nelns/login_system/nel_launcher_windows_ext/Configuration.cpp index f9092e56b..88b0d854a 100644 --- a/code/nelns/login_system/nel_launcher_windows_ext/Configuration.cpp +++ b/code/nelns/login_system/nel_launcher_windows_ext/Configuration.cpp @@ -52,7 +52,7 @@ BOOL CConfiguration::Load() // Reading the configuration file version GetValue(csBuffer, KEY_VERSION, csValue); - m_dVersion = atof(csValue); + NLMISC::fromString(csValue, m_dVersion); nlinfo("Config' version %s", csValue); if(m_dVersion < APP.m_dVersion) diff --git a/code/nelns/login_system/nel_launcher_windows_ext/nel_launcher.cpp b/code/nelns/login_system/nel_launcher_windows_ext/nel_launcher.cpp index 8ace867f7..2e36702d8 100644 --- a/code/nelns/login_system/nel_launcher_windows_ext/nel_launcher.cpp +++ b/code/nelns/login_system/nel_launcher_windows_ext/nel_launcher.cpp @@ -324,7 +324,7 @@ void CNel_launcherApp::LoadVersion() else { nlinfo("Launcher' version %s", csVersion); - m_dVersion = atof(csVersion); + NLMISC::fromString(csVersion, m_dVersion); } } diff --git a/code/ryzom/client/src/3d_notes.cpp b/code/ryzom/client/src/3d_notes.cpp index 7156854e4..618525de4 100644 --- a/code/ryzom/client/src/3d_notes.cpp +++ b/code/ryzom/client/src/3d_notes.cpp @@ -57,9 +57,10 @@ void cbNotesChanged() Notes.Notes.clear(); return; } - pos.x = (float)atof(posstr[0].c_str()); - pos.y = (float)atof(posstr[1].c_str()); - pos.z = (float)atof(posstr[2].c_str()); + + NLMISC::fromString(posstr[0], pos.x); + NLMISC::fromString(posstr[1], pos.y); + NLMISC::fromString(posstr[2], pos.z); string note(var.asString(i+2)); if(note.empty()) diff --git a/code/ryzom/client/src/interfaces_manager/interf_script.cpp b/code/ryzom/client/src/interfaces_manager/interf_script.cpp index f083eda18..734b99098 100644 --- a/code/ryzom/client/src/interfaces_manager/interf_script.cpp +++ b/code/ryzom/client/src/interfaces_manager/interf_script.cpp @@ -37,7 +37,11 @@ float getFloat() char delimiter[] = "[] \t"; char *ptr = strtok(NULL, delimiter); if(ptr != NULL) - return (float) atof(ptr); + { + float val; + NLMISC::fromString(ptr, val); + return val; + } return 0.f; }// getFloat // @@ -94,7 +98,7 @@ std::vector getVectorOfFloat(uint8 nbCol) ptr = strtok(NULL, delimiter); if(ptr != NULL) { - val = (float)atof(ptr); + NLMISC::fromString(ptr, val); if (val != 0.0f) vect.push_back(val); } diff --git a/code/ryzom/client/src/scene_parser.cpp b/code/ryzom/client/src/scene_parser.cpp index 1108f3a19..484c00129 100644 --- a/code/ryzom/client/src/scene_parser.cpp +++ b/code/ryzom/client/src/scene_parser.cpp @@ -123,7 +123,7 @@ void CSceneParser::load(const string &filename) char *ptr = strtok(tmpBuff, delimiter); if(ptr != NULL) - _FrameRate = atof(ptr); + NLMISC::fromString(ptr, _FrameRate); } // Close the speed file. @@ -1693,7 +1693,7 @@ void CSceneParser::loadScene(const string &filename) ptr = strtok(NULL, delimiter); if(ptr != NULL) { - seq.second = atof(ptr); + NLMISC::fromString(ptr, seq.second); _Scene.push_back(seq); } } diff --git a/code/ryzom/common/src/game_share/fame.cpp b/code/ryzom/common/src/game_share/fame.cpp index b453bca4e..ca226ecdc 100644 --- a/code/ryzom/common/src/game_share/fame.cpp +++ b/code/ryzom/common/src/game_share/fame.cpp @@ -479,10 +479,9 @@ void CStaticFames::loadStaticFame( const string& filename ) else NLMISC::fromString(s.substr(sep+1, s.size()-sep-1), factor); // Fames in file are in [-600;600] so don't forget 1000 factor - sint32 fame; float fameFloat; NLMISC::fromString(s.substr(0, sep), fameFloat); - fame = (sint32)(fameFloat * 1000.f); + sint32 fame = (sint32)(fameFloat * 1000.f); _FameTable[iFaction*_FameTableSize + jFaction] = fame; _PropagationFactorTable[iFaction*_FameTableSize + jFaction] = factor; diff --git a/code/ryzom/common/src/game_share/persistent_data_inline.h b/code/ryzom/common/src/game_share/persistent_data_inline.h index 72ef3fc9d..a2d575eef 100644 --- a/code/ryzom/common/src/game_share/persistent_data_inline.h +++ b/code/ryzom/common/src/game_share/persistent_data_inline.h @@ -706,7 +706,12 @@ inline float CPersistentDataRecord::CArg::asFloat() const case UINT64: return (float)(uint64)_Value.i64; case FLOAT32: return (float)_Value.f32; case FLOAT64: return (float)_Value.f64; - case STRING: return (float)atof(_String.c_str()); + case STRING: + { + float val; + NLMISC::fromString(_String, val); + return val; + } case FLAG: return 1.0f; case EXTEND_TYPE: switch(_Value.ExType) @@ -733,7 +738,12 @@ inline double CPersistentDataRecord::CArg::asDouble() const case UINT64: return (double)(uint64)_Value.i64; case FLOAT32: return (double)_Value.f32; case FLOAT64: return (double)_Value.f64; - case STRING: return (double)atof(_String.c_str()); + case STRING: + { + double val; + NLMISC::fromString(_String, val); + return val; + } case FLAG: return 1.0; case EXTEND_TYPE: switch(_Value.ExType) diff --git a/code/ryzom/server/src/admin_modules/aes_client_module.cpp b/code/ryzom/server/src/admin_modules/aes_client_module.cpp index e2b9ca390..9200f2d58 100644 --- a/code/ryzom/server/src/admin_modules/aes_client_module.cpp +++ b/code/ryzom/server/src/admin_modules/aes_client_module.cpp @@ -259,7 +259,7 @@ namespace ADMIN gs.HighRezTimeStamp = timer; IVariable *var = dynamic_cast(ICommand::getCommand(gvi.VarName)); if (var != NULL) - gs.SampleValue = atof(var->toString().c_str()); + NLMISC::fromString(var->toString(), gs.SampleValue); } } } @@ -305,7 +305,11 @@ namespace ADMIN // no sample collected yet, just ask a new one IVariable *var = dynamic_cast(ICommand::getCommand(gvi.VarName)); if (var != NULL) - gd.setValue(atof(var->toString().c_str())); + { + float val; + NLMISC::fromString(var->toString(), val); + gd.setValue(val); + } } else { diff --git a/code/ryzom/server/src/ags_test/commands.cpp b/code/ryzom/server/src/ags_test/commands.cpp index 7b2e6c2a8..4fa955401 100644 --- a/code/ryzom/server/src/ags_test/commands.cpp +++ b/code/ryzom/server/src/ags_test/commands.cpp @@ -586,7 +586,10 @@ NLMISC_COMMAND(actorSetOrientation,"Add one or more static actors"," if (i<(sizeof(angleNames)/sizeof(angleNames[0]))) theta=3.14159265359f*2.0f*(float)i/(float)(sizeof(angleNames)/sizeof(angleNames[0])); else - theta=(float)atof(args[0].c_str())/360.0f*2.0f*3.14159265359f; + { + NLMISC::fromString(args[0], theta); + theta = theta / 360.0f*2.0f*3.14159265359f; + } if (args.size()==1) { @@ -620,11 +623,13 @@ NLMISC_COMMAND(actorSetMagnetRange,"Set the magnet properties for wandering beha if(args.size() <1) return false; COMMAND_MACRO_RECORD_TEST - float range=(float)atof(args[0].c_str()); + float range; + NLMISC::fromString(args[0], range); if (range<=0.0f) return false; unsigned start; - float decay=(float)atof(args[0].c_str()); + float decay; + NLMISC::fromString(args[0], decay); if (decay<0.0f) return false; if (decay==0.0f) { @@ -664,7 +669,8 @@ NLMISC_COMMAND(actorSetAttackDistance,"set actor attack distance"," [< if(args.size() <1) return false; COMMAND_MACRO_RECORD_TEST - float distance=(float)atof(args[0].c_str()); + float distance; + NLMISC::fromString(args[0], distance); // if (distance<=0.0f) return false; if (args.size()<2) @@ -781,11 +787,13 @@ NLMISC_COMMAND(actorSetRespawnDelay,"set actor respawn delay"," [ filters; diff --git a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp index 28e55559c..9b5af1d5b 100644 --- a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp +++ b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp @@ -2465,9 +2465,17 @@ NLMISC_COMMAND(setDefaultStart,"Set the default start point for all continents", CVectorD startPoint; - startPoint.x = atof(args[0].c_str()); - startPoint.y = atof(args[1].c_str()); - startPoint.z = (args.size() < 3 ? 0.0 : atof(args[2].c_str())); + NLMISC::fromString(args[0], startPoint.x); + NLMISC::fromString(args[1], startPoint.y); + + if (args.size() > 2) + { + NLMISC::fromString(args[2], startPoint.z); + } + else + { + startPoint.z = 0.0; + } DefaultStartPoint = startPoint; @@ -2921,13 +2929,15 @@ NLMISC_COMMAND(testPacsMove, "test a pacs move", " " if (args.size() != 5) return false; - CPacsCruncher pc; + CPacsCruncher pc; + + string name = args[0]; - string name = args[0]; - double x = atof(args[1].c_str()); - double y = atof(args[2].c_str()); - double dx = atof(args[3].c_str()); - double dy = atof(args[4].c_str()); + double x, y, dx, dy; + NLMISC::fromString(args[1], x); + NLMISC::fromString(args[2], y); + NLMISC::fromString(args[3], dx); + NLMISC::fromString(args[4], dy); pc.init(name); diff --git a/code/ryzom/server/src/ai_service/commands.cpp b/code/ryzom/server/src/ai_service/commands.cpp index b51c7615b..350afa67d 100644 --- a/code/ryzom/server/src/ai_service/commands.cpp +++ b/code/ryzom/server/src/ai_service/commands.cpp @@ -229,8 +229,9 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " return true; } - double x = atof(args[3].c_str()); - double y = atof(args[4].c_str()); + double x, y; + NLMISC::fromString(args[3], x); + NLMISC::fromString(args[4], y); double dispersionRadius = 10.; if (args.size()>5) @@ -1970,8 +1971,8 @@ NLMISC_COMMAND(displayVision3x3,"display 3x3 cell vision centred on a given coor } CAICoord x, y; - x=atof(args[1].c_str()); - y=atof(args[2].c_str()); + NLMISC::fromString(args[1], x); + NLMISC::fromString(args[2], y); log.displayNL("3x3 Vision around (%.3f,%.3f)", x.asDouble(), y.asDouble()); uint32 botCount=0; diff --git a/code/ryzom/server/src/ai_service/generic_logic_action.cpp b/code/ryzom/server/src/ai_service/generic_logic_action.cpp index aaa113b30..e2c761619 100644 --- a/code/ryzom/server/src/ai_service/generic_logic_action.cpp +++ b/code/ryzom/server/src/ai_service/generic_logic_action.cpp @@ -1412,8 +1412,7 @@ public: if ((str[0]<='9' && str[0]>='0')||(str[0]=='-')) // its a number { var.Type = constant; - double val = atof(str.c_str()); - var.Value = float(val); + NLMISC::fromString(str, var.Value); return true; } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp index 85579dcf8..50b039522 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp @@ -1058,8 +1058,9 @@ NLMISC_COMMAND(getEffects, "get effects of a spire"," " ) return false; else { - float x = (float)atof(args[0].c_str()); - float y = (float)atof(args[1].c_str()); + float x, y; + NLMISC::fromString(args[0], x); + NLMISC::fromString(args[1], y); NLMISC::CVector vec( x, y, 0.0f ); @@ -1101,8 +1102,9 @@ NLMISC_COMMAND(buildSpirePos, "build a spire"," ") return true; } - float x = (float)atof(args[1].c_str()); - float y = (float)atof(args[2].c_str()); + float x, y; + NLMISC::fromString(args[1], x); + NLMISC::fromString(args[2], y); NLMISC::CVector vec( x, y, 0.0f ); @@ -1138,8 +1140,9 @@ NLMISC_COMMAND(destroySpirePos, "destroy a spire"," ") return false; else { - float x = (float)atof(args[0].c_str()); - float y = (float)atof(args[1].c_str()); + float x, y; + NLMISC::fromString(args[0], x); + NLMISC::fromString(args[1], y); NLMISC::CVector vec( x, y, 0.0f ); @@ -1178,8 +1181,9 @@ NLMISC_COMMAND(getEffectsPos, "get effects of a spire"," " ) return true; } - float x = (float)atof(args[1].c_str()); - float y = (float)atof(args[2].c_str()); + float x, y; + NLMISC::fromString(args[1], x); + NLMISC::fromString(args[2], y); NLMISC::CVector vec( x, y, 0.0f ); @@ -1265,8 +1269,9 @@ NLMISC_COMMAND(getRegionOwner, "display the faction which currently owns the reg return false; else { - float x = (float)atof(args[0].c_str()); - float y = (float)atof(args[1].c_str()); + float x, y; + NLMISC::fromString(args[0], x); + NLMISC::fromString(args[1], y); NLMISC::CVector vec( x, y, 0.0f ); @@ -1294,8 +1299,9 @@ NLMISC_COMMAND(getSpireStats, "display the status of spire in region correspondi return false; else { - float x = (float)atof(args[0].c_str()); - float y = (float)atof(args[1].c_str()); + float x, y; + NLMISC::fromString(args[0], x); + NLMISC::fromString(args[1], y); NLMISC::CVector vec( x, y, 0.0f ); diff --git a/code/ryzom/server/src/gpm_service/commands.cpp b/code/ryzom/server/src/gpm_service/commands.cpp index 127074856..8e5c8d1b8 100644 --- a/code/ryzom/server/src/gpm_service/commands.cpp +++ b/code/ryzom/server/src/gpm_service/commands.cpp @@ -179,8 +179,8 @@ NLMISC_COMMAND(getPatatEntryIndex, "Get the patat entry index at a pos", "x, y") CVector pos; - pos.x = (float)atof(args[0].c_str()); - pos.y = (float)atof(args[1].c_str()); + NLMISC::fromString(args[0], pos.x); + NLMISC::fromString(args[1], pos.y); pos.z = 0; nlinfo("entryIndex(%.1f, %.1f) = %d", pos.x, pos.y, CWorldPositionManager::getEntryIndex(pos)); diff --git a/code/ryzom/tools/leveldesign/georges_convert/type_unit_double.cpp b/code/ryzom/tools/leveldesign/georges_convert/type_unit_double.cpp index 6244c0f4a..674f77cd6 100644 --- a/code/ryzom/tools/leveldesign/georges_convert/type_unit_double.cpp +++ b/code/ryzom/tools/leveldesign/georges_convert/type_unit_double.cpp @@ -203,7 +203,7 @@ void CTypeUnitDouble::SetLowLimit( const CStringEx _sxll ) void CTypeUnitDouble::SetHighLimit( const CStringEx _sxhl ) { sxhighlimit = _sxhl; - dhighlimit = atof( sxhighlimit.c_str() ); + NLMISC::fromString(sxhighlimit, dhighlimit); } } diff --git a/code/ryzom/tools/leveldesign/prim_export/main.cpp b/code/ryzom/tools/leveldesign/prim_export/main.cpp index 86aeafa62..f9c33d953 100644 --- a/code/ryzom/tools/leveldesign/prim_export/main.cpp +++ b/code/ryzom/tools/leveldesign/prim_export/main.cpp @@ -629,7 +629,7 @@ void addPointPrimitive (CLandscape &landscape, const char *primFilename, uint32 string scaleText; float scale = 1; if (point->getPropertyByName ("scale", scaleText)) - scale = (float) atof (scaleText.c_str ()); + NLMISC::fromString(scaleText, scale); // Get zone coordinates sint x = (sint)floor (position.x / options.CellSize); @@ -654,7 +654,7 @@ void addPointPrimitive (CLandscape &landscape, const char *primFilename, uint32 // Get height if (!snap && point->getPropertyByName ("height", text)) - position.z = (float)atof(text.c_str()); + NLMISC::fromString(text, position.z); // *** Add the instance diff --git a/code/ryzom/tools/make_anim_melee_impact/main.cpp b/code/ryzom/tools/make_anim_melee_impact/main.cpp index 10fdeb0ed..3f67edd5e 100644 --- a/code/ryzom/tools/make_anim_melee_impact/main.cpp +++ b/code/ryzom/tools/make_anim_melee_impact/main.cpp @@ -79,7 +79,7 @@ void CAnimCombatState::build(const string &line) { StateCode= line.substr(4, 2); string time= line.substr(10, 5); - MeanAnimTime= (float)atof(time.c_str()); + NLMISC::fromString(time, MeanAnimTime); } From b26e7f4c1bea753cdc70185e814c211a13a6cc86 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 13 Jan 2015 20:35:34 +0100 Subject: [PATCH 201/344] Fixed: Compilation --HG-- branch : develop --- code/ryzom/server/src/ai_service/commands.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/ryzom/server/src/ai_service/commands.cpp b/code/ryzom/server/src/ai_service/commands.cpp index 350afa67d..52315372a 100644 --- a/code/ryzom/server/src/ai_service/commands.cpp +++ b/code/ryzom/server/src/ai_service/commands.cpp @@ -1970,9 +1970,13 @@ NLMISC_COMMAND(displayVision3x3,"display 3x3 cell vision centred on a given coor } } + double dx, dy; + NLMISC::fromString(args[1], dx); + NLMISC::fromString(args[2], dy); + CAICoord x, y; - NLMISC::fromString(args[1], x); - NLMISC::fromString(args[2], y); + x = dx; + y = dy; log.displayNL("3x3 Vision around (%.3f,%.3f)", x.asDouble(), y.asDouble()); uint32 botCount=0; From 53f6adb04145a5a8a6a08f672ce0193c3138f4a1 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 15 Jan 2015 20:08:28 +0200 Subject: [PATCH 202/344] Include chat message channel/type to chatlog file --HG-- branch : issue-221 --- code/ryzom/client/src/client_chat_manager.cpp | 2 +- .../client/src/interface_v3/chat_window.cpp | 2 +- .../src/interface_v3/interface_manager.cpp | 4 +-- .../src/interface_v3/interface_manager.h | 2 +- .../client/src/interface_v3/people_list.cpp | 4 +-- code/ryzom/client/src/net_manager.cpp | 25 +++++++++++++++++-- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp index bac2abf1e..141edea27 100644 --- a/code/ryzom/client/src/client_chat_manager.cpp +++ b/code/ryzom/client/src/client_chat_manager.cpp @@ -1204,7 +1204,7 @@ class CHandlerTell : public IActionHandler ucstring s = CI18N::get("youTellPlayer"); strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); - CInterfaceManager::getInstance()->log(finalMsg); + CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); } }; REGISTER_ACTION_HANDLER( CHandlerTell, "tell"); diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index 7dcf13eeb..dd483030b 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -483,7 +483,7 @@ void CChatWindow::displayLocalPlayerTell(const ucstring &receiver, const ucstrin strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); displayMessage(finalMsg, prop.getRGBA(), CChatGroup::tell, 0, numBlinks); - CInterfaceManager::getInstance()->log(finalMsg); + CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); } void CChatWindow::encodeColorTag(const NLMISC::CRGBA &color, ucstring &text, bool append) diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 541cb853a..75678f7e6 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -2684,7 +2684,7 @@ bool CInterfaceManager::deletePlayerKeys (const std::string &playerFileIdent) } // *************************************************************************** -void CInterfaceManager::log(const ucstring &str) +void CInterfaceManager::log(const ucstring &str, const std::string &cat) { if (_LogState) { @@ -2693,7 +2693,7 @@ void CInterfaceManager::log(const ucstring &str) FILE *f = fopen(fileName.c_str(), "at"); if (f != NULL) { - const string finalString = string(NLMISC::IDisplayer::dateToHumanString()) + " * " + str.toUtf8(); + const string finalString = string(NLMISC::IDisplayer::dateToHumanString()) + " (" + NLMISC::toUpper(cat) + ") * " + str.toUtf8(); fprintf(f, "%s\n", finalString.c_str()); } fclose(f); diff --git a/code/ryzom/client/src/interface_v3/interface_manager.h b/code/ryzom/client/src/interface_v3/interface_manager.h index 36bd909e3..d947f4912 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.h +++ b/code/ryzom/client/src/interface_v3/interface_manager.h @@ -218,7 +218,7 @@ public: // Log system (all chat/tell void setLogState(bool state) { _LogState = state; } bool getLogState() const { return _LogState; } - void log(const ucstring &str); + void log(const ucstring &str, const std::string &cat = ""); /// Text from here and from server diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index 4dc451ea3..c2167358f 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -478,7 +478,7 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); gl->addChild(getChatTextMngr().createMsgText(finalMsg, prop.getRGBA())); - CInterfaceManager::getInstance()->log(finalMsg); + CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); // if the group is closed, make it blink if (!gc->isOpen()) @@ -946,7 +946,7 @@ class CHandlerContactEntry : public IActionHandler ucstring s = CI18N::get("youTellPlayer"); strFindReplace(s, "%name", pWin->getFreeTellerName(str)); strFindReplace(final, CI18N::get("youTell"), s); - CInterfaceManager::getInstance()->log(final); + CInterfaceManager::getInstance()->log(final, CChatGroup::groupTypeToString(CChatGroup::tell)); } } } diff --git a/code/ryzom/client/src/net_manager.cpp b/code/ryzom/client/src/net_manager.cpp index 4b37b698a..66c4b83fc 100644 --- a/code/ryzom/client/src/net_manager.cpp +++ b/code/ryzom/client/src/net_manager.cpp @@ -879,7 +879,28 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c } // Log - pIM->log (finalString); + + string channel; + if (mode == CChatGroup::dyn_chat) + { + sint32 dbIndex = ChatMngr.getDynamicChannelDbIndexFromId(dynChatId); + clamp(dbIndex, (sint32)0 , (sint32)CChatGroup::MaxDynChanPerPlayer); + + channel = "dyn" + toString(dbIndex); + } + else + { + channel = CChatGroup::groupTypeToString(mode); + if (channel.empty()) + { + channel = "#" + toString((uint32)mode); + } + } + if (!stringCategory.empty() && NLMISC::toUpper(stringCategory) != "SYS") + { + channel = channel + "/" + stringCategory; + } + pIM->log (finalString, channel); } @@ -911,7 +932,7 @@ void CInterfaceChatDisplayer::displayTell(/*TDataSetIndex senderIndex, */const u colorizeSender(finalString, senderPart, prop.getRGBA()); PeopleInterraction.ChatInput.Tell.displayTellMessage(/*senderIndex, */finalString, goodSenderName, prop.getRGBA(), 2, &windowVisible); - CInterfaceManager::getInstance()->log(finalString); + CInterfaceManager::getInstance()->log(finalString, CChatGroup::groupTypeToString(CChatGroup::tell)); // Open the free teller window CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); From eea09d8893aa3697f3685b03f1b143a7a657fc1b Mon Sep 17 00:00:00 2001 From: kervala Date: Wed, 21 Jan 2015 13:20:56 +0100 Subject: [PATCH 203/344] Fixed: Guilds with same characters and not same spaces --HG-- branch : develop --- code/ryzom/server/src/shard_unifier_service/name_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/server/src/shard_unifier_service/name_manager.cpp b/code/ryzom/server/src/shard_unifier_service/name_manager.cpp index 5b50f6359..17b500f92 100644 --- a/code/ryzom/server/src/shard_unifier_service/name_manager.cpp +++ b/code/ryzom/server/src/shard_unifier_service/name_manager.cpp @@ -1138,7 +1138,7 @@ bool CNameManager::loadGuildsNamesFromTxt() // merge the first words until we have only 3 words while (words.size() > 3) { - words[0] += words[1]; + words[0] += " " + words[1]; words.erase(words.begin()+1); } BOMB_IF (words.size()!=3,"Invalid line "< Date: Fri, 23 Jan 2015 21:11:15 +0100 Subject: [PATCH 204/344] Changed: Optimize sorting of files (instead of doing it several times for each directory, do it only once) --HG-- branch : develop --- code/nel/src/misc/path.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/misc/path.cpp b/code/nel/src/misc/path.cpp index d47b8ce4a..8f2926728 100644 --- a/code/nel/src/misc/path.cpp +++ b/code/nel/src/misc/path.cpp @@ -858,6 +858,8 @@ string getname (dirent *de) void CPath::getPathContent (const string &path, bool recurse, bool wantDir, bool wantFile, vector &result, class IProgressCallback *progressCallBack, bool showEverything) { getInstance()->_FileContainer.getPathContent(path, recurse, wantDir, wantFile, result, progressCallBack, showEverything); + + sort(result.begin(), result.end()); } void CFileContainer::getPathContent (const string &path, bool recurse, bool wantDir, bool wantFile, vector &result, class IProgressCallback *progressCallBack, bool showEverything) @@ -960,8 +962,6 @@ void CFileContainer::getPathContent (const string &path, bool recurse, bool want progressCallBack->popCropedValues (); } } - - sort(result.begin(), result.end()); } void CPath::removeAllAlternativeSearchPath () From e311547a39ac9d07a7612b75eb313e4fdad9410b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 1 Feb 2015 20:29:26 +0100 Subject: [PATCH 205/344] Initialize Nel3D in the Object Viewer plugin too. --HG-- branch : hotfix --- code/nel/src/3d/driver_user.cpp | 15 +------------- code/nel/src/3d/init_3d.cpp | 20 ++++++++++++++++++- .../object_viewer/object_viewer_plugin.cpp | 3 +++ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index c4dc97655..017a2b6dc 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -109,10 +109,6 @@ void UDriver::purgeMemory() // *************************************************************************** -// *************************************************************************** -bool CDriverUser::_StaticInit= false; - - // *************************************************************************** CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFunc) { @@ -122,16 +118,7 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu nlassert((uint)IDriver::iconCount == (uint)UDriver::iconCount); - // Static Initialisation. - if(!_StaticInit) - { - _StaticInit= true; - // Register basic serial. - NL3D::registerSerial3d(); - - // Register basic csene. - CScene::registerBasics(); - } + NL3D::init3d(); _Driver = NULL; diff --git a/code/nel/src/3d/init_3d.cpp b/code/nel/src/3d/init_3d.cpp index bd8dffdfd..4ba439b73 100644 --- a/code/nel/src/3d/init_3d.cpp +++ b/code/nel/src/3d/init_3d.cpp @@ -19,18 +19,36 @@ #include "nel/3d/init_3d.h" #include +#include "nel/3d/scene.h" +#include "nel/3d/register_3d.h" + +namespace +{ +static bool _Initialized = false; +} namespace NL3D { void init3d () { + + if( _Initialized ) + return; + // Init for windows #ifdef NL_OS_WINDOWS // Enable FPU exceptions // Enable divid by zero and overflow exception - _control87 (_EM_INVALID|_EM_DENORMAL/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM); + //_control87 (_EM_INVALID|_EM_DENORMAL/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM); + + NL3D::registerSerial3d(); + CScene::registerBasics(); + + _Initialized = true; + + #endif // NL_OS_WINDOWS } diff --git a/code/studio/src/plugins/object_viewer/object_viewer_plugin.cpp b/code/studio/src/plugins/object_viewer/object_viewer_plugin.cpp index dce7ad08f..a4c948140 100644 --- a/code/studio/src/plugins/object_viewer/object_viewer_plugin.cpp +++ b/code/studio/src/plugins/object_viewer/object_viewer_plugin.cpp @@ -8,6 +8,7 @@ // NeL includes #include "nel/misc/debug.h" +#include "nel/3d/init_3d.h" // Qt includes #include @@ -32,6 +33,8 @@ bool ObjectViewerPlugin::initialize(ExtensionSystem::IPluginManager *pluginManag { Q_UNUSED(errorString); _plugMan = pluginManager; + + NL3D::init3d(); Modules::init(); addAutoReleasedObject(new CObjectViewerContext()); addAutoReleasedObject(new GraphicsSettingsPage()); From 2d308dc6e787fcbafd891889bfa27f925a31054d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Feb 2015 22:01:16 +0100 Subject: [PATCH 206/344] Fixed build of Object Viewer Widget Qt ( old, not part of Studio ). --HG-- branch : hotfix --- .../3d/object_viewer_widget/src/object_viewer_widget.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp index af026b3df..4d0936a1a 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp +++ b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp @@ -185,7 +185,7 @@ namespace NLQT NL3D::CBloomEffect::instance().setDriver(_Driver); NL3D::CBloomEffect::instance().setScene(_Scene); - NL3D::CBloomEffect::instance().init(!_Direct3D); + NL3D::CBloomEffect::instance().init(); //NL3D::CBloomEffect::instance().setDensityBloom(Modules::config().getConfigFile().getVar("BloomDensity").asInt()); //NL3D::CBloomEffect::instance().setSquareBloom(Modules::config().getConfigFile().getVar("BloomSquare").asBool()); } @@ -366,7 +366,7 @@ namespace NLQT // Render the scene. if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().initBloom(); + NL3D::CBloomEffect::instance().init(); } _Driver->clearBuffers(_BackgroundColor); } @@ -378,8 +378,7 @@ namespace NLQT if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().endBloom(); - NL3D::CBloomEffect::instance().endInterfacesDisplayBloom(); + NL3D::CBloomEffect::instance().applyBloom(); } } From 35c870c793b2f5f0d5d08008f8167c55e2e9a952 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Feb 2015 22:41:29 +0100 Subject: [PATCH 207/344] Install tile editor's plugin spec to the right directory. --HG-- branch : hotfix --- .../studio/src/plugins/tile_editor/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/tile_editor/CMakeLists.txt b/code/studio/src/plugins/tile_editor/CMakeLists.txt index 78cc5ef49..bfb9f3440 100644 --- a/code/studio/src/plugins/tile_editor/CMakeLists.txt +++ b/code/studio/src/plugins/tile_editor/CMakeLists.txt @@ -46,5 +46,18 @@ NL_ADD_LIB_SUFFIX(studio_plugin_tile_editor) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) -INSTALL(TARGETS studio_plugin_tile_editor LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) +IF(WIN32) + IF(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS studio_plugin_tile_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) + ELSE(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS studio_plugin_tile_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) + ENDIF(WITH_INSTALL_LIBRARIES) +ELSE(WIN32) + IF(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS studio_plugin_tile_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) + ELSE(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS studio_plugin_tile_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) + ENDIF(WITH_INSTALL_LIBRARIES) +ENDIF(WIN32) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/studio_plugin_tile_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) From e7066c1384e811026d15469c0c123cfc711c00f7 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Feb 2015 22:51:43 +0100 Subject: [PATCH 208/344] Some CPack renames. --HG-- branch : hotfix --- code/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0f9a72ac6..500331c43 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1,7 +1,7 @@ #----------------------------------------------------------------------------- # -# NeL -# Authors: Nevrax and the NeL Community +# Ryzom Core +# Authors: Nevrax and the Ryzom Core Community # Version: 0.11.2 # # Notes: @@ -228,30 +228,30 @@ IF(WITH_NEL_TESTS) ENDIF(WITH_NEL_TESTS) # packaging information -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "NeL MMORPG Framework") -SET(CPACK_PACKAGE_VENDOR "NeL") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ryzom Core MMORPG Framework") +SET(CPACK_PACKAGE_VENDOR "Ryzom Core") SET(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/README) SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING) SET(CPACK_PACKAGE_VERSION_MAJOR "${NL_VERSION_MAJOR}") SET(CPACK_PACKAGE_VERSION_MINOR "${NL_VERSION_MINOR}") SET(CPACK_PACKAGE_VERSION_PATCH "${NL_VERSION_PATCH}") SET(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};NeL;ALL;/") -SET(CPACK_PACKAGE_EXECUTABLES "nel${NL_VERSION}" "nel") +SET(CPACK_PACKAGE_EXECUTABLES "ryzomcore${NL_VERSION}" "ryzomcore") # NSIS Specific Packing Setup -SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "NeL") +SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "RyzomCore") SET(CPACK_NSIS_MODIFY_PATH "ON") SET(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/resources/nevraxpill.ico) SET(CPACK_NSIS_MUI_UNIICON ${CMAKE_SOURCE_DIR}/resources/nevraxpill.ico) SET(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/resources\\\\nel.bmp) -SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} NeL") +SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} RyzomCore") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\dev.ryzom.com") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\dev.ryzom.com\\\\projects\\\\nel\\\\wiki") SET(CPACK_NSIS_CONTACT "matt.raykowski@gmail.com") ## Source Packages -SET(CPACK_PACKAGE_FILE_NAME "nel-${NL_VERSION}") -SET(CPACK_SOURCE_PACKAGE_FILE_NAME "nel-${NL_VERSION}") +SET(CPACK_PACKAGE_FILE_NAME "ryzomcore-${NL_VERSION}") +SET(CPACK_SOURCE_PACKAGE_FILE_NAME "ryzomcore-${NL_VERSION}") IF(WIN32) #SET(CPACK_GENERATOR "NSIS") SET(CPACK_GENERATOR "NSIS;ZIP") From bdb633cf836511679875c38eb3b96c3c7745177b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Feb 2015 23:25:11 +0100 Subject: [PATCH 209/344] Use release squish if debug not found. Fixes s3tc compressor tool build. --HG-- branch : hotfix --- code/CMakeModules/FindSquish.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/CMakeModules/FindSquish.cmake b/code/CMakeModules/FindSquish.cmake index ad0f7ce80..61250fec1 100644 --- a/code/CMakeModules/FindSquish.cmake +++ b/code/CMakeModules/FindSquish.cmake @@ -55,10 +55,12 @@ FIND_LIBRARY(SQUISH_LIBRARY_DEBUG IF(SQUISH_INCLUDE_DIR) IF(SQUISH_LIBRARY_RELEASE) SET(SQUISH_FOUND "YES") - SET(SQUISH_LIBRARIES "optimized;${SQUISH_LIBRARY_RELEASE}") IF(SQUISH_LIBRARY_DEBUG) SET(SQUISH_LIBRARIES "${SQUISH_LIBRARIES};debug;${SQUISH_LIBRARY_DEBUG}") + ELSE(SQUISH_LIBRARY_DEBUG) + SET(SQUISH_LIBRARIES "${SQUISH_LIBRARIES};debug;${SQUISH_LIBRARY_RELEASE}") + MESSAGE("Debug Squish NOT found, using the release version!") ENDIF(SQUISH_LIBRARY_DEBUG) ENDIF(SQUISH_LIBRARY_RELEASE) ENDIF(SQUISH_INCLUDE_DIR) From ea3b16069bdcfe78eda876465fb2cd7eca8b67ec Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 5 Feb 2015 23:50:38 +0100 Subject: [PATCH 210/344] We need the LIGO config file, not directory in the first start settings dialog. --HG-- branch : hotfix --- code/studio/src/settings_dialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/studio/src/settings_dialog.cpp b/code/studio/src/settings_dialog.cpp index 78773a666..df2718b9b 100644 --- a/code/studio/src/settings_dialog.cpp +++ b/code/studio/src/settings_dialog.cpp @@ -170,7 +170,8 @@ void SettingsDialog::onPrimitivesBClicked() void SettingsDialog::onLigoBClicked() { - QString p = QFileDialog::getExistingDirectory( this, tr( "LIGO directory" ), "" ); + QString p; + p = QFileDialog::getOpenFileName( this, tr( "LIGO config file" ), "" ); ligoLE->setText( p ); } From 6c153a30b41e51053658950398b3998690f0f6a5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 6 Feb 2015 00:31:51 +0100 Subject: [PATCH 211/344] CPack should use the install prefix. --HG-- branch : hotfix --- code/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 500331c43..dcc9f9c93 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -237,6 +237,7 @@ SET(CPACK_PACKAGE_VERSION_MINOR "${NL_VERSION_MINOR}") SET(CPACK_PACKAGE_VERSION_PATCH "${NL_VERSION_PATCH}") SET(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};NeL;ALL;/") SET(CPACK_PACKAGE_EXECUTABLES "ryzomcore${NL_VERSION}" "ryzomcore") +SET(CPACK_SET_DESTDIR TRUE) # NSIS Specific Packing Setup SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "RyzomCore") From 5e55a7b7bb8663609e258760891ec2b29039a1fd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 6 Feb 2015 02:29:33 +0100 Subject: [PATCH 212/344] Erm. Initialize Nel3D on other platforms too... --HG-- branch : hotfix --- code/nel/src/3d/init_3d.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/nel/src/3d/init_3d.cpp b/code/nel/src/3d/init_3d.cpp index 4ba439b73..b2bf2c05e 100644 --- a/code/nel/src/3d/init_3d.cpp +++ b/code/nel/src/3d/init_3d.cpp @@ -42,14 +42,12 @@ void init3d () // Enable divid by zero and overflow exception //_control87 (_EM_INVALID|_EM_DENORMAL/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM); +#endif // NL_OS_WINDOWS NL3D::registerSerial3d(); CScene::registerBasics(); _Initialized = true; - - -#endif // NL_OS_WINDOWS } } // NL3D From 46cc31d0d06d78911b5f378335fe5806ad8a7816 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 8 Feb 2015 00:24:29 +0100 Subject: [PATCH 213/344] Handle relative paths when loading .worldedit files in World Editor. --HG-- branch : hotfix --- code/nel/include/nel/misc/path.h | 7 +++ code/nel/src/misc/path.cpp | 51 +++++++++++++++++++ .../world_editor/world_editor_misc.cpp | 7 +++ 3 files changed, 65 insertions(+) diff --git a/code/nel/include/nel/misc/path.h b/code/nel/include/nel/misc/path.h index f3120c907..cd19c43ee 100644 --- a/code/nel/include/nel/misc/path.h +++ b/code/nel/include/nel/misc/path.h @@ -507,6 +507,13 @@ public: */ static bool makePathRelative (const char *basePath, std::string &relativePath); + /** Make path absolute + * \param relativePath - The relative path + * \param directory - the directory to which the path is relative to + * returns the absolute path, or empty if something went wrong. + */ + static std::string makePathAbsolute (const std::string &relativePath, const std::string &directory ); + /** If File in this list is added more than one in an addSearchPath, it doesn't launch a warning. */ static void addIgnoredDoubleFile(const std::string &ignoredFile); diff --git a/code/nel/src/misc/path.cpp b/code/nel/src/misc/path.cpp index d47b8ce4a..2a25276e8 100644 --- a/code/nel/src/misc/path.cpp +++ b/code/nel/src/misc/path.cpp @@ -2544,6 +2544,57 @@ bool CPath::makePathRelative (const char *basePath, std::string &relativePath) return false; } +std::string CPath::makePathAbsolute( const std::string &relativePath, const std::string &directory ) +{ + if( relativePath.empty() ) + return ""; + if( directory.empty() ) + return ""; + +#ifdef NL_OS_WINDOWS + // Windows network address. Eg.: \\someshare\path + if( ( relativePath[ 0 ] == '\\' ) && ( relativePath[ 1 ] == '\\' ) ) + return relativePath; + + // Normal Windows absolute path. Eg.: C:\something + // + if( isalpha( relativePath[ 0 ] ) && ( relativePath[ 1 ] == ':' ) && ( ( relativePath[ 2 ] == '\\' ) || ( relativePath[ 2 ] == '/' ) ) ) + return relativePath; +#else + // Unix filesystem absolute path + if( relativePath[ 0 ] == '/' ) + return relativePath; + +#endif + + // Add a slash to the directory if necessary. + // If the relative path starts with dots we need a slash. + // If the relative path starts with a slash we don't. + // If it starts with neither, we need a slash. + bool needSlash = true; + char c = relativePath[ 0 ]; + if( ( c == '\\' ) || ( c == '/' ) ) + needSlash = false; + + bool hasSlash = false; + std::string npath = directory; + c = npath[ npath.size() - 1 ]; + if( ( c == '\\' ) || ( c == '/' ) ) + hasSlash = true; + + if( needSlash && !hasSlash ) + npath += '/'; + else + if( hasSlash && !needSlash ) + npath.resize( npath.size() - 1 ); + + // Now build the new absolute path + npath += relativePath; + npath = standardizePath( npath, false ); + + return npath; +} + bool CFile::setRWAccess(const std::string &filename) { #ifdef NL_OS_WINDOWS diff --git a/code/studio/src/plugins/world_editor/world_editor_misc.cpp b/code/studio/src/plugins/world_editor/world_editor_misc.cpp index 5d6b7f94e..a2736b1c5 100644 --- a/code/studio/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_misc.cpp @@ -59,6 +59,8 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList lastError = ""; + std::string p = NLMISC::CFile::getPath( fileName ); + // Load the document NLMISC::CIFile file; if (file.open(fileName)) @@ -122,6 +124,8 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList { std::string dataDir; NLMISC::CIXml::getPropertyString(dataDir, node, "VALUE"); + + dataDir = NLMISC::CPath::makePathAbsolute( dataDir, p ); worldEditList.push_back(WorldEditItem(DataDirectoryType, dataDir)); } @@ -149,6 +153,9 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList std::string filenameChild; if ( NLMISC::CIXml::getPropertyString(filenameChild, node, "FILENAME")) { + + filenameChild = NLMISC::CPath::makePathAbsolute( filenameChild, p ); + // Is it a landscape ? if (type == "landscape") { From a2c96c30539067b0634ce66f9302126be35da5fd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 8 Feb 2015 23:46:33 +0100 Subject: [PATCH 214/344] Install the GUI Editor widget and expression definition files to the data dir. --HG-- branch : hotfix --- code/studio/src/plugins/gui_editor/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index e1e8b38be..3813bec67 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -112,3 +112,9 @@ ELSE(WIN32) ENDIF(WIN32) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/studio_plugin_gui_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) + +FILE(GLOB widgets "${CMAKE_CURRENT_SOURCE_DIR}/widgets/*.xml") +FILE(GLOB expressions "${CMAKE_CURRENT_SOURCE_DIR}/expressions/*.xml") + +INSTALL(FILES ${widgets} DESTINATION "${OVQT_DATA_DIR}/widgets" COMPONENT tools3d) +INSTALL(FILES ${expressions} DESTINATION "${OVQT_DATA_DIR}/expressions" COMPONENT tools3d) From b881f9558b79256ef4a12e8e83ed351bc152f3ab Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 9 Feb 2015 01:48:39 +0100 Subject: [PATCH 215/344] Read the GUI Editor widget and expression definition XML files from the right directory. --HG-- branch : hotfix --- code/studio/CMakeLists.txt | 3 +++ code/studio/src/plugins/gui_editor/CMakeLists.txt | 2 ++ code/studio/src/plugins/gui_editor/expression_store.cpp | 3 ++- .../src/plugins/gui_editor/gui_editor_config.h.cmake | 8 ++++++++ .../src/plugins/gui_editor/widget_properties_parser.cpp | 5 +++-- 5 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/gui_editor_config.h.cmake diff --git a/code/studio/CMakeLists.txt b/code/studio/CMakeLists.txt index bf9ee062c..c10f2ea59 100644 --- a/code/studio/CMakeLists.txt +++ b/code/studio/CMakeLists.txt @@ -10,15 +10,18 @@ IF(WIN32) SET(OVQT_PLUGIN_SPECS_DIR "plugins") SET(OVQT_PLUGIN_DIR "plugins") SET(OVQT_DATA_DIR ".") + SET(OVQT_IMP_DATA_DIR "${OVQT_DATA_DIR}") ELSEIF(APPLE) # TODO: under Mac OS X, don't install but copy files in application package SET(OVQT_PLUGIN_SPECS_DIR "plugins") SET(OVQT_PLUGIN_DIR "plugins") SET(OVQT_DATA_DIR ".") + SET(OVQT_IMP_DATA_DIR "${OVQT_DATA_DIR}") ELSE(WIN32) SET(OVQT_PLUGIN_SPECS_DIR ${NL_SHARE_PREFIX}/studio/plugins) SET(OVQT_PLUGIN_DIR ${NL_LIB_PREFIX}/studio) SET(OVQT_DATA_DIR ${NL_SHARE_PREFIX}/studio/data) + SET(OVQT_IMP_DATA_DIR "${CMAKE_INSTALL_PREFIX}/${OVQT_DATA_DIR}") CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ovqt_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/ovqt_config.h) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 3813bec67..efa0a171c 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -4,6 +4,8 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${QT_INCLUDES} ${LUA_INCLUDE_DIR}) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/gui_editor_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/gui_editor_config.h) + FILE(GLOB SRC *.cpp *.h) SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h diff --git a/code/studio/src/plugins/gui_editor/expression_store.cpp b/code/studio/src/plugins/gui_editor/expression_store.cpp index 9f2218b4e..0016374d3 100644 --- a/code/studio/src/plugins/gui_editor/expression_store.cpp +++ b/code/studio/src/plugins/gui_editor/expression_store.cpp @@ -21,6 +21,7 @@ #include "expression_loader.h" #include #include +#include "gui_editor_config.h" class ExpressionStorePvt { @@ -50,7 +51,7 @@ ExpressionStore::~ExpressionStore() bool ExpressionStore::load() { - QDir d( "expressions" ); + QDir d( EXPRESSIONS_DIR ); if( !d.exists() ) return false; diff --git a/code/studio/src/plugins/gui_editor/gui_editor_config.h.cmake b/code/studio/src/plugins/gui_editor/gui_editor_config.h.cmake new file mode 100644 index 000000000..0e36dcb79 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/gui_editor_config.h.cmake @@ -0,0 +1,8 @@ +#ifndef GUI_EDITOR_CONFIG_H +#define GUI_EDITOR_CONFIG_H + +#define WIDGETS_DIR "${OVQT_IMP_DATA_DIR}/widgets" +#define EXPRESSIONS_DIR "${OVQT_IMP_DATA_DIR}/expressions" + +#endif + diff --git a/code/studio/src/plugins/gui_editor/widget_properties_parser.cpp b/code/studio/src/plugins/gui_editor/widget_properties_parser.cpp index e0f346fc9..fd74dcae4 100644 --- a/code/studio/src/plugins/gui_editor/widget_properties_parser.cpp +++ b/code/studio/src/plugins/gui_editor/widget_properties_parser.cpp @@ -20,6 +20,7 @@ #include #include "nel/misc/debug.h" #include "widget_info_tree.h" +#include "gui_editor_config.h" using namespace NLMISC; @@ -36,7 +37,7 @@ namespace GUIEditor void CWidgetPropParser::parseGUIWidgets() { - QDir d( "widgets" ); + QDir d( WIDGETS_DIR ); if( !d.exists() ) { nlwarning( "GUI widgets directory doesn't exist!" ); @@ -55,7 +56,7 @@ namespace GUIEditor QStringListIterator itr( files ); while( itr.hasNext() ) - parseGUIWidget( "widgets/" + itr.next() ); + parseGUIWidget( QString( WIDGETS_DIR ) + QString( "/" ) + itr.next() ); buildWidgetInfoTree(); From b530d99bf1c35b35a024e119cef746f74475d2b9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 9 Feb 2015 17:54:27 +0100 Subject: [PATCH 216/344] Renamed the studio startup settings dialog to avoid name conflict with the core plugin's settings dialog. --HG-- branch : hotfix --- code/studio/src/CMakeLists.txt | 4 +- code/studio/src/main.cpp | 4 +- .../studio/src/plugins/core/settings_dialog.h | 2 +- ...gs_dialog.cpp => startup_settings_dlg.cpp} | 42 +++++++++---------- ...ttings_dialog.h => startup_settings_dlg.h} | 12 +++--- ...ings_dialog.ui => startup_settings_dlg.ui} | 4 +- 6 files changed, 34 insertions(+), 34 deletions(-) rename code/studio/src/{settings_dialog.cpp => startup_settings_dlg.cpp} (84%) rename code/studio/src/{settings_dialog.h => startup_settings_dlg.h} (84%) rename code/studio/src/{settings_dialog.ui => startup_settings_dlg.ui} (95%) diff --git a/code/studio/src/CMakeLists.txt b/code/studio/src/CMakeLists.txt index 9bc071bf2..510f0f93b 100644 --- a/code/studio/src/CMakeLists.txt +++ b/code/studio/src/CMakeLists.txt @@ -11,7 +11,7 @@ FILE(GLOB STUDIO_SRC extension_system/*.h SET(STUDIO_HDR extension_system/iplugin_manager.h extension_system/plugin_manager.h - settings_dialog.h + startup_settings_dlg.h splash_screen.h pm_watcher.h ) @@ -22,7 +22,7 @@ SET(STUDIO_TS translations/object_viewer_qt_en.ts translations/object_viewer_qt_de.ts translations/object_viewer_qt_ru.ts) -SET(STUDIO_PLUGIN_UIS settings_dialog.ui ) +SET(STUDIO_PLUGIN_UIS startup_settings_dlg.ui ) SET(QT_USE_QTGUI TRUE) SET(QT_USE_QTOPENGL TRUE) diff --git a/code/studio/src/main.cpp b/code/studio/src/main.cpp index e758037c0..dc1e7efb6 100644 --- a/code/studio/src/main.cpp +++ b/code/studio/src/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "settings_dialog.h" +#include "startup_settings_dlg.h" #include "splash_screen.h" #include "pm_watcher.h" @@ -160,7 +160,7 @@ int main(int argc, char **argv) { settings->setValue( "FirstRun", false ); - SettingsDialog sd; + StartupSettingsDlg sd; sd.setSettings( settings ); sd.load(); sd.exec(); diff --git a/code/studio/src/plugins/core/settings_dialog.h b/code/studio/src/plugins/core/settings_dialog.h index a90f88b18..9e1c86444 100644 --- a/code/studio/src/plugins/core/settings_dialog.h +++ b/code/studio/src/plugins/core/settings_dialog.h @@ -19,7 +19,7 @@ #ifndef SETTINGS_DIALOG_H #define SETTINGS_DIALOG_H -#include "../core/ui_settings_dialog.h" +#include "ui_settings_dialog.h" // Qt includes #include diff --git a/code/studio/src/settings_dialog.cpp b/code/studio/src/startup_settings_dlg.cpp similarity index 84% rename from code/studio/src/settings_dialog.cpp rename to code/studio/src/startup_settings_dlg.cpp index df2718b9b..645df7040 100644 --- a/code/studio/src/settings_dialog.cpp +++ b/code/studio/src/startup_settings_dlg.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . -#include "settings_dialog.h" +#include "startup_settings_dlg.h" #include #include #include @@ -32,7 +32,7 @@ int findListItem( QListWidget *l, const QString &s ) return -1; } -SettingsDialog::SettingsDialog( QDialog *parent ) : +StartupSettingsDlg::StartupSettingsDlg( QDialog *parent ) : QDialog( parent ) { setupUi( this ); @@ -40,11 +40,11 @@ QDialog( parent ) settings = NULL; } -SettingsDialog::~SettingsDialog() +StartupSettingsDlg::~StartupSettingsDlg() { } -void SettingsDialog::load() +void StartupSettingsDlg::load() { pluginsLE->setText( settings->value( "PluginPath" ).toString() ); @@ -82,7 +82,7 @@ void SettingsDialog::load() settings->endGroup(); } -void SettingsDialog::saveSearchPaths() +void StartupSettingsDlg::saveSearchPaths() { QStringList l; for( int i = 0; i < searchLW->count(); i++ ) @@ -93,7 +93,7 @@ void SettingsDialog::saveSearchPaths() settings->setValue( "SearchPaths", l ); } -void SettingsDialog::saveRecursivePaths() +void StartupSettingsDlg::saveRecursivePaths() { QStringList l; for( int i = 0; i < recursiveLW->count(); i++ ) @@ -104,7 +104,7 @@ void SettingsDialog::saveRecursivePaths() settings->setValue( "RecursiveSearchPathes", l ); } -void SettingsDialog::save() +void StartupSettingsDlg::save() { settings->setValue( "PluginPath", pluginsLE->text() ); @@ -123,59 +123,59 @@ void SettingsDialog::save() settings->sync(); } -void SettingsDialog::accept() +void StartupSettingsDlg::accept() { save(); QDialog::accept(); } -void SettingsDialog::reject() +void StartupSettingsDlg::reject() { QDialog::reject(); } -void SettingsDialog::onOKClicked() +void StartupSettingsDlg::onOKClicked() { accept(); } -void SettingsDialog::onCancelClicked() +void StartupSettingsDlg::onCancelClicked() { reject(); } -void SettingsDialog::onPluginBClicked() +void StartupSettingsDlg::onPluginBClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Plugins directory" ), "" ); pluginsLE->setText( p ); } -void SettingsDialog::onSheetsBClicked() +void StartupSettingsDlg::onSheetsBClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Sheets directory" ), "" ); sheetsLE->setText( p ); } -void SettingsDialog::onAssetsBClicked() +void StartupSettingsDlg::onAssetsBClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Assets directory" ), "" ); assetsLE->setText( p ); } -void SettingsDialog::onPrimitivesBClicked() +void StartupSettingsDlg::onPrimitivesBClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Primitives directory" ), "" ); primitivesLE->setText( p ); } -void SettingsDialog::onLigoBClicked() +void StartupSettingsDlg::onLigoBClicked() { QString p; p = QFileDialog::getOpenFileName( this, tr( "LIGO config file" ), "" ); ligoLE->setText( p ); } -void SettingsDialog::onPathAddClicked() +void StartupSettingsDlg::onPathAddClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Search path" ), "" ); if( p.isEmpty() ) @@ -187,7 +187,7 @@ void SettingsDialog::onPathAddClicked() searchLW->addItem( p ); } -void SettingsDialog::onPathRemoveClicked() +void StartupSettingsDlg::onPathRemoveClicked() { QListWidgetItem *i = searchLW->currentItem(); if( i == NULL ) @@ -196,7 +196,7 @@ void SettingsDialog::onPathRemoveClicked() delete i; } -void SettingsDialog::onRecursiveAddClicked() +void StartupSettingsDlg::onRecursiveAddClicked() { QString p = QFileDialog::getExistingDirectory( this, tr( "Recursive search path" ), "" ); if( p.isEmpty() ) @@ -208,7 +208,7 @@ void SettingsDialog::onRecursiveAddClicked() recursiveLW->addItem( p ); } -void SettingsDialog::onRecursiveRemoveClicked() +void StartupSettingsDlg::onRecursiveRemoveClicked() { QListWidgetItem *i = recursiveLW->currentItem(); if( i == NULL ) @@ -218,7 +218,7 @@ void SettingsDialog::onRecursiveRemoveClicked() } -void SettingsDialog::setupConnections() +void StartupSettingsDlg::setupConnections() { connect( bb, SIGNAL( accepted() ), this, SLOT( onOKClicked() ) ); connect( bb, SIGNAL( rejected() ), this, SLOT( onCancelClicked() ) ); diff --git a/code/studio/src/settings_dialog.h b/code/studio/src/startup_settings_dlg.h similarity index 84% rename from code/studio/src/settings_dialog.h rename to code/studio/src/startup_settings_dlg.h index 173ba37d4..49dd01ef7 100644 --- a/code/studio/src/settings_dialog.h +++ b/code/studio/src/startup_settings_dlg.h @@ -14,19 +14,19 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef SETTINGS_DIALOG_H -#define SETTINGS_DIALOG_H +#ifndef STARTUP_SETTINGS_DIALOG_H +#define STARTUP_SETTINGS_DIALOG_H -#include "ui_settings_dialog.h" +#include "ui_startup_settings_dlg.h" class QSettings; -class SettingsDialog : public QDialog, public Ui::SettingsDialog +class StartupSettingsDlg : public QDialog, public Ui::StartupSettingsDlg { Q_OBJECT public: - SettingsDialog( QDialog *parent = NULL ); - ~SettingsDialog(); + StartupSettingsDlg( QDialog *parent = NULL ); + ~StartupSettingsDlg(); void setSettings( QSettings *s ){ settings = s; } diff --git a/code/studio/src/settings_dialog.ui b/code/studio/src/startup_settings_dlg.ui similarity index 95% rename from code/studio/src/settings_dialog.ui rename to code/studio/src/startup_settings_dlg.ui index 2fb6151d3..5f125ed14 100644 --- a/code/studio/src/settings_dialog.ui +++ b/code/studio/src/startup_settings_dlg.ui @@ -1,7 +1,7 @@ - SettingsDialog - + StartupSettingsDlg + Qt::ApplicationModal From 44c6f93b2601f2eedfc5a2a54b2a4cf3c3f0a315 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 9 Feb 2015 19:49:16 +0100 Subject: [PATCH 217/344] We can now set whether to use OpenGL in WE in the WE settings page. For whatever reason VMware despises the OpenGL viewport so it's a good idea to turn it off inside VMware. --HG-- branch : hotfix --- .../world_editor_settings_page.cpp | 22 +++++++ .../world_editor/world_editor_settings_page.h | 1 + .../world_editor_settings_page.ui | 63 ++++++++++++++++--- .../world_editor/world_editor_window.cpp | 1 + 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/code/studio/src/plugins/world_editor/world_editor_settings_page.cpp b/code/studio/src/plugins/world_editor/world_editor_settings_page.cpp index bb8ef2a00..d3b8bb849 100644 --- a/code/studio/src/plugins/world_editor/world_editor_settings_page.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_settings_page.cpp @@ -17,9 +17,11 @@ // Project includes #include "world_editor_settings_page.h" #include "world_editor_constants.h" +#include "../core/icore.h" // Qt includes #include +#include // NeL includes @@ -61,11 +63,31 @@ QWidget *WorldEditorSettingsPage::createPage(QWidget *parent) { m_currentPage = new QWidget(parent); m_ui.setupUi(m_currentPage); + readSettings(); + return m_currentPage; } +void WorldEditorSettingsPage::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::WORLD_EDITOR_SECTION); + bool b = false; + + b = settings->value( Constants::WORLD_EDITOR_USE_OPENGL, true ).toBool(); + m_ui.glCB->setChecked( b ); + + settings->endGroup(); +} + void WorldEditorSettingsPage::apply() { + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::WORLD_EDITOR_SECTION); + bool b = false; + b = m_ui.glCB->isChecked(); + settings->setValue( Constants::WORLD_EDITOR_USE_OPENGL, b ); + settings->endGroup(); } } /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/studio/src/plugins/world_editor/world_editor_settings_page.h b/code/studio/src/plugins/world_editor/world_editor_settings_page.h index aa7677b9f..7eeb30e1d 100644 --- a/code/studio/src/plugins/world_editor/world_editor_settings_page.h +++ b/code/studio/src/plugins/world_editor/world_editor_settings_page.h @@ -46,6 +46,7 @@ public: QIcon categoryIcon() const; virtual QWidget *createPage(QWidget *parent); + virtual void readSettings(); virtual void apply(); virtual void finish() {} diff --git a/code/studio/src/plugins/world_editor/world_editor_settings_page.ui b/code/studio/src/plugins/world_editor/world_editor_settings_page.ui index 9219da6c4..a5cb12559 100644 --- a/code/studio/src/plugins/world_editor/world_editor_settings_page.ui +++ b/code/studio/src/plugins/world_editor/world_editor_settings_page.ui @@ -3,7 +3,7 @@ WorldEditorSettingsPage - false + true @@ -25,6 +25,9 @@ + + true + Workspace @@ -37,10 +40,18 @@ - + + + false + + - + + + false + + @@ -50,15 +61,32 @@ - + + + false + + - + + + false + + - + + + true + - Use OpenGL + Use OpenGL ( requires restart ) + + + true + + + false @@ -79,7 +107,11 @@ - + + + false + + @@ -89,7 +121,11 @@ - + + + false + + @@ -101,10 +137,17 @@ - + + + false + + + + false + ... diff --git a/code/studio/src/plugins/world_editor/world_editor_window.cpp b/code/studio/src/plugins/world_editor/world_editor_window.cpp index cec3baee1..6dbd07a8a 100644 --- a/code/studio/src/plugins/world_editor/world_editor_window.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_window.cpp @@ -436,6 +436,7 @@ void WorldEditorWindow::writeSettings() settings->beginGroup(Constants::WORLD_EDITOR_SECTION); settings->setValue(Constants::WORLD_WINDOW_STATE, saveState()); settings->setValue(Constants::WORLD_WINDOW_GEOMETRY, saveGeometry()); + settings->setValue(Constants::WORLD_EDITOR_USE_OPENGL, settings->value(Constants::WORLD_EDITOR_USE_OPENGL)); settings->endGroup(); settings->sync(); } From 28b0a0a04084076581e6b18385878228b86609d5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 9 Feb 2015 19:55:27 +0100 Subject: [PATCH 218/344] Change the cursor to a wait cursor when applying settings in the settings dialog. --HG-- branch : hotfix --- code/studio/src/plugins/core/settings_dialog.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/code/studio/src/plugins/core/settings_dialog.cpp b/code/studio/src/plugins/core/settings_dialog.cpp index 0b38e4e80..b1027212c 100644 --- a/code/studio/src/plugins/core/settings_dialog.cpp +++ b/code/studio/src/plugins/core/settings_dialog.cpp @@ -145,11 +145,17 @@ void SettingsDialog::pageSelected() void SettingsDialog::accept() { m_applied = true; + + setCursor( Qt::WaitCursor ); + Q_FOREACH(IOptionsPage *page, m_pages) { page->apply(); page->finish(); } + + setCursor( Qt::ArrowCursor ); + done(QDialog::Accepted); } @@ -162,8 +168,13 @@ void SettingsDialog::reject() void SettingsDialog::apply() { + setCursor( Qt::WaitCursor ); + Q_FOREACH(IOptionsPage *page, m_pages) page->apply(); + + setCursor( Qt::ArrowCursor ); + m_applied = true; } From 79cd6bfaee6ac5c8fae2d05f6ad0fa3dc2e5b2d4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 9 Feb 2015 20:07:35 +0100 Subject: [PATCH 219/344] Include rgba.h in libwww.h. Thanks Nimetu! --HG-- branch : hotfix --- code/nel/include/nel/gui/libwww.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index 6a744b8c0..bb6b2da86 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -25,6 +25,8 @@ extern "C" #include "WWWInit.h" } +#include "nel/misc/rgba.h" + namespace NLGUI { class CCtrlBaseButton; From 26f1cc6fac5c6c51a50ba0966cbf6782039c36a1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 11 Feb 2015 19:55:16 +0100 Subject: [PATCH 220/344] Added ryzom.ttf, it will be installed to the data directory. --HG-- branch : hotfix --- .../src/plugins/gui_editor/CMakeLists.txt | 2 ++ .../src/plugins/gui_editor/fonts/ryzom.ttf | Bin 0 -> 622280 bytes 2 files changed, 2 insertions(+) create mode 100644 code/studio/src/plugins/gui_editor/fonts/ryzom.ttf diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index efa0a171c..f2f5bfcb1 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -120,3 +120,5 @@ FILE(GLOB expressions "${CMAKE_CURRENT_SOURCE_DIR}/expressions/*.xml") INSTALL(FILES ${widgets} DESTINATION "${OVQT_DATA_DIR}/widgets" COMPONENT tools3d) INSTALL(FILES ${expressions} DESTINATION "${OVQT_DATA_DIR}/expressions" COMPONENT tools3d) + +INSTALL(DIRECTORY fonts/ DESTINATION ${OVQT_DATA_DIR} COMPONENT data) diff --git a/code/studio/src/plugins/gui_editor/fonts/ryzom.ttf b/code/studio/src/plugins/gui_editor/fonts/ryzom.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c1b19d870590a7bbf0d238e0cefdce6689d3f342 GIT binary patch literal 622280 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
geGW9*=zyyC*n=}kiVSWwCU|u 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
  • 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 literal 0 HcmV?d00001 From b381ef6faed812d827311acc22572664383ed1ff Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 11 Feb 2015 20:42:31 +0100 Subject: [PATCH 221/344] Add the data directory to the search path. --HG-- branch : hotfix --- code/studio/src/plugins/core/CMakeLists.txt | 4 ++++ code/studio/src/plugins/core/core_config.h.cmake | 7 +++++++ .../src/plugins/core/search_paths_settings_page.cpp | 10 +++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 code/studio/src/plugins/core/core_config.h.cmake diff --git a/code/studio/src/plugins/core/CMakeLists.txt b/code/studio/src/plugins/core/CMakeLists.txt index 2c21c9b58..db99b807c 100644 --- a/code/studio/src/plugins/core/CMakeLists.txt +++ b/code/studio/src/plugins/core/CMakeLists.txt @@ -38,6 +38,10 @@ SET(OVQT_CORE_PLUGIN_UIS settings_dialog.ui SET(OVQT_CORE_PLUGIN_RCS core.qrc) +IF(NOT WIN32) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/core_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/core_config.h) +ENDIF(NOT WIN32) + SET(QT_USE_QTGUI TRUE) SET(QT_USE_QTOPENGL TRUE) diff --git a/code/studio/src/plugins/core/core_config.h.cmake b/code/studio/src/plugins/core/core_config.h.cmake new file mode 100644 index 000000000..1aab54c12 --- /dev/null +++ b/code/studio/src/plugins/core/core_config.h.cmake @@ -0,0 +1,7 @@ +#ifndef CORE_CONFIG_H +#define CORE_CONFIG_H + +#define STUDIO_DATA_DIR "${OVQT_IMP_DATA_DIR}" + +#endif + diff --git a/code/studio/src/plugins/core/search_paths_settings_page.cpp b/code/studio/src/plugins/core/search_paths_settings_page.cpp index e76d6c796..516d3d3f3 100644 --- a/code/studio/src/plugins/core/search_paths_settings_page.cpp +++ b/code/studio/src/plugins/core/search_paths_settings_page.cpp @@ -28,6 +28,10 @@ #include #include +#if !defined NL_OS_WINDOWS +#include "core_config.h" +#endif + namespace Core { @@ -118,6 +122,10 @@ void SearchPathsSettingsPage::applySearchPaths() for (int i = 1; i < remapExt.size(); i += 2) NLMISC::CPath::remapExtension(remapExt.at(i - 1).toUtf8().constData(), remapExt.at(i).toUtf8().constData(), true); +#if !defined NL_OS_WINDOWS + NLMISC::CPath::addSearchPath(std::string(STUDIO_DATA_DIR), false, false); +#endif + Q_FOREACH(QString path, paths) { NLMISC::CPath::addSearchPath(path.toUtf8().constData(), m_recurse, false); @@ -216,4 +224,4 @@ void SearchPathsSettingsPage::checkEnabledButton() m_ui.downToolButton->setEnabled(bEnabled); } -} /* namespace Core */ \ No newline at end of file +} /* namespace Core */ From eb5fecf8cead89f3242981e00daed63ecda70f41 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:06:19 +0100 Subject: [PATCH 222/344] Fixed: Only keep Release and Debug configurations in CMake --HG-- branch : hotfix --- code/CMakeModules/nel.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 0474c7d7b..fd7004884 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -6,6 +6,9 @@ IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) +# Declare CMAKE_CONFIGURATION_TYPES before PROJECT +SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) + ### # Helper macro that generates .pc and installs it. # Argument: name - the name of the .pc package, e.g. "nel-pacs.pc" @@ -384,8 +387,6 @@ MACRO(NL_SETUP_BUILD) # Debug = NL_DEBUG # Release = NL_RELEASE - SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) - IF(CMAKE_BUILD_TYPE MATCHES "Debug") SET(NL_BUILD_MODE "NL_DEBUG") ELSE(CMAKE_BUILD_TYPE MATCHES "Debug") From 3039428094fce5a5c9dd183d1db8b62aa821272c Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:41:59 +0100 Subject: [PATCH 223/344] Fixed: Compilation warnings --HG-- branch : hotfix --- code/nel/include/nel/3d/track_tcb.h | 2 +- code/nel/src/georges/form_elm.cpp | 2 +- code/ryzom/server/src/admin_modules/aes_module.cpp | 2 +- code/ryzom/server/src/ai_share/aids_messages.h | 4 ++-- .../entities_game_service/game_item_manager/game_item.cpp | 6 +++--- .../src/input_output_service/string_manager_parser.cpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/nel/include/nel/3d/track_tcb.h b/code/nel/include/nel/3d/track_tcb.h index e91cfb397..153dcbc54 100644 --- a/code/nel/include/nel/3d/track_tcb.h +++ b/code/nel/include/nel/3d/track_tcb.h @@ -218,7 +218,7 @@ protected: date*= previous->OODeltaTime; NLMISC::clamp(date, 0,1); - date = this->ease(previous, date); + date = this->ease(previous, (float)date); float hb[4]; this->computeHermiteBasis(date, hb); diff --git a/code/nel/src/georges/form_elm.cpp b/code/nel/src/georges/form_elm.cpp index 658d1d9f6..01e4010e2 100644 --- a/code/nel/src/georges/form_elm.cpp +++ b/code/nel/src/georges/form_elm.cpp @@ -231,7 +231,7 @@ bool CFormElm::isAtom () const const CType* CFormElm::getType () { warning (false, "getType", "This node is not an atom."); - return 0; + return NULL; } // *************************************************************************** diff --git a/code/ryzom/server/src/admin_modules/aes_module.cpp b/code/ryzom/server/src/admin_modules/aes_module.cpp index c4faf5c47..6a45e302d 100644 --- a/code/ryzom/server/src/admin_modules/aes_module.cpp +++ b/code/ryzom/server/src/admin_modules/aes_module.cpp @@ -573,7 +573,7 @@ namespace ADMIN time_t t = now; fprintf(fp, "AESReportDate=%s", ::ctime(&t)); - fprintf(fp, "NBService=%u\n", _ServiceStates.size()); + fprintf(fp, "NBService=%u\n", (uint)_ServiceStates.size()); // output state of each service TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); for (; first != last; ++first) diff --git a/code/ryzom/server/src/ai_share/aids_messages.h b/code/ryzom/server/src/ai_share/aids_messages.h index 7ef43817b..76283ec04 100644 --- a/code/ryzom/server/src/ai_share/aids_messages.h +++ b/code/ryzom/server/src/ai_share/aids_messages.h @@ -101,12 +101,12 @@ public: { } - CMsgAIFeedback(std::string message) + CMsgAIFeedback(const std::string &message) { Message=message; } - CMsgAIFeedback(char *msgStr) + CMsgAIFeedback(const char *msgStr) { Message=std::string(msgStr); } diff --git a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp index 30ff4acae..e36a4382e 100644 --- a/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp +++ b/code/ryzom/server/src/entities_game_service/game_item_manager/game_item.cpp @@ -242,11 +242,11 @@ float CItemCraftParameters::getCraftParameterValue( RM_FABER_STAT_TYPE::TRMStatT case RM_FABER_STAT_TYPE::ShockWaveProtection: case RM_FABER_STAT_TYPE::PoisonProtection: case RM_FABER_STAT_TYPE::ElectricityProtection: - if (Protection1 == statType) + if (Protection1 == (PROTECTION_TYPE::TProtectionType)statType) return Protection1Factor; - else if (Protection2 == statType) + else if (Protection2 == (PROTECTION_TYPE::TProtectionType)statType) return Protection2Factor; - else if (Protection3 == statType) + else if (Protection3 == (PROTECTION_TYPE::TProtectionType)statType) return Protection3Factor; else return 0.0f; case RM_FABER_STAT_TYPE::DesertResistance: diff --git a/code/ryzom/server/src/input_output_service/string_manager_parser.cpp b/code/ryzom/server/src/input_output_service/string_manager_parser.cpp index 67ce62f10..0cbfbf595 100644 --- a/code/ryzom/server/src/input_output_service/string_manager_parser.cpp +++ b/code/ryzom/server/src/input_output_service/string_manager_parser.cpp @@ -650,7 +650,7 @@ bool CStringManager::parseBlock(const ucstring &block, CPhrase &phrase) && (first - clause.String.begin()) == (sint) clause.Replacements[repCount].InsertPlace) { // check parameter type - char *subst; + const char *subst; uint paramIndex = clause.Replacements[repCount].ParamIndex; TParamId ¶mId = phrase.Params[paramIndex]->ParamId; From 685349759349863ff7bf30f0643da5a915e13e76 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:43:29 +0100 Subject: [PATCH 224/344] Changed: Replaced atof by NLMISC::fromString --HG-- branch : hotfix --- .../ryzom/server/src/entities_game_service/zone_manager.cpp | 2 +- .../server/src/persistant_data_service/pds_database.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/zone_manager.cpp b/code/ryzom/server/src/entities_game_service/zone_manager.cpp index dd9e817b1..f55222dca 100644 --- a/code/ryzom/server/src/entities_game_service/zone_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/zone_manager.cpp @@ -201,7 +201,7 @@ bool CTpSpawnZone::build(const NLLIGO::CPrimPoint * point) nlwarning(" : no z in CTpSpawnZone '%s'",_Name.c_str() ); return false; } - Point.z = ( float ) atof( value.c_str() ); + NLMISC::fromString(value, Point.z); Point.z = float( sint32 (1000.0f* Point.z) ); } else diff --git a/code/ryzom/server/src/persistant_data_service/pds_database.cpp b/code/ryzom/server/src/persistant_data_service/pds_database.cpp index 66b272d5c..84148220b 100644 --- a/code/ryzom/server/src/persistant_data_service/pds_database.cpp +++ b/code/ryzom/server/src/persistant_data_service/pds_database.cpp @@ -905,14 +905,16 @@ bool CDatabase::set(RY_PDS::TTableIndex table, RY_PDS::TRowIndex row, RY_PDS::TC case PDS_float: { - float data = (float)atof(value.c_str()); + float data; + NLMISC::fromString(value, data); return set(table, row, column, sizeof(data), &data); } break; case PDS_double: { - double data = (double)atof(value.c_str()); + double data; + NLMISC::fromString(value, data); return set(table, row, column, sizeof(data), &data); } break; From b0937ec02b3bd07cd6cbac0b5ba32a9bb000dc92 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:47:03 +0100 Subject: [PATCH 225/344] Changed: Minor changes --HG-- branch : hotfix --- code/nel/src/gui/libwww_nel_stream.cpp | 375 ++++++++++-------- .../tools/3d/panoply_maker/color_modifier.cpp | 2 - code/ryzom/client/src/session_browser_impl.h | 1 - .../ryzom/server/src/ai_share/aids_messages.h | 3 +- .../src/server_share/used_continent.cpp | 3 +- 5 files changed, 210 insertions(+), 174 deletions(-) diff --git a/code/nel/src/gui/libwww_nel_stream.cpp b/code/nel/src/gui/libwww_nel_stream.cpp index f6a45cf06..b7e218b30 100644 --- a/code/nel/src/gui/libwww_nel_stream.cpp +++ b/code/nel/src/gui/libwww_nel_stream.cpp @@ -21,7 +21,7 @@ extern "C" { - /* Library Includes */ +/* Library Includes */ #include "wwwsys.h" #include "WWWUtil.h" #include "WWWCore.h" @@ -41,8 +41,9 @@ using namespace NLMISC; extern "C" { - /* Final states have negative value */ -typedef enum _FileState { +/* Final states have negative value */ +typedef enum _FileState +{ FS_RETRY = -4, FS_ERROR = -3, FS_NO_DATA = -2, @@ -57,26 +58,29 @@ typedef enum _FileState { } FileState; /* This is the context structure for the this module */ -typedef struct _file_info { - FileState state; /* Current state of the connection */ - char * local; /* Local representation of file name */ - struct stat stat_info; /* Contains actual file chosen */ +typedef struct _file_info +{ + FileState state; /* Current state of the connection */ + char * local; /* Local representation of file name */ + struct stat stat_info; /* Contains actual file chosen */ HTNet * net; HTTimer * timer; } file_info; -struct _HTStream { +struct _HTStream +{ const HTStreamClass * isa; }; -struct _HTInputStream { +struct _HTInputStream +{ const HTInputStreamClass * isa; HTChannel * ch; HTHost * host; - char * write; /* Last byte written */ - char * read; /* Last byte read */ + char * write; /* Last byte written */ + char * read; /* Last byte read */ int b_read; - char data [INPUT_BUFFER_SIZE]; /* buffer */ + char data [INPUT_BUFFER_SIZE]; /* buffer */ }; PRIVATE int FileCleanup (HTRequest *req, int status) @@ -96,7 +100,7 @@ PRIVATE int FileCleanup (HTRequest *req, int status) } /* - ** Remove if we have registered a timer function as a callback + ** Remove if we have registered a timer function as a callback */ if (file->timer) { @@ -123,10 +127,8 @@ PUBLIC int HTLoadNeLFile (SOCKET soc, HTRequest * request) HTNet * net = HTRequest_net(request); HTParentAnchor * anchor = HTRequest_anchor(request); - HTTRACE(PROT_TRACE, "HTLoadFile.. Looking for `%s\'\n" _ - HTAnchor_physical(anchor)); - if ((file = (file_info *) HT_CALLOC(1, sizeof(file_info))) == NULL) - HT_OUTOFMEM((char*)"HTLoadFILE"); + HTTRACE(PROT_TRACE, "HTLoadFile.. Looking for `%s\'\n" _ HTAnchor_physical(anchor)); + if ((file = (file_info *) HT_CALLOC(1, sizeof(file_info))) == NULL) HT_OUTOFMEM("HTLoadFILE"); file->state = FS_BEGIN; file->net = net; HTNet_setContext(net, file); @@ -139,8 +141,8 @@ PUBLIC int HTLoadNeLFile (SOCKET soc, HTRequest * request) PRIVATE int ReturnEvent (HTTimer * timer, void * param, HTEventType /* type */) { file_info * file = (file_info *) param; - if (timer != file->timer) - HTDEBUGBREAK((char*)"File timer %p not in sync\n" _ timer); + if (timer != file->timer) HTDEBUGBREAK("File timer %p not in sync\n" _ timer); + HTTRACE(PROT_TRACE, "HTLoadFile.. Continuing %p with timer %p\n" _ file _ timer); /* @@ -163,7 +165,7 @@ PUBLIC int HTNeLFileOpen (HTNet * net, char * local, HTLocalMode /* mode */) if (!fp->open (local)) { - HTRequest_addSystemError(request, ERR_FATAL, errno, NO, (char*)"CIFile::open"); + HTRequest_addSystemError(request, ERR_FATAL, errno, NO, "CIFile::open"); return HT_ERROR; } @@ -186,7 +188,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) { /* Interrupted */ HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED, - NULL, 0, (char*)"HTLoadFile"); + NULL, 0, "HTLoadFile"); FileCleanup(request, HT_INTERRUPTED); return HT_OK; } @@ -202,7 +204,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) /* We only support safe (GET, HEAD, etc) methods for the moment */ if (!HTMethod_isSafe(HTRequest_method(request))) { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_ALLOWED, - NULL, 0, (char*)"HTLoadFile"); + NULL, 0, "HTLoadFile"); file->state = FS_ERROR; break; } @@ -234,166 +236,188 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) /* Create a new host object and link it to the net object */ { - HTHost * host = NULL; - if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR; - HTNet_setHost(net, host); - if (HTHost_addNet(host, net) == HT_PENDING) { - HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); - /* move to the hack state */ - file->state = FS_PENDING; - return HT_OK; - } + HTHost * host = NULL; + if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR; + HTNet_setHost(net, host); + if (HTHost_addNet(host, net) == HT_PENDING) + { + HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); + /* move to the hack state */ + file->state = FS_PENDING; + return HT_OK; + } } file->state = FS_DO_CN; break; case FS_PENDING: { - HTHost * host = NULL; - if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR; - HTNet_setHost(net, host); - if (HTHost_addNet(host, net) == HT_PENDING) { - HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); - file->state = FS_PENDING; - return HT_OK; - } + HTHost * host = NULL; + if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR; + HTNet_setHost(net, host); + if (HTHost_addNet(host, net) == HT_PENDING) + { + HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); + file->state = FS_PENDING; + return HT_OK; + } } file->state = FS_DO_CN; break; case FS_DO_CN: if (HTRequest_negotiation(request) && - HTMethod_isSafe(HTRequest_method(request))) { - - HTAnchor_setPhysical(anchor, file->local); - HTTRACE(PROT_TRACE, "Load File... Found `%s\'\n" _ file->local); - - } else { - if (HT_STAT(file->local, &file->stat_info) == -1) { - HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local); - HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND, - NULL, 0, (char*)"HTLoadFile"); - file->state = FS_ERROR; - break; + HTMethod_isSafe(HTRequest_method(request))) + { + HTAnchor_setPhysical(anchor, file->local); + HTTRACE(PROT_TRACE, "Load File... Found `%s\'\n" _ file->local); } + else + { + if (HT_STAT(file->local, &file->stat_info) == -1) + { + HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local); + HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND, NULL, 0, "HTLoadFile"); + file->state = FS_ERROR; + break; + } } - if (((file->stat_info.st_mode) & S_IFMT) == S_IFDIR) { - if (HTRequest_method(request) == METHOD_GET) - file->state = FS_PARSE_DIR; - else { - HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, - NULL, 0, (char*)"HTLoadFile"); - file->state = FS_NO_DATA; - } - break; + if (((file->stat_info.st_mode) & S_IFMT) == S_IFDIR) + { + if (HTRequest_method(request) == METHOD_GET) + { + file->state = FS_PARSE_DIR; + } + else + { + HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, NULL, 0, "HTLoadFile"); + file->state = FS_NO_DATA; + } + break; } { - BOOL editable = FALSE; - HTBind_getAnchorBindings(anchor); - if (editable) HTAnchor_appendAllow(anchor, METHOD_PUT); + BOOL editable = FALSE; + HTBind_getAnchorBindings(anchor); + if (editable) HTAnchor_appendAllow(anchor, METHOD_PUT); - /* Set the file size */ - CIFile nelFile; - if (nelFile.open (file->local)) - { - file->stat_info.st_size = nelFile.getFileSize(); - } - nelFile.close(); - - if (file->stat_info.st_size) - HTAnchor_setLength(anchor, file->stat_info.st_size); - - /* Set the file last modified time stamp */ - if (file->stat_info.st_mtime > 0) - HTAnchor_setLastModified(anchor, file->stat_info.st_mtime); - - /* Check to see if we can edit it */ - if (!editable && !file->stat_info.st_size) { - HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, - NULL, 0, (char*)"HTLoadFile"); - file->state = FS_NO_DATA; - } else { - file->state = (HTRequest_method(request)==METHOD_GET) ? - FS_NEED_OPEN_FILE : FS_GOT_DATA; - } + /* Set the file size */ + CIFile nelFile; + if (nelFile.open (file->local)) + { + file->stat_info.st_size = nelFile.getFileSize(); + } + nelFile.close(); + + if (file->stat_info.st_size) + HTAnchor_setLength(anchor, file->stat_info.st_size); + + /* Set the file last modified time stamp */ + if (file->stat_info.st_mtime > 0) + HTAnchor_setLastModified(anchor, file->stat_info.st_mtime); + + /* Check to see if we can edit it */ + if (!editable && !file->stat_info.st_size) + { + HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, NULL, 0, "HTLoadFile"); + file->state = FS_NO_DATA; + } + else + { + file->state = (HTRequest_method(request)==METHOD_GET) ? FS_NEED_OPEN_FILE : FS_GOT_DATA; + } } break; case FS_NEED_OPEN_FILE: status = HTNeLFileOpen(net, file->local, HT_FB_RDONLY); - if (status == HT_OK) { + if (status == HT_OK) { - HTStream * rstream = HTStreamStack(HTAnchor_format(anchor), - HTRequest_outputFormat(request), - HTRequest_outputStream(request), - request, YES); - HTNet_setReadStream(net, rstream); - HTRequest_setOutputConnected(request, YES); - } + { + HTStream * rstream = HTStreamStack(HTAnchor_format(anchor), + HTRequest_outputFormat(request), + HTRequest_outputStream(request), + request, YES); + HTNet_setReadStream(net, rstream); + HTRequest_setOutputConnected(request, YES); + } - { - HTOutputStream * output = HTNet_getOutput(net, NULL, 0); - HTRequest_setInputStream(request, (HTStream *) output); - } + { + HTOutputStream * output = HTNet_getOutput(net, NULL, 0); + HTRequest_setInputStream(request, (HTStream *) output); + } - if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request)) - return HT_OK; - HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, - (char*)"HTLoadFile"); - file->state = FS_NEED_BODY; - - if (HTEvent_isCallbacksRegistered()) { - if (!HTRequest_preemptive(request)) { - if (!HTNet_preemptive(net)) { - HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n"); - HTHost_register(HTNet_host(net), net, HTEvent_READ); - } else if (!file->timer) { - HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n"); - file->timer = - HTTimer_new(NULL, ReturnEvent, file, 1, YES, NO); + if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request)) return HT_OK; + + HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, "HTLoadFile"); + file->state = FS_NEED_BODY; + + if (HTEvent_isCallbacksRegistered()) + { + if (!HTRequest_preemptive(request)) + { + if (!HTNet_preemptive(net)) + { + HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n"); + HTHost_register(HTNet_host(net), net, HTEvent_READ); + } + else if (!file->timer) + { + HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n"); + file->timer = HTTimer_new(NULL, ReturnEvent, file, 1, YES, NO); + } + return HT_OK; + } } + } + else if (status == HT_WOULD_BLOCK || status == HT_PENDING) + { return HT_OK; - } } - } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) - return HT_OK; - else { - HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL, - NULL, 0, (char*)"HTLoadFile"); - file->state = FS_ERROR; /* Error or interrupt */ + else + { + HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL, NULL, 0, "HTLoadFile"); + file->state = FS_ERROR; /* Error or interrupt */ } break; - case FS_NEED_BODY: + case FS_NEED_BODY: status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) - return HT_OK; - else if (status == HT_LOADED || status == HT_CLOSED) { - file->state = FS_GOT_DATA; - } else { - HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN, - NULL, 0, (char*)"HTLoadFile"); - file->state = FS_ERROR; + { + return HT_OK; + } + else if (status == HT_LOADED || status == HT_CLOSED) + { + file->state = FS_GOT_DATA; + } + else + { + HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN, NULL, 0, "HTLoadFile"); + file->state = FS_ERROR; } break; case FS_TRY_FTP: { - char *url = HTAnchor_physical(anchor); - HTAnchor *anchor; - char *newname = NULL; - StrAllocCopy(newname, "ftp:"); - if (!strncmp(url, "file:", 5)) - StrAllocCat(newname, url+5); - else - StrAllocCat(newname, url); - anchor = HTAnchor_findAddress(newname); - HTRequest_setAnchor(request, anchor); - HT_FREE(newname); - FileCleanup(request, HT_IGNORE); - return HTLoad(request, YES); + char *url = HTAnchor_physical(anchor); + HTAnchor *anchor; + char *newname = NULL; + StrAllocCopy(newname, "ftp:"); + if (!strncmp(url, "file:", 5)) + { + StrAllocCat(newname, url+5); + } + else + { + StrAllocCat(newname, url); + } + anchor = HTAnchor_findAddress(newname); + HTRequest_setAnchor(request, anchor); + HT_FREE(newname); + FileCleanup(request, HT_IGNORE); + return HTLoad(request, YES); } break; @@ -461,7 +485,8 @@ PRIVATE int HTNeLReader_read (HTInputStream * me) { HTAlertCallback * cbf = HTAlert_find(HT_PROG_READ); HTNet_addBytesRead(net, me->b_read); - if (cbf) { + if (cbf) + { int tr = HTNet_bytesRead(net); (*cbf)(net->request, HT_PROG_READ, HT_MSG_NULL, NULL, &tr, NULL); } @@ -472,18 +497,28 @@ PRIVATE int HTNeLReader_read (HTInputStream * me) /* Now push the data down the stream */ if ((status = (*net->readStream->isa->put_block) - (net->readStream, me->data, me->b_read)) != HT_OK) { - if (status == HT_WOULD_BLOCK) { + (net->readStream, me->data, me->b_read)) != HT_OK) + { + if (status == HT_WOULD_BLOCK) + { HTTRACE(PROT_TRACE, "ANSI read... Target WOULD BLOCK\n"); return HT_WOULD_BLOCK; - } else if (status == HT_PAUSE) { + } + else if (status == HT_PAUSE) + { HTTRACE(PROT_TRACE, "ANSI read... Target PAUSED\n"); return HT_PAUSE; - } else if (status > 0) { /* Stream specific return code */ + } + else if (status > 0) + { + /* Stream specific return code */ HTTRACE(PROT_TRACE, "ANSI read... Target returns %d\n" _ status); me->write = me->data + me->b_read; return status; - } else { /* We have a real error */ + } + else + { + /* We have a real error */ HTTRACE(PROT_TRACE, "ANSI read... Target ERROR\n"); return status; } @@ -506,13 +541,15 @@ PRIVATE int HTNeLReader_close (HTInputStream * me) HTNet * net = HTHost_getReadNet(me->host); - if (net && net->readStream) { - if ((status = (*net->readStream->isa->_free)(net->readStream))==HT_WOULD_BLOCK) - return HT_WOULD_BLOCK; - net->readStream = NULL; + if (net && net->readStream) + { + if ((status = (*net->readStream->isa->_free)(net->readStream))==HT_WOULD_BLOCK) return HT_WOULD_BLOCK; + net->readStream = NULL; } + HTTRACE(STREAM_TRACE, "Socket read. FREEING....\n"); HT_FREE(me); + return status; } @@ -540,7 +577,8 @@ PRIVATE int HTNeLReader_free (HTInputStream * me) } HTNet * net = HTHost_getReadNet(me->host); - if (net && net->readStream) { + if (net && net->readStream) + { int status = (*net->readStream->isa->_free)(net->readStream); if (status == HT_OK) net->readStream = NULL; return status; @@ -551,7 +589,8 @@ PRIVATE int HTNeLReader_free (HTInputStream * me) PRIVATE int HTNeLReader_abort (HTInputStream * me, HTList * /* e */) { HTNet * net = HTHost_getReadNet(me->host); - if (net && net->readStream) { + if (net && net->readStream) + { int status = (*net->readStream->isa->abort)(net->readStream, NULL); if (status != HT_IGNORE) net->readStream = NULL; } @@ -560,7 +599,7 @@ PRIVATE int HTNeLReader_abort (HTInputStream * me, HTList * /* e */) PRIVATE const HTInputStreamClass HTNeLReader = { - (char*)"SocketReader", + "SocketReader", HTNeLReader_flush, HTNeLReader_free, HTNeLReader_abort, @@ -569,20 +608,20 @@ PRIVATE const HTInputStreamClass HTNeLReader = HTNeLReader_consumed }; -PUBLIC HTInputStream * HTNeLReader_new (HTHost * host, HTChannel * ch, - void * /* param */, int /* mode */) +PUBLIC HTInputStream * HTNeLReader_new (HTHost * host, HTChannel * ch, void * /* param */, int /* mode */) { - if (host && ch) { - HTInputStream * me = HTChannel_input(ch); - if (me == NULL) { - if ((me=(HTInputStream *) HT_CALLOC(1, sizeof(HTInputStream))) == NULL) - HT_OUTOFMEM((char*)"HTNeLReader_new"); - me->isa = &HTNeLReader; - me->ch = ch; - me->host = host; - HTTRACE(STREAM_TRACE, "Reader...... Created reader stream %p\n" _ me); - } - return me; + if (host && ch) + { + HTInputStream * me = HTChannel_input(ch); + if (me == NULL) + { + if ((me=(HTInputStream *) HT_CALLOC(1, sizeof(HTInputStream))) == NULL) HT_OUTOFMEM("HTNeLReader_new"); + me->isa = &HTNeLReader; + me->ch = ch; + me->host = host; + HTTRACE(STREAM_TRACE, "Reader...... Created reader stream %p\n" _ me); + } + return me; } return NULL; } diff --git a/code/nel/tools/3d/panoply_maker/color_modifier.cpp b/code/nel/tools/3d/panoply_maker/color_modifier.cpp index 3c4b1814d..a55936b7c 100644 --- a/code/nel/tools/3d/panoply_maker/color_modifier.cpp +++ b/code/nel/tools/3d/panoply_maker/color_modifier.cpp @@ -70,7 +70,6 @@ void CColorModifier::convertBitmap(NLMISC::CBitmap &destBitmap, const NLMISC::CB // blend to the destination by using the mask alpha result.blendFromui(*dest, result, mask->R); - /// keep alpha from the source dest->R = result.R; @@ -78,7 +77,6 @@ void CColorModifier::convertBitmap(NLMISC::CBitmap &destBitmap, const NLMISC::CB dest->B = result.B; dest->A = src->A; - ++ mask; ++ src; ++ dest; diff --git a/code/ryzom/client/src/session_browser_impl.h b/code/ryzom/client/src/session_browser_impl.h index 6235128b0..68f2de29d 100644 --- a/code/ryzom/client/src/session_browser_impl.h +++ b/code/ryzom/client/src/session_browser_impl.h @@ -21,7 +21,6 @@ #include "session_browser.h" #include "game_share/ring_session_manager_itf.h" #include "nel/gui/lua_helper.h" -using namespace NLGUI; #include "far_tp.h" class CSessionBrowserImpl : public CSessionBrowser, diff --git a/code/ryzom/server/src/ai_share/aids_messages.h b/code/ryzom/server/src/ai_share/aids_messages.h index 76283ec04..734acbec3 100644 --- a/code/ryzom/server/src/ai_share/aids_messages.h +++ b/code/ryzom/server/src/ai_share/aids_messages.h @@ -97,7 +97,7 @@ class CMsgAIFeedback : public NLNET::CTransportClass public: std::string Message; - CMsgAIFeedback() + CMsgAIFeedback() { } @@ -120,6 +120,5 @@ public: virtual void callback (const std::string &name, NLNET::TServiceId id); }; - #endif diff --git a/code/ryzom/server/src/server_share/used_continent.cpp b/code/ryzom/server/src/server_share/used_continent.cpp index 01ab2beda..9e9a310d9 100644 --- a/code/ryzom/server/src/server_share/used_continent.cpp +++ b/code/ryzom/server/src/server_share/used_continent.cpp @@ -17,8 +17,9 @@ #include "stdpch.h" -#include #include "used_continent.h" +#include "nel/net/service.h" + using namespace std; using namespace NLMISC; From 4de072865b82a38943fedec2768f9bf31294c59c Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:47:54 +0100 Subject: [PATCH 226/344] Changed: Check getSpawn() before calling its methods --HG-- branch : hotfix --- code/ryzom/server/src/ai_service/ai_bot_npc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp b/code/ryzom/server/src/ai_service/ai_bot_npc.cpp index cb183850e..8a7518709 100644 --- a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp +++ b/code/ryzom/server/src/ai_service/ai_bot_npc.cpp @@ -714,9 +714,12 @@ void CBotNpc::sendVPA() // alternate VPA void CBotNpc::sendVisualProperties() // VisualPropertyA, B, C { - CMirrors::setVisualPropertyA( getSpawn()->dataSetRow(), _VisualPropertyA ); - CMirrors::setVisualPropertyB( getSpawn()->dataSetRow(), _VisualPropertyB ); - CMirrors::setVisualPropertyC( getSpawn()->dataSetRow(), _VisualPropertyC ); + if (getSpawn()) + { + CMirrors::setVisualPropertyA( getSpawn()->dataSetRow(), _VisualPropertyA ); + CMirrors::setVisualPropertyB( getSpawn()->dataSetRow(), _VisualPropertyB ); + CMirrors::setVisualPropertyC( getSpawn()->dataSetRow(), _VisualPropertyC ); + } } bool CBotNpc::reSpawn(bool sendMessage) From 165524d1df843cdf6032d6880fbfda8951e466b1 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:48:29 +0100 Subject: [PATCH 227/344] Changed: Used PCH for admin_modules --HG-- branch : hotfix --- code/ryzom/server/src/admin_modules/CMakeLists.txt | 4 ++++ code/ryzom/server/src/admin_modules/admin_modules_itf.cpp | 1 + code/ryzom/server/src/admin_modules/aes_client_module.cpp | 1 + code/ryzom/server/src/admin_modules/aes_module.cpp | 1 + code/ryzom/server/src/admin_modules/as_module.cpp | 1 + 5 files changed, 8 insertions(+) diff --git a/code/ryzom/server/src/admin_modules/CMakeLists.txt b/code/ryzom/server/src/admin_modules/CMakeLists.txt index ea8d8a5ff..9809b2f29 100644 --- a/code/ryzom/server/src/admin_modules/CMakeLists.txt +++ b/code/ryzom/server/src/admin_modules/CMakeLists.txt @@ -11,4 +11,8 @@ NL_ADD_LIB_SUFFIX(ryzom_adminmodules) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +IF(WITH_PCH) + ADD_NATIVE_PRECOMPILED_HEADER(ryzom_adminmodules ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) +ENDIF(WITH_PCH) + INSTALL(TARGETS ryzom_adminmodules LIBRARY DESTINATION ${RYZOM_LIB_PREFIX} ARCHIVE DESTINATION ${RYZOM_LIB_PREFIX} COMPONENT libraries) diff --git a/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp b/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp index 258409d16..39dfc6948 100644 --- a/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp +++ b/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp @@ -18,6 +18,7 @@ // WARNING : this is a generated file, don't change it ! ///////////////////////////////////////////////////////////////// +#include "stdpch.h" #include "admin_modules_itf.h" namespace ADMIN diff --git a/code/ryzom/server/src/admin_modules/aes_client_module.cpp b/code/ryzom/server/src/admin_modules/aes_client_module.cpp index e2b9ca390..66dddbe1e 100644 --- a/code/ryzom/server/src/admin_modules/aes_client_module.cpp +++ b/code/ryzom/server/src/admin_modules/aes_client_module.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . +#include "stdpch.h" #include "nel/misc/singleton.h" #include "nel/net/module.h" #include "nel/net/module_builder_parts.h" diff --git a/code/ryzom/server/src/admin_modules/aes_module.cpp b/code/ryzom/server/src/admin_modules/aes_module.cpp index 6a45e302d..734dfff64 100644 --- a/code/ryzom/server/src/admin_modules/aes_module.cpp +++ b/code/ryzom/server/src/admin_modules/aes_module.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . +#include "stdpch.h" #include "nel/misc/singleton.h" #include #include "nel/misc/path.h" diff --git a/code/ryzom/server/src/admin_modules/as_module.cpp b/code/ryzom/server/src/admin_modules/as_module.cpp index cbe1b2818..9717da358 100644 --- a/code/ryzom/server/src/admin_modules/as_module.cpp +++ b/code/ryzom/server/src/admin_modules/as_module.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "nel/misc/types_nl.h" #include #include "nel/misc/file.h" From 6e1abd80d3a569812a20b04c7934de7972da9ba8 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:52:57 +0100 Subject: [PATCH 228/344] Fixed: Unable to patch when Ryzom was located on a mounted FS --HG-- branch : hotfix --- code/ryzom/client/src/login_patch.cpp | 10 +++++----- code/ryzom/client/src/login_patch.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index 5b9a83c83..e98cd1e32 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -1068,12 +1068,12 @@ float CPatchManager::getCurrentFileProgress() const } // **************************************************************************** -void CPatchManager::setRWAccess (const string &filename) +void CPatchManager::setRWAccess (const string &filename, bool bThrowException) { ucstring s = CI18N::get("uiSetAttrib") + " " + filename; setState(true, s); - if (!NLMISC::CFile::setRWAccess(filename)) + if (!NLMISC::CFile::setRWAccess(filename) && bThrowException) { s = CI18N::get("uiAttribErr") + " " + filename + " (" + toString(errno) + "," + strerror(errno) + ")"; setState(true, s); @@ -1351,7 +1351,7 @@ void CPatchManager::downloadFileWithCurl (const string &source, const string &de // create the local file if (NLMISC::CFile::fileExists(dest)) { - setRWAccess(dest); + setRWAccess(dest, false); NLMISC::CFile::deleteFile(dest.c_str()); } FILE *fp = fopen (dest.c_str(), "wb"); @@ -1492,7 +1492,7 @@ void CPatchManager::decompressFile (const string &filename) } string dest = filename.substr(0, filename.size ()-4); - setRWAccess(dest); + setRWAccess(dest, false); //if(isVerboseLog()) nlinfo("Calling fopen('%s','wb')", dest.c_str()); FILE *fp = fopen (dest.c_str(), "wb"); if (fp == NULL) @@ -1566,7 +1566,7 @@ void CPatchManager::applyDate (const string &sFilename, uint32 nDate) { // _utimbuf utb; // utb.actime = utb.modtime = nDate; - setRWAccess(sFilename); + setRWAccess(sFilename, false); ucstring s = CI18N::get("uiChangeDate") + " " + NLMISC::CFile::getFilename(sFilename) + " " + toString(NLMISC::CFile::getFileModificationDate (sFilename)) + " -> " + toString(nDate); setState(true,s); diff --git a/code/ryzom/client/src/login_patch.h b/code/ryzom/client/src/login_patch.h index de7351775..565de7da2 100644 --- a/code/ryzom/client/src/login_patch.h +++ b/code/ryzom/client/src/login_patch.h @@ -302,7 +302,7 @@ private: /// Read the description of the highest client version file found void readClientVersionAndDescFile(); - void setRWAccess (const std::string &filename); + void setRWAccess (const std::string &filename, bool bThrowException=true); std::string deleteFile (const std::string &filename, bool bThrowException=true, bool bWarning=true); From ee7008ae029d4a67e18fac4fb2be7a3be23309f9 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 12:54:17 +0100 Subject: [PATCH 229/344] Changed: Possible bug if string not found --HG-- branch : hotfix --- code/ryzom/client/src/interface_v3/chat_window.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index e74392432..1d4c0516b 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -604,7 +604,11 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC pos = newmsg.find(ucstring("}"));; prefix += " "; } - newmsg = newmsg.substr(0, pos + 1) + prefix + newmsg.substr(pos + 1); + + if (pos == ucstring::npos) + newmsg = prefix + newmsg; + else + newmsg = newmsg.substr(0, pos + 1) + prefix + newmsg.substr(pos + 1); // Add dynchannel number and optionally name before text if user channel CCDBNodeLeaf* node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_DYN_CHANNEL_NAME_IN_CHAT_CB", false); @@ -615,7 +619,11 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title); prefix = title.empty() ? ucstring("") : ucstring(" ") + title; pos = newmsg.find(ucstring("] ")); - newmsg = newmsg.substr(0, pos) + prefix + newmsg.substr(pos); + + if (pos == ucstring::npos) + newmsg = prefix + newmsg; + else + newmsg = newmsg.substr(0, pos) + prefix + newmsg.substr(pos); } } break; From 76e64fcb4285c0490f76a821ce39c75b199abc60 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:03:27 +0100 Subject: [PATCH 230/344] Changed: Used INVALID_AI_INSTANCE in CUsedContinent::getInstanceForContinent --HG-- branch : hotfix --- code/ryzom/server/src/ai_service/commands.cpp | 4 ++-- code/ryzom/server/src/ai_share/primitive_parser.cpp | 4 ++-- code/ryzom/server/src/entities_game_service/admin.cpp | 2 +- code/ryzom/server/src/server_share/used_continent.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/ryzom/server/src/ai_service/commands.cpp b/code/ryzom/server/src/ai_service/commands.cpp index d257d0492..7a4ff6f0d 100644 --- a/code/ryzom/server/src/ai_service/commands.cpp +++ b/code/ryzom/server/src/ai_service/commands.cpp @@ -577,10 +577,10 @@ NLMISC_COMMAND(createStaticAIInstance, "Create a new static AIInstance for a giv CUsedContinent &uc = CUsedContinent::instance(); const uint32 in = uc.getInstanceForContinent(args[0]); - if (in == ~0) + if (in == INVALID_AI_INSTANCE) { nlwarning("The continent '%s' is unknow or not active. Can't create instance, FATAL", args[0].c_str()); - nlassert(in != ~0); + nlassert(in != INVALID_AI_INSTANCE); // nlassertex(in != ~0, ("The continent '%s' is unknow or not active. Can't create instance, FATAL", args[0].c_str())); } diff --git a/code/ryzom/server/src/ai_share/primitive_parser.cpp b/code/ryzom/server/src/ai_share/primitive_parser.cpp index 892120902..dd52b4d7a 100644 --- a/code/ryzom/server/src/ai_share/primitive_parser.cpp +++ b/code/ryzom/server/src/ai_share/primitive_parser.cpp @@ -4176,7 +4176,7 @@ NLMISC_COMMAND(loadMap,"load a complete set of primitive files","") // check that the continent is active CUsedContinent &uc = CUsedContinent::instance(); uint32 in = uc.getInstanceForContinent(continentName); - if (in == ~0) + if (in == INVALID_AI_INSTANCE) { log.displayNL("loadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active", args[0].c_str(), @@ -4216,7 +4216,7 @@ NLMISC_COMMAND(unloadMap,"unload a complete set of primitive files","" // check that the continent is active CUsedContinent &uc = CUsedContinent::instance(); uint32 in = uc.getInstanceForContinent(continentName); - if (in == ~0) + if (in == INVALID_AI_INSTANCE) { log.displayNL("unloadMap : while loading map '%s', can't load primitive '%s' coz continent '%s' is not active", args[0].c_str(), diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index 20941e77f..6e06da000 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -420,7 +420,7 @@ bool getAIInstanceFromGroupName(string& groupName, uint32& instanceNumber) { string continent = groupName.substr(0, groupName.find('@')); uint32 nr = CUsedContinent::instance().getInstanceForContinent(continent); - if (nr == ~0) + if (nr == INVALID_AI_INSTANCE) { return false; } diff --git a/code/ryzom/server/src/server_share/used_continent.cpp b/code/ryzom/server/src/server_share/used_continent.cpp index 9e9a310d9..9d2b48f0d 100644 --- a/code/ryzom/server/src/server_share/used_continent.cpp +++ b/code/ryzom/server/src/server_share/used_continent.cpp @@ -106,7 +106,7 @@ uint32 CUsedContinent::getInstanceForContinent(const std::string &continentName) if (it != _Continents.end()) return it->ContinentInstance; else - return ~0; + return INVALID_AI_INSTANCE; } uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEnum) const @@ -116,7 +116,7 @@ uint32 CUsedContinent::getInstanceForContinent(CONTINENT::TContinent continentEn if (it != _Continents.end()) return it->ContinentInstance; else - return ~0; + return INVALID_AI_INSTANCE; } const std::string &CUsedContinent::getContinentForInstance(uint32 instanceNumber) const From 1960f5c448f8ca4a2d42a8be25e53b6277ad4db2 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:18:51 +0100 Subject: [PATCH 231/344] Changed: std::string already initialized to en empty string --HG-- branch : hotfix --- .../client/src/interface_v3/interface_manager.cpp | 2 +- code/ryzom/client/src/login_progress_post_thread.cpp | 2 +- code/ryzom/client/src/misc.cpp | 2 +- code/ryzom/client/src/net_manager.cpp | 2 +- code/ryzom/client/src/r2/displayer_visual_entity.cpp | 4 ++-- .../client/src/r2/dmc/client_edition_module.cpp | 12 ++++++------ code/ryzom/client/src/r2/dmc/com_lua_module.cpp | 8 ++++---- code/ryzom/client/src/r2/dmc/dmc.cpp | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index b89566ecd..6f4f31d14 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -2925,7 +2925,7 @@ void CInterfaceManager::initEmotes() CSkillManager *pSM = CSkillManager::getInstance(); betaTester = pSM->isTitleUnblocked(CHARACTER_TITLE::FBT); - string previousMind = ""; + string previousMind; CGroupSubMenu *pFirstMenu = 0; for (list::const_iterator it = entries.begin(); it != entries.end(); it++) diff --git a/code/ryzom/client/src/login_progress_post_thread.cpp b/code/ryzom/client/src/login_progress_post_thread.cpp index bc833fb04..76ce9c2e3 100644 --- a/code/ryzom/client/src/login_progress_post_thread.cpp +++ b/code/ryzom/client/src/login_progress_post_thread.cpp @@ -85,7 +85,7 @@ static std::string sizeToHumanStd(uint64 size) static std::string getVideoInfoDeviceName() { uint64 version; - std::string ret = ""; + std::string ret; bool ok = CSystemInfo::getVideoInfo(ret, version); if (ok) { diff --git a/code/ryzom/client/src/misc.cpp b/code/ryzom/client/src/misc.cpp index 9adf00a9a..7e018a576 100644 --- a/code/ryzom/client/src/misc.cpp +++ b/code/ryzom/client/src/misc.cpp @@ -920,7 +920,7 @@ std::string getStringCategory(const ucstring &src, ucstring &dest, bool alwaysAd std::string getStringCategoryIfAny(const ucstring &src, ucstring &dest) { - std::string colorCode = ""; + std::string colorCode; if (src.size() >= 3) { uint startPos = 0; diff --git a/code/ryzom/client/src/net_manager.cpp b/code/ryzom/client/src/net_manager.cpp index 4b37b698a..0d369fe85 100644 --- a/code/ryzom/client/src/net_manager.cpp +++ b/code/ryzom/client/src/net_manager.cpp @@ -4109,7 +4109,7 @@ void CNetManagerMulti::init( const std::string& cookie, const std::string& addr // uint32 ShardId = 0; -std::string WebServer = ""; +std::string WebServer; diff --git a/code/ryzom/client/src/r2/displayer_visual_entity.cpp b/code/ryzom/client/src/r2/displayer_visual_entity.cpp index 37632f4d4..5bc8638f0 100644 --- a/code/ryzom/client/src/r2/displayer_visual_entity.cpp +++ b/code/ryzom/client/src/r2/displayer_visual_entity.cpp @@ -564,7 +564,7 @@ void CDisplayerVisualEntity::updateWorldMapPresence() _MapDeco.setDisplayedInstance(getDisplayedInstance(), true); // retrieve icon from the displayed object (lua code) CLuaState &ls = getEditor().getLua(); - std::string texName = ""; + std::string texName; { CLuaStackChecker lsc(&ls); if (getDisplayedInstance()->getLuaProjection().callMethodByNameNoThrow("getSelectBarIcon", 0, 1)) @@ -984,7 +984,7 @@ void CDisplayerVisualEntity::updateName() break; } } - std::string firstPart = ""; + std::string firstPart; if(actNb>0) firstPart = CI18N::get("uiR2EDDefaultActTitle").toString() + " " + NLMISC::toString(actNb); diff --git a/code/ryzom/client/src/r2/dmc/client_edition_module.cpp b/code/ryzom/client/src/r2/dmc/client_edition_module.cpp index 0a5f74cc5..93978800d 100644 --- a/code/ryzom/client/src/r2/dmc/client_edition_module.cpp +++ b/code/ryzom/client/src/r2/dmc/client_edition_module.cpp @@ -1116,12 +1116,12 @@ void CClientEditionModule::startingScenario(class NLNET::IModuleProxy * /* serve uint32 myUserId = NetMngr.getUserId(); - std::string connectionState = ""; + std::string connectionState; if (myUserId == (charId>>4) || ClientCfg.Local) { - std::string errorMsg = ""; + std::string errorMsg; CObject* hlScenario = _Scenario->getHighLevel(); hlData.setData(hlScenario); // clone before modify by translateFeatures @@ -2425,10 +2425,10 @@ bool CClientEditionModule::addToLoadList( const std::string& filename, CScenario void CClientEditionModule::loadScenarioSucceded(const std::string& filename, const std::string& body, const CScenarioValidator::TValues& values) { //H_AUTO(R2_CClientEditionModule_loadScenarioSucceded) - string initialIsland="", initialEntryPoint="", initialSeason = ""; - string creatorMD5 = "", modifiedByMD5=""; - string name = ""; - string locked = ""; + string initialIsland, initialEntryPoint, initialSeason; + string creatorMD5, modifiedByMD5; + string name; + string locked; for(uint i=0; i& pair = values[i]; diff --git a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp index c9b6a6df2..b73813786 100644 --- a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp +++ b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp @@ -834,7 +834,7 @@ sint CComLuaModule::luaRequestEraseNode(lua_State* state) if (args>2) { luaL_checknumber(state, 3); } std::string instanceId(lua_tostring(state, 1)); - std::string attrName = ""; + std::string attrName; sint position = -1; if (args>1){ attrName = lua_tostring(state, 2);} if (args>2){ position = static_cast(lua_tonumber(state, 3));} @@ -1255,7 +1255,7 @@ CObject* CComLuaModule::getObjectFromLua(lua_State* state, sint idx) lua_pushnil(state); while (lua_next(state, -2) != 0) { - std::string key = ""; + std::string key; if ( lua_type(state, -2) == LUA_TSTRING) { key = lua_tostring(state, -2); @@ -1285,7 +1285,7 @@ CObject* CComLuaModule::getObjectFromLua(lua_State* state, sint idx) CObject* CComLuaModule::loadLocal(const std::string& filename, const CScenarioValidator::TValues& values) { CScenarioValidator::TValues::const_iterator first(values.begin()), last(values.end()); - std::string name = ""; + std::string name; for (; first != last; ++first) { if (first->first == "Name" ) { name = first->second; } @@ -1347,7 +1347,7 @@ bool CComLuaModule::loadUserComponent(const std::string& filename) CObject* CComLuaModule::loadFromBuffer(const std::string& data, const std::string& filename, const CScenarioValidator::TValues& values) { CScenarioValidator::TValues::const_iterator first(values.begin()), last(values.end()); - std::string name = ""; + std::string name; for (; first != last; ++first) { if (first->first == "Name" ) { name = first->second; } diff --git a/code/ryzom/client/src/r2/dmc/dmc.cpp b/code/ryzom/client/src/r2/dmc/dmc.cpp index 4642dfa10..0659f0a56 100644 --- a/code/ryzom/client/src/r2/dmc/dmc.cpp +++ b/code/ryzom/client/src/r2/dmc/dmc.cpp @@ -267,7 +267,7 @@ void CDynamicMapClient::save(const std::string& /* filename */) void CDynamicMapClient::saveRtData(const std::string& filename) { //H_AUTO(R2_CDynamicMapClient_saveRtData) - std::string name = ""; + std::string name; name += filename; //std::ostringstream out2; std::string out2; From 49bbb10b58935bdc0bba43a43e5c1b79b5e00a8d Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:19:09 +0100 Subject: [PATCH 232/344] Fixed: Missing namespace --HG-- branch : hotfix --- code/ryzom/client/src/session_browser_impl.h | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/code/ryzom/client/src/session_browser_impl.h b/code/ryzom/client/src/session_browser_impl.h index 68f2de29d..302da2864 100644 --- a/code/ryzom/client/src/session_browser_impl.h +++ b/code/ryzom/client/src/session_browser_impl.h @@ -36,7 +36,7 @@ public: * - RingAccessPoint:onConnectionClosed() * - RingAccessPoint:onConnectionFailed() */ - void init(CLuaState *ls); + void init(NLGUI::CLuaState *ls); // from CSessionBrowser virtual void on_connectionFailed(); virtual void on_connectionClosed(); @@ -98,17 +98,17 @@ public: static const std::string &getFrontEndAddress(); private: - CLuaState::TRefPtr _Lua; - static int luaGetRingSessionList(CLuaState &ls); - static int luaGetRingCharList(CLuaState &ls); - static int luaJoinRingSession(CLuaState &ls); - static int luaCheckRingAccess(CLuaState &ls); - static int luaGetFileHeader(CLuaState &ls); - static int luaGetRingStats(CLuaState &ls); - static int luaGetScenarioScores(CLuaState &ls); - static int luaUpdateScenarioScores(CLuaState &ls); - static int luaGetSessionAverageScores(CLuaState &ls); - static int luaGetScenarioAverageScores(CLuaState &ls); + NLGUI::CLuaState::TRefPtr _Lua; + static int luaGetRingSessionList(NLGUI::CLuaState &ls); + static int luaGetRingCharList(NLGUI::CLuaState &ls); + static int luaJoinRingSession(NLGUI::CLuaState &ls); + static int luaCheckRingAccess(NLGUI::CLuaState &ls); + static int luaGetFileHeader(NLGUI::CLuaState &ls); + static int luaGetRingStats(NLGUI::CLuaState &ls); + static int luaGetScenarioScores(NLGUI::CLuaState &ls); + static int luaUpdateScenarioScores(NLGUI::CLuaState &ls); + static int luaGetSessionAverageScores(NLGUI::CLuaState &ls); + static int luaGetScenarioAverageScores(NLGUI::CLuaState &ls); // Call a method inside the 'RingAccessPoint' lua table void callRingAccessPointMethod(const char *name, int numArg, int numResult); void callRingCharTrackingMethod(const char *name, int numArg, int numResult); From d774dcac3ece5337d859d149be6355d2f6f09924 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:19:53 +0100 Subject: [PATCH 233/344] Changed: Use Ryzom user agent for CURL --HG-- branch : hotfix --- code/ryzom/client/src/interface_v3/group_html_webig.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index 8ffa25878..680a26273 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -22,6 +22,7 @@ #include "../user_entity.h" #include "../entities.h" #include "interface_manager.h" +#include "user_agent.h" // used for login cookie to be sent to the web server #include "../net_manager.h" @@ -157,7 +158,7 @@ struct CWebigNotificationThread : public NLMISC::IRunnable if(!Curl) return; curl_easy_setopt(Curl, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(Curl, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(Curl, CURLOPT_USERAGENT, "Ryzom"); + curl_easy_setopt(Curl, CURLOPT_USERAGENT, getUserAgent().c_str()); curl_easy_setopt(Curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(Curl, CURLOPT_WRITEFUNCTION, writeDataFromCurl); //nlinfo("ctor CWebigNotificationThread"); From 174299798419ab5a725b884f677664a469f281c2 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:34:45 +0100 Subject: [PATCH 234/344] Changed: Minor changes --HG-- branch : hotfix --- code/ryzom/client/src/init.cpp | 3 +-- code/ryzom/client/src/login_patch.cpp | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 1644f7e2d..6958fe790 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -556,10 +556,9 @@ void checkDriverDepth () static std::string replaceApplicationDirToken(const std::string &dir) { - #ifdef NL_OS_MAC // if client_default.cfg is not in current directory, and it's not an absolute path, use application default directory - if (!CFile::isExists("client_default.cfg") && dir.size()>0 && dir[0]!='/') + if (!CFile::isExists("client_default.cfg") && !dir.empty() && dir[0]!='/') { return getAppBundlePath() + "/Contents/Resources/" + dir; } diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index e98cd1e32..da94f37d6 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -3398,6 +3398,7 @@ bool CPatchManager::extract(const std::string& patchPath, ok = true; } } + if (!ok) { // nothing to extract @@ -3407,15 +3408,21 @@ bool CPatchManager::extract(const std::string& patchPath, // extract uint nblab = 0; pPM->deleteFile(updateBatchFilename, false, false); + FILE *fp = fopen (updateBatchFilename.c_str(), "wt"); + if (fp == 0) { string err = toString("Can't open file '%s' for writing: code=%d %s (error code 29)", updateBatchFilename.c_str(), errno, strerror(errno)); throw Exception (err); } + +#ifdef NL_OS_WINDOWS fprintf(fp, "@echo off\n"); fprintf(fp, "ping 127.0.0.1 -n 7 -w 1000 > nul\n"); // wait - +#else + // TODO: for Linux and OS X +#endif // Unpack files with category ExtractPath non empty for (uint32 j = 0; j < sourceFilename.size(); ++j) @@ -3442,21 +3449,32 @@ bool CPatchManager::extract(const std::string& patchPath, string DstPath = CPath::standardizeDosPath(extractPath[j]); string DstName = DstPath + vFilenames[fff]; NLMISC::CFile::createDirectoryTree(extractPath[j]); - // this file must be moved + // this file must be moved +#ifdef NL_OS_WINDOWS fprintf(fp, ":loop%u\n", nblab); fprintf(fp, "attrib -r -a -s -h %s\n", DstName.c_str()); fprintf(fp, "del %s\n", DstName.c_str()); fprintf(fp, "if exist %s goto loop%u\n", DstName.c_str(), nblab); fprintf(fp, "move %s %s\n", SrcName.c_str(), DstPath.c_str()); +#else + // TODO: for Linux and OS X +#endif + nblab++; + } } } } +#ifdef NL_OS_WINDOWS fprintf(fp, "start %s %%1 %%2 %%3\n", execName.c_str()); +#else + // TODO: for Linux and OS X +#endif + fclose(fp); if (stopFun) From 943131b8022e2f4d9c8457f5fb5764114c5f6a64 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:46:21 +0100 Subject: [PATCH 235/344] Changed: Replaced atoi and atof by NLMISC::fromString --HG-- branch : hotfix --- code/nel/src/misc/config_file/cf_gramatical.cpp | 4 ++-- code/nel/src/misc/config_file/cf_gramatical.ypp | 4 ++-- code/nel/src/misc/config_file/cf_lexical.cpp | 2 +- code/nel/src/misc/config_file/config_file.cpp | 6 +++++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/code/nel/src/misc/config_file/cf_gramatical.cpp b/code/nel/src/misc/config_file/cf_gramatical.cpp index c6a50934f..bc51ef371 100644 --- a/code/nel/src/misc/config_file/cf_gramatical.cpp +++ b/code/nel/src/misc/config_file/cf_gramatical.cpp @@ -1499,7 +1499,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_REAL: Var.IntValues.push_back ((int)Val.Real); break; - case NLMISC::CConfigFile::CVar::T_STRING: Var.IntValues.push_back (atoi(Val.String)); break; + case NLMISC::CConfigFile::CVar::T_STRING: int val = 0; NLMISC::fromString(Val.String, val); Var.IntValues.push_back(val); break; default: break; } break; @@ -1507,7 +1507,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_INT: Var.RealValues.push_back ((double)Val.Int); break; - case NLMISC::CConfigFile::CVar::T_STRING: Var.RealValues.push_back (atof(Val.String)); break; + case NLMISC::CConfigFile::CVar::T_STRING: double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; default: break; } break; diff --git a/code/nel/src/misc/config_file/cf_gramatical.ypp b/code/nel/src/misc/config_file/cf_gramatical.ypp index 199f3df9a..0f4fd2405 100644 --- a/code/nel/src/misc/config_file/cf_gramatical.ypp +++ b/code/nel/src/misc/config_file/cf_gramatical.ypp @@ -517,7 +517,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_REAL: Var.IntValues.push_back ((int)Val.Real); break; - case NLMISC::CConfigFile::CVar::T_STRING: Var.IntValues.push_back (atoi(Val.String)); break; + case NLMISC::CConfigFile::CVar::T_STRING: int val = 0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; default: break; } break; @@ -525,7 +525,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_INT: Var.RealValues.push_back ((double)Val.Int); break; - case NLMISC::CConfigFile::CVar::T_STRING: Var.RealValues.push_back (atof(Val.String)); break; + case NLMISC::CConfigFile::CVar::T_STRING: double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; default: break; } break; diff --git a/code/nel/src/misc/config_file/cf_lexical.cpp b/code/nel/src/misc/config_file/cf_lexical.cpp index 80fd4fd36..8c39112a6 100644 --- a/code/nel/src/misc/config_file/cf_lexical.cpp +++ b/code/nel/src/misc/config_file/cf_lexical.cpp @@ -2337,7 +2337,7 @@ YY_RULE_SETUP if (!cf_Ignore) { cflval.Val.Type = T_REAL; - cflval.Val.Real = atof (yytext); + NLMISC::fromString(yytext, cflval.Val.Real); DEBUG_PRINTF("lex: real '%s' '%f\n", yytext, cflval.Val.Real); return REAL; } diff --git a/code/nel/src/misc/config_file/config_file.cpp b/code/nel/src/misc/config_file/config_file.cpp index 6113a7a2c..c969f614d 100644 --- a/code/nel/src/misc/config_file/config_file.cpp +++ b/code/nel/src/misc/config_file/config_file.cpp @@ -85,8 +85,12 @@ double CConfigFile::CVar::asDouble (int index) const if (index >= (int)IntValues.size () || index < 0) throw EBadSize (Name, (int)IntValues.size (), index); return (double)IntValues[index]; case T_STRING: + { if (index >= (int)StrValues.size () || index < 0) throw EBadSize (Name, (int)StrValues.size (), index); - return atof(StrValues[index].c_str()); + double val; + NLMISC::fromString(StrValues[index], val); + return val; + } default: if (index >= (int)RealValues.size () || index < 0) throw EBadSize (Name, (int)RealValues.size (), index); return RealValues[index]; From e0c95a74af15c0a89a112f63daea14bae33fb6a6 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:47:37 +0100 Subject: [PATCH 236/344] Changed: Updated CMale modules --HG-- branch : hotfix --- code/CMakeModules/AndroidToolChain.cmake | 157 +++++++++++++++-------- code/CMakeModules/FindMSVC.cmake | 5 + code/CMakeModules/FindMySQL.cmake | 27 ++-- code/CMakeModules/FindWindowsSDK.cmake | 16 ++- code/CMakeModules/GetRevision.cmake | 34 +++-- 5 files changed, 154 insertions(+), 85 deletions(-) diff --git a/code/CMakeModules/AndroidToolChain.cmake b/code/CMakeModules/AndroidToolChain.cmake index 049c39adf..6690497d4 100644 --- a/code/CMakeModules/AndroidToolChain.cmake +++ b/code/CMakeModules/AndroidToolChain.cmake @@ -26,63 +26,46 @@ IF(TARGET_CPU STREQUAL "armv7") SET(LIBRARY_ARCHITECTURE "armeabi-v7a") SET(CMAKE_SYSTEM_PROCESSOR "armv7") SET(TOOLCHAIN_ARCH "arm") - SET(TOOLCHAIN_PREFIX "arm-linux-androideabi") + SET(GCC_TOOLCHAIN_PREFIX "arm-linux-androideabi") SET(TOOLCHAIN_BIN_PREFIX "arm") SET(MINIMUM_NDK_TARGET 4) ELSEIF(TARGET_CPU STREQUAL "armv5") SET(LIBRARY_ARCHITECTURE "armeabi") SET(CMAKE_SYSTEM_PROCESSOR "armv5") SET(TOOLCHAIN_ARCH "arm") - SET(TOOLCHAIN_PREFIX "arm-linux-androideabi") + SET(GCC_TOOLCHAIN_PREFIX "arm-linux-androideabi") SET(TOOLCHAIN_BIN_PREFIX "arm") SET(MINIMUM_NDK_TARGET 4) ELSEIF(TARGET_CPU STREQUAL "x86") SET(LIBRARY_ARCHITECTURE "x86") SET(CMAKE_SYSTEM_PROCESSOR "x86") SET(TOOLCHAIN_ARCH "x86") - SET(TOOLCHAIN_PREFIX "x86") + SET(GCC_TOOLCHAIN_PREFIX "x86") SET(TOOLCHAIN_BIN_PREFIX "i686") SET(MINIMUM_NDK_TARGET 9) ELSEIF(TARGET_CPU STREQUAL "mips") SET(LIBRARY_ARCHITECTURE "mips") SET(CMAKE_SYSTEM_PROCESSOR "mips") SET(TOOLCHAIN_ARCH "mips") - SET(TOOLCHAIN_PREFIX "mipsel-linux-android") + SET(GCC_TOOLCHAIN_PREFIX "mipsel-linux-android") SET(TOOLCHAIN_BIN_PREFIX "mipsel") SET(MINIMUM_NDK_TARGET 9) ENDIF(TARGET_CPU STREQUAL "armv7") +SET(ANDROID_COMPILER "GCC") + +IF(NDK_TOOLCHAIN_VERSION STREQUAL "clang") + SET(ANDROID_COMPILER "clang") + SET(CLANG_TOOLCHAIN_PREFIX "llvm") + SET(CLANG ON) +ELSE() + SET(GCC_TOOLCHAIN_VERSION ${NDK_TOOLCHAIN_VERSION}) +ENDIF() + IF(NOT NDK_TARGET) SET(NDK_TARGET ${MINIMUM_NDK_TARGET}) ENDIF(NOT NDK_TARGET) -FILE(GLOB _TOOLCHAIN_VERSIONS "${NDK_ROOT}/toolchains/${TOOLCHAIN_PREFIX}-*") -IF(_TOOLCHAIN_VERSIONS) - LIST(SORT _TOOLCHAIN_VERSIONS) - LIST(REVERSE _TOOLCHAIN_VERSIONS) - FOREACH(_TOOLCHAIN_VERSION ${_TOOLCHAIN_VERSIONS}) - STRING(REGEX REPLACE ".+${TOOLCHAIN_PREFIX}-([0-9.]+)" "\\1" _TOOLCHAIN_VERSION "${_TOOLCHAIN_VERSION}") - IF(_TOOLCHAIN_VERSION MATCHES "^([0-9.]+)$") - LIST(APPEND NDK_TOOLCHAIN_VERSIONS ${_TOOLCHAIN_VERSION}) - ENDIF(_TOOLCHAIN_VERSION MATCHES "^([0-9.]+)$") - ENDFOREACH(_TOOLCHAIN_VERSION) -ENDIF(_TOOLCHAIN_VERSIONS) - -IF(NOT NDK_TOOLCHAIN_VERSIONS) - MESSAGE(FATAL_ERROR "No Android toolchain found in default search path ${NDK_ROOT}/toolchains") -ENDIF(NOT NDK_TOOLCHAIN_VERSIONS) - -IF(NDK_TOOLCHAIN_VERSION) - LIST(FIND NDK_TOOLCHAIN_VERSIONS "${NDK_TOOLCHAIN_VERSION}" _INDEX) - IF(_INDEX EQUAL -1) - LIST(GET NDK_TOOLCHAIN_VERSIONS 0 NDK_TOOLCHAIN_VERSION) - ENDIF(_INDEX EQUAL -1) -ELSE(NDK_TOOLCHAIN_VERSION) - LIST(GET NDK_TOOLCHAIN_VERSIONS 0 NDK_TOOLCHAIN_VERSION) -ENDIF(NDK_TOOLCHAIN_VERSION) - -MESSAGE(STATUS "Target Android NDK ${NDK_TARGET} and use GCC ${NDK_TOOLCHAIN_VERSION}") - IF(CMAKE_HOST_WIN32) SET(TOOLCHAIN_HOST "windows") SET(TOOLCHAIN_BIN_SUFFIX ".exe") @@ -94,33 +77,73 @@ ELSEIF(CMAKE_HOST_UNIX) SET(TOOLCHAIN_BIN_SUFFIX "") ENDIF(CMAKE_HOST_WIN32) -SET(TOOLCHAIN_ROOT "${NDK_ROOT}/toolchains/${TOOLCHAIN_PREFIX}-${NDK_TOOLCHAIN_VERSION}/prebuilt/${TOOLCHAIN_HOST}") -SET(PLATFORM_ROOT "${NDK_ROOT}/platforms/android-${NDK_TARGET}/arch-${TOOLCHAIN_ARCH}") +MACRO(SEARCH_TOOLCHAIN _COMPILER) + SET(${_COMPILER}_TOOLCHAIN_VERSIONS) + FILE(GLOB _TOOLCHAIN_VERSIONS "${NDK_ROOT}/toolchains/${${_COMPILER}_TOOLCHAIN_PREFIX}-*") + IF(_TOOLCHAIN_VERSIONS) + LIST(SORT _TOOLCHAIN_VERSIONS) + LIST(REVERSE _TOOLCHAIN_VERSIONS) + FOREACH(_TOOLCHAIN_VERSION ${_TOOLCHAIN_VERSIONS}) + STRING(REGEX REPLACE ".+${_PREFIX}-([0-9.]+)" "\\1" _TOOLCHAIN_VERSION "${_TOOLCHAIN_VERSION}") + IF(_TOOLCHAIN_VERSION MATCHES "^([0-9.]+)$") + LIST(APPEND ${_COMPILER}_TOOLCHAIN_VERSIONS ${_TOOLCHAIN_VERSION}) + ENDIF() + ENDFOREACH() + ENDIF() + + IF(NOT ${_COMPILER}_TOOLCHAIN_VERSIONS) + MESSAGE(FATAL_ERROR "No Android ${_COMPILER} toolchain found in default search path ${NDK_ROOT}/toolchains") + ENDIF() + + IF(${_COMPILER}_TOOLCHAIN_VERSIONS) + LIST(FIND ${_COMPILER}_TOOLCHAIN_VERSIONS "${${_COMPILER}_TOOLCHAIN_VERSION}" _INDEX) + IF(_INDEX EQUAL -1) + LIST(GET ${_COMPILER}_TOOLCHAIN_VERSIONS 0 ${_COMPILER}_TOOLCHAIN_VERSION) + ENDIF() + ELSE() + LIST(GET ${_COMPILER}_TOOLCHAIN_VERSIONS 0 ${_COMPILER}_TOOLCHAIN_VERSION) + ENDIF() + + SET(${_COMPILER}_TOOLCHAIN_ROOT "${NDK_ROOT}/toolchains/${${_COMPILER}_TOOLCHAIN_PREFIX}-${${_COMPILER}_TOOLCHAIN_VERSION}/prebuilt/${TOOLCHAIN_HOST}") + + IF(NOT EXISTS "${${_COMPILER}_TOOLCHAIN_ROOT}") + FILE(GLOB _TOOLCHAIN_PREFIXES "${${_COMPILER}_TOOLCHAIN_ROOT}*") + IF(_TOOLCHAIN_PREFIXES) + LIST(GET _TOOLCHAIN_PREFIXES 0 ${_COMPILER}_TOOLCHAIN_ROOT) + ENDIF(_TOOLCHAIN_PREFIXES) + ENDIF() +ENDMACRO() + +IF(CLANG) + SEARCH_TOOLCHAIN(CLANG) + + MESSAGE(STATUS "Target Android NDK ${NDK_TARGET} and use clang ${CLANG_TOOLCHAIN_VERSION}") +ENDIF() + +SEARCH_TOOLCHAIN(GCC) -IF(NOT EXISTS "${TOOLCHAIN_ROOT}") - FILE(GLOB _TOOLCHAIN_PREFIXES "${TOOLCHAIN_ROOT}*") - IF(_TOOLCHAIN_PREFIXES) - LIST(GET _TOOLCHAIN_PREFIXES 0 TOOLCHAIN_ROOT) - ENDIF(_TOOLCHAIN_PREFIXES) -ENDIF(NOT EXISTS "${TOOLCHAIN_ROOT}") +MESSAGE(STATUS "Target Android NDK ${NDK_TARGET} and use GCC ${GCC_TOOLCHAIN_VERSION}") +MESSAGE(STATUS "Found Android LLVM toolchain in ${CLANG_TOOLCHAIN_ROOT}") +MESSAGE(STATUS "Found Android GCC toolchain in ${GCC_TOOLCHAIN_ROOT}") + +SET(PLATFORM_ROOT "${NDK_ROOT}/platforms/android-${NDK_TARGET}/arch-${TOOLCHAIN_ARCH}") -MESSAGE(STATUS "Found Android toolchain in ${TOOLCHAIN_ROOT}") MESSAGE(STATUS "Found Android platform in ${PLATFORM_ROOT}") # include dirs SET(PLATFORM_INCLUDE_DIR "${PLATFORM_ROOT}/usr/include") SET(STL_DIR "${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++") -IF(EXISTS "${STL_DIR}/${NDK_TOOLCHAIN_VERSION}") +IF(EXISTS "${STL_DIR}/${GCC_TOOLCHAIN_VERSION}") # NDK version >= 8b - SET(STL_DIR "${STL_DIR}/${NDK_TOOLCHAIN_VERSION}") -ENDIF(EXISTS "${STL_DIR}/${NDK_TOOLCHAIN_VERSION}") + SET(STL_DIR "${STL_DIR}/${GCC_TOOLCHAIN_VERSION}") +ENDIF(EXISTS "${STL_DIR}/${GCC_TOOLCHAIN_VERSION}") # Determine bin prefix for toolchain -FILE(GLOB _TOOLCHAIN_BIN_PREFIXES "${TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_BIN_PREFIX}-*-gcc${TOOLCHAIN_BIN_SUFFIX}") +FILE(GLOB _TOOLCHAIN_BIN_PREFIXES "${GCC_TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_BIN_PREFIX}-*-gcc${TOOLCHAIN_BIN_SUFFIX}") IF(_TOOLCHAIN_BIN_PREFIXES) LIST(GET _TOOLCHAIN_BIN_PREFIXES 0 _TOOLCHAIN_BIN_PREFIX) - STRING(REGEX REPLACE "${TOOLCHAIN_ROOT}/bin/([a-z0-9-]+)-gcc${TOOLCHAIN_BIN_SUFFIX}" "\\1" TOOLCHAIN_BIN_PREFIX "${_TOOLCHAIN_BIN_PREFIX}") + STRING(REGEX REPLACE "${GCC_TOOLCHAIN_ROOT}/bin/([a-z0-9-]+)-gcc${TOOLCHAIN_BIN_SUFFIX}" "\\1" TOOLCHAIN_BIN_PREFIX "${_TOOLCHAIN_BIN_PREFIX}") ENDIF(_TOOLCHAIN_BIN_PREFIXES) SET(STL_INCLUDE_DIR "${STL_DIR}/include") @@ -128,22 +151,48 @@ SET(STL_LIBRARY_DIR "${STL_DIR}/libs/${LIBRARY_ARCHITECTURE}") SET(STL_INCLUDE_CPU_DIR "${STL_LIBRARY_DIR}/include") SET(STL_LIBRARY "${STL_LIBRARY_DIR}/libgnustl_static.a") -SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_ROOT} ${PLATFORM_ROOT}/usr ${CMAKE_PREFIX_PATH} ${CMAKE_INSTALL_PREFIX} $ENV{EXTERNAL_ANDROID_PATH} CACHE string "Android find search path root") +MESSAGE(STATUS "STL include dir: ${STL_INCLUDE_DIR}") +MESSAGE(STATUS "STL library dir: ${STL_LIBRARY_DIR}") + +SET(CMAKE_FIND_ROOT_PATH ${CLANG_TOOLCHAIN_ROOT} ${GCC_TOOLCHAIN_ROOT} ${PLATFORM_ROOT}/usr ${CMAKE_PREFIX_PATH} ${CMAKE_INSTALL_PREFIX} $ENV{EXTERNAL_ANDROID_PATH} CACHE string "Android find search path root") SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -INCLUDE_DIRECTORIES(${STL_INCLUDE_DIR} ${STL_INCLUDE_CPU_DIR}) - MACRO(SET_TOOLCHAIN_BINARY _NAME _BINARY) - SET(${_NAME} ${TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_BIN_PREFIX}-${_BINARY}${TOOLCHAIN_BIN_SUFFIX}) + IF("${_BINARY}" MATCHES "clang") + SET(${_NAME} ${CLANG_TOOLCHAIN_ROOT}/bin/${_BINARY}${TOOLCHAIN_BIN_SUFFIX} CACHE PATH "" FORCE ) + ELSE() + SET(${_NAME} ${GCC_TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_BIN_PREFIX}-${_BINARY}${TOOLCHAIN_BIN_SUFFIX} CACHE PATH "" FORCE) + ENDIF() ENDMACRO(SET_TOOLCHAIN_BINARY) -SET_TOOLCHAIN_BINARY(CMAKE_C_COMPILER gcc) -SET_TOOLCHAIN_BINARY(CMAKE_CXX_COMPILER g++) - # Force the compilers to GCC for Android include (CMakeForceCompiler) -CMAKE_FORCE_C_COMPILER(${CMAKE_C_COMPILER} GNU) -CMAKE_FORCE_CXX_COMPILER(${CMAKE_CXX_COMPILER} GNU) + +IF(CLANG) + SET_TOOLCHAIN_BINARY(CMAKE_C_COMPILER clang) + SET_TOOLCHAIN_BINARY(CMAKE_CXX_COMPILER clang++) + + CMAKE_FORCE_C_COMPILER(${CMAKE_C_COMPILER} clang) + CMAKE_FORCE_CXX_COMPILER(${CMAKE_CXX_COMPILER} clang) + + MESSAGE(STATUS "Using clang compiler") +ELSE() + SET_TOOLCHAIN_BINARY(CMAKE_C_COMPILER gcc) + SET_TOOLCHAIN_BINARY(CMAKE_CXX_COMPILER g++) + + CMAKE_FORCE_C_COMPILER(${CMAKE_C_COMPILER} GNU) + CMAKE_FORCE_CXX_COMPILER(${CMAKE_CXX_COMPILER} GNU) + + MESSAGE(STATUS "Using GCC compiler") +ENDIF() + +SET_TOOLCHAIN_BINARY(CMAKE_STRIP strip) +SET_TOOLCHAIN_BINARY(CMAKE_AR ar) +SET_TOOLCHAIN_BINARY(CMAKE_LINKER ld) +SET_TOOLCHAIN_BINARY(CMAKE_NM nm) +SET_TOOLCHAIN_BINARY(CMAKE_OBJCOPY objcopy) +SET_TOOLCHAIN_BINARY(CMAKE_OBJDUMP objdump) +SET_TOOLCHAIN_BINARY(CMAKE_RANLIB ranlib) diff --git a/code/CMakeModules/FindMSVC.cmake b/code/CMakeModules/FindMSVC.cmake index 16455b02d..644fc57e6 100644 --- a/code/CMakeModules/FindMSVC.cmake +++ b/code/CMakeModules/FindMSVC.cmake @@ -57,6 +57,7 @@ ENDMACRO(DETECT_EXPRESS_VERSION) IF(MSVC12) DETECT_VC_VERSION("12.0") + SET(MSVC_TOOLSET "120") IF(NOT MSVC12_REDIST_DIR) # If you have VC++ 2013 Express, put x64/Microsoft.VC120.CRT/*.dll in ${EXTERNAL_PATH}/redist @@ -64,6 +65,7 @@ IF(MSVC12) ENDIF(NOT MSVC11_REDIST_DIR) ELSEIF(MSVC11) DETECT_VC_VERSION("11.0") + SET(MSVC_TOOLSET "110") IF(NOT MSVC11_REDIST_DIR) # If you have VC++ 2012 Express, put x64/Microsoft.VC110.CRT/*.dll in ${EXTERNAL_PATH}/redist @@ -71,6 +73,7 @@ ELSEIF(MSVC11) ENDIF(NOT MSVC11_REDIST_DIR) ELSEIF(MSVC10) DETECT_VC_VERSION("10.0") + SET(MSVC_TOOLSET "100") IF(NOT MSVC10_REDIST_DIR) # If you have VC++ 2010 Express, put x64/Microsoft.VC100.CRT/*.dll in ${EXTERNAL_PATH}/redist @@ -78,8 +81,10 @@ ELSEIF(MSVC10) ENDIF(NOT MSVC10_REDIST_DIR) ELSEIF(MSVC90) DETECT_VC_VERSION("9.0") + SET(MSVC_TOOLSET "90") ELSEIF(MSVC80) DETECT_VC_VERSION("8.0") + SET(MSVC_TOOLSET "80") ENDIF(MSVC12) # If you plan to use VC++ compilers with WINE, set VC_DIR environment variable diff --git a/code/CMakeModules/FindMySQL.cmake b/code/CMakeModules/FindMySQL.cmake index eb2102c8d..0e0ebfd48 100644 --- a/code/CMakeModules/FindMySQL.cmake +++ b/code/CMakeModules/FindMySQL.cmake @@ -13,7 +13,7 @@ IF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) SET(MYSQL_FOUND TRUE) -ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) +ELSE() FIND_PATH(MYSQL_INCLUDE_DIR mysql.h PATH_SUFFIXES mysql @@ -33,7 +33,7 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) PATHS $ENV{ProgramFiles}/MySQL/*/lib/opt $ENV{SystemDrive}/MySQL/*/lib/opt) - ELSE(WIN32 AND MSVC) + ELSE() FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient PATHS /usr/lib @@ -51,31 +51,30 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) /usr/local/lib/mysql /opt/local/lib/mysql5/mysql ) - ENDIF(WIN32 AND MSVC) + ENDIF() IF(MYSQL_INCLUDE_DIR) IF(MYSQL_LIBRARY_RELEASE) - SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE}) IF(MYSQL_LIBRARY_DEBUG) - SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_DEBUG}) - ELSE(MYSQL_LIBRARY_DEBUG) - SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_RELEASE}) - ENDIF(MYSQL_LIBRARY_DEBUG) + SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE} debug ${MYSQL_LIBRARY_DEBUG}) + ELSE() + SET(MYSQL_LIBRARIES ${MYSQL_LIBRARY_RELEASE}) + ENDIF() FIND_PACKAGE(OpenSSL) IF(OPENSSL_FOUND) SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} ${OPENSSL_LIBRARIES}) - ENDIF(OPENSSL_FOUND) - ENDIF(MYSQL_LIBRARY_RELEASE) - ENDIF(MYSQL_INCLUDE_DIR) + ENDIF() + ENDIF() + ENDIF() IF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) SET(MYSQL_FOUND TRUE) MESSAGE(STATUS "Found MySQL: ${MYSQL_INCLUDE_DIR}, ${MYSQL_LIBRARIES}") - ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) + ELSE() SET(MYSQL_FOUND FALSE) MESSAGE(STATUS "MySQL not found.") - ENDIF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) + ENDIF() MARK_AS_ADVANCED(MYSQL_LIBRARY_RELEASE MYSQL_LIBRARY_DEBUG) -ENDIF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) +ENDIF() diff --git a/code/CMakeModules/FindWindowsSDK.cmake b/code/CMakeModules/FindWindowsSDK.cmake index 2e72af9e5..31288eb03 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -68,6 +68,10 @@ ENDIF(WINSDKCURRENT_VERSION_INCLUDE) SET(WINSDKENV_DIR $ENV{WINSDK_DIR}) +IF(NOT WINSDKENV_DIR) + SET(WINSDKENV_DIR $ENV{WindowsSDKDir}) +ENDIF(NOT WINSDKENV_DIR) + MACRO(FIND_WINSDK_VERSION_HEADERS) IF(WINSDK_DIR AND NOT WINSDK_VERSION) # Search version in headers @@ -78,7 +82,6 @@ MACRO(FIND_WINSDK_VERSION_HEADERS) ) IF(_MSI_FILE) - # Look for Windows SDK 8.0 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8") @@ -181,7 +184,7 @@ MACRO(USE_CURRENT_WINSDK) # Look for Windows.h because there are several paths IF(EXISTS ${_INCLUDE}/Windows.h) STRING(REGEX REPLACE "/(include|INCLUDE|Include)(.*)" "" WINSDK_DIR ${_INCLUDE}) - MESSAGE(STATUS "Found Windows SDK from include environment variable in ${WINSDK_DIR}") + MESSAGE(STATUS "Found Windows SDK in INCLUDE environment variable: ${WINSDK_DIR}") BREAK() ENDIF(EXISTS ${_INCLUDE}/Windows.h) ENDFOREACH(_INCLUDE) @@ -280,6 +283,13 @@ FIND_PATH(WINSDK_SHARED_INCLUDE_DIR d3d9.h ${WINSDK_DIR}/Include ) +# directory where OpenGL headers are found +FIND_PATH(WINSDK_OPENGL_INCLUDE_DIR GL.h + HINTS + ${WINSDK_DIR}/Include/gl + ${WINSDK_DIR}/Include +) + # directory where all libraries are found FIND_PATH(WINSDK_LIBRARY_DIR ComCtl32.lib HINTS @@ -303,7 +313,7 @@ FIND_PROGRAM(WINSDK_MIDL midl IF(WINSDK_INCLUDE_DIR) SET(WINSDK_FOUND ON) - SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIR} ${WINSDK_SHARED_INCLUDE_DIR}) + SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIR} ${WINSDK_SHARED_INCLUDE_DIR} ${WINSDK_OPENGL_INCLUDE_DIR}) SET(CMAKE_LIBRARY_PATH ${WINSDK_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH}) INCLUDE_DIRECTORIES(${WINSDK_INCLUDE_DIRS}) diff --git a/code/CMakeModules/GetRevision.cmake b/code/CMakeModules/GetRevision.cmake index 21b234f74..7f0a4e5f1 100644 --- a/code/CMakeModules/GetRevision.cmake +++ b/code/CMakeModules/GetRevision.cmake @@ -13,38 +13,44 @@ IF(SOURCE_DIR) IF(NOT ROOT_DIR AND SOURCE_DIR) SET(ROOT_DIR ${SOURCE_DIR}) - ENDIF(NOT ROOT_DIR AND SOURCE_DIR) + ENDIF() IF(NOT SOURCE_DIR AND ROOT_DIR) SET(SOURCE_DIR ${ROOT_DIR}) - ENDIF(NOT SOURCE_DIR AND ROOT_DIR) -ELSE(SOURCE_DIR) + ENDIF() +ELSE() SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}) SET(ROOT_DIR ${CMAKE_SOURCE_DIR}) -ENDIF(SOURCE_DIR) +ENDIF() MACRO(NOW RESULT) IF (WIN32) EXECUTE_PROCESS(COMMAND "wmic" "os" "get" "localdatetime" OUTPUT_VARIABLE DATETIME) IF(NOT DATETIME MATCHES "ERROR") STRING(REGEX REPLACE ".*\n([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9]).*" "\\1-\\2-\\3 \\4:\\5:\\6" ${RESULT} "${DATETIME}") - ENDIF(NOT DATETIME MATCHES "ERROR") + ENDIF() ELSEIF(UNIX) EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE DATETIME) STRING(REGEX REPLACE "([0-9: -]+).*" "\\1" ${RESULT} "${DATETIME}") - ELSE (WIN32) + ELSE() MESSAGE(SEND_ERROR "date not implemented") SET(${RESULT} "0000-00-00 00:00:00") - ENDIF (WIN32) + ENDIF() ENDMACRO(NOW) IF(EXISTS "${ROOT_DIR}/.svn/") - FIND_PACKAGE(Subversion) + FIND_PACKAGE(Subversion QUIET) IF(SUBVERSION_FOUND) Subversion_WC_INFO(${ROOT_DIR} ER) SET(REVISION ${ER_WC_REVISION}) ENDIF(SUBVERSION_FOUND) + + FIND_PACKAGE(TortoiseSVN QUIET) + + IF(TORTOISESVN_FOUND) + TORTOISESVN_GET_REVISION(${ROOT_DIR} REVISION) + ENDIF(TORTOISESVN_FOUND) ENDIF(EXISTS "${ROOT_DIR}/.svn/") IF(EXISTS "${ROOT_DIR}/.hg/") @@ -55,8 +61,8 @@ IF(EXISTS "${ROOT_DIR}/.hg/") SET(REVISION ${ER_WC_REVISION}) SET(CHANGESET ${ER_WC_CHANGESET}) SET(BRANCH ${ER_WC_BRANCH}) - ENDIF(MERCURIAL_FOUND) -ENDIF(EXISTS "${ROOT_DIR}/.hg/") + ENDIF() +ENDIF() # if processing exported sources, use "revision" file if exists IF(SOURCE_DIR AND NOT DEFINED REVISION) @@ -64,8 +70,8 @@ IF(SOURCE_DIR AND NOT DEFINED REVISION) IF(EXISTS ${REVISION_FILE}) FILE(STRINGS ${REVISION_FILE} REVISION LIMIT_COUNT 1) MESSAGE(STATUS "Read revision ${REVISION} from file") - ENDIF(EXISTS ${REVISION_FILE}) -ENDIF(SOURCE_DIR AND NOT DEFINED REVISION) + ENDIF() +ENDIF() IF(SOURCE_DIR AND DEFINED REVISION) IF(EXISTS ${SOURCE_DIR}/revision.h.in) @@ -73,5 +79,5 @@ IF(SOURCE_DIR AND DEFINED REVISION) NOW(BUILD_DATE) CONFIGURE_FILE(${SOURCE_DIR}/revision.h.in revision.h.txt) EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy revision.h.txt revision.h) # copy_if_different - ENDIF(EXISTS ${SOURCE_DIR}/revision.h.in) -ENDIF(SOURCE_DIR AND DEFINED REVISION) + ENDIF() +ENDIF() From 8472a6ff7fa7bc2558296cac94dab16c47037223 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 13:57:06 +0100 Subject: [PATCH 237/344] Fixed: Compilation --HG-- branch : hotfix --- code/nel/src/misc/config_file/cf_gramatical.cpp | 4 ++-- code/nel/src/misc/config_file/cf_gramatical.ypp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/nel/src/misc/config_file/cf_gramatical.cpp b/code/nel/src/misc/config_file/cf_gramatical.cpp index bc51ef371..1d8c568b7 100644 --- a/code/nel/src/misc/config_file/cf_gramatical.cpp +++ b/code/nel/src/misc/config_file/cf_gramatical.cpp @@ -1499,7 +1499,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_REAL: Var.IntValues.push_back ((int)Val.Real); break; - case NLMISC::CConfigFile::CVar::T_STRING: int val = 0; NLMISC::fromString(Val.String, val); Var.IntValues.push_back(val); break; + case NLMISC::CConfigFile::CVar::T_STRING: { int val = 0; NLMISC::fromString(Val.String, val); Var.IntValues.push_back(val); break; } default: break; } break; @@ -1507,7 +1507,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_INT: Var.RealValues.push_back ((double)Val.Int); break; - case NLMISC::CConfigFile::CVar::T_STRING: double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; + case NLMISC::CConfigFile::CVar::T_STRING: { double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; } default: break; } break; diff --git a/code/nel/src/misc/config_file/cf_gramatical.ypp b/code/nel/src/misc/config_file/cf_gramatical.ypp index 0f4fd2405..578bf53bf 100644 --- a/code/nel/src/misc/config_file/cf_gramatical.ypp +++ b/code/nel/src/misc/config_file/cf_gramatical.ypp @@ -517,7 +517,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_REAL: Var.IntValues.push_back ((int)Val.Real); break; - case NLMISC::CConfigFile::CVar::T_STRING: int val = 0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; + case NLMISC::CConfigFile::CVar::T_STRING: { int val = 0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; } default: break; } break; @@ -525,7 +525,7 @@ void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val) switch (Val.Type) { case NLMISC::CConfigFile::CVar::T_INT: Var.RealValues.push_back ((double)Val.Int); break; - case NLMISC::CConfigFile::CVar::T_STRING: double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; + case NLMISC::CConfigFile::CVar::T_STRING: { double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; } default: break; } break; From cdd35f58a1ea23584cfcbce8eae71b0e373db943 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 14:25:50 +0100 Subject: [PATCH 238/344] Fixed: Warning with multichars to int conversion --HG-- branch : hotfix --- code/nel/src/3d/vertex_program_parse.cpp | 183 ++++++++++++++++------- 1 file changed, 131 insertions(+), 52 deletions(-) diff --git a/code/nel/src/3d/vertex_program_parse.cpp b/code/nel/src/3d/vertex_program_parse.cpp index 40ac2282e..0e144d54f 100644 --- a/code/nel/src/3d/vertex_program_parse.cpp +++ b/code/nel/src/3d/vertex_program_parse.cpp @@ -17,7 +17,86 @@ #include "std3d.h" #include "nel/3d/vertex_program_parse.h" - +enum TArguments +{ +#ifdef NL_LITTLE_ENDIAN + ADD = 1094992928, + ARL = 1095912480, + BFC0 = 1111900976, + BFC1 = 1111900977, + COL0 = 1129270320, + COL1 = 1129270321, + DP3 = 1146106656, + DP4 = 1146106912, + DST = 1146311712, + END = 1162757152, + EXP = 1163415584, + EXPP = 1163415632, + FOGC = 1179600707, + HPOS = 1213222739, + LIT = 1279874080, + LOG = 1280263968, + MAD = 1296122912, + MAX = 1296128032, + MIN = 1296649760, + MOV = 1297045024, + MUL = 1297435680, + NRML = 1314016588, + OPOS = 1330663251, + PSIZ = 1347635546, + RCP = 1380143136, + RSQ = 1381191968, + SGE = 1397179680, + SLT = 1397511200, + TEX0 = 1413830704, + TEX1 = 1413830705, + TEX2 = 1413830706, + TEX3 = 1413830707, + TEX4 = 1413830708, + TEX5 = 1413830709, + TEX6 = 1413830710, + TEX7 = 1413830711, + WGHT = 1464289364, +#else + ADD = 541344833, + ARL = 541872705, + BFC0 = 809715266, + BFC1 = 826492482, + COL0 = 810307395, + COL1 = 827084611, + DP3 = 540233796, + DP4 = 540299332, + DST = 542397252, + END = 541347397, + EXP = 542136389, + EXPP = 1347442757, + FOGC = 1128746822, + HPOS = 1397706824, + LIT = 542394700, + LOG = 541544268, + MAD = 541344077, + MAX = 542654797, + MIN = 542001485, + MOV = 542527309, + MUL = 541873485, + NRML = 1280135758, + OPOS = 1397706831, + PSIZ = 1514754896, + RCP = 542131026, + RSQ = 542200658, + SGE = 541411155, + SLT = 542395475, + TEX0 = 811091284, + TEX1 = 827868500, + TEX2 = 844645716, + TEX3 = 861422932, + TEX4 = 878200148, + TEX5 = 894977364, + TEX6 = 911754580, + TEX7 = 928531796, + WGHT = 1414022999, +#endif +}; //===================================== bool CVPParser::parseWriteMask(uint &mask, std::string &errorOutput) @@ -256,23 +335,23 @@ bool CVPParser::parseInputRegister(CVPOperand &operand, std::string &errorOutput strValue |= ((uint32) *_CurrChar) << (8 * (3 - k)); ++_CurrChar; } - switch (strValue) + switch ((TArguments)strValue) { - case 'OPOS': operand.Value.InputRegisterValue = CVPOperand::IPosition; break; - case 'WGHT': operand.Value.InputRegisterValue = CVPOperand::IWeight; break; - case 'NRML': operand.Value.InputRegisterValue = CVPOperand::INormal; break; - case 'COL0': operand.Value.InputRegisterValue = CVPOperand::IPrimaryColor; break; - case 'COL1': operand.Value.InputRegisterValue = CVPOperand::ISecondaryColor; break; - case 'FOGC': operand.Value.InputRegisterValue = CVPOperand::IFogCoord; break; + case OPOS: operand.Value.InputRegisterValue = CVPOperand::IPosition; break; + case WGHT: operand.Value.InputRegisterValue = CVPOperand::IWeight; break; + case NRML: operand.Value.InputRegisterValue = CVPOperand::INormal; break; + case COL0: operand.Value.InputRegisterValue = CVPOperand::IPrimaryColor; break; + case COL1: operand.Value.InputRegisterValue = CVPOperand::ISecondaryColor; break; + case FOGC: operand.Value.InputRegisterValue = CVPOperand::IFogCoord; break; // texture argument - case 'TEX0': - case 'TEX1': - case 'TEX2': - case 'TEX3': - case 'TEX4': - case 'TEX5': - case 'TEX6': - case 'TEX7': + case TEX0: + case TEX1: + case TEX2: + case TEX3: + case TEX4: + case TEX5: + case TEX6: + case TEX7: operand.Value.InputRegisterValue = (CVPOperand::EInputRegister) (((CVPOperand::ITex0 + strValue) & 0xff) - '0'); break; default: @@ -384,23 +463,23 @@ bool CVPParser::parseOutputRegister(CVPOperand &operand, std::string &errorOutpu ++_CurrChar; } // convert to enum - switch(strValue) + switch((TArguments)strValue) { - case 'HPOS': operand.Value.OutputRegisterValue = CVPOperand::OHPosition; break; - case 'COL0': operand.Value.OutputRegisterValue = CVPOperand::OPrimaryColor; break; - case 'COL1': operand.Value.OutputRegisterValue = CVPOperand::OSecondaryColor; break; - case 'BFC0': operand.Value.OutputRegisterValue = CVPOperand::OBackFacePrimaryColor; break; - case 'BFC1': operand.Value.OutputRegisterValue = CVPOperand::OBackFaceSecondaryColor; break; - case 'FOGC': operand.Value.OutputRegisterValue = CVPOperand::OFogCoord; break; - case 'PSIZ': operand.Value.OutputRegisterValue = CVPOperand::OPointSize; break; - case 'TEX0': operand.Value.OutputRegisterValue = CVPOperand::OTex0; break; - case 'TEX1': operand.Value.OutputRegisterValue = CVPOperand::OTex1; break; - case 'TEX2': operand.Value.OutputRegisterValue = CVPOperand::OTex2; break; - case 'TEX3': operand.Value.OutputRegisterValue = CVPOperand::OTex3; break; - case 'TEX4': operand.Value.OutputRegisterValue = CVPOperand::OTex4; break; - case 'TEX5': operand.Value.OutputRegisterValue = CVPOperand::OTex5; break; - case 'TEX6': operand.Value.OutputRegisterValue = CVPOperand::OTex6; break; - case 'TEX7': operand.Value.OutputRegisterValue = CVPOperand::OTex7; break; + case HPOS: operand.Value.OutputRegisterValue = CVPOperand::OHPosition; break; + case COL0: operand.Value.OutputRegisterValue = CVPOperand::OPrimaryColor; break; + case COL1: operand.Value.OutputRegisterValue = CVPOperand::OSecondaryColor; break; + case BFC0: operand.Value.OutputRegisterValue = CVPOperand::OBackFacePrimaryColor; break; + case BFC1: operand.Value.OutputRegisterValue = CVPOperand::OBackFaceSecondaryColor; break; + case FOGC: operand.Value.OutputRegisterValue = CVPOperand::OFogCoord; break; + case PSIZ: operand.Value.OutputRegisterValue = CVPOperand::OPointSize; break; + case TEX0: operand.Value.OutputRegisterValue = CVPOperand::OTex0; break; + case TEX1: operand.Value.OutputRegisterValue = CVPOperand::OTex1; break; + case TEX2: operand.Value.OutputRegisterValue = CVPOperand::OTex2; break; + case TEX3: operand.Value.OutputRegisterValue = CVPOperand::OTex3; break; + case TEX4: operand.Value.OutputRegisterValue = CVPOperand::OTex4; break; + case TEX5: operand.Value.OutputRegisterValue = CVPOperand::OTex5; break; + case TEX6: operand.Value.OutputRegisterValue = CVPOperand::OTex6; break; + case TEX7: operand.Value.OutputRegisterValue = CVPOperand::OTex7; break; default: errorOutput = "Can't read index for output register."; return false; @@ -753,9 +832,9 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput { instrStr |= (uint32) ' '; } - switch (instrStr) + switch ((TArguments)instrStr) { - case 'ARL ': + case ARL: instr.Opcode = CVPInstruction::ARL; if (!parseOp2(instr, errorOutput)) return false; if (!instr.Src1.Swizzle.isScalar()) @@ -764,7 +843,7 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput return false; } break; - case 'RSQ ': + case RSQ: instr.Opcode = CVPInstruction::RSQ; if (!parseOp2(instr, errorOutput)) return false; if (!instr.Src1.Swizzle.isScalar()) @@ -773,8 +852,8 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput return false; } break; - case 'EXP ': - case 'EXPP': + case EXP: + case EXPP: instr.Opcode = CVPInstruction::EXPP; if (!parseOp2(instr, errorOutput)) return false; if (!instr.Src1.Swizzle.isScalar()) @@ -789,7 +868,7 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput return false; }*/ break; - case 'LOG ': + case LOG: instr.Opcode = CVPInstruction::LOG; if (!parseOp2(instr, errorOutput)) return false; if (!instr.Src1.Swizzle.isScalar()) @@ -805,7 +884,7 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput } */ break; - case 'RCP ': + case RCP: instr.Opcode = CVPInstruction::RCP; if (!parseOp2(instr, errorOutput)) return false; if (!instr.Src1.Swizzle.isScalar()) @@ -815,60 +894,60 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput } break; ///////////////// - case 'MOV ': + case MOV: instr.Opcode = CVPInstruction::MOV; if (!parseOp2(instr, errorOutput)) return false; break; - case 'LIT ': + case LIT: instr.Opcode = CVPInstruction::LIT; if (!parseOp2(instr, errorOutput)) return false; break; ///////////////// - case 'MAD ': + case MAD: instr.Opcode = CVPInstruction::MAD; if (!parseOp4(instr, errorOutput)) return false; break; ///////////////// - case 'ADD ': + case ADD: instr.Opcode = CVPInstruction::ADD; if (!parseOp3(instr, errorOutput)) return false; break; ///////////////// - case 'MUL ': + case MUL: instr.Opcode = CVPInstruction::MUL; if (!parseOp3(instr, errorOutput)) return false; break; - case 'DP3 ': + case DP3: instr.Opcode = CVPInstruction::DP3; if (!parseOp3(instr, errorOutput)) return false; break; - case 'DP4 ': + case DP4: instr.Opcode = CVPInstruction::DP4; if (!parseOp3(instr, errorOutput)) return false; break; - case 'DST ': + case DST: instr.Opcode = CVPInstruction::DST; if (!parseOp3(instr, errorOutput)) return false; break; - case 'MIN ': + case MIN: instr.Opcode = CVPInstruction::MIN; if (!parseOp3(instr, errorOutput)) return false; break; - case 'MAX ': + case MAX: instr.Opcode = CVPInstruction::MAX; if (!parseOp3(instr, errorOutput)) return false; break; - case 'SLT ': + case SLT: instr.Opcode = CVPInstruction::SLT; if (!parseOp3(instr, errorOutput)) return false; break; - case 'SGE ': + case SGE: instr.Opcode = CVPInstruction::SGE; if (!parseOp3(instr, errorOutput)) return false; break; ///////////////// - case 'END ': + case END: endEncountered = true; return true; break; From 4b397f3e5b826ac0ad46bda02df94932cb7c2a2c Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 15:18:53 +0100 Subject: [PATCH 239/344] Changed: Improved User Agent management --HG-- branch : hotfix --- .../src/interface_v3/interface_manager.cpp | 4 ++-- code/ryzom/client/src/user_agent.cpp | 17 ++++++++++++++--- code/ryzom/client/src/user_agent.h | 2 ++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 6f4f31d14..8186d246b 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -467,8 +467,8 @@ CInterfaceManager::CInterfaceManager() CGroupHTML::options.trustedDomains = ClientCfg.WebIgTrustedDomains; CGroupHTML::options.languageCode = ClientCfg.getHtmlLanguageCode(); - CGroupHTML::options.appName = "Ryzom"; - CGroupHTML::options.appVersion = getUserAgent(); + CGroupHTML::options.appName = getUserAgentName(); + CGroupHTML::options.appVersion = getUserAgentVersion(); NLGUI::CDBManager::getInstance()->resizeBanks( NB_CDB_BANKS ); interfaceLinkUpdater = new CInterfaceLink::CInterfaceLinkUpdater(); diff --git a/code/ryzom/client/src/user_agent.cpp b/code/ryzom/client/src/user_agent.cpp index af07e8b86..1452aa584 100644 --- a/code/ryzom/client/src/user_agent.cpp +++ b/code/ryzom/client/src/user_agent.cpp @@ -21,7 +21,7 @@ #include "game_share/ryzom_version.h" -#ifdef HAVE_REVISION_H +#if defined(RYZOM_COMPATIBILITY_VERSION) && defined(HAVE_REVISION_H) #include "revision.h" #endif @@ -45,6 +45,16 @@ #endif std::string getUserAgent() +{ + return getUserAgentName() + "/" + getUserAgentVersion(); +} + +std::string getUserAgentName() +{ + return "Ryzom"; +} + +std::string getUserAgentVersion() { static std::string s_userAgent; @@ -52,8 +62,9 @@ std::string getUserAgent() { char buffer[256]; -#ifdef REVISION - sprintf(buffer, "%s.%s-%s-%s", RYZOM_VERSION, REVISION, RYZOM_SYSTEM, RYZOM_ARCH); +#if defined(REVISION) && defined(RYZOM_COMPATIBILITY_VERSION) + // we don't need RYZOM_VERSION if we already have a numeric form a.b.c, we just need to append revision to it + sprintf(buffer, "%s.%s-%s-%s", RYZOM_COMPATIBILITY_VERSION, REVISION, RYZOM_SYSTEM, RYZOM_ARCH); #else sprintf(buffer, "%s-%s-%s", RYZOM_VERSION, RYZOM_SYSTEM, RYZOM_ARCH); #endif diff --git a/code/ryzom/client/src/user_agent.h b/code/ryzom/client/src/user_agent.h index e42635871..bc508273d 100644 --- a/code/ryzom/client/src/user_agent.h +++ b/code/ryzom/client/src/user_agent.h @@ -18,6 +18,8 @@ #define CL_USER_AGENT_H std::string getUserAgent(); +std::string getUserAgentName(); +std::string getUserAgentVersion(); #endif // CL_USER_AGENT_H From a42569ad24f0b4cf87e29e83e107d70ba1ee0a17 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 15:43:05 +0100 Subject: [PATCH 240/344] Added: PCH for admin_modules --HG-- branch : hotfix --- .../ryzom/server/src/admin_modules/stdpch.cpp | 17 +++++++ code/ryzom/server/src/admin_modules/stdpch.h | 45 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 code/ryzom/server/src/admin_modules/stdpch.cpp create mode 100644 code/ryzom/server/src/admin_modules/stdpch.h diff --git a/code/ryzom/server/src/admin_modules/stdpch.cpp b/code/ryzom/server/src/admin_modules/stdpch.cpp new file mode 100644 index 000000000..a3d45576c --- /dev/null +++ b/code/ryzom/server/src/admin_modules/stdpch.cpp @@ -0,0 +1,17 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" diff --git a/code/ryzom/server/src/admin_modules/stdpch.h b/code/ryzom/server/src/admin_modules/stdpch.h new file mode 100644 index 000000000..b7c667c73 --- /dev/null +++ b/code/ryzom/server/src/admin_modules/stdpch.h @@ -0,0 +1,45 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef AI_SHARE_STDPCH_H +#define AI_SHARE_STDPCH_H + +#include +#include + +#include "nel/misc/types_nl.h" + +#include "nel/misc/file.h" +#include "nel/misc/hierarchical_timer.h" +#include "nel/misc/mutable_container.h" +#include "nel/misc/path.h" +#include "nel/misc/singleton.h" +#include "nel/misc/sstring.h" +#include "nel/misc/string_conversion.h" +#include "nel/misc/time_nl.h" +#include "nel/net/message.h" +#include "nel/net/module.h" +#include "nel/net/module_builder_parts.h" +#include "nel/net/module_gateway.h" +#include "nel/net/module_manager.h" +#include "nel/net/module_message.h" +#include "nel/net/service.h" +#include "nel/net/unified_network.h" + +#include "game_share/callback_adaptor.h" +#include "game_share/utils.h" + +#endif From 859387758d1530f4d98c4b5b5f39c126643d9afb Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 16:05:45 +0100 Subject: [PATCH 241/344] Fixed: Compilation --HG-- branch : hotfix --- code/ryzom/server/src/server_share/used_continent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ryzom/server/src/server_share/used_continent.h b/code/ryzom/server/src/server_share/used_continent.h index 150b6342c..40b1eb6fc 100644 --- a/code/ryzom/server/src/server_share/used_continent.h +++ b/code/ryzom/server/src/server_share/used_continent.h @@ -21,6 +21,7 @@ #include "nel/misc/types_nl.h" #include "nel/net/service.h" #include "game_share/continent.h" +#include "game_share/misc_const.h" #include From 3509d75ad686b49fc40fe0c93a330995fca91e27 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 17:47:10 +0100 Subject: [PATCH 242/344] Fixed: Warning comparing an enum to an int --HG-- branch : hotfix --- code/ryzom/client/src/interface_v3/character_3d.cpp | 2 +- code/ryzom/common/src/game_share/people_pd.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/interface_v3/character_3d.cpp b/code/ryzom/client/src/interface_v3/character_3d.cpp index c76407f11..f711fb764 100644 --- a/code/ryzom/client/src/interface_v3/character_3d.cpp +++ b/code/ryzom/client/src/interface_v3/character_3d.cpp @@ -797,7 +797,7 @@ void CCharacter3D::setup (const SCharacter3DSetup &c3ds) } // Instance skin color - if (c3ds.People != -1) + if (c3ds.People != EGSPD::CPeople::Undefined) if ((c3ds.People != _CurrentSetup.People) || bInstanceRebuilt || bQualityRebuilt) { if (!_Instances[i].empty()) diff --git a/code/ryzom/common/src/game_share/people_pd.h b/code/ryzom/common/src/game_share/people_pd.h index 379a09378..ffcf8732f 100644 --- a/code/ryzom/common/src/game_share/people_pd.h +++ b/code/ryzom/common/src/game_share/people_pd.h @@ -51,6 +51,7 @@ public: enum TPeople { + Undefined = -1, Humanoid = 0, Playable = 0, Fyros = 0, From 5aa8a1d6152137f49b697a3979a867a489438b61 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 17:47:55 +0100 Subject: [PATCH 243/344] Fixed: Warning assert always false --HG-- branch : hotfix --- code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp | 2 +- code/ryzom/common/src/game_share/brick_types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 293582f52..6aa1f0e40 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -456,7 +456,7 @@ bool CCtrlSheetInfo::parseCtrlInfo(xmlNodePtr cur, CInterfaceGroup * /* parentGr else { // must not have so much brick type, else must change code! - nlassert(brickType<32); + // nlassert(brickType<32); // Ok set the bit associated _BrickTypeBitField|= 1< Date: Sat, 14 Feb 2015 17:52:15 +0100 Subject: [PATCH 244/344] Fixed: Unnamed semaphores are deprecated under OS X --HG-- branch : hotfix --- code/nel/include/nel/misc/mutex.h | 12 +++++++++--- code/nel/src/misc/mutex.cpp | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/misc/mutex.h b/code/nel/include/nel/misc/mutex.h index adbc7e7e5..cb7e9a188 100644 --- a/code/nel/include/nel/misc/mutex.h +++ b/code/nel/include/nel/misc/mutex.h @@ -28,7 +28,11 @@ # endif #elif defined(NL_OS_UNIX) # include // PThread -# include // PThread POSIX semaphores +# ifdef NL_OS_MAC +# include +# else +# include // PThread POSIX semaphores +# endif # include # define __forceinline # ifdef NL_OS_MAC @@ -532,8 +536,10 @@ private: #ifdef NL_OS_WINDOWS TNelRtlCriticalSection _Cs; -#elif defined NL_OS_UNIX - sem_t _Sem; +#elif defined(NL_OS_MAC) + dispatch_semaphore_t _Sem; +#elif defined(NL_OS_UNIX) + sem_t _Sem; #else # error "No fair mutex implementation for this OS" #endif diff --git a/code/nel/src/misc/mutex.cpp b/code/nel/src/misc/mutex.cpp index 3c86e2b29..28f6bae37 100644 --- a/code/nel/src/misc/mutex.cpp +++ b/code/nel/src/misc/mutex.cpp @@ -406,13 +406,21 @@ void CUnfairMutex::leave() */ CFairMutex::CFairMutex() { +#ifdef NL_OS_MAC + _Sem = dispatch_semaphore_create(1); +#else sem_init( const_cast(&_Sem), 0, 1 ); +#endif } CFairMutex::CFairMutex( const std::string &name ) { +#ifdef NL_OS_MAC + _Sem = dispatch_semaphore_create(1); +#else sem_init( const_cast(&_Sem), 0, 1 ); +#endif } @@ -421,7 +429,11 @@ CFairMutex::CFairMutex( const std::string &name ) */ CFairMutex::~CFairMutex() { +#ifdef NL_OS_MAC + dispatch_release(_Sem); +#else sem_destroy( const_cast(&_Sem) ); // needs that no thread is waiting on the semaphore +#endif } @@ -430,7 +442,11 @@ CFairMutex::~CFairMutex() */ void CFairMutex::enter() { +#ifdef NL_OS_MAC + dispatch_semaphore_wait(_Sem, DISPATCH_TIME_FOREVER); +#else sem_wait( const_cast(&_Sem) ); +#endif } @@ -439,7 +455,11 @@ void CFairMutex::enter() */ void CFairMutex::leave() { +#ifdef NL_OS_MAC + dispatch_semaphore_signal(_Sem); +#else sem_post( const_cast(&_Sem) ); +#endif } From bd054ea7769291bd03454b55f736ed01c709f1e8 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 14 Feb 2015 17:54:05 +0100 Subject: [PATCH 245/344] Fixed: Warning multichars --HG-- branch : hotfix --- code/ryzom/client/src/hair_set.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/code/ryzom/client/src/hair_set.cpp b/code/ryzom/client/src/hair_set.cpp index d82733162..5d44e2857 100644 --- a/code/ryzom/client/src/hair_set.cpp +++ b/code/ryzom/client/src/hair_set.cpp @@ -45,20 +45,20 @@ void CHairSet::init (NLMISC::IProgressCallback &progress) progress.progress ((float)k/(float)numHairItem); const CItemSheet *item = SheetMngr.getItem(SLOTTYPE::HEAD_SLOT, k); - if( (item) && (!item->getShape().empty()) ) + if (item && !item->getShape().empty()) { - std::string itemName = NLMISC::toLower(item->getShape()); - if (item->getShape().find("cheveux", 0) != std::string::npos) { // get race - uint16 race = (uint16) itemName[1] | ((uint16) itemName[0] << 8); - switch(race) + std::string itemName = NLMISC::toLower(item->getShape()); + + // fortunately, first character of each race is distinct + switch(itemName[0]) { - case 'ma': _Hairs[Matis].push_back(k); break; - case 'tr': _Hairs[Tryker].push_back(k); break; - case 'zo': _Hairs[Zorai].push_back(k); break; - case 'fy': _Hairs[Fyros].push_back(k); break; + case 'm': _Hairs[Matis].push_back(k); break; + case 't': _Hairs[Tryker].push_back(k); break; + case 'z': _Hairs[Zorai].push_back(k); break; + case 'f': _Hairs[Fyros].push_back(k); break; } } } From 9d6b9daebe6243979fd648802da769a463f02cbc Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 15 Feb 2015 09:53:56 +0100 Subject: [PATCH 246/344] Fixed: Wrong include guard for admin_modules PCH --HG-- branch : hotfix --- code/ryzom/server/src/admin_modules/stdpch.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/server/src/admin_modules/stdpch.h b/code/ryzom/server/src/admin_modules/stdpch.h index b7c667c73..be01e5019 100644 --- a/code/ryzom/server/src/admin_modules/stdpch.h +++ b/code/ryzom/server/src/admin_modules/stdpch.h @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef AI_SHARE_STDPCH_H -#define AI_SHARE_STDPCH_H +#ifndef ADMIN_MODULES_STDPCH_H +#define ADMIN_MODULES_STDPCH_H #include #include From fea7cff850d609907935f967ff3a6cb5e03959fc Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 17 Feb 2015 03:12:26 +0100 Subject: [PATCH 247/344] CMsgBoxDisplayer should not present a dialog now, but write the report to a file then attempt to launch the error reporter application. Which ofc doesn't exist yet in this commit. --HG-- branch : hotfix --- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/report.cpp | 291 ++------------------------------- code/ryzom/client/src/init.cpp | 2 + 3 files changed, 18 insertions(+), 277 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index c7667acc2..2d09f5ef8 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -83,7 +83,7 @@ using namespace std; #define LOG_IN_FILE NEL_LOG_IN_FILE // If true, debug system will trap crash even if the application is in debugger -static const bool TrapCrashInDebugger = false; +static const bool TrapCrashInDebugger = true; #ifdef DEBUG_NEW #define new DEBUG_NEW diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 20b2b1c11..39f27de5f 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -42,25 +42,14 @@ using namespace std; namespace NLMISC { -#ifdef NL_OS_WINDOWS -static HWND sendReport=NULL; -#endif - //old doesn't work on visual c++ 7.1 due to default parameter typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile = "", bool onlyCheck = false); typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile, bool onlyCheck); -#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } - static TEmailFunction EmailFunction = NULL; void setReportEmailFunction (void *emailFunction) { EmailFunction = (TEmailFunction)emailFunction; - -#ifdef NL_OS_WINDOWS - if (sendReport) - EnableWindow(sendReport, FALSE); -#endif } #ifndef NL_OS_WINDOWS @@ -73,91 +62,26 @@ void report () #else -// Windows specific version - -static string Body; -static string Subject; -static string AttachedFile; - -static HWND checkIgnore=NULL; -static HWND debug=NULL; -static HWND ignore=NULL; -static HWND quit=NULL; -static HWND dialog=NULL; - -static bool NeedExit; -static TReportResult Result; -static bool IgnoreNextTime; -static bool CanSendMailReport= false; +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +{ + std::string fname; -static bool DebugDefaultBehavior, QuitDefaultBehavior; + time_t s = time( NULL ); + fname = std::string( "log_" ) + toString( s ) + ".txt"; -static void sendEmail() -{ - if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) - { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - // EnableWindow(sendReport, FALSE); - // MessageBox (dialog, "The email was successfully sent", "email", MB_OK); -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_sent"); -#endif - } - else - { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_failed"); -#endif - // MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } - } - else + std::ofstream f; + f.open( fname.c_str() ); + if( f.good() ) { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_refused"); -#endif - } -} + f << body; + f.close(); -static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - //MSGFILTER *pmf; + NLMISC::launchProgram( "rcerror", fname ); + } - if (message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) - { - if ((HWND) lParam == checkIgnore) - { - IgnoreNextTime = !IgnoreNextTime; - } - else if ((HWND) lParam == debug) - { - sendEmail(); - NeedExit = true; - Result = ReportDebug; - if (DebugDefaultBehavior) - { - NLMISC_BREAKPOINT; - } - } - else if ((HWND) lParam == ignore) - { - sendEmail(); - NeedExit = true; - Result = ReportIgnore; - } - else if ((HWND) lParam == quit) - { - sendEmail(); - NeedExit = true; - Result = ReportQuit; + NLMISC::CFile::deleteFile( fname ); + - if (QuitDefaultBehavior) - { - // ace: we cannot call exit() because it's call the static object dtor and can crash the application - // if the dtor call order is not good. - //exit(EXIT_SUCCESS); #ifdef NL_OS_WINDOWS #ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. @@ -166,193 +90,8 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM #endif // quit without calling atexit or static object dtors. abort(); - } - } - /*else if ((HWND) lParam == sendReport) - { - if (EmailFunction != NULL) - { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - EnableWindow(sendReport, FALSE); - MessageBox (dialog, "The email was successfully sent", "email", MB_OK); - CFile::createEmptyFile(getLogDirectory() + "report_sent"); - } - else - { - MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } - } - }*/ - } - else if (message == WM_CHAR) - { - if (wParam == 27) - { - // ESC -> ignore - sendEmail(); - NeedExit = true; - Result = ReportIgnore; - } - } - - return DefWindowProc (hWnd, message, wParam, lParam); -} - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) -{ - // register the window - static bool AlreadyRegister = false; - if(!AlreadyRegister) - { - WNDCLASSW wc; - memset (&wc,0,sizeof(wc)); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"NLReportWindow"; - wc.lpszMenuName = NULL; - if (!RegisterClassW(&wc)) return ReportError; - AlreadyRegister = true; - } - - ucstring formatedTitle = title.empty() ? ucstring("NeL report") : ucstring(title); - - - // create the window - dialog = CreateWindowW (L"NLReportWindow", (LPCWSTR)formatedTitle.c_str(), WS_DLGFRAME | WS_CAPTION /*| WS_THICKFRAME*/, CW_USEDEFAULT, CW_USEDEFAULT, 456, 400, NULL, NULL, GetModuleHandle(NULL), NULL); - - // create the font - HFONT font = CreateFont (-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); - - Subject = subject; - AttachedFile = attachedFile; - - // create the edit control - HWND edit = CreateWindowW (L"EDIT", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_READONLY | ES_LEFT | ES_MULTILINE, 7, 70, 429, 212, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (edit, WM_SETFONT, (WPARAM) font, TRUE); - - // set the edit text limit to lot of :) - SendMessage (edit, EM_LIMITTEXT, ~0U, 0); - - Body = addSlashR (body); - - // set the message in the edit text - SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)Body.c_str()); - - if (enableCheckIgnore) - { - // create the combo box control - checkIgnore = CreateWindowW (L"BUTTON", L"Don't display this report again", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_CHECKBOX, 7, 290, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (checkIgnore, WM_SETFONT, (WPARAM) font, TRUE); - - if(ignoreNextTime) - { - SendMessage (checkIgnore, BM_SETCHECK, BST_CHECKED, 0); - } - } - - // create the debug button control - debug = CreateWindowW (L"BUTTON", L"Debug", WS_CHILD | WS_VISIBLE, 7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (debug, WM_SETFONT, (WPARAM) font, TRUE); - - if (debugButton == 0) - EnableWindow(debug, FALSE); - - // create the ignore button control - ignore = CreateWindowW (L"BUTTON", L"Ignore", WS_CHILD | WS_VISIBLE, 75+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (ignore, WM_SETFONT, (WPARAM) font, TRUE); - - if (ignoreButton == 0) - EnableWindow(ignore, FALSE); - - // create the quit button control - quit = CreateWindowW (L"BUTTON", L"Quit", WS_CHILD | WS_VISIBLE, 75+75+7+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (quit, WM_SETFONT, (WPARAM) font, TRUE); - - if (quitButton == 0) - EnableWindow(quit, FALSE); - - // create the debug button control - sendReport = CreateWindowW (L"BUTTON", L"Don't send the report", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 7, 315+32, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (sendReport, WM_SETFONT, (WPARAM) font, TRUE); - - string formatedHeader; - if (header.empty()) - { - formatedHeader = "This application stopped to display this report."; - } - else - { - formatedHeader = header; - } - - // ace don't do that because it s slow to try to send a mail - //CanSendMailReport = sendReportButton && EmailFunction != NULL && EmailFunction("", "", "", "", "", true); - CanSendMailReport = sendReportButton && EmailFunction != NULL; - - if (CanSendMailReport) - formatedHeader += " Send report will only email the contents of the box below. Please, send it to help us (it could take few minutes to send the email, be patient)."; - else - EnableWindow(sendReport, FALSE); - - ucstring uc = ucstring::makeFromUtf8(formatedHeader); - - // create the label control - HWND label = CreateWindowW (L"STATIC", (LPCWSTR)uc.c_str(), WS_CHILD | WS_VISIBLE /*| SS_WHITERECT*/, 7, 7, 429, 51, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (label, WM_SETFONT, (WPARAM) font, TRUE); - - - DebugDefaultBehavior = debugButton==1; - QuitDefaultBehavior = quitButton==1; - - IgnoreNextTime = ignoreNextTime; - - // show until the cursor really show :) - while (ShowCursor(TRUE) < 0) - ; - - SetWindowPos (dialog, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - - SetFocus(dialog); - SetForegroundWindow(dialog); - - NeedExit = false; - - while(!NeedExit) - { - MSG msg; - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - nlSleep (1); - } - - // set the user result - ignoreNextTime = IgnoreNextTime; - - ShowWindow(dialog, SW_HIDE); - - - - DELETE_OBJECT(sendReport) - DELETE_OBJECT(quit) - DELETE_OBJECT(ignore) - DELETE_OBJECT(debug) - DELETE_OBJECT(checkIgnore) - DELETE_OBJECT(edit) - DELETE_OBJECT(label) - DELETE_OBJECT(dialog) - return Result; + return ReportQuit; } #endif diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 6958fe790..c7fdc97f8 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -539,6 +539,8 @@ void checkDriverVersion() void checkDriverDepth () { + nlassert( false ); + // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From 73020237773b0c5dd4165988a9ae1f285d4dd675 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 17 Feb 2015 03:12:26 +0100 Subject: [PATCH 249/344] CMsgBoxDisplayer should not present a dialog now, but write the report to a file then attempt to launch the error reporter application. Which ofc doesn't exist yet in this commit. --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/report.cpp | 291 ++------------------------------- code/ryzom/client/src/init.cpp | 2 + 3 files changed, 18 insertions(+), 277 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index c7667acc2..2d09f5ef8 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -83,7 +83,7 @@ using namespace std; #define LOG_IN_FILE NEL_LOG_IN_FILE // If true, debug system will trap crash even if the application is in debugger -static const bool TrapCrashInDebugger = false; +static const bool TrapCrashInDebugger = true; #ifdef DEBUG_NEW #define new DEBUG_NEW diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 20b2b1c11..39f27de5f 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -42,25 +42,14 @@ using namespace std; namespace NLMISC { -#ifdef NL_OS_WINDOWS -static HWND sendReport=NULL; -#endif - //old doesn't work on visual c++ 7.1 due to default parameter typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile = "", bool onlyCheck = false); typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile, bool onlyCheck); -#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } - static TEmailFunction EmailFunction = NULL; void setReportEmailFunction (void *emailFunction) { EmailFunction = (TEmailFunction)emailFunction; - -#ifdef NL_OS_WINDOWS - if (sendReport) - EnableWindow(sendReport, FALSE); -#endif } #ifndef NL_OS_WINDOWS @@ -73,91 +62,26 @@ void report () #else -// Windows specific version - -static string Body; -static string Subject; -static string AttachedFile; - -static HWND checkIgnore=NULL; -static HWND debug=NULL; -static HWND ignore=NULL; -static HWND quit=NULL; -static HWND dialog=NULL; - -static bool NeedExit; -static TReportResult Result; -static bool IgnoreNextTime; -static bool CanSendMailReport= false; +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +{ + std::string fname; -static bool DebugDefaultBehavior, QuitDefaultBehavior; + time_t s = time( NULL ); + fname = std::string( "log_" ) + toString( s ) + ".txt"; -static void sendEmail() -{ - if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) - { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - // EnableWindow(sendReport, FALSE); - // MessageBox (dialog, "The email was successfully sent", "email", MB_OK); -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_sent"); -#endif - } - else - { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_failed"); -#endif - // MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } - } - else + std::ofstream f; + f.open( fname.c_str() ); + if( f.good() ) { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_refused"); -#endif - } -} + f << body; + f.close(); -static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - //MSGFILTER *pmf; + NLMISC::launchProgram( "rcerror", fname ); + } - if (message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) - { - if ((HWND) lParam == checkIgnore) - { - IgnoreNextTime = !IgnoreNextTime; - } - else if ((HWND) lParam == debug) - { - sendEmail(); - NeedExit = true; - Result = ReportDebug; - if (DebugDefaultBehavior) - { - NLMISC_BREAKPOINT; - } - } - else if ((HWND) lParam == ignore) - { - sendEmail(); - NeedExit = true; - Result = ReportIgnore; - } - else if ((HWND) lParam == quit) - { - sendEmail(); - NeedExit = true; - Result = ReportQuit; + NLMISC::CFile::deleteFile( fname ); + - if (QuitDefaultBehavior) - { - // ace: we cannot call exit() because it's call the static object dtor and can crash the application - // if the dtor call order is not good. - //exit(EXIT_SUCCESS); #ifdef NL_OS_WINDOWS #ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. @@ -166,193 +90,8 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM #endif // quit without calling atexit or static object dtors. abort(); - } - } - /*else if ((HWND) lParam == sendReport) - { - if (EmailFunction != NULL) - { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - EnableWindow(sendReport, FALSE); - MessageBox (dialog, "The email was successfully sent", "email", MB_OK); - CFile::createEmptyFile(getLogDirectory() + "report_sent"); - } - else - { - MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } - } - }*/ - } - else if (message == WM_CHAR) - { - if (wParam == 27) - { - // ESC -> ignore - sendEmail(); - NeedExit = true; - Result = ReportIgnore; - } - } - - return DefWindowProc (hWnd, message, wParam, lParam); -} - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) -{ - // register the window - static bool AlreadyRegister = false; - if(!AlreadyRegister) - { - WNDCLASSW wc; - memset (&wc,0,sizeof(wc)); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"NLReportWindow"; - wc.lpszMenuName = NULL; - if (!RegisterClassW(&wc)) return ReportError; - AlreadyRegister = true; - } - - ucstring formatedTitle = title.empty() ? ucstring("NeL report") : ucstring(title); - - - // create the window - dialog = CreateWindowW (L"NLReportWindow", (LPCWSTR)formatedTitle.c_str(), WS_DLGFRAME | WS_CAPTION /*| WS_THICKFRAME*/, CW_USEDEFAULT, CW_USEDEFAULT, 456, 400, NULL, NULL, GetModuleHandle(NULL), NULL); - - // create the font - HFONT font = CreateFont (-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); - - Subject = subject; - AttachedFile = attachedFile; - - // create the edit control - HWND edit = CreateWindowW (L"EDIT", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_READONLY | ES_LEFT | ES_MULTILINE, 7, 70, 429, 212, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (edit, WM_SETFONT, (WPARAM) font, TRUE); - - // set the edit text limit to lot of :) - SendMessage (edit, EM_LIMITTEXT, ~0U, 0); - - Body = addSlashR (body); - - // set the message in the edit text - SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)Body.c_str()); - - if (enableCheckIgnore) - { - // create the combo box control - checkIgnore = CreateWindowW (L"BUTTON", L"Don't display this report again", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_CHECKBOX, 7, 290, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (checkIgnore, WM_SETFONT, (WPARAM) font, TRUE); - - if(ignoreNextTime) - { - SendMessage (checkIgnore, BM_SETCHECK, BST_CHECKED, 0); - } - } - - // create the debug button control - debug = CreateWindowW (L"BUTTON", L"Debug", WS_CHILD | WS_VISIBLE, 7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (debug, WM_SETFONT, (WPARAM) font, TRUE); - - if (debugButton == 0) - EnableWindow(debug, FALSE); - - // create the ignore button control - ignore = CreateWindowW (L"BUTTON", L"Ignore", WS_CHILD | WS_VISIBLE, 75+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (ignore, WM_SETFONT, (WPARAM) font, TRUE); - - if (ignoreButton == 0) - EnableWindow(ignore, FALSE); - - // create the quit button control - quit = CreateWindowW (L"BUTTON", L"Quit", WS_CHILD | WS_VISIBLE, 75+75+7+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (quit, WM_SETFONT, (WPARAM) font, TRUE); - - if (quitButton == 0) - EnableWindow(quit, FALSE); - - // create the debug button control - sendReport = CreateWindowW (L"BUTTON", L"Don't send the report", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 7, 315+32, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (sendReport, WM_SETFONT, (WPARAM) font, TRUE); - - string formatedHeader; - if (header.empty()) - { - formatedHeader = "This application stopped to display this report."; - } - else - { - formatedHeader = header; - } - - // ace don't do that because it s slow to try to send a mail - //CanSendMailReport = sendReportButton && EmailFunction != NULL && EmailFunction("", "", "", "", "", true); - CanSendMailReport = sendReportButton && EmailFunction != NULL; - - if (CanSendMailReport) - formatedHeader += " Send report will only email the contents of the box below. Please, send it to help us (it could take few minutes to send the email, be patient)."; - else - EnableWindow(sendReport, FALSE); - - ucstring uc = ucstring::makeFromUtf8(formatedHeader); - - // create the label control - HWND label = CreateWindowW (L"STATIC", (LPCWSTR)uc.c_str(), WS_CHILD | WS_VISIBLE /*| SS_WHITERECT*/, 7, 7, 429, 51, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (label, WM_SETFONT, (WPARAM) font, TRUE); - - - DebugDefaultBehavior = debugButton==1; - QuitDefaultBehavior = quitButton==1; - - IgnoreNextTime = ignoreNextTime; - - // show until the cursor really show :) - while (ShowCursor(TRUE) < 0) - ; - - SetWindowPos (dialog, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - - SetFocus(dialog); - SetForegroundWindow(dialog); - - NeedExit = false; - - while(!NeedExit) - { - MSG msg; - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - nlSleep (1); - } - - // set the user result - ignoreNextTime = IgnoreNextTime; - - ShowWindow(dialog, SW_HIDE); - - - - DELETE_OBJECT(sendReport) - DELETE_OBJECT(quit) - DELETE_OBJECT(ignore) - DELETE_OBJECT(debug) - DELETE_OBJECT(checkIgnore) - DELETE_OBJECT(edit) - DELETE_OBJECT(label) - DELETE_OBJECT(dialog) - return Result; + return ReportQuit; } #endif diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 6958fe790..c7fdc97f8 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -539,6 +539,8 @@ void checkDriverVersion() void checkDriverDepth () { + nlassert( false ); + // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From 8208a473c4211a59db694fd4a5f4361edbf8e45f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 19 Feb 2015 00:20:18 +0100 Subject: [PATCH 250/344] Added the Ryzom Core Error Reporter's skeleton. --HG-- branch : hotfix --- code/nel/CMakeLists.txt | 3 ++ code/nel/rcerror/CMakeLists.txt | 37 +++++++++++++ code/nel/rcerror/rcerror.cpp | 50 ++++++++++++++++++ code/nel/rcerror/rcerror_socket.cpp | 20 +++++++ code/nel/rcerror/rcerror_socket.h | 23 ++++++++ code/nel/rcerror/rcerror_widget.cpp | 70 ++++++++++++++++++++++++ code/nel/rcerror/rcerror_widget.h | 47 +++++++++++++++++ code/nel/rcerror/rcerror_widget.ui | 82 +++++++++++++++++++++++++++++ 8 files changed, 332 insertions(+) create mode 100644 code/nel/rcerror/CMakeLists.txt create mode 100644 code/nel/rcerror/rcerror.cpp create mode 100644 code/nel/rcerror/rcerror_socket.cpp create mode 100644 code/nel/rcerror/rcerror_socket.h create mode 100644 code/nel/rcerror/rcerror_widget.cpp create mode 100644 code/nel/rcerror/rcerror_widget.h create mode 100644 code/nel/rcerror/rcerror_widget.ui diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 53bf071e3..00290d097 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -84,3 +84,6 @@ IF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) ADD_SUBDIRECTORY(tools) ENDIF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) +IF(WITH_QT) + ADD_SUBDIRECTORY(rcerror) +ENDIF(WITH_QT) diff --git a/code/nel/rcerror/CMakeLists.txt b/code/nel/rcerror/CMakeLists.txt new file mode 100644 index 000000000..412da9b6c --- /dev/null +++ b/code/nel/rcerror/CMakeLists.txt @@ -0,0 +1,37 @@ +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SRC_DIR} ${QT_INCLUDES}) +FILE(GLOB RCERROR_SRC *.cpp) +FILE(GLOB RCERROR_HDR *h) + +SET(RCERROR_MOC_HDR +rcerror_socket.h +rcerror_widget.h +) + +SET(RCERROR_UI +rcerror_widget.ui +) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTNETWORK TRUE) +SET(QT_USE_QTMAIN TRUE) +SET(QT_USE_QTOPENGL FALSE) +SET(QT_USE_QTXML FALSE) + +INCLUDE(${QT_USE_FILE}) +ADD_DEFINITIONS(${QT_DEFINITIONS}) + +QT4_WRAP_CPP(RCERROR_MOC_SRC ${RCERROR_MOC_HDR}) +QT4_WRAP_UI(RCERROR_UI_HDR ${RCERROR_UI}) + +SOURCE_GROUP(QtResources FILES ${RCERROR_UI}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${RCERROR_UI_HDR}) +SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${RCERROR_MOC_SRC}) +SOURCE_GROUP("source files" FILES ${RCERROR_SRC}) +SOURCE_GROUP("header files" FILES ${RCERROR_HDR}) + +ADD_EXECUTABLE(rcerror WIN32 MACOSX_BUNDLE ${RCERROR_SRC} ${RCERROR_MOC_HDR} ${RCERROR_MOC_SRC} ${RCERROR_UI_HDR}) +TARGET_LINK_LIBRARIES(rcerror ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) + +NL_DEFAULT_PROPS(rcerror "Ryzom Core Error Reporter") +NL_ADD_RUNTIME_FLAGS(rcerror) + diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp new file mode 100644 index 000000000..6fa876e81 --- /dev/null +++ b/code/nel/rcerror/rcerror.cpp @@ -0,0 +1,50 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "rcerror_widget.h" +#include +#include + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + +#if 0 + + if( argc < 2 ) + { + QMessageBox::information( NULL, + QObject::tr( "Error" ), + QObject::tr( "Need to specify a path to the error report." ) ); + return 1; + } +#endif + + RCErrorWidget w; + +#if 0 + w.setFileName( argv[ 1 ] ); +#else + w.setFileName( "log.log" ); +#endif + + w.show(); + + return app.exec(); +} \ No newline at end of file diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp new file mode 100644 index 000000000..f39946423 --- /dev/null +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -0,0 +1,20 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "rcerror_socket.h" + diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h new file mode 100644 index 000000000..8cd9f54ad --- /dev/null +++ b/code/nel/rcerror/rcerror_socket.h @@ -0,0 +1,23 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_SOCKET +#define RCERROR_SOCKET +#endif + diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp new file mode 100644 index 000000000..a50b273d3 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -0,0 +1,70 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "rcerror_widget.h" +#include +#include +#include + +RCErrorWidget::RCErrorWidget( QWidget *parent ) : +QWidget( parent ) +{ + m_ui.setupUi( this ); + QTimer::singleShot( 1, this, SLOT( onLoad() ) ); + + connect( m_ui.sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); + connect( m_ui.canceButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); +} + +RCErrorWidget::~RCErrorWidget() +{ +} + +void RCErrorWidget::onLoad() +{ + QFile f( m_fileName ); + bool b = f.open( QFile::ReadOnly | QFile::Text ); + if( !b ) + { + return; + } + + QTextStream ss( &f ); + m_ui.reportEdit->setPlainText( ss.readAll() ); + f.close(); +} + +void RCErrorWidget::onSendClicked() +{ + close(); +} + +void RCErrorWidget::onCancelClicked() +{ + close(); +} + +void RCErrorWidget::onCBClicked() +{ + m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); +} + + + diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h new file mode 100644 index 000000000..ae5629e55 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.h @@ -0,0 +1,47 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_WIDGET +#define RCERROR_SOCKET + + +#include "ui_rcerror_widget.h" + +class RCErrorWidget : public QWidget +{ + Q_OBJECT +public: + RCErrorWidget( QWidget *parent = NULL ); + ~RCErrorWidget(); + + void setFileName( const char *fn ){ m_fileName = fn; } + +private Q_SLOTS: + void onLoad(); + void onSendClicked(); + void onCancelClicked(); + void onCBClicked(); + +private: + Ui::RCErrorWidget m_ui; + QString m_fileName; +}; + +#endif + diff --git a/code/nel/rcerror/rcerror_widget.ui b/code/nel/rcerror/rcerror_widget.ui new file mode 100644 index 000000000..72e5f92f5 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.ui @@ -0,0 +1,82 @@ + + + RCErrorWidget + + + Qt::ApplicationModal + + + + 0 + 0 + 400 + 407 + + + + Ryzom Core error report + + + + + + What were you doing when the crash occured? + + + + + + + + + + Contents of the report ( automatically generated ) + + + + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Email me if you have further questions, or updates on this issue + + + + + + + false + + + Enter your email address here + + + + + + + Send + + + + + + + Cancel + + + + + + + + From ee0b630f95bcee30e8678104de553b388e13bd3f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 19 Feb 2015 00:20:18 +0100 Subject: [PATCH 251/344] Added the Ryzom Core Error Reporter's skeleton. --HG-- branch : feature-crashreport --- code/nel/CMakeLists.txt | 3 ++ code/nel/rcerror/CMakeLists.txt | 37 +++++++++++++ code/nel/rcerror/rcerror.cpp | 50 ++++++++++++++++++ code/nel/rcerror/rcerror_socket.cpp | 20 +++++++ code/nel/rcerror/rcerror_socket.h | 23 ++++++++ code/nel/rcerror/rcerror_widget.cpp | 70 ++++++++++++++++++++++++ code/nel/rcerror/rcerror_widget.h | 47 +++++++++++++++++ code/nel/rcerror/rcerror_widget.ui | 82 +++++++++++++++++++++++++++++ 8 files changed, 332 insertions(+) create mode 100644 code/nel/rcerror/CMakeLists.txt create mode 100644 code/nel/rcerror/rcerror.cpp create mode 100644 code/nel/rcerror/rcerror_socket.cpp create mode 100644 code/nel/rcerror/rcerror_socket.h create mode 100644 code/nel/rcerror/rcerror_widget.cpp create mode 100644 code/nel/rcerror/rcerror_widget.h create mode 100644 code/nel/rcerror/rcerror_widget.ui diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 53bf071e3..00290d097 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -84,3 +84,6 @@ IF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) ADD_SUBDIRECTORY(tools) ENDIF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) +IF(WITH_QT) + ADD_SUBDIRECTORY(rcerror) +ENDIF(WITH_QT) diff --git a/code/nel/rcerror/CMakeLists.txt b/code/nel/rcerror/CMakeLists.txt new file mode 100644 index 000000000..412da9b6c --- /dev/null +++ b/code/nel/rcerror/CMakeLists.txt @@ -0,0 +1,37 @@ +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SRC_DIR} ${QT_INCLUDES}) +FILE(GLOB RCERROR_SRC *.cpp) +FILE(GLOB RCERROR_HDR *h) + +SET(RCERROR_MOC_HDR +rcerror_socket.h +rcerror_widget.h +) + +SET(RCERROR_UI +rcerror_widget.ui +) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTNETWORK TRUE) +SET(QT_USE_QTMAIN TRUE) +SET(QT_USE_QTOPENGL FALSE) +SET(QT_USE_QTXML FALSE) + +INCLUDE(${QT_USE_FILE}) +ADD_DEFINITIONS(${QT_DEFINITIONS}) + +QT4_WRAP_CPP(RCERROR_MOC_SRC ${RCERROR_MOC_HDR}) +QT4_WRAP_UI(RCERROR_UI_HDR ${RCERROR_UI}) + +SOURCE_GROUP(QtResources FILES ${RCERROR_UI}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${RCERROR_UI_HDR}) +SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${RCERROR_MOC_SRC}) +SOURCE_GROUP("source files" FILES ${RCERROR_SRC}) +SOURCE_GROUP("header files" FILES ${RCERROR_HDR}) + +ADD_EXECUTABLE(rcerror WIN32 MACOSX_BUNDLE ${RCERROR_SRC} ${RCERROR_MOC_HDR} ${RCERROR_MOC_SRC} ${RCERROR_UI_HDR}) +TARGET_LINK_LIBRARIES(rcerror ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) + +NL_DEFAULT_PROPS(rcerror "Ryzom Core Error Reporter") +NL_ADD_RUNTIME_FLAGS(rcerror) + diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp new file mode 100644 index 000000000..6fa876e81 --- /dev/null +++ b/code/nel/rcerror/rcerror.cpp @@ -0,0 +1,50 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "rcerror_widget.h" +#include +#include + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + +#if 0 + + if( argc < 2 ) + { + QMessageBox::information( NULL, + QObject::tr( "Error" ), + QObject::tr( "Need to specify a path to the error report." ) ); + return 1; + } +#endif + + RCErrorWidget w; + +#if 0 + w.setFileName( argv[ 1 ] ); +#else + w.setFileName( "log.log" ); +#endif + + w.show(); + + return app.exec(); +} \ No newline at end of file diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp new file mode 100644 index 000000000..f39946423 --- /dev/null +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -0,0 +1,20 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "rcerror_socket.h" + diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h new file mode 100644 index 000000000..8cd9f54ad --- /dev/null +++ b/code/nel/rcerror/rcerror_socket.h @@ -0,0 +1,23 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_SOCKET +#define RCERROR_SOCKET +#endif + diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp new file mode 100644 index 000000000..a50b273d3 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -0,0 +1,70 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "rcerror_widget.h" +#include +#include +#include + +RCErrorWidget::RCErrorWidget( QWidget *parent ) : +QWidget( parent ) +{ + m_ui.setupUi( this ); + QTimer::singleShot( 1, this, SLOT( onLoad() ) ); + + connect( m_ui.sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); + connect( m_ui.canceButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); +} + +RCErrorWidget::~RCErrorWidget() +{ +} + +void RCErrorWidget::onLoad() +{ + QFile f( m_fileName ); + bool b = f.open( QFile::ReadOnly | QFile::Text ); + if( !b ) + { + return; + } + + QTextStream ss( &f ); + m_ui.reportEdit->setPlainText( ss.readAll() ); + f.close(); +} + +void RCErrorWidget::onSendClicked() +{ + close(); +} + +void RCErrorWidget::onCancelClicked() +{ + close(); +} + +void RCErrorWidget::onCBClicked() +{ + m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); +} + + + diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h new file mode 100644 index 000000000..ae5629e55 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.h @@ -0,0 +1,47 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_WIDGET +#define RCERROR_SOCKET + + +#include "ui_rcerror_widget.h" + +class RCErrorWidget : public QWidget +{ + Q_OBJECT +public: + RCErrorWidget( QWidget *parent = NULL ); + ~RCErrorWidget(); + + void setFileName( const char *fn ){ m_fileName = fn; } + +private Q_SLOTS: + void onLoad(); + void onSendClicked(); + void onCancelClicked(); + void onCBClicked(); + +private: + Ui::RCErrorWidget m_ui; + QString m_fileName; +}; + +#endif + diff --git a/code/nel/rcerror/rcerror_widget.ui b/code/nel/rcerror/rcerror_widget.ui new file mode 100644 index 000000000..72e5f92f5 --- /dev/null +++ b/code/nel/rcerror/rcerror_widget.ui @@ -0,0 +1,82 @@ + + + RCErrorWidget + + + Qt::ApplicationModal + + + + 0 + 0 + 400 + 407 + + + + Ryzom Core error report + + + + + + What were you doing when the crash occured? + + + + + + + + + + Contents of the report ( automatically generated ) + + + + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Email me if you have further questions, or updates on this issue + + + + + + + false + + + Enter your email address here + + + + + + + Send + + + + + + + Cancel + + + + + + + + From a6ee23ebe415ba1636362048c1df9e35d7a01471 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 01:59:04 +0100 Subject: [PATCH 252/344] Implemented the bug report Qt app and an example web app that takes the report. --HG-- branch : hotfix --- code/nel/rcerror/rcerror_data.h | 33 ++++++++ code/nel/rcerror/rcerror_socket.cpp | 46 +++++++++++ code/nel/rcerror/rcerror_socket.h | 26 ++++++ code/nel/rcerror/rcerror_widget.cpp | 25 +++++- code/nel/rcerror/rcerror_widget.h | 7 +- code/web/rcerror_web/config.inc.php | 30 +++++++ code/web/rcerror_web/log.inc.php | 45 +++++++++++ code/web/rcerror_web/rcerror.php | 112 ++++++++++++++++++++++++++ code/web/rcerror_web/rcerror_test.htm | 19 +++++ 9 files changed, 341 insertions(+), 2 deletions(-) create mode 100644 code/nel/rcerror/rcerror_data.h create mode 100644 code/web/rcerror_web/config.inc.php create mode 100644 code/web/rcerror_web/log.inc.php create mode 100644 code/web/rcerror_web/rcerror.php create mode 100644 code/web/rcerror_web/rcerror_test.htm diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/rcerror/rcerror_data.h new file mode 100644 index 000000000..146102038 --- /dev/null +++ b/code/nel/rcerror/rcerror_data.h @@ -0,0 +1,33 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_DATA +#define RCERROR_DATA + +#include + + +struct RCErrorData +{ + QString description; + QString report; + QString email; +}; + +#endif diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index f39946423..d84f69ec8 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -17,4 +17,50 @@ // along with this program. If not, see . #include "rcerror_socket.h" +#include +#include +#include + +namespace +{ + static const char *BUG_URL = "http://192.168.2.67/dfighter/r.php"; +} + +class RCErrorSocketPvt +{ +public: + QNetworkAccessManager mgr; +}; + +RCErrorSocket::RCErrorSocket( QObject *parent ) : +QObject( parent ) +{ + m_pvt = new RCErrorSocketPvt(); + + connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished() ) ); +} + +RCErrorSocket::~RCErrorSocket() +{ + delete m_pvt; +} + +void RCErrorSocket::sendReport( const RCErrorData &data ) +{ + QUrl params; + params.addQueryItem( "report", data.report ); + params.addQueryItem( "descr", data.description ); + params.addQueryItem( "email", data.email ); + + QUrl url( BUG_URL ); + QNetworkRequest request( url ); + request.setRawHeader( "Connection", "close" ); + + m_pvt->mgr.post( request, params.encodedQuery() ); +} + +void RCErrorSocket::onFinished() +{ + Q_EMIT reportSent(); +} diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index 8cd9f54ad..ee0f510b1 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -19,5 +19,31 @@ #ifndef RCERROR_SOCKET #define RCERROR_SOCKET + +#include +#include "rcerror_data.h" + +class RCErrorSocketPvt; + +class RCErrorSocket : public QObject +{ + Q_OBJECT + +public: + RCErrorSocket( QObject *parent ); + ~RCErrorSocket(); + + void sendReport( const RCErrorData &data ); + +Q_SIGNALS: + void reportSent(); + +private Q_SLOTS: + void onFinished(); + +private: + RCErrorSocketPvt *m_pvt; +}; + #endif diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index a50b273d3..faded0afa 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -18,23 +18,32 @@ #include "rcerror_widget.h" +#include "rcerror_socket.h" +#include "rcerror_data.h" #include #include #include +#include RCErrorWidget::RCErrorWidget( QWidget *parent ) : QWidget( parent ) { m_ui.setupUi( this ); + + m_socket = new RCErrorSocket( this ); + QTimer::singleShot( 1, this, SLOT( onLoad() ) ); connect( m_ui.sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); connect( m_ui.canceButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); + + connect( m_socket, SIGNAL( reportSent() ), this, SLOT( onReportSent() ) ); } RCErrorWidget::~RCErrorWidget() { + m_socket = NULL; } void RCErrorWidget::onLoad() @@ -53,7 +62,14 @@ void RCErrorWidget::onLoad() void RCErrorWidget::onSendClicked() { - close(); + m_ui.sendButton->setEnabled( false ); + + RCErrorData data; + data.description = m_ui.descriptionEdit->toPlainText(); + data.report = m_ui.reportEdit->toPlainText(); + data.email = m_ui.emailEdit->text(); + + m_socket->sendReport( data ); } void RCErrorWidget::onCancelClicked() @@ -66,5 +82,12 @@ void RCErrorWidget::onCBClicked() m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } +void RCErrorWidget::onReportSent() +{ + QMessageBox::information( this, + tr( "Report sent" ), + tr( "The report has been sent." ) ); + close(); +} diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index ae5629e55..869838e41 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -18,11 +18,13 @@ #ifndef RCERROR_WIDGET -#define RCERROR_SOCKET +#define RCERROR_WIDGET #include "ui_rcerror_widget.h" +class RCErrorSocket; + class RCErrorWidget : public QWidget { Q_OBJECT @@ -37,10 +39,13 @@ private Q_SLOTS: void onSendClicked(); void onCancelClicked(); void onCBClicked(); + + void onReportSent(); private: Ui::RCErrorWidget m_ui; QString m_fileName; + RCErrorSocket *m_socket; }; #endif diff --git a/code/web/rcerror_web/config.inc.php b/code/web/rcerror_web/config.inc.php new file mode 100644 index 000000000..fe4b3e928 --- /dev/null +++ b/code/web/rcerror_web/config.inc.php @@ -0,0 +1,30 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +class BugReportConfig +{ + static public $dbhost = "localhost"; + static public $dbport = "3306"; + static public $dbdb = "bugs"; + static public $dbuser = "bugs"; + static public $dbpw = "bugs"; +} + +?> diff --git a/code/web/rcerror_web/log.inc.php b/code/web/rcerror_web/log.inc.php new file mode 100644 index 000000000..71deee24f --- /dev/null +++ b/code/web/rcerror_web/log.inc.php @@ -0,0 +1,45 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +/// Simple file logger class +class Logger +{ + private $lf = NULL; + + function __construct() + { + $this->lf = fopen( 'log.txt', 'a' ); + if( $this->lf === FALSE ) + exit( 1 ); + } + + function __destruct() + { + fclose( $this->lf ); + } + + public function log( $msg ) + { + $date = date( "[M d, Y H:i:s] " ); + fwrite( $this->lf, $date . $msg . "\n" ); + } +} + +?> diff --git a/code/web/rcerror_web/rcerror.php b/code/web/rcerror_web/rcerror.php new file mode 100644 index 000000000..d20214d11 --- /dev/null +++ b/code/web/rcerror_web/rcerror.php @@ -0,0 +1,112 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +require_once( 'config.inc.php' ); +require_once( 'log.inc.php' ); + +/// Example web application that takes bug reports from the bug reporter Qt app +class BugReportGatherApp +{ + private $db = NULL; + private $logger = NULL; + + function __construct() + { + $this->logger = new Logger(); + } + + private function logPOSTVars() + { + $report = ""; + $descr = ""; + $email = ""; + + if( isset( $_POST[ 'report' ] ) ) + $report = $_POST[ 'report' ]; + + if( isset( $_POST[ 'descr' ] ) ) + $descr = $_POST[ 'descr' ]; + + if( isset( $_POST[ 'email' ] ) ) + $email = $_POST[ 'email' ]; + + $this->logger->log( 'report: ' . "\n" . $report ); + $this->logger->log( 'description: ' . "\n" . $descr ); + $this->logger->log( 'email: ' . "\n" . $email ); + } + + private function buildQuery() + { + $report = ""; + $descr = ""; + $email = ""; + + if( isset( $_POST[ 'report' ] ) ) + $report = $_POST[ 'report' ]; + + if( isset( $_POST[ 'descr' ] ) ) + $descr = $_POST[ 'descr' ]; + + if( isset( $_POST[ 'email' ] ) ) + $email = $_POST[ 'email' ]; + + $report = $this->db->real_escape_string( $report ); + $descr = $this->db->real_escape_string( $descr ); + $email = $this->db->real_escape_string( $email ); + + + $q = "INSERT INTO `bugs` (`report`,`description`,`email`) VALUES ("; + $q .= "'$report',"; + $q .= "'$descr',"; + $q .= "'$email')"; + + return $q; + } + + public function exec() + { + //$this->logPOSTVars(); + + $this->db = new mysqli( BugReportConfig::$dbhost, BugReportConfig::$dbuser, BugReportConfig::$dbpw, BugReportConfig::$dbdb, BugReportConfig::$dbport ); + if( mysqli_connect_error() ) + { + $this->logger->log( "Connection error :(" ); + $this->logger->log( mysqli_connect_error() ); + return; + } + + $q = $this->buildQuery(); + $result = $this->db->query( $q ); + if( $result !== TRUE ) + { + $this->logger->log( "Query failed :(" ); + $this->logger->log( 'Query: ' . $q ); + $this->logPOSTVars(); + } + + $this->db->close(); + } +} + + +$app = new BugReportGatherApp(); +$app->exec(); + +?> diff --git a/code/web/rcerror_web/rcerror_test.htm b/code/web/rcerror_web/rcerror_test.htm new file mode 100644 index 000000000..eb314d3f7 --- /dev/null +++ b/code/web/rcerror_web/rcerror_test.htm @@ -0,0 +1,19 @@ + +Ryzom Core Error Report Web application test harness + +
    + + + + + + + + + +
    Description
    Report
    Email
    + +
    +
    + + From 03ce683e4960d5f8606b05ca12083e10c6599e86 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 01:59:04 +0100 Subject: [PATCH 253/344] Implemented the bug report Qt app and an example web app that takes the report. --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror_data.h | 33 ++++++++ code/nel/rcerror/rcerror_socket.cpp | 46 +++++++++++ code/nel/rcerror/rcerror_socket.h | 26 ++++++ code/nel/rcerror/rcerror_widget.cpp | 25 +++++- code/nel/rcerror/rcerror_widget.h | 7 +- code/web/rcerror_web/config.inc.php | 30 +++++++ code/web/rcerror_web/log.inc.php | 45 +++++++++++ code/web/rcerror_web/rcerror.php | 112 ++++++++++++++++++++++++++ code/web/rcerror_web/rcerror_test.htm | 19 +++++ 9 files changed, 341 insertions(+), 2 deletions(-) create mode 100644 code/nel/rcerror/rcerror_data.h create mode 100644 code/web/rcerror_web/config.inc.php create mode 100644 code/web/rcerror_web/log.inc.php create mode 100644 code/web/rcerror_web/rcerror.php create mode 100644 code/web/rcerror_web/rcerror_test.htm diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/rcerror/rcerror_data.h new file mode 100644 index 000000000..146102038 --- /dev/null +++ b/code/nel/rcerror/rcerror_data.h @@ -0,0 +1,33 @@ +// Ryzom Core MMORPG framework - Error Reporter +// +// Copyright (C) 2015 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RCERROR_DATA +#define RCERROR_DATA + +#include + + +struct RCErrorData +{ + QString description; + QString report; + QString email; +}; + +#endif diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index f39946423..d84f69ec8 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -17,4 +17,50 @@ // along with this program. If not, see . #include "rcerror_socket.h" +#include +#include +#include + +namespace +{ + static const char *BUG_URL = "http://192.168.2.67/dfighter/r.php"; +} + +class RCErrorSocketPvt +{ +public: + QNetworkAccessManager mgr; +}; + +RCErrorSocket::RCErrorSocket( QObject *parent ) : +QObject( parent ) +{ + m_pvt = new RCErrorSocketPvt(); + + connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished() ) ); +} + +RCErrorSocket::~RCErrorSocket() +{ + delete m_pvt; +} + +void RCErrorSocket::sendReport( const RCErrorData &data ) +{ + QUrl params; + params.addQueryItem( "report", data.report ); + params.addQueryItem( "descr", data.description ); + params.addQueryItem( "email", data.email ); + + QUrl url( BUG_URL ); + QNetworkRequest request( url ); + request.setRawHeader( "Connection", "close" ); + + m_pvt->mgr.post( request, params.encodedQuery() ); +} + +void RCErrorSocket::onFinished() +{ + Q_EMIT reportSent(); +} diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index 8cd9f54ad..ee0f510b1 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -19,5 +19,31 @@ #ifndef RCERROR_SOCKET #define RCERROR_SOCKET + +#include +#include "rcerror_data.h" + +class RCErrorSocketPvt; + +class RCErrorSocket : public QObject +{ + Q_OBJECT + +public: + RCErrorSocket( QObject *parent ); + ~RCErrorSocket(); + + void sendReport( const RCErrorData &data ); + +Q_SIGNALS: + void reportSent(); + +private Q_SLOTS: + void onFinished(); + +private: + RCErrorSocketPvt *m_pvt; +}; + #endif diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index a50b273d3..faded0afa 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -18,23 +18,32 @@ #include "rcerror_widget.h" +#include "rcerror_socket.h" +#include "rcerror_data.h" #include #include #include +#include RCErrorWidget::RCErrorWidget( QWidget *parent ) : QWidget( parent ) { m_ui.setupUi( this ); + + m_socket = new RCErrorSocket( this ); + QTimer::singleShot( 1, this, SLOT( onLoad() ) ); connect( m_ui.sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); connect( m_ui.canceButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); + + connect( m_socket, SIGNAL( reportSent() ), this, SLOT( onReportSent() ) ); } RCErrorWidget::~RCErrorWidget() { + m_socket = NULL; } void RCErrorWidget::onLoad() @@ -53,7 +62,14 @@ void RCErrorWidget::onLoad() void RCErrorWidget::onSendClicked() { - close(); + m_ui.sendButton->setEnabled( false ); + + RCErrorData data; + data.description = m_ui.descriptionEdit->toPlainText(); + data.report = m_ui.reportEdit->toPlainText(); + data.email = m_ui.emailEdit->text(); + + m_socket->sendReport( data ); } void RCErrorWidget::onCancelClicked() @@ -66,5 +82,12 @@ void RCErrorWidget::onCBClicked() m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } +void RCErrorWidget::onReportSent() +{ + QMessageBox::information( this, + tr( "Report sent" ), + tr( "The report has been sent." ) ); + close(); +} diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index ae5629e55..869838e41 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -18,11 +18,13 @@ #ifndef RCERROR_WIDGET -#define RCERROR_SOCKET +#define RCERROR_WIDGET #include "ui_rcerror_widget.h" +class RCErrorSocket; + class RCErrorWidget : public QWidget { Q_OBJECT @@ -37,10 +39,13 @@ private Q_SLOTS: void onSendClicked(); void onCancelClicked(); void onCBClicked(); + + void onReportSent(); private: Ui::RCErrorWidget m_ui; QString m_fileName; + RCErrorSocket *m_socket; }; #endif diff --git a/code/web/rcerror_web/config.inc.php b/code/web/rcerror_web/config.inc.php new file mode 100644 index 000000000..fe4b3e928 --- /dev/null +++ b/code/web/rcerror_web/config.inc.php @@ -0,0 +1,30 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +class BugReportConfig +{ + static public $dbhost = "localhost"; + static public $dbport = "3306"; + static public $dbdb = "bugs"; + static public $dbuser = "bugs"; + static public $dbpw = "bugs"; +} + +?> diff --git a/code/web/rcerror_web/log.inc.php b/code/web/rcerror_web/log.inc.php new file mode 100644 index 000000000..71deee24f --- /dev/null +++ b/code/web/rcerror_web/log.inc.php @@ -0,0 +1,45 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +/// Simple file logger class +class Logger +{ + private $lf = NULL; + + function __construct() + { + $this->lf = fopen( 'log.txt', 'a' ); + if( $this->lf === FALSE ) + exit( 1 ); + } + + function __destruct() + { + fclose( $this->lf ); + } + + public function log( $msg ) + { + $date = date( "[M d, Y H:i:s] " ); + fwrite( $this->lf, $date . $msg . "\n" ); + } +} + +?> diff --git a/code/web/rcerror_web/rcerror.php b/code/web/rcerror_web/rcerror.php new file mode 100644 index 000000000..d20214d11 --- /dev/null +++ b/code/web/rcerror_web/rcerror.php @@ -0,0 +1,112 @@ + +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +require_once( 'config.inc.php' ); +require_once( 'log.inc.php' ); + +/// Example web application that takes bug reports from the bug reporter Qt app +class BugReportGatherApp +{ + private $db = NULL; + private $logger = NULL; + + function __construct() + { + $this->logger = new Logger(); + } + + private function logPOSTVars() + { + $report = ""; + $descr = ""; + $email = ""; + + if( isset( $_POST[ 'report' ] ) ) + $report = $_POST[ 'report' ]; + + if( isset( $_POST[ 'descr' ] ) ) + $descr = $_POST[ 'descr' ]; + + if( isset( $_POST[ 'email' ] ) ) + $email = $_POST[ 'email' ]; + + $this->logger->log( 'report: ' . "\n" . $report ); + $this->logger->log( 'description: ' . "\n" . $descr ); + $this->logger->log( 'email: ' . "\n" . $email ); + } + + private function buildQuery() + { + $report = ""; + $descr = ""; + $email = ""; + + if( isset( $_POST[ 'report' ] ) ) + $report = $_POST[ 'report' ]; + + if( isset( $_POST[ 'descr' ] ) ) + $descr = $_POST[ 'descr' ]; + + if( isset( $_POST[ 'email' ] ) ) + $email = $_POST[ 'email' ]; + + $report = $this->db->real_escape_string( $report ); + $descr = $this->db->real_escape_string( $descr ); + $email = $this->db->real_escape_string( $email ); + + + $q = "INSERT INTO `bugs` (`report`,`description`,`email`) VALUES ("; + $q .= "'$report',"; + $q .= "'$descr',"; + $q .= "'$email')"; + + return $q; + } + + public function exec() + { + //$this->logPOSTVars(); + + $this->db = new mysqli( BugReportConfig::$dbhost, BugReportConfig::$dbuser, BugReportConfig::$dbpw, BugReportConfig::$dbdb, BugReportConfig::$dbport ); + if( mysqli_connect_error() ) + { + $this->logger->log( "Connection error :(" ); + $this->logger->log( mysqli_connect_error() ); + return; + } + + $q = $this->buildQuery(); + $result = $this->db->query( $q ); + if( $result !== TRUE ) + { + $this->logger->log( "Query failed :(" ); + $this->logger->log( 'Query: ' . $q ); + $this->logPOSTVars(); + } + + $this->db->close(); + } +} + + +$app = new BugReportGatherApp(); +$app->exec(); + +?> diff --git a/code/web/rcerror_web/rcerror_test.htm b/code/web/rcerror_web/rcerror_test.htm new file mode 100644 index 000000000..eb314d3f7 --- /dev/null +++ b/code/web/rcerror_web/rcerror_test.htm @@ -0,0 +1,19 @@ + +Ryzom Core Error Report Web application test harness + +
    + + + + + + + + + +
    Description
    Report
    Email
    + +
    +
    + + From 2fe77d719f5c41fd64aa71c886abd6e71ddc49c3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:03:33 +0100 Subject: [PATCH 254/344] Probably a good idea to look for rcerror as rcerror.exe on Windows. --HG-- branch : hotfix --- code/nel/src/misc/report.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 39f27de5f..1a94e17a6 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -76,7 +76,11 @@ TReportResult report (const std::string &title, const std::string &header, const f << body; f.close(); +#ifdef NL_OS_WINDOWS + NLMISC::launchProgram( "rcerror.exe", fname ); +#else NLMISC::launchProgram( "rcerror", fname ); +#endif } NLMISC::CFile::deleteFile( fname ); From 9518a80c99da94ed0e9d4ca46d63da686f9d6966 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:03:33 +0100 Subject: [PATCH 255/344] Probably a good idea to look for rcerror as rcerror.exe on Windows. --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 39f27de5f..1a94e17a6 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -76,7 +76,11 @@ TReportResult report (const std::string &title, const std::string &header, const f << body; f.close(); +#ifdef NL_OS_WINDOWS + NLMISC::launchProgram( "rcerror.exe", fname ); +#else NLMISC::launchProgram( "rcerror", fname ); +#endif } NLMISC::CFile::deleteFile( fname ); From 469e5583c1871a8911fb5e4d188c5a70355350b9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:35:11 +0100 Subject: [PATCH 256/344] Unfortunately on Windows argc and argv parameters are unreliable inside a Qt application, so I had to hardcode the report file name. :( --HG-- branch : hotfix --- code/nel/rcerror/rcerror.cpp | 19 +------------------ code/nel/rcerror/rcerror_widget.cpp | 5 ++++- code/nel/src/misc/report.cpp | 8 +------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp index 6fa876e81..0d5088167 100644 --- a/code/nel/rcerror/rcerror.cpp +++ b/code/nel/rcerror/rcerror.cpp @@ -25,25 +25,8 @@ int main( int argc, char **argv ) { QApplication app( argc, argv ); -#if 0 - - if( argc < 2 ) - { - QMessageBox::information( NULL, - QObject::tr( "Error" ), - QObject::tr( "Need to specify a path to the error report." ) ); - return 1; - } -#endif - RCErrorWidget w; - -#if 0 - w.setFileName( argv[ 1 ] ); -#else - w.setFileName( "log.log" ); -#endif - + w.setFileName( "rcerrorlog.txt" ); w.show(); return app.exec(); diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index faded0afa..6c31533ad 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -52,7 +52,10 @@ void RCErrorWidget::onLoad() bool b = f.open( QFile::ReadOnly | QFile::Text ); if( !b ) { - return; + QMessageBox::information( this, + tr( "No log file found" ), + tr( "There was no log file found, therefore nothing to report. Exiting..." ) ); + close(); } QTextStream ss( &f ); diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 1a94e17a6..88c707aaa 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -64,10 +64,7 @@ void report () TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { - std::string fname; - - time_t s = time( NULL ); - fname = std::string( "log_" ) + toString( s ) + ".txt"; + std::string fname = "rcerrorlog.txt"; std::ofstream f; f.open( fname.c_str() ); @@ -83,9 +80,6 @@ TReportResult report (const std::string &title, const std::string &header, const #endif } - NLMISC::CFile::deleteFile( fname ); - - #ifdef NL_OS_WINDOWS #ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. From f0869aa65961ce24fea94e44358df57c0b964a06 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:35:11 +0100 Subject: [PATCH 257/344] Unfortunately on Windows argc and argv parameters are unreliable inside a Qt application, so I had to hardcode the report file name. :( --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror.cpp | 19 +------------------ code/nel/rcerror/rcerror_widget.cpp | 5 ++++- code/nel/src/misc/report.cpp | 8 +------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp index 6fa876e81..0d5088167 100644 --- a/code/nel/rcerror/rcerror.cpp +++ b/code/nel/rcerror/rcerror.cpp @@ -25,25 +25,8 @@ int main( int argc, char **argv ) { QApplication app( argc, argv ); -#if 0 - - if( argc < 2 ) - { - QMessageBox::information( NULL, - QObject::tr( "Error" ), - QObject::tr( "Need to specify a path to the error report." ) ); - return 1; - } -#endif - RCErrorWidget w; - -#if 0 - w.setFileName( argv[ 1 ] ); -#else - w.setFileName( "log.log" ); -#endif - + w.setFileName( "rcerrorlog.txt" ); w.show(); return app.exec(); diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index faded0afa..6c31533ad 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -52,7 +52,10 @@ void RCErrorWidget::onLoad() bool b = f.open( QFile::ReadOnly | QFile::Text ); if( !b ) { - return; + QMessageBox::information( this, + tr( "No log file found" ), + tr( "There was no log file found, therefore nothing to report. Exiting..." ) ); + close(); } QTextStream ss( &f ); diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 1a94e17a6..88c707aaa 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -64,10 +64,7 @@ void report () TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { - std::string fname; - - time_t s = time( NULL ); - fname = std::string( "log_" ) + toString( s ) + ".txt"; + std::string fname = "rcerrorlog.txt"; std::ofstream f; f.open( fname.c_str() ); @@ -83,9 +80,6 @@ TReportResult report (const std::string &title, const std::string &header, const #endif } - NLMISC::CFile::deleteFile( fname ); - - #ifdef NL_OS_WINDOWS #ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. From 3c61e39ce3cc7ae6bf6167e2752841e42fe884ef Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:44:22 +0100 Subject: [PATCH 258/344] Override the cursor while sending the report. --HG-- branch : hotfix --- code/nel/rcerror/rcerror_socket.cpp | 2 +- code/nel/rcerror/rcerror_widget.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index d84f69ec8..6b1fd932d 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -23,7 +23,7 @@ namespace { - static const char *BUG_URL = "http://192.168.2.67/dfighter/r.php"; + static const char *BUG_URL = "http://192.168.2.66/dfighter/r.php"; } class RCErrorSocketPvt diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index 6c31533ad..e02090e0d 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -66,6 +66,7 @@ void RCErrorWidget::onLoad() void RCErrorWidget::onSendClicked() { m_ui.sendButton->setEnabled( false ); + QApplication::setOverrideCursor( Qt::WaitCursor ); RCErrorData data; data.description = m_ui.descriptionEdit->toPlainText(); @@ -87,6 +88,8 @@ void RCErrorWidget::onCBClicked() void RCErrorWidget::onReportSent() { + QApplication::setOverrideCursor( Qt::ArrowCursor ); + QMessageBox::information( this, tr( "Report sent" ), tr( "The report has been sent." ) ); From 14a709449a4b6271a4762ba8c758b54bdb0745f1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:44:22 +0100 Subject: [PATCH 259/344] Override the cursor while sending the report. --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror_socket.cpp | 2 +- code/nel/rcerror/rcerror_widget.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index d84f69ec8..6b1fd932d 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -23,7 +23,7 @@ namespace { - static const char *BUG_URL = "http://192.168.2.67/dfighter/r.php"; + static const char *BUG_URL = "http://192.168.2.66/dfighter/r.php"; } class RCErrorSocketPvt diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index 6c31533ad..e02090e0d 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -66,6 +66,7 @@ void RCErrorWidget::onLoad() void RCErrorWidget::onSendClicked() { m_ui.sendButton->setEnabled( false ); + QApplication::setOverrideCursor( Qt::WaitCursor ); RCErrorData data; data.description = m_ui.descriptionEdit->toPlainText(); @@ -87,6 +88,8 @@ void RCErrorWidget::onCBClicked() void RCErrorWidget::onReportSent() { + QApplication::setOverrideCursor( Qt::ArrowCursor ); + QMessageBox::information( this, tr( "Report sent" ), tr( "The report has been sent." ) ); From bb9f6261d76521663097811fcb7f1c4ede55a3a0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:54:05 +0100 Subject: [PATCH 260/344] Tell the user if the report couldn't be sent. --HG-- branch : hotfix --- code/nel/rcerror/rcerror_socket.cpp | 10 +++++++--- code/nel/rcerror/rcerror_socket.h | 4 +++- code/nel/rcerror/rcerror_widget.cpp | 11 +++++++++++ code/nel/rcerror/rcerror_widget.h | 1 + 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index 6b1fd932d..8a011c046 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace { @@ -37,7 +38,7 @@ QObject( parent ) { m_pvt = new RCErrorSocketPvt(); - connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished() ) ); + connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished( QNetworkReply* ) ) ); } RCErrorSocket::~RCErrorSocket() @@ -59,8 +60,11 @@ void RCErrorSocket::sendReport( const RCErrorData &data ) m_pvt->mgr.post( request, params.encodedQuery() ); } -void RCErrorSocket::onFinished() +void RCErrorSocket::onFinished( QNetworkReply *reply ) { - Q_EMIT reportSent(); + if( reply->error() != QNetworkReply::NoError ) + Q_EMIT reportFailed(); + else + Q_EMIT reportSent(); } diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index ee0f510b1..a37fa32d0 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -24,6 +24,7 @@ #include "rcerror_data.h" class RCErrorSocketPvt; +class QNetworkReply; class RCErrorSocket : public QObject { @@ -37,9 +38,10 @@ public: Q_SIGNALS: void reportSent(); + void reportFailed(); private Q_SLOTS: - void onFinished(); + void onFinished( QNetworkReply *reply ); private: RCErrorSocketPvt *m_pvt; diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index e02090e0d..a28afbca6 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -39,6 +39,7 @@ QWidget( parent ) connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); connect( m_socket, SIGNAL( reportSent() ), this, SLOT( onReportSent() ) ); + connect( m_socket, SIGNAL( reportFailed() ), this, SLOT( onReportFailed() ) ); } RCErrorWidget::~RCErrorWidget() @@ -97,3 +98,13 @@ void RCErrorWidget::onReportSent() close(); } +void RCErrorWidget::onReportFailed() +{ + QApplication::setOverrideCursor( Qt::ArrowCursor ); + + QMessageBox::information( this, + tr( "Report failed" ), + tr( "Failed to send the report..." ) ); + + close(); +} \ No newline at end of file diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index 869838e41..1dd51c2af 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -41,6 +41,7 @@ private Q_SLOTS: void onCBClicked(); void onReportSent(); + void onReportFailed(); private: Ui::RCErrorWidget m_ui; From 72566f1a71ae580ad3a61e4376f24c111b750a04 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:54:05 +0100 Subject: [PATCH 261/344] Tell the user if the report couldn't be sent. --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror_socket.cpp | 10 +++++++--- code/nel/rcerror/rcerror_socket.h | 4 +++- code/nel/rcerror/rcerror_widget.cpp | 11 +++++++++++ code/nel/rcerror/rcerror_widget.h | 1 + 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index 6b1fd932d..8a011c046 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace { @@ -37,7 +38,7 @@ QObject( parent ) { m_pvt = new RCErrorSocketPvt(); - connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished() ) ); + connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished( QNetworkReply* ) ) ); } RCErrorSocket::~RCErrorSocket() @@ -59,8 +60,11 @@ void RCErrorSocket::sendReport( const RCErrorData &data ) m_pvt->mgr.post( request, params.encodedQuery() ); } -void RCErrorSocket::onFinished() +void RCErrorSocket::onFinished( QNetworkReply *reply ) { - Q_EMIT reportSent(); + if( reply->error() != QNetworkReply::NoError ) + Q_EMIT reportFailed(); + else + Q_EMIT reportSent(); } diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index ee0f510b1..a37fa32d0 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -24,6 +24,7 @@ #include "rcerror_data.h" class RCErrorSocketPvt; +class QNetworkReply; class RCErrorSocket : public QObject { @@ -37,9 +38,10 @@ public: Q_SIGNALS: void reportSent(); + void reportFailed(); private Q_SLOTS: - void onFinished(); + void onFinished( QNetworkReply *reply ); private: RCErrorSocketPvt *m_pvt; diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index e02090e0d..a28afbca6 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -39,6 +39,7 @@ QWidget( parent ) connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); connect( m_socket, SIGNAL( reportSent() ), this, SLOT( onReportSent() ) ); + connect( m_socket, SIGNAL( reportFailed() ), this, SLOT( onReportFailed() ) ); } RCErrorWidget::~RCErrorWidget() @@ -97,3 +98,13 @@ void RCErrorWidget::onReportSent() close(); } +void RCErrorWidget::onReportFailed() +{ + QApplication::setOverrideCursor( Qt::ArrowCursor ); + + QMessageBox::information( this, + tr( "Report failed" ), + tr( "Failed to send the report..." ) ); + + close(); +} \ No newline at end of file diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index 869838e41..1dd51c2af 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -41,6 +41,7 @@ private Q_SLOTS: void onCBClicked(); void onReportSent(); + void onReportFailed(); private: Ui::RCErrorWidget m_ui; From c7681bcb2b712b0969a10e5f3aaf180da39ae6b9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:56:22 +0100 Subject: [PATCH 262/344] Oups --HG-- branch : hotfix --- code/ryzom/client/src/init.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index c7fdc97f8..6958fe790 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -539,8 +539,6 @@ void checkDriverVersion() void checkDriverDepth () { - nlassert( false ); - // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From ef56d28542c2f4f840eebbf0c52965158dfd5b79 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 02:56:22 +0100 Subject: [PATCH 263/344] Oups --HG-- branch : feature-crashreport --- code/ryzom/client/src/init.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index c7fdc97f8..6958fe790 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -539,8 +539,6 @@ void checkDriverVersion() void checkDriverDepth () { - nlassert( false ); - // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From 141dddb58c519c53cf7f62cf2196f91af3e71cdf Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 03:22:02 +0100 Subject: [PATCH 264/344] Typo... --HG-- branch : hotfix --- code/nel/rcerror/rcerror_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/rcerror/rcerror_data.h index 146102038..9f12b12fd 100644 --- a/code/nel/rcerror/rcerror_data.h +++ b/code/nel/rcerror/rcerror_data.h @@ -20,7 +20,7 @@ #ifndef RCERROR_DATA #define RCERROR_DATA -#include +#include struct RCErrorData From 9b29695635c22349a848b05b188ec258d2a4c20c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 20 Feb 2015 03:22:02 +0100 Subject: [PATCH 265/344] Typo... --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/rcerror/rcerror_data.h index 146102038..9f12b12fd 100644 --- a/code/nel/rcerror/rcerror_data.h +++ b/code/nel/rcerror/rcerror_data.h @@ -20,7 +20,7 @@ #ifndef RCERROR_DATA #define RCERROR_DATA -#include +#include struct RCErrorData From 6db8abf95cef7cda4ff7e9cecd8bef90c066ac2a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 16:24:19 +0100 Subject: [PATCH 266/344] Visual Studio 2013 compilation support for NLMISC --HG-- branch : develop --- code/CMakeLists.txt | 10 +- code/CMakeModules/FindIconv.cmake | 131 +++++++++++-------------- code/CMakeModules/FindMSVC.cmake | 2 +- code/CMakeModules/nel.cmake | 19 +++- code/nel/include/nel/misc/types_nl.h | 6 ++ code/nel/src/misc/debug.cpp | 29 +++--- code/nel/src/misc/displayer.cpp | 26 ++--- code/nel/src/misc/words_dictionary.cpp | 2 +- 8 files changed, 114 insertions(+), 111 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index dcc9f9c93..0ffef9c1e 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -112,16 +112,20 @@ IF(WITH_STATIC_LIBXML2) SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) ENDIF(WITH_STATIC_LIBXML2) +IF(WITH_LIBXML2_ICONV) + FIND_PACKAGE(Iconv REQUIRED) + INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR}) + SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${ICONV_LIBRARIES}) +ENDIF(WITH_LIBXML2_ICONV) + IF(WITH_STATIC) # libxml2 could need winsock2 library SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${WINSOCK2_LIB}) # on Mac OS X libxml2 requires iconv and liblzma IF(APPLE) - FIND_PACKAGE(Iconv REQUIRED) FIND_PACKAGE(LibLZMA REQUIRED) - SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${ICONV_LIBRARIES} ${LIBLZMA_LIBRARIES}) - INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR}) + SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) ENDIF(APPLE) ENDIF(WITH_STATIC) diff --git a/code/CMakeModules/FindIconv.cmake b/code/CMakeModules/FindIconv.cmake index 5e9e48250..092b35702 100644 --- a/code/CMakeModules/FindIconv.cmake +++ b/code/CMakeModules/FindIconv.cmake @@ -1,4 +1,4 @@ -# - Try to find Iconv on Mac OS X +# - Try to find Iconv # Once done this will define # # ICONV_FOUND - system has Iconv @@ -6,78 +6,59 @@ # ICONV_LIBRARIES - Link these to use Iconv # ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const # +include(CheckCCompilerFlag) +include(CheckCSourceCompiles) -IF(APPLE) - include(CheckCCompilerFlag) - include(CheckCSourceCompiles) - - IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) - # Already in cache, be silent - SET(ICONV_FIND_QUIETLY TRUE) - ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) - - IF(APPLE) - FIND_PATH(ICONV_INCLUDE_DIR iconv.h - PATHS - /opt/local/include/ - NO_CMAKE_SYSTEM_PATH - ) - - FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c - PATHS - /opt/local/lib/ - NO_CMAKE_SYSTEM_PATH - ) - ENDIF(APPLE) - - FIND_PATH(ICONV_INCLUDE_DIR iconv.h PATHS /opt/local/include /sw/include) - - string(REGEX REPLACE "(.*)/include/?" "\\1" ICONV_INCLUDE_BASE_DIR "${ICONV_INCLUDE_DIR}") - - FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c HINTS "${ICONV_INCLUDE_BASE_DIR}/lib" PATHS /opt/local/lib) - - IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) - SET(ICONV_FOUND TRUE) - ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) - - set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) - IF(ICONV_FOUND) - check_c_compiler_flag("-Werror" ICONV_HAVE_WERROR) - set (CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}") - if(ICONV_HAVE_WERROR) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") - endif(ICONV_HAVE_WERROR) - check_c_source_compiles(" - #include - int main(){ - iconv_t conv = 0; - const char* in = 0; - size_t ilen = 0; - char* out = 0; - size_t olen = 0; - iconv(conv, &in, &ilen, &out, &olen); - return 0; - } - " ICONV_SECOND_ARGUMENT_IS_CONST ) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}") - ENDIF(ICONV_FOUND) - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_LIBRARIES) - - IF(ICONV_FOUND) - IF(NOT ICONV_FIND_QUIETLY) - MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") - ENDIF(NOT ICONV_FIND_QUIETLY) - ELSE(ICONV_FOUND) - IF(Iconv_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Iconv") - ENDIF(Iconv_FIND_REQUIRED) - ENDIF(ICONV_FOUND) - - MARK_AS_ADVANCED( - ICONV_INCLUDE_DIR - ICONV_LIBRARIES - ICONV_SECOND_ARGUMENT_IS_CONST - ) -ENDIF(APPLE) +IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + # Already in cache, be silent + SET(ICONV_FIND_QUIETLY TRUE) +ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + +FIND_PATH(ICONV_INCLUDE_DIR iconv.h HINTS /sw/include/ PATHS /opt/local) + +FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c PATHS /opt/local) + +IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + SET(ICONV_FOUND TRUE) +ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + +set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) +set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) +IF(ICONV_FOUND) + check_c_compiler_flag("-Werror" ICONV_HAVE_WERROR) + set (CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}") + if(ICONV_HAVE_WERROR) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif(ICONV_HAVE_WERROR) + check_c_source_compiles(" + #include + int main(){ + iconv_t conv = 0; + const char* in = 0; + size_t ilen = 0; + char* out = 0; + size_t olen = 0; + iconv(conv, &in, &ilen, &out, &olen); + return 0; + } +" ICONV_SECOND_ARGUMENT_IS_CONST ) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}") +ENDIF(ICONV_FOUND) +set(CMAKE_REQUIRED_INCLUDES) +set(CMAKE_REQUIRED_LIBRARIES) + +IF(ICONV_FOUND) + IF(NOT ICONV_FIND_QUIETLY) + MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") + ENDIF(NOT ICONV_FIND_QUIETLY) +ELSE(ICONV_FOUND) + IF(Iconv_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Iconv") + ENDIF(Iconv_FIND_REQUIRED) +ENDIF(ICONV_FOUND) + +MARK_AS_ADVANCED( + ICONV_INCLUDE_DIR + ICONV_LIBRARIES + ICONV_SECOND_ARGUMENT_IS_CONST +) diff --git a/code/CMakeModules/FindMSVC.cmake b/code/CMakeModules/FindMSVC.cmake index 644fc57e6..94146775d 100644 --- a/code/CMakeModules/FindMSVC.cmake +++ b/code/CMakeModules/FindMSVC.cmake @@ -62,7 +62,7 @@ IF(MSVC12) IF(NOT MSVC12_REDIST_DIR) # If you have VC++ 2013 Express, put x64/Microsoft.VC120.CRT/*.dll in ${EXTERNAL_PATH}/redist SET(MSVC12_REDIST_DIR "${EXTERNAL_PATH}/redist") - ENDIF(NOT MSVC11_REDIST_DIR) + ENDIF(NOT MSVC12_REDIST_DIR) ELSEIF(MSVC11) DETECT_VC_VERSION("11.0") SET(MSVC_TOOLSET "110") diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 15f6d131d..081da67ca 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -255,6 +255,11 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) ELSE(WITH_STATIC) OPTION(WITH_STATIC_LIBXML2 "With static libxml2" OFF) ENDIF(WITH_STATIC) + IF(APPLE) + OPTION(WITH_LIBXML2_ICONV "With libxml2 using iconv" ON ) + ELSE(APPLE) + OPTION(WITH_LIBXML2_ICONV "With libxml2 using iconv" OFF) + ENDIF(APPLE) OPTION(WITH_STATIC_DRIVERS "With static drivers." OFF) IF(WIN32) OPTION(WITH_EXTERNAL "With provided external." ON ) @@ -558,9 +563,15 @@ MACRO(NL_SETUP_BUILD) # Ignore default include paths ADD_PLATFORM_FLAGS("/X") - IF(MSVC11) + IF(MSVC12) ADD_PLATFORM_FLAGS("/Gy- /MP") - # /Ox is working with VC++ 2010, but custom optimizations don't exist + # /Ox is working with VC++ 2013, but custom optimizations don't exist + SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}") + # without inlining it's unusable, use custom optimizations again + SET(DEBUG_CFLAGS "/Od /Ob1 /GF- ${DEBUG_CFLAGS}") + ELSEIF(MSVC11) + ADD_PLATFORM_FLAGS("/Gy- /MP") + # /Ox is working with VC++ 2012, but custom optimizations don't exist SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}") # without inlining it's unusable, use custom optimizations again SET(DEBUG_CFLAGS "/Od /Ob1 /GF- ${DEBUG_CFLAGS}") @@ -582,9 +593,9 @@ MACRO(NL_SETUP_BUILD) SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}") # without inlining it's unusable, use custom optimizations again SET(DEBUG_CFLAGS "/Od /Ob1 ${DEBUG_CFLAGS}") - ELSE(MSVC11) + ELSE(MSVC12) MESSAGE(FATAL_ERROR "Can't determine compiler version ${MSVC_VERSION}") - ENDIF(MSVC11) + ENDIF(MSVC12) ADD_PLATFORM_FLAGS("/D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DWIN32 /D_WINDOWS /Zm1000 /wd4250") diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h index f1ed871fc..7a6ee2662 100644 --- a/code/nel/include/nel/misc/types_nl.h +++ b/code/nel/include/nel/misc/types_nl.h @@ -414,6 +414,12 @@ extern void operator delete[](void *p) throw(); # define CHashMap stdext::hash_map # define CHashSet stdext::hash_set # define CHashMultiMap stdext::hash_multimap +#elif defined(NL_COMP_VC) && (NL_COMP_VC_VERSION == 110) +# include +# include +# define CHashMap ::std::hash_map +# define CHashSet ::std::hash_set +# define CHashMultiMap ::std::hash_multimap #elif defined(NL_COMP_GCC) // GCC4 # include # include diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index c7667acc2..a4037607f 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -17,20 +17,6 @@ #include "stdmisc.h" #include "nel/misc/types_nl.h" -#include "nel/misc/debug.h" - -#ifdef HAVE_NELCONFIG_H -# include "nelconfig.h" -#endif // HAVE_NELCONFIG_H - -#include "nel/misc/log.h" -#include "nel/misc/displayer.h" -#include "nel/misc/mem_displayer.h" -#include "nel/misc/command.h" -#include "nel/misc/report.h" -#include "nel/misc/path.h" -#include "nel/misc/variable.h" -#include "nel/misc/system_info.h" #ifdef NL_OS_WINDOWS # define _WIN32_WINDOWS 0x0410 @@ -59,6 +45,21 @@ # include #endif +#include "nel/misc/debug.h" + +#ifdef HAVE_NELCONFIG_H +# include "nelconfig.h" +#endif // HAVE_NELCONFIG_H + +#include "nel/misc/log.h" +#include "nel/misc/displayer.h" +#include "nel/misc/mem_displayer.h" +#include "nel/misc/command.h" +#include "nel/misc/report.h" +#include "nel/misc/path.h" +#include "nel/misc/variable.h" +#include "nel/misc/system_info.h" + #define NL_NO_DEBUG_FILES 1 using namespace std; diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index d48c44d02..8b6b7a577 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -18,6 +18,19 @@ #include "nel/misc/types_nl.h" +#ifdef NL_OS_WINDOWS +// these defines is for IsDebuggerPresent(). it'll not compile on windows 95 +// just comment this and the IsDebuggerPresent to compile on windows 95 +# define _WIN32_WINDOWS 0x0410 +# ifndef NL_COMP_MINGW +# define WINVER 0x0400 +# define NOMINMAX +# endif +# include +#else +# define IsDebuggerPresent() false +#endif + #ifdef NL_OS_WINDOWS # include # include @@ -35,19 +48,6 @@ #include "nel/misc/debug.h" -#ifdef NL_OS_WINDOWS -// these defines is for IsDebuggerPresent(). it'll not compile on windows 95 -// just comment this and the IsDebuggerPresent to compile on windows 95 -# define _WIN32_WINDOWS 0x0410 -# ifndef NL_COMP_MINGW -# define WINVER 0x0400 -# define NOMINMAX -# endif -# include -#else -# define IsDebuggerPresent() false -#endif - #include "nel/misc/displayer.h" using namespace std; diff --git a/code/nel/src/misc/words_dictionary.cpp b/code/nel/src/misc/words_dictionary.cpp index e2113e62d..4d5057dd7 100644 --- a/code/nel/src/misc/words_dictionary.cpp +++ b/code/nel/src/misc/words_dictionary.cpp @@ -251,7 +251,7 @@ void CWordsDictionary::exactLookupByKey( const CSString& key, CVectorSString& re */ inline CSString CWordsDictionary::makeResult( const CSString &key, const CSString &word ) { - return key + CSString(": ") + word; + return key + ": " + word.c_str(); } From 7ea4cff032bb5ff3a73ef5a65b2eee1f5c6d8804 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 16:29:09 +0100 Subject: [PATCH 267/344] Visual Studio 2013 compilation support for NLNET --HG-- branch : develop --- code/nel/src/net/service.cpp | 6 ------ code/nel/src/net/stdnet.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp index f42806245..84abb4bfb 100644 --- a/code/nel/src/net/service.cpp +++ b/code/nel/src/net/service.cpp @@ -23,12 +23,6 @@ #ifdef NL_OS_WINDOWS // these defines is for IsDebuggerPresent(). it'll not compile on windows 95 // just comment this and the IsDebuggerPresent to compile on windows 95 -# define _WIN32_WINDOWS 0x0410 -# ifndef NL_COMP_MINGW -# define WINVER 0x0400 -# define NOMINMAX -# endif -# include # include #elif defined NL_OS_UNIX # include diff --git a/code/nel/src/net/stdnet.h b/code/nel/src/net/stdnet.h index d18db3222..df2bc931d 100644 --- a/code/nel/src/net/stdnet.h +++ b/code/nel/src/net/stdnet.h @@ -17,7 +17,9 @@ #include "nel/misc/types_nl.h" #ifdef NL_OS_WINDOWS +# define _WIN32_WINDOWS 0x0410 # ifndef NL_COMP_MINGW +# define WINVER 0x0400 # define NOMINMAX # endif # include From cb986cba6f1a1e4d34db90f4a95eafc58de50c06 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 16:31:54 +0100 Subject: [PATCH 268/344] Visual Studio 2013 compilation support for NLPACS --HG-- branch : develop --- code/nel/src/pacs/local_retriever.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/pacs/local_retriever.cpp b/code/nel/src/pacs/local_retriever.cpp index 7158cee0a..c17709c70 100644 --- a/code/nel/src/pacs/local_retriever.cpp +++ b/code/nel/src/pacs/local_retriever.cpp @@ -2253,7 +2253,7 @@ bool NLPACS::CLocalRetriever::checkSurfaceIntegrity(uint surf, NLMISC::CVector t for (k=0; k+1(ochain[k], ochain[k+1])); + edges.push_back(std::pair(ochain[k], ochain[k+1])); } } } From f5335f068dea17139e63be70311edda749fe3566 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:07:23 +0100 Subject: [PATCH 269/344] Visual Studio 2013 compilation support for NLMISC --HG-- branch : develop --- code/nel/include/nel/misc/string_common.h | 34 +++++++++++++++++++++++ code/nel/include/nel/misc/xml_auto_ptr.h | 2 +- code/nel/src/misc/debug.cpp | 6 ---- code/nel/src/misc/displayer.cpp | 11 +------- code/nel/src/misc/mem_displayer.cpp | 2 +- code/nel/src/misc/mutex.cpp | 9 ------ code/nel/src/misc/stdmisc.h | 6 ++-- 7 files changed, 41 insertions(+), 29 deletions(-) diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h index 4a455247d..2d2a7e676 100644 --- a/code/nel/include/nel/misc/string_common.h +++ b/code/nel/include/nel/misc/string_common.h @@ -264,6 +264,40 @@ inline bool fromString(const std::string &str, bool &val) return true; } +inline bool fromString(const char *str, uint32 &val) { if (strstr(str, "-") != NULL) { val = 0; return false; } char *end; unsigned long v; errno = 0; v = strtoul(str, &end, 10); if (errno || v > UINT_MAX || end == str) { val = 0; return false; } else { val = (uint32)v; return true; } } +inline bool fromString(const char *str, sint32 &val) { char *end; long v; errno = 0; v = strtol(str, &end, 10); if (errno || v > INT_MAX || v < INT_MIN || end == str) { val = 0; return false; } else { val = (sint32)v; return true; } } +inline bool fromString(const char *str, uint8 &val) { char *end; long v; errno = 0; v = strtol(str, &end, 10); if (errno || v > UCHAR_MAX || v < 0 || end == str) { val = 0; return false; } else { val = (uint8)v; return true; } } +inline bool fromString(const char *str, sint8 &val) { char *end; long v; errno = 0; v = strtol(str, &end, 10); if (errno || v > SCHAR_MAX || v < SCHAR_MIN || end == str) { val = 0; return false; } else { val = (sint8)v; return true; } } +inline bool fromString(const char *str, uint16 &val) { char *end; long v; errno = 0; v = strtol(str, &end, 10); if (errno || v > USHRT_MAX || v < 0 || end == str) { val = 0; return false; } else { val = (uint16)v; return true; } } +inline bool fromString(const char *str, sint16 &val) { char *end; long v; errno = 0; v = strtol(str, &end, 10); if (errno || v > SHRT_MAX || v < SHRT_MIN || end == str) { val = 0; return false; } else { val = (sint16)v; return true; } } +inline bool fromString(const char *str, uint64 &val) { bool ret = sscanf(str, "%"NL_I64"u", &val) == 1; if (!ret) val = 0; return ret; } +inline bool fromString(const char *str, sint64 &val) { bool ret = sscanf(str, "%"NL_I64"d", &val) == 1; if (!ret) val = 0; return ret; } +inline bool fromString(const char *str, float &val) { bool ret = sscanf(str, "%f", &val) == 1; if (!ret) val = 0.0f; return ret; } +inline bool fromString(const char *str, double &val) { bool ret = sscanf(str, "%lf", &val) == 1; if (!ret) val = 0.0; return ret; } + +inline bool fromString(const char *str, bool &val) +{ + switch (str[0]) + { + case '1': + case 't': + case 'y': + case 'T': + case 'Y': + val = true; + return true; + case '0': + case 'f': + case 'n': + case 'F': + case 'N': + val = false; + return true; + } + + return false; +} + inline bool fromString(const std::string &str, std::string &val) { val = str; return true; } // stl vectors of bool use bit reference and not real bools, so define the operator for bit reference diff --git a/code/nel/include/nel/misc/xml_auto_ptr.h b/code/nel/include/nel/misc/xml_auto_ptr.h index eacde74da..8e0c3adb7 100644 --- a/code/nel/include/nel/misc/xml_auto_ptr.h +++ b/code/nel/include/nel/misc/xml_auto_ptr.h @@ -31,7 +31,7 @@ public: ~CXMLAutoPtr() { destroy(); } operator const char *() const { return _Value; } operator bool() const { return _Value != NULL; } - operator std::string() const { return std::string(_Value); } + inline std::string str() const { return _Value; } bool operator ! () const { return _Value == NULL; } operator const unsigned char *() const { return (const unsigned char *) _Value; } char operator * () const { nlassert(_Value); return *_Value; } diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index a4037607f..2a9c5282a 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -19,12 +19,6 @@ #include "nel/misc/types_nl.h" #ifdef NL_OS_WINDOWS -# define _WIN32_WINDOWS 0x0410 -# ifndef NL_COMP_MINGW -# define WINVER 0x0400 -# define NOMINMAX -# endif -# include # include # include # include diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 8b6b7a577..4b9231663 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -18,16 +18,7 @@ #include "nel/misc/types_nl.h" -#ifdef NL_OS_WINDOWS -// these defines is for IsDebuggerPresent(). it'll not compile on windows 95 -// just comment this and the IsDebuggerPresent to compile on windows 95 -# define _WIN32_WINDOWS 0x0410 -# ifndef NL_COMP_MINGW -# define WINVER 0x0400 -# define NOMINMAX -# endif -# include -#else +#ifndef NL_OS_WINDOWS # define IsDebuggerPresent() false #endif diff --git a/code/nel/src/misc/mem_displayer.cpp b/code/nel/src/misc/mem_displayer.cpp index 49431097d..fc5681657 100644 --- a/code/nel/src/misc/mem_displayer.cpp +++ b/code/nel/src/misc/mem_displayer.cpp @@ -103,7 +103,7 @@ static string getFuncInfo (DWORD_TYPE funcAddr, DWORD_TYPE stackAddr) if (stop==0 && (parse[i] == ',' || parse[i] == ')')) { char tmp[32]; - sprintf (tmp, "=0x%p", *((ULONG*)(stackAddr) + 2 + pos++)); + sprintf(tmp, "=0x%p", *((DWORD_TYPE*)(stackAddr) + 2 + pos++)); str += tmp; } str += parse[i]; diff --git a/code/nel/src/misc/mutex.cpp b/code/nel/src/misc/mutex.cpp index 28f6bae37..8135d954f 100644 --- a/code/nel/src/misc/mutex.cpp +++ b/code/nel/src/misc/mutex.cpp @@ -41,15 +41,6 @@ using namespace std; #ifdef NL_OS_WINDOWS -// these defines are for IsDebuggerPresent(). It'll not compile on windows 95 -// just comment this and the IsDebuggerPresent to compile on windows 95 -#define _WIN32_WINDOWS 0x0410 -#ifndef NL_COMP_MINGW -# define WINVER 0x0400 -# define NOMINMAX -#endif -#include - #ifdef DEBUG_NEW #define new DEBUG_NEW #endif diff --git a/code/nel/src/misc/stdmisc.h b/code/nel/src/misc/stdmisc.h index b98d92d2a..37284511c 100644 --- a/code/nel/src/misc/stdmisc.h +++ b/code/nel/src/misc/stdmisc.h @@ -43,8 +43,10 @@ #include #ifdef _WIN32 -# ifndef __MINGW32__ - #define NOMINMAX +# define _WIN32_WINDOWS 0x0410 +# ifndef NL_COMP_MINGW +# define WINVER 0x0400 +# define NOMINMAX # endif # include # include From a15221b00df3970a1c3e673f64d94e81a588a2a7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:14:00 +0100 Subject: [PATCH 270/344] Visual Studio 2013 compilation support for NLSOUND --HG-- branch : develop --- code/nel/src/sound/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/src/sound/CMakeLists.txt b/code/nel/src/sound/CMakeLists.txt index 2cf570f69..6b0dc285d 100644 --- a/code/nel/src/sound/CMakeLists.txt +++ b/code/nel/src/sound/CMakeLists.txt @@ -86,6 +86,7 @@ NL_TARGET_LIB(nelsound ${HEADERS} ${SRC}) INCLUDE_DIRECTORIES(${VORBIS_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${OGG_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(nelsound ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}) From 221267364d1cf27481d78383d95f1867da133cae Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:14:12 +0100 Subject: [PATCH 271/344] Visual Studio 2013 compilation support for NL3D --HG-- branch : develop --- code/nel/src/3d/zone_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/3d/zone_search.cpp b/code/nel/src/3d/zone_search.cpp index cbadc8c39..f850d4377 100644 --- a/code/nel/src/3d/zone_search.cpp +++ b/code/nel/src/3d/zone_search.cpp @@ -73,7 +73,7 @@ pair CZoneSearch::getZoneName(uint x, uint y, uint cx, uint cy) sprintf(name, "%d_%c%c.zonel", zoneY, firstLetter, secondLetter); - return make_pair(string(name), distance); + return std::pair(string(name), distance); } From 1879a434f7c3a2bdd3fdbfe0c693625bc017d68d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:17:07 +0100 Subject: [PATCH 272/344] Visual Studio 2013 compilation support for NLGUI --HG-- branch : develop --- code/nel/include/nel/gui/dbgroup_combo_box.h | 2 +- code/nel/src/gui/CMakeLists.txt | 2 +- code/nel/src/gui/ctrl_scroll.cpp | 10 +++++----- code/nel/src/gui/dbgroup_combo_box.cpp | 4 ++-- code/nel/src/gui/group_menu.cpp | 2 +- code/nel/src/gui/interface_anim.cpp | 2 +- code/nel/src/gui/interface_parser.cpp | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/code/nel/include/nel/gui/dbgroup_combo_box.h b/code/nel/include/nel/gui/dbgroup_combo_box.h index 75208b1e3..e7be1de4b 100644 --- a/code/nel/include/nel/gui/dbgroup_combo_box.h +++ b/code/nel/include/nel/gui/dbgroup_combo_box.h @@ -60,7 +60,7 @@ namespace NLGUI void setText(uint i, const ucstring &text); void insertText(uint i, const ucstring &text); const ucstring &getText(uint i) const; - const uint &getTextId(uint i) const; + uint getTextId(uint i) const; uint getTextPos(uint nId) const; const ucstring &getTexture(uint i) const; void removeText(uint nPos); diff --git a/code/nel/src/gui/CMakeLists.txt b/code/nel/src/gui/CMakeLists.txt index e3d501e23..32125791d 100644 --- a/code/nel/src/gui/CMakeLists.txt +++ b/code/nel/src/gui/CMakeLists.txt @@ -6,7 +6,7 @@ SOURCE_GROUP("src" FILES ${SRC}) NL_TARGET_LIB(nelgui ${SRC} ${HEADERS}) -INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR} ${LUABIND_INCLUDE_DIR} ${LIBWWW_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR} ${LUABIND_INCLUDE_DIR} ${LIBWWW_INCLUDE_DIR} ${CURL_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(nelgui nelmisc nel3d ${LUA_LIBRARIES} ${LUABIND_LIBRARIES} ${LIBXML2_LIBRARIES} ${LIBWWW_LIBRARIES} ${CURL_LIBRARIES}) SET_TARGET_PROPERTIES(nelgui PROPERTIES LINK_INTERFACE_LIBRARIES "") diff --git a/code/nel/src/gui/ctrl_scroll.cpp b/code/nel/src/gui/ctrl_scroll.cpp index f534fc0a1..c29f73fea 100644 --- a/code/nel/src/gui/ctrl_scroll.cpp +++ b/code/nel/src/gui/ctrl_scroll.cpp @@ -519,17 +519,17 @@ namespace NLGUI // Read Action handlers prop = (char*) xmlGetProp( node, (xmlChar*)"onscroll" ); - if (prop) _AHOnScroll = NLMISC::strlwr(prop); + if (prop) _AHOnScroll = NLMISC::strlwr(prop.str()); prop = (char*) xmlGetProp( node, (xmlChar*)"params" ); if (prop) _AHOnScrollParams = string((const char*)prop); // prop = (char*) xmlGetProp( node, (xmlChar*)"onscrollend" ); - if (prop) _AHOnScrollEnd = NLMISC::strlwr(prop); + if (prop) _AHOnScrollEnd = NLMISC::strlwr(prop.str()); prop = (char*) xmlGetProp( node, (xmlChar*)"end_params" ); if (prop) _AHOnScrollEndParams = string((const char*)prop); // prop = (char*) xmlGetProp( node, (xmlChar*)"onscrollcancel" ); - if (prop) _AHOnScrollCancel = NLMISC::strlwr(prop); + if (prop) _AHOnScrollCancel = NLMISC::strlwr(prop.str()); prop = (char*) xmlGetProp( node, (xmlChar*)"cancel_params" ); if (prop) _AHOnScrollCancelParams = string((const char*)prop); @@ -538,9 +538,9 @@ namespace NLGUI prop = (char*) xmlGetProp( node, (xmlChar*)"target" ); if (prop) { - CInterfaceGroup *group = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(prop)); + CInterfaceGroup *group = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(prop.str())); if(group == NULL) - group = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(this->getId(), prop)); + group = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(this->getId(), prop.str())); if(group != NULL) setTarget (group); diff --git a/code/nel/src/gui/dbgroup_combo_box.cpp b/code/nel/src/gui/dbgroup_combo_box.cpp index 61b8ec3e6..39ddd63c1 100644 --- a/code/nel/src/gui/dbgroup_combo_box.cpp +++ b/code/nel/src/gui/dbgroup_combo_box.cpp @@ -268,7 +268,7 @@ namespace NLGUI void CDBGroupComboBox::addText(const ucstring &text) { dirt(); - _Texts.push_back(make_pair(_Texts.size(), text)); + _Texts.push_back(make_pair((uint)_Texts.size(), text)); _Textures.push_back(std::string()); } @@ -330,7 +330,7 @@ namespace NLGUI } // *************************************************************************** - const uint &CDBGroupComboBox::getTextId(uint i) const + uint CDBGroupComboBox::getTextId(uint i) const { static uint null = 0; if(i<_Texts.size()) diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp index 08f887e9e..ddd022310 100644 --- a/code/nel/src/gui/group_menu.cpp +++ b/code/nel/src/gui/group_menu.cpp @@ -2200,7 +2200,7 @@ namespace NLGUI if( editorMode ) _Extends = std::string( (const char*)prop ); - CGroupMenu *gm = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(prop)); + CGroupMenu *gm = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(prop.str())); if (!gm) { gm = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:" + std::string((const char*)prop))); diff --git a/code/nel/src/gui/interface_anim.cpp b/code/nel/src/gui/interface_anim.cpp index 627a93280..693e63f09 100644 --- a/code/nel/src/gui/interface_anim.cpp +++ b/code/nel/src/gui/interface_anim.cpp @@ -74,7 +74,7 @@ namespace NLGUI } // - if (!CInterfaceLink::splitLinkTargets (ptr, parentGroup, _Targets)) + if (!CInterfaceLink::splitLinkTargets (ptr.str(), parentGroup, _Targets)) { nlwarning ("no target for track"); return false; diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index 096c001ae..a3e2c48aa 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -1771,7 +1771,7 @@ namespace NLGUI { CInterfaceExprValue res; - if (CInterfaceExpr::eval(ptrVal2, res)) + if (CInterfaceExpr::eval(ptrVal2.str(), res)) { if (!res.toString()) { From 32b3b4ac80d306dcf3a8ef8af270c7b9b73d8e86 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:50:58 +0100 Subject: [PATCH 273/344] Visual Studio 2013 compilation support for Ryzom Client --HG-- branch : develop --- code/ryzom/client/src/init.cpp | 2 +- .../client/src/interface_v3/dbctrl_sheet.cpp | 24 ++++++++-------- .../src/interface_v3/dbgroup_list_sheet.cpp | 2 +- .../interface_v3/dbgroup_list_sheet_text.cpp | 2 +- .../src/interface_v3/interface_3d_scene.cpp | 8 +++--- .../src/interface_v3/inventory_manager.cpp | 14 +++++----- .../src/interface_v3/parser_modules.cpp | 2 +- .../_backup_service_interface_non_module.cpp | 2 +- .../game_share/deployment_configuration.cpp | 26 ++++++++--------- .../src/game_share/persistent_data_tree.cpp | 28 +++++++++---------- .../game_share/server_animation_module.cpp | 2 +- 11 files changed, 56 insertions(+), 56 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index ed7943b8f..33bec822f 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -568,7 +568,7 @@ void listStereoDisplayDevices(std::vector &devices) std::stringstream name; name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; std::stringstream fullname; - fullname << std::string("[") << name << "] [" << it->Serial << "]"; + fullname << std::string("[") << name.str() << "] [" << it->Serial << "]"; nlinfo("VR [C]: Stereo Display: %s", name.str().c_str()); if (cache) { diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index fe7f20e1f..d72a975f3 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -333,29 +333,29 @@ bool CCtrlSheetInfo::parseCtrlInfo(xmlNodePtr cur, CInterfaceGroup * /* parentGr prop = (char*) xmlGetProp( cur, (xmlChar*)"nature" ); if (prop) { - if (NLMISC::strlwr(prop) == "item") + if (NLMISC::strlwr(prop.str()) == "item") _Type = CCtrlSheetInfo::SheetType_Item; - else if (NLMISC::strlwr(prop) == "pact") + else if (NLMISC::strlwr(prop.str()) == "pact") _Type = CCtrlSheetInfo::SheetType_Pact; - else if (NLMISC::strlwr(prop) == "skill") + else if (NLMISC::strlwr(prop.str()) == "skill") _Type = CCtrlSheetInfo::SheetType_Skill; - else if (NLMISC::strlwr(prop) == "auto") + else if (NLMISC::strlwr(prop.str()) == "auto") _Type = CCtrlSheetInfo::SheetType_Auto; - else if (NLMISC::strlwr(prop) == "macro") + else if (NLMISC::strlwr(prop.str()) == "macro") _Type = CCtrlSheetInfo::SheetType_Macro; - else if (NLMISC::strlwr(prop) == "guild_flag") + else if (NLMISC::strlwr(prop.str()) == "guild_flag") _Type = CCtrlSheetInfo::SheetType_GuildFlag; - else if (NLMISC::strlwr(prop) == "mission") + else if (NLMISC::strlwr(prop.str()) == "mission") _Type = CCtrlSheetInfo::SheetType_Mission; - else if (NLMISC::strlwr(prop) == "sbrick") + else if (NLMISC::strlwr(prop.str()) == "sbrick") _Type = CCtrlSheetInfo::SheetType_SBrick; - else if (NLMISC::strlwr(prop) == "sphraseid") + else if (NLMISC::strlwr(prop.str()) == "sphraseid") _Type = CCtrlSheetInfo::SheetType_SPhraseId; - else if (NLMISC::strlwr(prop) == "sphrase") + else if (NLMISC::strlwr(prop.str()) == "sphrase") _Type = CCtrlSheetInfo::SheetType_SPhrase; - else if (NLMISC::strlwr(prop) == "elevator_destination") + else if (NLMISC::strlwr(prop.str()) == "elevator_destination") _Type = CCtrlSheetInfo::SheetType_ElevatorDestination; - else if (NLMISC::strlwr(prop) == "outpost_building") + else if (NLMISC::strlwr(prop.str()) == "outpost_building") _Type = CCtrlSheetInfo::SheetType_OutpostBuilding; } diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp index 74bd2be47..2966e65b4 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp @@ -115,7 +115,7 @@ bool CDBGroupListSheet::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) if (prop) { // get a branch in the database. - CCDBNodeBranch *branch= NLGUI::CDBManager::getInstance()->getDbBranch(prop); + CCDBNodeBranch *branch = NLGUI::CDBManager::getInstance()->getDbBranch(prop.str()); if(!branch) { nlinfo ("Branch not found in the database %s", (const char*)prop); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp index 772f99418..2294d3926 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp @@ -98,7 +98,7 @@ bool CDBGroupListSheetText::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) if (prop) { // get a branch in the database. - CCDBNodeBranch *branch= NLGUI::CDBManager::getInstance()->getDbBranch(prop); + CCDBNodeBranch *branch = NLGUI::CDBManager::getInstance()->getDbBranch(prop.str()); if(!branch) { nlinfo ("Branch not found in the database %s", (const char*)prop); diff --git a/code/ryzom/client/src/interface_v3/interface_3d_scene.cpp b/code/ryzom/client/src/interface_v3/interface_3d_scene.cpp index 0d51a538e..6acc2a17b 100644 --- a/code/ryzom/client/src/interface_v3/interface_3d_scene.cpp +++ b/code/ryzom/client/src/interface_v3/interface_3d_scene.cpp @@ -162,13 +162,13 @@ bool CInterface3DScene::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) _Ref3DScene = NULL; if (ptr) { - CInterfaceElement *pIE = CWidgetManager::getInstance()->getElementFromId(this->getId(), ptr); + CInterfaceElement *pIE = CWidgetManager::getInstance()->getElementFromId(this->getId(), ptr.str()); _Ref3DScene = dynamic_cast(pIE); } if (_Ref3DScene != NULL) { ptr = (char*) xmlGetProp( cur, (xmlChar*)"curcam" ); - if (ptr) setCurrentCamera (ptr); + if (ptr) setCurrentCamera (ptr.str()); return true; } @@ -294,7 +294,7 @@ bool CInterface3DScene::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) CXMLAutoPtr ptr((const char*)xmlGetProp (cur, (xmlChar*)"name")); string animName; if (ptr) - animName = strlwr (CFile::getFilenameWithoutExtension(ptr)); + animName = strlwr (CFile::getFilenameWithoutExtension(ptr.str())); if (!animName.empty()) { @@ -340,7 +340,7 @@ bool CInterface3DScene::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) // Get the current camera ptr = (char*) xmlGetProp( cur, (xmlChar*)"curcam" ); - if (ptr) setCurrentCamera (ptr); + if (ptr) setCurrentCamera(ptr.str()); return true; } diff --git a/code/ryzom/client/src/interface_v3/inventory_manager.cpp b/code/ryzom/client/src/interface_v3/inventory_manager.cpp index 5e7d66075..7a56e470e 100644 --- a/code/ryzom/client/src/interface_v3/inventory_manager.cpp +++ b/code/ryzom/client/src/interface_v3/inventory_manager.cpp @@ -1981,7 +1981,7 @@ bool SBagOptions::parse(xmlNodePtr cur, CInterfaceGroup * /* parentGroup */) prop = xmlGetProp (cur, (xmlChar*)"inv_type"); if (prop) { - InvType = CInventoryManager::invTypeFromString(prop); + InvType = CInventoryManager::invTypeFromString(prop.str()); } else { @@ -1990,22 +1990,22 @@ bool SBagOptions::parse(xmlNodePtr cur, CInterfaceGroup * /* parentGroup */) } prop = xmlGetProp (cur, (xmlChar*)"filter_armor"); - if (prop) DbFilterArmor = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterArmor = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); prop = xmlGetProp (cur, (xmlChar*)"filter_weapon"); - if (prop) DbFilterWeapon = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterWeapon = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); prop = xmlGetProp (cur, (xmlChar*)"filter_tool"); - if (prop) DbFilterTool = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterTool = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); prop = xmlGetProp (cur, (xmlChar*)"filter_mp"); - if (prop) DbFilterMP = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterMP = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); prop = xmlGetProp (cur, (xmlChar*)"filter_missmp"); - if (prop) DbFilterMissMP = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterMissMP = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); prop = xmlGetProp (cur, (xmlChar*)"filter_tp"); - if (prop) DbFilterTP = NLGUI::CDBManager::getInstance()->getDbProp(prop); + if (prop) DbFilterTP = NLGUI::CDBManager::getInstance()->getDbProp(prop.str()); return true; } diff --git a/code/ryzom/client/src/interface_v3/parser_modules.cpp b/code/ryzom/client/src/interface_v3/parser_modules.cpp index ff1c93645..58158ea62 100644 --- a/code/ryzom/client/src/interface_v3/parser_modules.cpp +++ b/code/ryzom/client/src/interface_v3/parser_modules.cpp @@ -369,7 +369,7 @@ bool CCommandParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup // if prop "ctrlchar" is declared with false, then disable ctrlchar for this command CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"ctrlchar" )); if( (const char*)prop && (CInterfaceElement::convertBool((const char*)prop)==false) ) - ICommand::enableControlCharForCommand(ptrName, false); + ICommand::enableControlCharForCommand(ptrName.str(), false); // Done ret = true; diff --git a/code/ryzom/common/src/game_share/_backup_service_interface_non_module.cpp b/code/ryzom/common/src/game_share/_backup_service_interface_non_module.cpp index 2e1d474b2..801d78433 100644 --- a/code/ryzom/common/src/game_share/_backup_service_interface_non_module.cpp +++ b/code/ryzom/common/src/game_share/_backup_service_interface_non_module.cpp @@ -381,7 +381,7 @@ void CBSIINonModule::activate() // setup the callback array CUnifiedNetwork::getInstance()->addCallbackArray( CbArray, sizeof(CbArray)/sizeof(CbArray[0]) ); - string host = BackupServiceIP; + string host = BackupServiceIP.get(); if(host.empty()) { nlwarning("Can't use backup because BSHost variable is empty"); diff --git a/code/ryzom/common/src/game_share/deployment_configuration.cpp b/code/ryzom/common/src/game_share/deployment_configuration.cpp index 52fc9087c..8957c89ac 100644 --- a/code/ryzom/common/src/game_share/deployment_configuration.cpp +++ b/code/ryzom/common/src/game_share/deployment_configuration.cpp @@ -313,13 +313,13 @@ namespace DEPCFG void CInfoBlock::addUseEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) { - DROP_IF(_UseEntries.find(entry)!=_UseEntries.end(),context+"Ignoring duplicate refference to 'use' clause: "+entry,return); + DROP_IF(_UseEntries.find(entry) != _UseEntries.end(), context + "Ignoring duplicate refference to 'use' clause: " + entry.c_str(), return); _UseEntries.insert(entry); } void CInfoBlock::addDataEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) { - DROP_IF(_DataEntries.find(entry)!=_DataEntries.end(),context+"Ignoring duplicate refference to 'data' clause: "+entry,return); + DROP_IF(_DataEntries.find(entry) != _DataEntries.end(), context + "Ignoring duplicate refference to 'data' clause: " + entry.c_str(), return); _DataEntries.insert(entry); } @@ -406,10 +406,10 @@ namespace DEPCFG // try to get a pointer to the refferenced info block... CInfoBlock* infoBlockPtr= container->getInfoBlock(theEntry); - DROP_IF(infoBlockPtr==NULL,"Failed to find block named '"+theEntry+"' while fixing up children of block: "+_Name, ++errors;continue); + DROP_IF(infoBlockPtr == NULL, "Failed to find block named '" + theEntry + "' while fixing up children of block: " + _Name.c_str(), ++errors; continue); // make sure that this block doesn't figure amongst the children of the refferenced info block (to avoid circular refs) - DROP_IF(_haveCircularRef(infoBlockPtr),"Circular dependency found between definitions of '"+_Name+"' and '"+theEntry+"'", ++errors;continue); + DROP_IF(_haveCircularRef(infoBlockPtr), "Circular dependency found between definitions of '" + _Name + "' and '" + theEntry.c_str() + "'", ++errors; continue); // add the info block to our children _Children.push_back(infoBlockPtr); @@ -431,7 +431,7 @@ namespace DEPCFG DROP_IF(!_ShardName.empty() && !theExe.ShardName.empty(), "more than one shard found in: "+theExe.FullName, ++errors ); DROP_IF(!_CmdLine.empty() && !theExe.CmdLine.empty(), "more than one cmdLine found in: "+theExe.FullName, ++errors ); DROP_IF(!_Host.empty() && !theExe.Host.empty(), "more than one host found in: "+theExe.FullName, ++errors ); - WARN_IF(!_UniqueName.empty() && !theExe.UniqueName.empty(), "replacing name '"+theExe.UniqueName+"' with '"+_UniqueName+"' in: "+theExe.FullName); + WARN_IF(!_UniqueName.empty() && !theExe.UniqueName.empty(), "replacing name '" + theExe.UniqueName + "' with '" + _UniqueName.c_str() + "' in: " + theExe.FullName.c_str()); // fill our own data into the exe record if (!_DomainName.empty()) theExe.DomainName = _DomainName; @@ -645,22 +645,22 @@ namespace DEPCFG // try to treat the keyword if (keyword=="include") { - DROP_IF(args.empty(),context+"No file name found following 'include': "+line, ++errors;continue); - DROP_IF(fileNameSet.find(args)!=fileNameSet.end(),context+"Warning: Duplicate 'include' block ignored: "+line, continue); + DROP_IF(args.empty(), context + "No file name found following 'include': " + line.c_str(), ++errors; continue); + DROP_IF(fileNameSet.find(args) != fileNameSet.end(), context + "Warning: Duplicate 'include' block ignored: " + line.c_str(), continue); fileNameSet.insert(args); _readFile(args.unquoteIfQuoted(),errors,fileNameSet); } else if (keyword=="define") { - DROP_IF(args.empty(),context+"No block name found following 'define': "+line, ++errors;continue); - DROP_IF(_InfoBlocks.find(args)!=_InfoBlocks.end(),context+"Duplicate 'define' block found: "+line, ++errors;continue); + DROP_IF(args.empty(), context + "No block name found following 'define': " + line.c_str(), ++errors; continue); + DROP_IF(_InfoBlocks.find(args) != _InfoBlocks.end(), context + "Duplicate 'define' block found: " + line.c_str(), ++errors; continue); // create a new info block and push it into our infoblock set _CurrentInfoBlock= new CInfoBlock(args); _InfoBlocks[args]= _CurrentInfoBlock; } else { - DROP_IF(_CurrentInfoBlock==NULL,context+"Expecting 'define ' but found: "+line, ++errors;continue); + DROP_IF(_CurrentInfoBlock == NULL, context + "Expecting 'define ' but found: " + line.c_str(), ++errors; continue); if (keyword=="domain") { _CurrentInfoBlock->setDomainName(args,context,errors); } else if (keyword=="shard") { _CurrentInfoBlock->setShardName(args,context,errors); } @@ -674,7 +674,7 @@ namespace DEPCFG else if (keyword=="cfgAfter") { _CurrentInfoBlock->addCfgEntryPost(rawArgs,context,errors); } else if (keyword=="cfgFile") { _CurrentInfoBlock->addCfgFile(args,context,errors); } else if (keyword=="cfgFileAfter") { _CurrentInfoBlock->addCfgFilePost(args,context,errors); } - else { DROP(context+"Unrecognised keyword: "+line, ++errors;continue); } + else { DROP(context + "Unrecognised keyword: " + line.c_str(), ++errors; continue); } } } } @@ -725,7 +725,7 @@ namespace DEPCFG // yell if the name already looks like a 'fixed up' name DROP_IF(name.right(3).left(1)=="_" && (name.right(2)=="00" || name.right(2).atoui()!=0),"Appending '_' to name ending in '_00' style format as this can clash with auto renumbering => "+name+'_',name+='_') // compose a second version of the name with the shard name added - NLMISC::CSString name_with_shard= name+'_'+it2->ShardName; + NLMISC::CSString name_with_shard = name + '_' + it2->ShardName.c_str(); // insert both versions of the name into the unique name counter ++nameCounts[name]; ++nameCounts[name_with_shard]; @@ -1123,7 +1123,7 @@ namespace DEPCFG result.CfgFile= "// Auto generated config file\n" "// Use with commandline: "+theApp.CmdLine+"\n" - "AESAliasName= \""+appName+"\";\n" + "AESAliasName= \"" + appName.c_str() + "\";\n" "\n"; // copy the cfg set to the result record (the cfgAfter set should have been merged in already) diff --git a/code/ryzom/common/src/game_share/persistent_data_tree.cpp b/code/ryzom/common/src/game_share/persistent_data_tree.cpp index 63252a70c..feefbad1c 100644 --- a/code/ryzom/common/src/game_share/persistent_data_tree.cpp +++ b/code/ryzom/common/src/game_share/persistent_data_tree.cpp @@ -139,10 +139,10 @@ bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent) bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent,uint32 idx) { // check value of 'idx' - BOMB_IF(parent!=NULL && idx>1024*1024,"Implausibly high number of children requested ("+NLMISC::toString("%d",idx)+") for persistent data tree node: "+parent->getNodeName(),return false); + BOMB_IF(parent != NULL && idx>1024 * 1024, "Implausibly high number of children requested (" + NLMISC::toString("%d", idx) + ") for persistent data tree node: " + parent->getNodeName().c_str(), return false); // check for attachment to previous parent - BOMB_IF(_Parent!=NULL,"Attempting to attach a persistent data node to parent '"+(parent==NULL?"NULL":parent->getNodeName())+"' when it's already attached to another parent as: "+getNodeName(),return false); + BOMB_IF(_Parent != NULL, "Attempting to attach a persistent data node to parent '" + (parent == NULL ? "NULL" : parent->getNodeName()) + "' when it's already attached to another parent as: " + getNodeName().c_str(), return false); // split the name into its component parts CSString mapIndex= _Name; @@ -159,7 +159,7 @@ bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent,uin if (parent!=NULL) { // check parent isn't a value - BOMB_IF(parent->_IsValue,"Attempting to attach a persistent data node to parent that has a value '"+parent->getNodeName()+"' = "+parent->_Value,return false); + BOMB_IF(parent->_IsValue, "Attempting to attach a persistent data node to parent that has a value '" + parent->getNodeName() + "' = " + parent->_Value.c_str(), return false); if (hasExplicitIndex) { @@ -179,7 +179,7 @@ bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent,uin } // ensure that there isn't already a node with the same '#' value attached to the same parent - DROP_IF(parent->_ChildIndex.find(nameBase+'#'+mapIndex)!=parent->_ChildIndex.end(),"Failed to add child '"+_Name+"' to parent '"+parent->getNodeName()+"' because another child of same name already exists",return false); + DROP_IF(parent->_ChildIndex.find(nameBase + '#' + mapIndex.c_str()) != parent->_ChildIndex.end(), "Failed to add child '" + _Name + "' to parent '" + parent->getNodeName().c_str() + "' because another child of same name already exists", return false); } } if (!hasExplicitIndex) @@ -190,7 +190,7 @@ bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent,uin } // construct our cleaned up name from its constituent parts - _Name= nameBase+'#'+mapIndex; + _Name = nameBase + '#' + mapIndex.c_str(); // setup own _Parent property and ensure that there are no trailing spaces round the _Name _Parent= parent; @@ -205,7 +205,7 @@ bool CPersistentDataTreeNode::attachToParent(CPersistentDataTreeNode* parent,uin } // ensure that there isn't another child already assigned to this parent slot - BOMB_IF(_Parent->_Children[idx]!=NULL,"Ignoring attempt to add second child to same slot ("+NLMISC::toString("%d",idx)+") in persistent data tree node's children: "+_Parent->getNodeName(),return false); + BOMB_IF(_Parent->_Children[idx] != NULL, "Ignoring attempt to add second child to same slot (" + NLMISC::toString("%d", idx) + ") in persistent data tree node's children: " + _Parent->getNodeName().c_str(), return false); // write own pointer into parent's _Children vector _Parent->_Children[idx]= this; @@ -239,7 +239,7 @@ bool CPersistentDataTreeNode::readFromPdr(CPersistentDataRecord& pdr) return false; // pop the end of block token for the block we just finished processing - DROP_IF(pdr.peekNextToken()!=token,"ERROR: End of "+pdr.lookupString(token)+" block expected but not found at: "+getNodeName(),return false); + DROP_IF(pdr.peekNextToken() != token, "ERROR: End of " + pdr.lookupString(token) + " block expected but not found at: " + getNodeName().c_str(), return false); pdr.popStructEnd(token); } else if (pdr.isEndOfStruct()) @@ -259,7 +259,7 @@ bool CPersistentDataTreeNode::readFromPdr(CPersistentDataRecord& pdr) // extract the map key and ensure that it's followed by a valid __Val__ entry CSString mapKey; pdr.pop(mapKeyToken,mapKey); - DROP_IF(pdr.isEndOfData() || pdr.peekNextToken()!=mapValToken,"ERROR: Ignoring map key (__Key__) because __Val__ token expected but not found at: "+getNodeName()+":"+mapKey,continue); + DROP_IF(pdr.isEndOfData() || pdr.peekNextToken() != mapValToken, "ERROR: Ignoring map key (__Key__) because __Val__ token expected but not found at: " + getNodeName() + ":" + mapKey.c_str(), continue); if (needsQuotes(mapKey)) mapKey=mapKey.quote(); @@ -278,7 +278,7 @@ bool CPersistentDataTreeNode::readFromPdr(CPersistentDataRecord& pdr) return false; // pop the end of struct marker - DROP_IF(pdr.peekNextToken()!=mapValToken,"ERROR: End of __Val__ block expected but not found at: "+getNodeName()+":"+mapKey,return false); + DROP_IF(pdr.peekNextToken() != mapValToken, "ERROR: End of __Val__ block expected but not found at: " + getNodeName() + ":" + mapKey.c_str(), return false); pdr.popStructEnd(mapValToken); } else @@ -419,9 +419,9 @@ bool CPersistentDataTreeNode::writeToBuffer(NLMISC::CSString& buffer) const { // write a value if (needsQuotes(_Value)) - buffer+= getNodeName()+"=="+_Value.quote()+"\n"; + buffer += getNodeName() + "==" + _Value.quote().c_str() + "\n"; else - buffer+= getNodeName()+"="+_Value+"\n"; + buffer += getNodeName() + "=" + _Value.c_str() + "\n"; } else { @@ -468,8 +468,8 @@ CSString CPersistentDataTreeNode::getNodeName() const // return one of name, parentName.name and parentName:name if (parentName.empty()) return name; - if (isMapEntry()) return parentName+":"+name; - else return parentName+"."+name; + if (isMapEntry()) return parentName + ":" + name.c_str(); + else return parentName + "." + name.c_str(); } void CPersistentDataTreeNode::setValue(const TValue& value) @@ -507,7 +507,7 @@ bool CPersistentDataTreeNode::isMapEntry() const bool CPersistentDataTreeNode::flagAsMap() { - DROP_IF(_IsValue,"ERROR: Failed to flag persistent data tree node '"+getNodeName()+"' as a map as it already has a value: "+_Value,return false); + DROP_IF(_IsValue, "ERROR: Failed to flag persistent data tree node '" + getNodeName() + "' as a map as it already has a value: " + _Value.c_str(), return false); if (_IsMap) return true; diff --git a/code/ryzom/common/src/game_share/server_animation_module.cpp b/code/ryzom/common/src/game_share/server_animation_module.cpp index 51d7ce19e..3d3548d54 100644 --- a/code/ryzom/common/src/game_share/server_animation_module.cpp +++ b/code/ryzom/common/src/game_share/server_animation_module.cpp @@ -1017,7 +1017,7 @@ IPrimitive* CServerAnimationModule::getAction(CObject* action, const std::string } if(result.size()>=2) - result[1] = "DSS_"+toString(scenarioId)+" "+result[1]; + result[1] = "DSS_"+toString(scenarioId)+" "+result[1].c_str(); if(result.size()>=3) { for(uint32 i=2;i Date: Fri, 20 Feb 2015 17:51:13 +0100 Subject: [PATCH 274/344] Visual Studio 2013 compilation support for NeL Tools --HG-- branch : develop --- code/nel/tools/misc/make_sheet_id/make_sheet_id.cpp | 2 +- code/nel/tools/misc/xml_packer/xml_packer.cpp | 2 +- code/nel/tools/pacs/build_rbank/build_rbank.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/misc/make_sheet_id/make_sheet_id.cpp b/code/nel/tools/misc/make_sheet_id/make_sheet_id.cpp index 53d515fdd..851dfe6df 100644 --- a/code/nel/tools/misc/make_sheet_id/make_sheet_id.cpp +++ b/code/nel/tools/misc/make_sheet_id/make_sheet_id.cpp @@ -163,7 +163,7 @@ void readFormId( string& outputFileName ) map::iterator itFT = FileTypeToId.find(fileType); if( itFT == FileTypeToId.end() ) { - FileTypeToId.insert( make_pair(fileType,fid.FormIDInfos.Type) ); + FileTypeToId.insert( std::pair(fileType,fid.FormIDInfos.Type) ); } } else diff --git a/code/nel/tools/misc/xml_packer/xml_packer.cpp b/code/nel/tools/misc/xml_packer/xml_packer.cpp index 6f82b5426..2d7695de4 100644 --- a/code/nel/tools/misc/xml_packer/xml_packer.cpp +++ b/code/nel/tools/misc/xml_packer/xml_packer.cpp @@ -379,7 +379,7 @@ int main(int argc, char *argv[]) CSString subFileName = parser.leftCrop(sizeof(" (i, fi)); + faultyInstances.insert(std::pair(i, fi)); } } @@ -1046,7 +1046,7 @@ void processGlobalRetriever() { if (Verbose) nlinfo("after fix: unlink: %s", unlinkstr.c_str()); - faultyInstances.insert(make_pair(i, fi)); + faultyInstances.insert(std::pair(i, fi)); } } } From aebda454dc61d2b884b3048d142d64aa9e10d130 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:53:39 +0100 Subject: [PATCH 275/344] Visual Studio 2013 compilation support for Ryzom Client --HG-- branch : develop --- code/ryzom/client/src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ryzom/client/src/CMakeLists.txt b/code/ryzom/client/src/CMakeLists.txt index a2f89420b..9c2b4b431 100644 --- a/code/ryzom/client/src/CMakeLists.txt +++ b/code/ryzom/client/src/CMakeLists.txt @@ -83,6 +83,7 @@ INCLUDE_DIRECTORIES( ${LUABIND_INCLUDE_DIR} ${LIBWWW_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIR} ) TARGET_LINK_LIBRARIES(ryzom_client From 2667c5d8a2d2429b6e73a93285cf194f17a6b701 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 17:57:11 +0100 Subject: [PATCH 276/344] Visual Studio 2013 compilation support for Ryzom Client --HG-- branch : develop --- code/ryzom/client/src/r2/dmc/client_edition_module.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/r2/dmc/client_edition_module.cpp b/code/ryzom/client/src/r2/dmc/client_edition_module.cpp index 93978800d..5d00cdc2b 100644 --- a/code/ryzom/client/src/r2/dmc/client_edition_module.cpp +++ b/code/ryzom/client/src/r2/dmc/client_edition_module.cpp @@ -1352,8 +1352,8 @@ bool CClientEditionModule::loadUserComponent(const std::string& filename, bool m } } - std::string sourceExtension = UserComponentsSourceExtension; - std::string componentExtension = UserComponentsComponentExtension; + std::string sourceExtension = UserComponentsSourceExtension.get(); + std::string componentExtension = UserComponentsComponentExtension.get(); uint32 uncompressedFileLength = 0; From a8db3b2dda53e3ce8245d6c67566a005fb497c6b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 20 Feb 2015 18:10:06 +0100 Subject: [PATCH 277/344] Visual Studio 2013 compilation support for Ryzom Client --HG-- branch : develop --- code/CMakeLists.txt | 6 ++++-- code/CMakeModules/nel.cmake | 5 +++++ code/nel/include/nel/gui/group_html.h | 1 - code/nel/include/nel/misc/sstring.h | 8 ++++---- code/nel/include/nel/misc/types_nl.h | 5 ++++- code/ryzom/client/src/http_client_curl.cpp | 1 - 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0ffef9c1e..279aa3d49 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -156,9 +156,11 @@ IF(WITH_NEL) FIND_PACKAGE(Luabind REQUIRED) FIND_PACKAGE(CURL REQUIRED) - IF(WIN32 OR CURL_LIBRARIES MATCHES "\\.a") + IF((WIN32 OR CURL_LIBRARIES MATCHES "\\.a") AND WITH_STATIC_CURL) SET(CURL_STATIC ON) - ENDIF(WIN32 OR CURL_LIBRARIES MATCHES "\\.a") + ELSE((WIN32 OR CURL_LIBRARIES MATCHES "\\.a") AND WITH_STATIC_CURL) + SET(CURL_STATIC OFF) + ENDIF((WIN32 OR CURL_LIBRARIES MATCHES "\\.a") AND WITH_STATIC_CURL) IF(CURL_STATIC) SET(CURL_DEFINITIONS -DCURL_STATICLIB) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 081da67ca..70113e11b 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -255,6 +255,11 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) ELSE(WITH_STATIC) OPTION(WITH_STATIC_LIBXML2 "With static libxml2" OFF) ENDIF(WITH_STATIC) + IF (WITH_STATIC) + OPTION(WITH_STATIC_CURL "With static curl" ON ) + ELSE(WITH_STATIC) + OPTION(WITH_STATIC_CURL "With static curl" OFF) + ENDIF(WITH_STATIC) IF(APPLE) OPTION(WITH_LIBXML2_ICONV "With libxml2 using iconv" ON ) ELSE(APPLE) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 333800760..4f9bee46c 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -17,7 +17,6 @@ #ifndef CL_GROUP_HTML_H #define CL_GROUP_HTML_H -#define CURL_STATICLIB 1 #include #include "nel/misc/types_nl.h" diff --git a/code/nel/include/nel/misc/sstring.h b/code/nel/include/nel/misc/sstring.h index fdeebcfc8..c9ebff721 100644 --- a/code/nel/include/nel/misc/sstring.h +++ b/code/nel/include/nel/misc/sstring.h @@ -937,21 +937,21 @@ inline CSString operator+(const CSString& s0,const CSString& s1) */ inline CSString operator+(char s0,const CSString& s1) { - return CSString(s0)+s1; + return CSString(s0) + s1.c_str(); } inline CSString operator+(const char* s0,const CSString& s1) { - return CSString(s0)+s1; + return CSString(s0) + s1.c_str(); } -#ifndef NL_COMP_VC10 +#if !defined(NL_COMP_VC) || (NL_COMP_VC_VERSION <= 100) // TODO: check if it can be disabled for other compilers too inline CSString operator+(const std::string& s0,const CSString& s1) { return s0+static_cast(s1); } -#endif // NL_COMP_VC10 +#endif } // NLMISC diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h index 7a6ee2662..7091f4905 100644 --- a/code/nel/include/nel/misc/types_nl.h +++ b/code/nel/include/nel/misc/types_nl.h @@ -54,6 +54,9 @@ # ifdef _MSC_VER # define NL_COMP_VC # if _MSC_VER >= 1700 +# define NL_COMP_VC12 +# define NL_COMP_VC_VERSION 120 +# elif _MSC_VER >= 1700 # define NL_COMP_VC11 # define NL_COMP_VC_VERSION 110 # elif _MSC_VER >= 1600 @@ -414,7 +417,7 @@ extern void operator delete[](void *p) throw(); # define CHashMap stdext::hash_map # define CHashSet stdext::hash_set # define CHashMultiMap stdext::hash_multimap -#elif defined(NL_COMP_VC) && (NL_COMP_VC_VERSION == 110) +#elif defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 120) # include # include # define CHashMap ::std::hash_map diff --git a/code/ryzom/client/src/http_client_curl.cpp b/code/ryzom/client/src/http_client_curl.cpp index db830a9df..008bef19a 100644 --- a/code/ryzom/client/src/http_client_curl.cpp +++ b/code/ryzom/client/src/http_client_curl.cpp @@ -15,7 +15,6 @@ // along with this program. If not, see . #include "stdpch.h" -#define CURL_STATICLIB 1 #include #include "http_client_curl.h" From 4fd17a428d9bd9e7f1ac5d72b48ff402eaae3b59 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 20:01:44 +0100 Subject: [PATCH 278/344] Install rcerror --HG-- branch : hotfix --- code/nel/rcerror/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/rcerror/CMakeLists.txt b/code/nel/rcerror/CMakeLists.txt index 412da9b6c..51522cf0c 100644 --- a/code/nel/rcerror/CMakeLists.txt +++ b/code/nel/rcerror/CMakeLists.txt @@ -35,3 +35,5 @@ TARGET_LINK_LIBRARIES(rcerror ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) NL_DEFAULT_PROPS(rcerror "Ryzom Core Error Reporter") NL_ADD_RUNTIME_FLAGS(rcerror) +INSTALL(TARGETS rcerror RUNTIME DESTINATION ${NL_BIN_PREFIX}) + From 7efb3334fc6b47ea4659ea48e11af5d7ddfb46a7 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 20:01:44 +0100 Subject: [PATCH 279/344] Install rcerror --HG-- branch : feature-crashreport --- code/nel/rcerror/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/rcerror/CMakeLists.txt b/code/nel/rcerror/CMakeLists.txt index 412da9b6c..51522cf0c 100644 --- a/code/nel/rcerror/CMakeLists.txt +++ b/code/nel/rcerror/CMakeLists.txt @@ -35,3 +35,5 @@ TARGET_LINK_LIBRARIES(rcerror ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) NL_DEFAULT_PROPS(rcerror "Ryzom Core Error Reporter") NL_ADD_RUNTIME_FLAGS(rcerror) +INSTALL(TARGETS rcerror RUNTIME DESTINATION ${NL_BIN_PREFIX}) + From 070dad8e53ff2b703fedf82320be599e3269ba71 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 21:28:56 +0100 Subject: [PATCH 280/344] Use CMsgBoxDisplayer on platforms other than Windows as well. --HG-- branch : hotfix --- code/nel/src/misc/debug.cpp | 8 +------- code/nel/src/misc/displayer.cpp | 2 -- code/nel/src/misc/report.cpp | 12 ------------ 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 2d09f5ef8..aaa551f1f 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -1193,13 +1193,7 @@ void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) INelContext::getInstance().setAssertLog(new CLog (CLog::LOG_ASSERT)); sd = new CStdDisplayer ("DEFAULT_SD"); - -#ifdef NL_OS_WINDOWS - if (TrapCrashInDebugger || !IsDebuggerPresent ()) - { - DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); - } -#endif + DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); #if LOG_IN_FILE if (logInFile) diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index d48c44d02..35ae27964 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,7 +529,6 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { -#ifdef NL_OS_WINDOWS bool needSpace = false; // stringstream ss; @@ -720,7 +719,6 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m } */ } -#endif } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 88c707aaa..b165e29f5 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -52,16 +52,6 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -#ifndef NL_OS_WINDOWS - -// GNU/Linux, do nothing - -void report () -{ -} - -#else - TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { std::string fname = "rcerrorlog.txt"; @@ -92,7 +82,5 @@ TReportResult report (const std::string &title, const std::string &header, const return ReportQuit; } -#endif - } // NLMISC From 1476bfe648a1b88213453592ba9587b206ba5dbc Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 21:28:56 +0100 Subject: [PATCH 281/344] Use CMsgBoxDisplayer on platforms other than Windows as well. --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 8 +------- code/nel/src/misc/displayer.cpp | 2 -- code/nel/src/misc/report.cpp | 12 ------------ 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 2d09f5ef8..aaa551f1f 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -1193,13 +1193,7 @@ void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) INelContext::getInstance().setAssertLog(new CLog (CLog::LOG_ASSERT)); sd = new CStdDisplayer ("DEFAULT_SD"); - -#ifdef NL_OS_WINDOWS - if (TrapCrashInDebugger || !IsDebuggerPresent ()) - { - DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); - } -#endif + DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); #if LOG_IN_FILE if (logInFile) diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index d48c44d02..35ae27964 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,7 +529,6 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { -#ifdef NL_OS_WINDOWS bool needSpace = false; // stringstream ss; @@ -720,7 +719,6 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m } */ } -#endif } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 88c707aaa..b165e29f5 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -52,16 +52,6 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -#ifndef NL_OS_WINDOWS - -// GNU/Linux, do nothing - -void report () -{ -} - -#else - TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { std::string fname = "rcerrorlog.txt"; @@ -92,7 +82,5 @@ TReportResult report (const std::string &title, const std::string &header, const return ReportQuit; } -#endif - } // NLMISC From ac6bda50841608435d1f24e34d1dbf1868aa875a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 22:32:11 +0100 Subject: [PATCH 282/344] A little cleanup of CMsgBoxDisplayer. --HG-- branch : hotfix --- code/nel/include/nel/misc/report.h | 17 +-- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/displayer.cpp | 174 +---------------------------- code/nel/src/misc/report.cpp | 19 +--- 4 files changed, 7 insertions(+), 205 deletions(-) diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index 11745b6e3..6bf3df959 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,21 +21,8 @@ namespace NLMISC { -/** Display a custom message box. - * - * \param title set the title of the report. If empty, it'll display "NeL report". - * \param header message displayed before the edit text box. If empty, it displays the default message. - * \param body message displayed in the edit text box. This string will be sent by email. - * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior - * - * - * - * \return the button clicked or error - */ - -enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); +/// Prepares the error report, writes it to disk and launches the error reporter +void report ( const std::string &body ); /** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); */ diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index aaa551f1f..67c8cb0f3 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -553,7 +553,7 @@ public: // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). bool i = false; - report (progname+shortExc, "", subject, _Reason, true, 1, true, 1, !isCrashAlreadyReported(), i, NL_CRASH_DUMP_FILE); + report ( _Reason ); // no more sent mail for crash setCrashAlreadyReported(true); diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 35ae27964..8296d1c0b 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,114 +529,7 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { - - bool needSpace = false; -// stringstream ss; - string str; - - // create the string for the clipboard - - if (args.Date != 0) - { - str += dateToHumanString(args.Date); - needSpace = true; - } - - if (args.LogType != CLog::LOG_NO) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += logTypeToString(args.LogType); - needSpace = true; - } - - if (!args.ProcessName.empty()) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += args.ProcessName; - needSpace = true; - } - - if (args.FileName != NULL) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += CFile::getFilename(args.FileName); - needSpace = true; - } - - if (args.Line != -1) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += NLMISC::toString(args.Line); - needSpace = true; - } - - if (args.FuncName != NULL) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += args.FuncName; - needSpace = true; - } - - if (needSpace) { str += ": "; needSpace = false; } - - str += message; - - CSystemUtils::copyTextToClipboard(str); - - // create the string on the screen - needSpace = false; -// stringstream ss2; - string str2; - -#ifdef NL_DEBUG - if (!args.ProcessName.empty()) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += args.ProcessName; - needSpace = true; - } - - if (args.FileName != NULL) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += CFile::getFilename(args.FileName); - needSpace = true; - } - - if (args.Line != -1) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += NLMISC::toString(args.Line); - needSpace = true; - } - - if (args.FuncName != NULL) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += args.FuncName; - needSpace = true; - } - - if (needSpace) { str2 += ": "; needSpace = false; } - -#endif // NL_DEBUG - - str2 += message; - str2 += "\n\n(this message was copied in the clipboard)"; - -/* if (IsDebuggerPresent ()) - { - // Must break in assert call - DebugNeedAssert = true; - } - else -*/ { - + // Display the report string body; @@ -656,69 +549,8 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m body += "Reason: " + toString(message); body += args.CallstackAndLog; - - string subject; - - // procname is host/service_name-sid we only want the service_name to avoid redondant mail - string procname; - string::size_type pos = args.ProcessName.find ("/"); - if (pos == string::npos) - { - procname = args.ProcessName; - } - else - { - string::size_type pos2 = args.ProcessName.find ("-", pos+1); - if (pos2 == string::npos) - { - procname = args.ProcessName.substr (pos+1); - } - else - { - procname = args.ProcessName.substr (pos+1, pos2-pos-1); - } - } - - subject += procname + " NeL " + toString(LogTypeToString[0][args.LogType]) + " " + (args.FileName?string(args.FileName):"") + " " + toString(args.Line) + " " + (args.FuncName?string(args.FuncName):""); - - // Check the envvar NEL_IGNORE_ASSERT - if (getenv ("NEL_IGNORE_ASSERT") == NULL) - { - // yoyo: allow only to send the crash report once. Because users usually click ignore, - // which create noise into list of bugs (once a player crash, it will surely continues to do it). - std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; - - if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) - { - INelContext::getInstance().setDebugNeedAssert(true); - } - - // no more sent mail for crash - setCrashAlreadyReported(true); - } - -/* // Check the envvar NEL_IGNORE_ASSERT - if (getenv ("NEL_IGNORE_ASSERT") == NULL) - { - // Ask the user to continue, debug or ignore - int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); - if (result == IDABORT) - { - // Exit the program now - exit (EXIT_FAILURE); - } - else if (result == IDRETRY) - { - // Give the debugger a try - DebugNeedAssert = true; - } - else if (result == IDIGNORE) - { - // Continue, do nothing - } - } -*/ } - + + report( body ); } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index b165e29f5..54c456ade 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -22,23 +22,8 @@ #include "nel/misc/report.h" #include "nel/misc/path.h" -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include -# include -# include -#endif // NL_OS_WINDOWS - -#define NL_NO_DEBUG_FILES 1 - using namespace std; -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - namespace NLMISC { @@ -52,7 +37,7 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +void report ( const std::string &body ) { std::string fname = "rcerrorlog.txt"; @@ -78,8 +63,6 @@ TReportResult report (const std::string &title, const std::string &header, const #endif // quit without calling atexit or static object dtors. abort(); - - return ReportQuit; } From e130625ccab79190121cc76247cc634f26c6d3d8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 22:32:11 +0100 Subject: [PATCH 283/344] A little cleanup of CMsgBoxDisplayer. --HG-- branch : feature-crashreport --- code/nel/include/nel/misc/report.h | 17 +-- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/displayer.cpp | 174 +---------------------------- code/nel/src/misc/report.cpp | 19 +--- 4 files changed, 7 insertions(+), 205 deletions(-) diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index 11745b6e3..6bf3df959 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,21 +21,8 @@ namespace NLMISC { -/** Display a custom message box. - * - * \param title set the title of the report. If empty, it'll display "NeL report". - * \param header message displayed before the edit text box. If empty, it displays the default message. - * \param body message displayed in the edit text box. This string will be sent by email. - * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior - * - * - * - * \return the button clicked or error - */ - -enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); +/// Prepares the error report, writes it to disk and launches the error reporter +void report ( const std::string &body ); /** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); */ diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index aaa551f1f..67c8cb0f3 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -553,7 +553,7 @@ public: // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). bool i = false; - report (progname+shortExc, "", subject, _Reason, true, 1, true, 1, !isCrashAlreadyReported(), i, NL_CRASH_DUMP_FILE); + report ( _Reason ); // no more sent mail for crash setCrashAlreadyReported(true); diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 35ae27964..8296d1c0b 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,114 +529,7 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { - - bool needSpace = false; -// stringstream ss; - string str; - - // create the string for the clipboard - - if (args.Date != 0) - { - str += dateToHumanString(args.Date); - needSpace = true; - } - - if (args.LogType != CLog::LOG_NO) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += logTypeToString(args.LogType); - needSpace = true; - } - - if (!args.ProcessName.empty()) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += args.ProcessName; - needSpace = true; - } - - if (args.FileName != NULL) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += CFile::getFilename(args.FileName); - needSpace = true; - } - - if (args.Line != -1) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += NLMISC::toString(args.Line); - needSpace = true; - } - - if (args.FuncName != NULL) - { - //if (needSpace) { ss << " "; needSpace = false; } - if (needSpace) { str += " "; needSpace = false; } - str += args.FuncName; - needSpace = true; - } - - if (needSpace) { str += ": "; needSpace = false; } - - str += message; - - CSystemUtils::copyTextToClipboard(str); - - // create the string on the screen - needSpace = false; -// stringstream ss2; - string str2; - -#ifdef NL_DEBUG - if (!args.ProcessName.empty()) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += args.ProcessName; - needSpace = true; - } - - if (args.FileName != NULL) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += CFile::getFilename(args.FileName); - needSpace = true; - } - - if (args.Line != -1) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += NLMISC::toString(args.Line); - needSpace = true; - } - - if (args.FuncName != NULL) - { - if (needSpace) { str2 += " "; needSpace = false; } - str2 += args.FuncName; - needSpace = true; - } - - if (needSpace) { str2 += ": "; needSpace = false; } - -#endif // NL_DEBUG - - str2 += message; - str2 += "\n\n(this message was copied in the clipboard)"; - -/* if (IsDebuggerPresent ()) - { - // Must break in assert call - DebugNeedAssert = true; - } - else -*/ { - + // Display the report string body; @@ -656,69 +549,8 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m body += "Reason: " + toString(message); body += args.CallstackAndLog; - - string subject; - - // procname is host/service_name-sid we only want the service_name to avoid redondant mail - string procname; - string::size_type pos = args.ProcessName.find ("/"); - if (pos == string::npos) - { - procname = args.ProcessName; - } - else - { - string::size_type pos2 = args.ProcessName.find ("-", pos+1); - if (pos2 == string::npos) - { - procname = args.ProcessName.substr (pos+1); - } - else - { - procname = args.ProcessName.substr (pos+1, pos2-pos-1); - } - } - - subject += procname + " NeL " + toString(LogTypeToString[0][args.LogType]) + " " + (args.FileName?string(args.FileName):"") + " " + toString(args.Line) + " " + (args.FuncName?string(args.FuncName):""); - - // Check the envvar NEL_IGNORE_ASSERT - if (getenv ("NEL_IGNORE_ASSERT") == NULL) - { - // yoyo: allow only to send the crash report once. Because users usually click ignore, - // which create noise into list of bugs (once a player crash, it will surely continues to do it). - std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; - - if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) - { - INelContext::getInstance().setDebugNeedAssert(true); - } - - // no more sent mail for crash - setCrashAlreadyReported(true); - } - -/* // Check the envvar NEL_IGNORE_ASSERT - if (getenv ("NEL_IGNORE_ASSERT") == NULL) - { - // Ask the user to continue, debug or ignore - int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); - if (result == IDABORT) - { - // Exit the program now - exit (EXIT_FAILURE); - } - else if (result == IDRETRY) - { - // Give the debugger a try - DebugNeedAssert = true; - } - else if (result == IDIGNORE) - { - // Continue, do nothing - } - } -*/ } - + + report( body ); } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index b165e29f5..54c456ade 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -22,23 +22,8 @@ #include "nel/misc/report.h" #include "nel/misc/path.h" -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include -# include -# include -#endif // NL_OS_WINDOWS - -#define NL_NO_DEBUG_FILES 1 - using namespace std; -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - namespace NLMISC { @@ -52,7 +37,7 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +void report ( const std::string &body ) { std::string fname = "rcerrorlog.txt"; @@ -78,8 +63,6 @@ TReportResult report (const std::string &title, const std::string &header, const #endif // quit without calling atexit or static object dtors. abort(); - - return ReportQuit; } From 2f808280c863aa2057592b8622af17ce652529a7 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 22:34:02 +0100 Subject: [PATCH 284/344] Removed unused references to CMsgBoxDisplayer. --HG-- branch : hotfix --- code/ryzom/client/src/connection.cpp | 1 - code/ryzom/client/src/init.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 8b07cc7f2..22354e436 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -103,7 +103,6 @@ extern uint32 Version; // Client Version. extern UDriver *Driver; extern UTextContext *TextContext; extern bool game_exit; -extern CMsgBoxDisplayer MsgBoxError; extern CSoundManager *SoundMngr; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 6958fe790..f0fd40dae 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -142,7 +142,6 @@ using namespace std; // Ligo primitive class CLigoConfig LigoConfig; -CMsgBoxDisplayer MsgBoxError; CClientChatManager ChatMngr; bool LastScreenSaverEnabled = false; From d2194cda05e647151b522e6d2014480726bd0b69 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 21 Feb 2015 22:34:02 +0100 Subject: [PATCH 285/344] Removed unused references to CMsgBoxDisplayer. --HG-- branch : feature-crashreport --- code/ryzom/client/src/connection.cpp | 1 - code/ryzom/client/src/init.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 8b07cc7f2..22354e436 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -103,7 +103,6 @@ extern uint32 Version; // Client Version. extern UDriver *Driver; extern UTextContext *TextContext; extern bool game_exit; -extern CMsgBoxDisplayer MsgBoxError; extern CSoundManager *SoundMngr; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 6958fe790..f0fd40dae 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -142,7 +142,6 @@ using namespace std; // Ligo primitive class CLigoConfig LigoConfig; -CMsgBoxDisplayer MsgBoxError; CClientChatManager ChatMngr; bool LastScreenSaverEnabled = false; From 4e00903dccfdacf1dce6fbd9d75879dd245299e4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 17:15:41 +0100 Subject: [PATCH 286/344] Back out from 5bb3dad --HG-- branch : feature-crashreport --- code/nel/include/nel/misc/report.h | 17 ++- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/displayer.cpp | 174 ++++++++++++++++++++++++++++- code/nel/src/misc/report.cpp | 19 +++- 4 files changed, 205 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index 6bf3df959..11745b6e3 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,8 +21,21 @@ namespace NLMISC { -/// Prepares the error report, writes it to disk and launches the error reporter -void report ( const std::string &body ); +/** Display a custom message box. + * + * \param title set the title of the report. If empty, it'll display "NeL report". + * \param header message displayed before the edit text box. If empty, it displays the default message. + * \param body message displayed in the edit text box. This string will be sent by email. + * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior + * + * + * + * \return the button clicked or error + */ + +enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; + +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); /** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); */ diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 67c8cb0f3..aaa551f1f 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -553,7 +553,7 @@ public: // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). bool i = false; - report ( _Reason ); + report (progname+shortExc, "", subject, _Reason, true, 1, true, 1, !isCrashAlreadyReported(), i, NL_CRASH_DUMP_FILE); // no more sent mail for crash setCrashAlreadyReported(true); diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 8296d1c0b..35ae27964 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,7 +529,114 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { - + + bool needSpace = false; +// stringstream ss; + string str; + + // create the string for the clipboard + + if (args.Date != 0) + { + str += dateToHumanString(args.Date); + needSpace = true; + } + + if (args.LogType != CLog::LOG_NO) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += logTypeToString(args.LogType); + needSpace = true; + } + + if (!args.ProcessName.empty()) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += args.ProcessName; + needSpace = true; + } + + if (args.FileName != NULL) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += CFile::getFilename(args.FileName); + needSpace = true; + } + + if (args.Line != -1) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += NLMISC::toString(args.Line); + needSpace = true; + } + + if (args.FuncName != NULL) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += args.FuncName; + needSpace = true; + } + + if (needSpace) { str += ": "; needSpace = false; } + + str += message; + + CSystemUtils::copyTextToClipboard(str); + + // create the string on the screen + needSpace = false; +// stringstream ss2; + string str2; + +#ifdef NL_DEBUG + if (!args.ProcessName.empty()) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += args.ProcessName; + needSpace = true; + } + + if (args.FileName != NULL) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += CFile::getFilename(args.FileName); + needSpace = true; + } + + if (args.Line != -1) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += NLMISC::toString(args.Line); + needSpace = true; + } + + if (args.FuncName != NULL) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += args.FuncName; + needSpace = true; + } + + if (needSpace) { str2 += ": "; needSpace = false; } + +#endif // NL_DEBUG + + str2 += message; + str2 += "\n\n(this message was copied in the clipboard)"; + +/* if (IsDebuggerPresent ()) + { + // Must break in assert call + DebugNeedAssert = true; + } + else +*/ { + // Display the report string body; @@ -549,8 +656,69 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m body += "Reason: " + toString(message); body += args.CallstackAndLog; - - report( body ); + + string subject; + + // procname is host/service_name-sid we only want the service_name to avoid redondant mail + string procname; + string::size_type pos = args.ProcessName.find ("/"); + if (pos == string::npos) + { + procname = args.ProcessName; + } + else + { + string::size_type pos2 = args.ProcessName.find ("-", pos+1); + if (pos2 == string::npos) + { + procname = args.ProcessName.substr (pos+1); + } + else + { + procname = args.ProcessName.substr (pos+1, pos2-pos-1); + } + } + + subject += procname + " NeL " + toString(LogTypeToString[0][args.LogType]) + " " + (args.FileName?string(args.FileName):"") + " " + toString(args.Line) + " " + (args.FuncName?string(args.FuncName):""); + + // Check the envvar NEL_IGNORE_ASSERT + if (getenv ("NEL_IGNORE_ASSERT") == NULL) + { + // yoyo: allow only to send the crash report once. Because users usually click ignore, + // which create noise into list of bugs (once a player crash, it will surely continues to do it). + std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; + + if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) + { + INelContext::getInstance().setDebugNeedAssert(true); + } + + // no more sent mail for crash + setCrashAlreadyReported(true); + } + +/* // Check the envvar NEL_IGNORE_ASSERT + if (getenv ("NEL_IGNORE_ASSERT") == NULL) + { + // Ask the user to continue, debug or ignore + int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); + if (result == IDABORT) + { + // Exit the program now + exit (EXIT_FAILURE); + } + else if (result == IDRETRY) + { + // Give the debugger a try + DebugNeedAssert = true; + } + else if (result == IDIGNORE) + { + // Continue, do nothing + } + } +*/ } + } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 54c456ade..b165e29f5 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -22,8 +22,23 @@ #include "nel/misc/report.h" #include "nel/misc/path.h" +#ifdef NL_OS_WINDOWS +# ifndef NL_COMP_MINGW +# define NOMINMAX +# endif +# include +# include +# include +#endif // NL_OS_WINDOWS + +#define NL_NO_DEBUG_FILES 1 + using namespace std; +#ifdef DEBUG_NEW + #define new DEBUG_NEW +#endif + namespace NLMISC { @@ -37,7 +52,7 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -void report ( const std::string &body ) +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { std::string fname = "rcerrorlog.txt"; @@ -63,6 +78,8 @@ void report ( const std::string &body ) #endif // quit without calling atexit or static object dtors. abort(); + + return ReportQuit; } From 7efbee6d0a67030281c823a91f5c0c6ba5c40cdd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 17:20:24 +0100 Subject: [PATCH 287/344] Backed out from 5942903 --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 8 +++++++- code/nel/src/misc/displayer.cpp | 2 ++ code/nel/src/misc/report.cpp | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index aaa551f1f..2d09f5ef8 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -1193,7 +1193,13 @@ void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) INelContext::getInstance().setAssertLog(new CLog (CLog::LOG_ASSERT)); sd = new CStdDisplayer ("DEFAULT_SD"); - DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); + +#ifdef NL_OS_WINDOWS + if (TrapCrashInDebugger || !IsDebuggerPresent ()) + { + DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); + } +#endif #if LOG_IN_FILE if (logInFile) diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 35ae27964..d48c44d02 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,6 +529,7 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { +#ifdef NL_OS_WINDOWS bool needSpace = false; // stringstream ss; @@ -719,6 +720,7 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m } */ } +#endif } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index b165e29f5..88c707aaa 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -52,6 +52,16 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } +#ifndef NL_OS_WINDOWS + +// GNU/Linux, do nothing + +void report () +{ +} + +#else + TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { std::string fname = "rcerrorlog.txt"; @@ -82,5 +92,7 @@ TReportResult report (const std::string &title, const std::string &header, const return ReportQuit; } +#endif + } // NLMISC From 3d9357637b6d48d806ab5f0d76a33325d0b96770 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 17:38:06 +0100 Subject: [PATCH 288/344] Backed out from fdc0d40 --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/report.cpp | 291 +++++++++++++++++++++++++++++++++-- 2 files changed, 278 insertions(+), 15 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 2d09f5ef8..c7667acc2 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -83,7 +83,7 @@ using namespace std; #define LOG_IN_FILE NEL_LOG_IN_FILE // If true, debug system will trap crash even if the application is in debugger -static const bool TrapCrashInDebugger = true; +static const bool TrapCrashInDebugger = false; #ifdef DEBUG_NEW #define new DEBUG_NEW diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 88c707aaa..20b2b1c11 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -42,14 +42,25 @@ using namespace std; namespace NLMISC { +#ifdef NL_OS_WINDOWS +static HWND sendReport=NULL; +#endif + //old doesn't work on visual c++ 7.1 due to default parameter typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile = "", bool onlyCheck = false); typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile, bool onlyCheck); +#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } + static TEmailFunction EmailFunction = NULL; void setReportEmailFunction (void *emailFunction) { EmailFunction = (TEmailFunction)emailFunction; + +#ifdef NL_OS_WINDOWS + if (sendReport) + EnableWindow(sendReport, FALSE); +#endif } #ifndef NL_OS_WINDOWS @@ -62,24 +73,91 @@ void report () #else -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) -{ - std::string fname = "rcerrorlog.txt"; +// Windows specific version - std::ofstream f; - f.open( fname.c_str() ); - if( f.good() ) - { - f << body; - f.close(); +static string Body; +static string Subject; +static string AttachedFile; -#ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "rcerror.exe", fname ); -#else - NLMISC::launchProgram( "rcerror", fname ); +static HWND checkIgnore=NULL; +static HWND debug=NULL; +static HWND ignore=NULL; +static HWND quit=NULL; +static HWND dialog=NULL; + +static bool NeedExit; +static TReportResult Result; +static bool IgnoreNextTime; +static bool CanSendMailReport= false; + +static bool DebugDefaultBehavior, QuitDefaultBehavior; + +static void sendEmail() +{ + if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) + { + bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); + if (res) + { + // EnableWindow(sendReport, FALSE); + // MessageBox (dialog, "The email was successfully sent", "email", MB_OK); +#ifndef NL_NO_DEBUG_FILES + CFile::createEmptyFile(getLogDirectory() + "report_sent"); +#endif + } + else + { +#ifndef NL_NO_DEBUG_FILES + CFile::createEmptyFile(getLogDirectory() + "report_failed"); +#endif + // MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); + } + } + else + { +#ifndef NL_NO_DEBUG_FILES + CFile::createEmptyFile(getLogDirectory() + "report_refused"); #endif } +} + +static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + //MSGFILTER *pmf; + + if (message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) + { + if ((HWND) lParam == checkIgnore) + { + IgnoreNextTime = !IgnoreNextTime; + } + else if ((HWND) lParam == debug) + { + sendEmail(); + NeedExit = true; + Result = ReportDebug; + if (DebugDefaultBehavior) + { + NLMISC_BREAKPOINT; + } + } + else if ((HWND) lParam == ignore) + { + sendEmail(); + NeedExit = true; + Result = ReportIgnore; + } + else if ((HWND) lParam == quit) + { + sendEmail(); + NeedExit = true; + Result = ReportQuit; + if (QuitDefaultBehavior) + { + // ace: we cannot call exit() because it's call the static object dtor and can crash the application + // if the dtor call order is not good. + //exit(EXIT_SUCCESS); #ifdef NL_OS_WINDOWS #ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. @@ -88,8 +166,193 @@ TReportResult report (const std::string &title, const std::string &header, const #endif // quit without calling atexit or static object dtors. abort(); + } + } + /*else if ((HWND) lParam == sendReport) + { + if (EmailFunction != NULL) + { + bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); + if (res) + { + EnableWindow(sendReport, FALSE); + MessageBox (dialog, "The email was successfully sent", "email", MB_OK); + CFile::createEmptyFile(getLogDirectory() + "report_sent"); + } + else + { + MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); + } + } + }*/ + } + else if (message == WM_CHAR) + { + if (wParam == 27) + { + // ESC -> ignore + sendEmail(); + NeedExit = true; + Result = ReportIgnore; + } + } + + return DefWindowProc (hWnd, message, wParam, lParam); +} + +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +{ + // register the window + static bool AlreadyRegister = false; + if(!AlreadyRegister) + { + WNDCLASSW wc; + memset (&wc,0,sizeof(wc)); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.lpszClassName = L"NLReportWindow"; + wc.lpszMenuName = NULL; + if (!RegisterClassW(&wc)) return ReportError; + AlreadyRegister = true; + } + + ucstring formatedTitle = title.empty() ? ucstring("NeL report") : ucstring(title); + + + // create the window + dialog = CreateWindowW (L"NLReportWindow", (LPCWSTR)formatedTitle.c_str(), WS_DLGFRAME | WS_CAPTION /*| WS_THICKFRAME*/, CW_USEDEFAULT, CW_USEDEFAULT, 456, 400, NULL, NULL, GetModuleHandle(NULL), NULL); + + // create the font + HFONT font = CreateFont (-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); + + Subject = subject; + AttachedFile = attachedFile; + + // create the edit control + HWND edit = CreateWindowW (L"EDIT", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_READONLY | ES_LEFT | ES_MULTILINE, 7, 70, 429, 212, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (edit, WM_SETFONT, (WPARAM) font, TRUE); + + // set the edit text limit to lot of :) + SendMessage (edit, EM_LIMITTEXT, ~0U, 0); + + Body = addSlashR (body); + + // set the message in the edit text + SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)Body.c_str()); + + if (enableCheckIgnore) + { + // create the combo box control + checkIgnore = CreateWindowW (L"BUTTON", L"Don't display this report again", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_CHECKBOX, 7, 290, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (checkIgnore, WM_SETFONT, (WPARAM) font, TRUE); + + if(ignoreNextTime) + { + SendMessage (checkIgnore, BM_SETCHECK, BST_CHECKED, 0); + } + } + + // create the debug button control + debug = CreateWindowW (L"BUTTON", L"Debug", WS_CHILD | WS_VISIBLE, 7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (debug, WM_SETFONT, (WPARAM) font, TRUE); + + if (debugButton == 0) + EnableWindow(debug, FALSE); + + // create the ignore button control + ignore = CreateWindowW (L"BUTTON", L"Ignore", WS_CHILD | WS_VISIBLE, 75+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (ignore, WM_SETFONT, (WPARAM) font, TRUE); + + if (ignoreButton == 0) + EnableWindow(ignore, FALSE); + + // create the quit button control + quit = CreateWindowW (L"BUTTON", L"Quit", WS_CHILD | WS_VISIBLE, 75+75+7+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (quit, WM_SETFONT, (WPARAM) font, TRUE); + + if (quitButton == 0) + EnableWindow(quit, FALSE); + + // create the debug button control + sendReport = CreateWindowW (L"BUTTON", L"Don't send the report", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 7, 315+32, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (sendReport, WM_SETFONT, (WPARAM) font, TRUE); + + string formatedHeader; + if (header.empty()) + { + formatedHeader = "This application stopped to display this report."; + } + else + { + formatedHeader = header; + } + + // ace don't do that because it s slow to try to send a mail + //CanSendMailReport = sendReportButton && EmailFunction != NULL && EmailFunction("", "", "", "", "", true); + CanSendMailReport = sendReportButton && EmailFunction != NULL; + + if (CanSendMailReport) + formatedHeader += " Send report will only email the contents of the box below. Please, send it to help us (it could take few minutes to send the email, be patient)."; + else + EnableWindow(sendReport, FALSE); + + ucstring uc = ucstring::makeFromUtf8(formatedHeader); + + // create the label control + HWND label = CreateWindowW (L"STATIC", (LPCWSTR)uc.c_str(), WS_CHILD | WS_VISIBLE /*| SS_WHITERECT*/, 7, 7, 429, 51, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); + SendMessage (label, WM_SETFONT, (WPARAM) font, TRUE); + + + DebugDefaultBehavior = debugButton==1; + QuitDefaultBehavior = quitButton==1; + + IgnoreNextTime = ignoreNextTime; + + // show until the cursor really show :) + while (ShowCursor(TRUE) < 0) + ; + + SetWindowPos (dialog, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + + SetFocus(dialog); + SetForegroundWindow(dialog); + + NeedExit = false; + + while(!NeedExit) + { + MSG msg; + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + nlSleep (1); + } + + // set the user result + ignoreNextTime = IgnoreNextTime; + + ShowWindow(dialog, SW_HIDE); + + + + DELETE_OBJECT(sendReport) + DELETE_OBJECT(quit) + DELETE_OBJECT(ignore) + DELETE_OBJECT(debug) + DELETE_OBJECT(checkIgnore) + DELETE_OBJECT(edit) + DELETE_OBJECT(label) + DELETE_OBJECT(dialog) - return ReportQuit; + return Result; } #endif From 24aa500d0b1c2fccf1e2a547a77bb54c1002092a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 18:45:41 +0100 Subject: [PATCH 289/344] Launch the error report application instead of sending an email. --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 3 ++- code/nel/src/misc/report.cpp | 38 ++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index c7667acc2..3f0c26f69 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -83,7 +83,8 @@ using namespace std; #define LOG_IN_FILE NEL_LOG_IN_FILE // If true, debug system will trap crash even if the application is in debugger -static const bool TrapCrashInDebugger = false; +//static const bool TrapCrashInDebugger = false; +static const bool TrapCrashInDebugger = true; #ifdef DEBUG_NEW #define new DEBUG_NEW diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 20b2b1c11..d761373fd 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -92,6 +92,36 @@ static bool CanSendMailReport= false; static bool DebugDefaultBehavior, QuitDefaultBehavior; +static void doSendReport() +{ + std::string filename; + + // Unfortunately Qt 4.8.5 on Windows messes up arguments. + // As a workaround the report filename is hardcoded for now. + // + //filename = "report_"; + //filename += NLMISC::toString( time( NULL ) ); + //filename += ".txt"; + + filename = "rcerrorlog.txt"; + + std::ofstream f; + f.open( filename.c_str() ); + if( !f.good() ) + return; + + f << Body; + + f.close(); + +#ifdef NL_OS_WINDOWS + NLMISC::launchProgram( "rcerror.exe", filename ); +#else + NLMISC::launchProgram( "rcerror", filename ); +#endif + +} + static void sendEmail() { if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) @@ -133,7 +163,7 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM } else if ((HWND) lParam == debug) { - sendEmail(); + doSendReport(); NeedExit = true; Result = ReportDebug; if (DebugDefaultBehavior) @@ -143,13 +173,13 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM } else if ((HWND) lParam == ignore) { - sendEmail(); + doSendReport(); NeedExit = true; Result = ReportIgnore; } else if ((HWND) lParam == quit) { - sendEmail(); + doSendReport(); NeedExit = true; Result = ReportQuit; @@ -191,7 +221,7 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM if (wParam == 27) { // ESC -> ignore - sendEmail(); + doSendReport(); NeedExit = true; Result = ReportIgnore; } From bdb20d32dd37be4e7b513e2be9a52c1a20896cdc Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 18:59:35 +0100 Subject: [PATCH 290/344] Copyright header changed to Nel... --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror.cpp | 2 +- code/nel/rcerror/rcerror_socket.cpp | 2 +- code/nel/rcerror/rcerror_socket.h | 2 +- code/nel/rcerror/rcerror_widget.cpp | 2 +- code/nel/rcerror/rcerror_widget.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp index 0d5088167..4f9174f78 100644 --- a/code/nel/rcerror/rcerror.cpp +++ b/code/nel/rcerror/rcerror.cpp @@ -1,4 +1,4 @@ -// Ryzom Core MMORPG framework - Error Reporter +// Nel MMORPG framework - Error Reporter // // Copyright (C) 2015 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index 8a011c046..721265d1e 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -1,4 +1,4 @@ -// Ryzom Core MMORPG framework - Error Reporter +// Nel MMORPG framework - Error Reporter // // Copyright (C) 2015 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index a37fa32d0..f64b8a708 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -1,4 +1,4 @@ -// Ryzom Core MMORPG framework - Error Reporter +// Nel MMORPG framework - Error Reporter // // Copyright (C) 2015 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index a28afbca6..86c68504e 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -1,4 +1,4 @@ -// Ryzom Core MMORPG framework - Error Reporter +// Nel MMORPG framework - Error Reporter // // Copyright (C) 2015 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index 1dd51c2af..7393793e9 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -1,4 +1,4 @@ -// Ryzom Core MMORPG framework - Error Reporter +// Nel MMORPG framework - Error Reporter // // Copyright (C) 2015 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core From b5c72182edfb8b26b74efaa2f7bb0474ff2ada0a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:04:11 +0100 Subject: [PATCH 291/344] Class names in Nel start with a C... --HG-- branch : feature-crashreport --- code/nel/rcerror/rcerror.cpp | 2 +- code/nel/rcerror/rcerror_data.h | 2 +- code/nel/rcerror/rcerror_socket.cpp | 12 ++++++------ code/nel/rcerror/rcerror_socket.h | 12 ++++++------ code/nel/rcerror/rcerror_widget.cpp | 20 ++++++++++---------- code/nel/rcerror/rcerror_widget.h | 10 +++++----- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/rcerror/rcerror.cpp index 4f9174f78..f26886735 100644 --- a/code/nel/rcerror/rcerror.cpp +++ b/code/nel/rcerror/rcerror.cpp @@ -25,7 +25,7 @@ int main( int argc, char **argv ) { QApplication app( argc, argv ); - RCErrorWidget w; + CRCErrorWidget w; w.setFileName( "rcerrorlog.txt" ); w.show(); diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/rcerror/rcerror_data.h index 9f12b12fd..8accc75a3 100644 --- a/code/nel/rcerror/rcerror_data.h +++ b/code/nel/rcerror/rcerror_data.h @@ -23,7 +23,7 @@ #include -struct RCErrorData +struct SRCErrorData { QString description; QString report; diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/rcerror/rcerror_socket.cpp index 721265d1e..720cb792b 100644 --- a/code/nel/rcerror/rcerror_socket.cpp +++ b/code/nel/rcerror/rcerror_socket.cpp @@ -27,26 +27,26 @@ namespace static const char *BUG_URL = "http://192.168.2.66/dfighter/r.php"; } -class RCErrorSocketPvt +class CRCErrorSocketPvt { public: QNetworkAccessManager mgr; }; -RCErrorSocket::RCErrorSocket( QObject *parent ) : +CRCErrorSocket::CRCErrorSocket( QObject *parent ) : QObject( parent ) { - m_pvt = new RCErrorSocketPvt(); + m_pvt = new CRCErrorSocketPvt(); connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished( QNetworkReply* ) ) ); } -RCErrorSocket::~RCErrorSocket() +CRCErrorSocket::~CRCErrorSocket() { delete m_pvt; } -void RCErrorSocket::sendReport( const RCErrorData &data ) +void CRCErrorSocket::sendReport( const SRCErrorData &data ) { QUrl params; params.addQueryItem( "report", data.report ); @@ -60,7 +60,7 @@ void RCErrorSocket::sendReport( const RCErrorData &data ) m_pvt->mgr.post( request, params.encodedQuery() ); } -void RCErrorSocket::onFinished( QNetworkReply *reply ) +void CRCErrorSocket::onFinished( QNetworkReply *reply ) { if( reply->error() != QNetworkReply::NoError ) Q_EMIT reportFailed(); diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/rcerror/rcerror_socket.h index f64b8a708..95092a250 100644 --- a/code/nel/rcerror/rcerror_socket.h +++ b/code/nel/rcerror/rcerror_socket.h @@ -23,18 +23,18 @@ #include #include "rcerror_data.h" -class RCErrorSocketPvt; +class CRCErrorSocketPvt; class QNetworkReply; -class RCErrorSocket : public QObject +class CRCErrorSocket : public QObject { Q_OBJECT public: - RCErrorSocket( QObject *parent ); - ~RCErrorSocket(); + CRCErrorSocket( QObject *parent ); + ~CRCErrorSocket(); - void sendReport( const RCErrorData &data ); + void sendReport( const SRCErrorData &data ); Q_SIGNALS: void reportSent(); @@ -44,7 +44,7 @@ private Q_SLOTS: void onFinished( QNetworkReply *reply ); private: - RCErrorSocketPvt *m_pvt; + CRCErrorSocketPvt *m_pvt; }; #endif diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/rcerror/rcerror_widget.cpp index 86c68504e..04d06ff94 100644 --- a/code/nel/rcerror/rcerror_widget.cpp +++ b/code/nel/rcerror/rcerror_widget.cpp @@ -25,12 +25,12 @@ #include #include -RCErrorWidget::RCErrorWidget( QWidget *parent ) : +CRCErrorWidget::CRCErrorWidget( QWidget *parent ) : QWidget( parent ) { m_ui.setupUi( this ); - m_socket = new RCErrorSocket( this ); + m_socket = new CRCErrorSocket( this ); QTimer::singleShot( 1, this, SLOT( onLoad() ) ); @@ -42,12 +42,12 @@ QWidget( parent ) connect( m_socket, SIGNAL( reportFailed() ), this, SLOT( onReportFailed() ) ); } -RCErrorWidget::~RCErrorWidget() +CRCErrorWidget::~CRCErrorWidget() { m_socket = NULL; } -void RCErrorWidget::onLoad() +void CRCErrorWidget::onLoad() { QFile f( m_fileName ); bool b = f.open( QFile::ReadOnly | QFile::Text ); @@ -64,12 +64,12 @@ void RCErrorWidget::onLoad() f.close(); } -void RCErrorWidget::onSendClicked() +void CRCErrorWidget::onSendClicked() { m_ui.sendButton->setEnabled( false ); QApplication::setOverrideCursor( Qt::WaitCursor ); - RCErrorData data; + SRCErrorData data; data.description = m_ui.descriptionEdit->toPlainText(); data.report = m_ui.reportEdit->toPlainText(); data.email = m_ui.emailEdit->text(); @@ -77,17 +77,17 @@ void RCErrorWidget::onSendClicked() m_socket->sendReport( data ); } -void RCErrorWidget::onCancelClicked() +void CRCErrorWidget::onCancelClicked() { close(); } -void RCErrorWidget::onCBClicked() +void CRCErrorWidget::onCBClicked() { m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } -void RCErrorWidget::onReportSent() +void CRCErrorWidget::onReportSent() { QApplication::setOverrideCursor( Qt::ArrowCursor ); @@ -98,7 +98,7 @@ void RCErrorWidget::onReportSent() close(); } -void RCErrorWidget::onReportFailed() +void CRCErrorWidget::onReportFailed() { QApplication::setOverrideCursor( Qt::ArrowCursor ); diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/rcerror/rcerror_widget.h index 7393793e9..1d016fa52 100644 --- a/code/nel/rcerror/rcerror_widget.h +++ b/code/nel/rcerror/rcerror_widget.h @@ -23,14 +23,14 @@ #include "ui_rcerror_widget.h" -class RCErrorSocket; +class CRCErrorSocket; -class RCErrorWidget : public QWidget +class CRCErrorWidget : public QWidget { Q_OBJECT public: - RCErrorWidget( QWidget *parent = NULL ); - ~RCErrorWidget(); + CRCErrorWidget( QWidget *parent = NULL ); + ~CRCErrorWidget(); void setFileName( const char *fn ){ m_fileName = fn; } @@ -46,7 +46,7 @@ private Q_SLOTS: private: Ui::RCErrorWidget m_ui; QString m_fileName; - RCErrorSocket *m_socket; + CRCErrorSocket *m_socket; }; #endif From 4ec87b3d6ddaa2a02e0e884364c92b42cab93066 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:24:38 +0100 Subject: [PATCH 292/344] Moved to nel\tools\misc --HG-- branch : feature-crashreport --- code/nel/CMakeLists.txt | 4 ---- code/nel/tools/misc/CMakeLists.txt | 1 + code/nel/{ => tools/misc}/rcerror/CMakeLists.txt | 0 code/nel/{ => tools/misc}/rcerror/rcerror.cpp | 0 code/nel/{ => tools/misc}/rcerror/rcerror_data.h | 0 code/nel/{ => tools/misc}/rcerror/rcerror_socket.cpp | 0 code/nel/{ => tools/misc}/rcerror/rcerror_socket.h | 0 code/nel/{ => tools/misc}/rcerror/rcerror_widget.cpp | 0 code/nel/{ => tools/misc}/rcerror/rcerror_widget.h | 0 code/nel/{ => tools/misc}/rcerror/rcerror_widget.ui | 0 10 files changed, 1 insertion(+), 4 deletions(-) rename code/nel/{ => tools/misc}/rcerror/CMakeLists.txt (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror.cpp (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_data.h (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_socket.cpp (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_socket.h (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_widget.cpp (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_widget.h (100%) rename code/nel/{ => tools/misc}/rcerror/rcerror_widget.ui (100%) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 00290d097..16a8166fe 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -83,7 +83,3 @@ IF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) ENDIF(WITH_NEL_TOOLS) ADD_SUBDIRECTORY(tools) ENDIF(WITH_NEL_TOOLS OR WITH_NEL_MAXPLUGIN) - -IF(WITH_QT) - ADD_SUBDIRECTORY(rcerror) -ENDIF(WITH_QT) diff --git a/code/nel/tools/misc/CMakeLists.txt b/code/nel/tools/misc/CMakeLists.txt index 5386cbbc6..1cda7e8e6 100644 --- a/code/nel/tools/misc/CMakeLists.txt +++ b/code/nel/tools/misc/CMakeLists.txt @@ -3,6 +3,7 @@ SUBDIRS(bnp_make disp_sheet_id extract_filename lock make_sheet_id xml_packer) IF(WITH_QT) ADD_SUBDIRECTORY(words_dic_qt) ADD_SUBDIRECTORY(message_box_qt) + ADD_SUBDIRECTORY(rcerror) ENDIF(WITH_QT) IF(WIN32) diff --git a/code/nel/rcerror/CMakeLists.txt b/code/nel/tools/misc/rcerror/CMakeLists.txt similarity index 100% rename from code/nel/rcerror/CMakeLists.txt rename to code/nel/tools/misc/rcerror/CMakeLists.txt diff --git a/code/nel/rcerror/rcerror.cpp b/code/nel/tools/misc/rcerror/rcerror.cpp similarity index 100% rename from code/nel/rcerror/rcerror.cpp rename to code/nel/tools/misc/rcerror/rcerror.cpp diff --git a/code/nel/rcerror/rcerror_data.h b/code/nel/tools/misc/rcerror/rcerror_data.h similarity index 100% rename from code/nel/rcerror/rcerror_data.h rename to code/nel/tools/misc/rcerror/rcerror_data.h diff --git a/code/nel/rcerror/rcerror_socket.cpp b/code/nel/tools/misc/rcerror/rcerror_socket.cpp similarity index 100% rename from code/nel/rcerror/rcerror_socket.cpp rename to code/nel/tools/misc/rcerror/rcerror_socket.cpp diff --git a/code/nel/rcerror/rcerror_socket.h b/code/nel/tools/misc/rcerror/rcerror_socket.h similarity index 100% rename from code/nel/rcerror/rcerror_socket.h rename to code/nel/tools/misc/rcerror/rcerror_socket.h diff --git a/code/nel/rcerror/rcerror_widget.cpp b/code/nel/tools/misc/rcerror/rcerror_widget.cpp similarity index 100% rename from code/nel/rcerror/rcerror_widget.cpp rename to code/nel/tools/misc/rcerror/rcerror_widget.cpp diff --git a/code/nel/rcerror/rcerror_widget.h b/code/nel/tools/misc/rcerror/rcerror_widget.h similarity index 100% rename from code/nel/rcerror/rcerror_widget.h rename to code/nel/tools/misc/rcerror/rcerror_widget.h diff --git a/code/nel/rcerror/rcerror_widget.ui b/code/nel/tools/misc/rcerror/rcerror_widget.ui similarity index 100% rename from code/nel/rcerror/rcerror_widget.ui rename to code/nel/tools/misc/rcerror/rcerror_widget.ui From 195dfcc3f3061d714c4a9ae7ba0557a33a031072 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:26:03 +0100 Subject: [PATCH 293/344] Changed default title to NeL Error Report. --HG-- branch : feature-crashreport --- code/nel/tools/misc/rcerror/rcerror_widget.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/misc/rcerror/rcerror_widget.ui b/code/nel/tools/misc/rcerror/rcerror_widget.ui index 72e5f92f5..b92ac65a6 100644 --- a/code/nel/tools/misc/rcerror/rcerror_widget.ui +++ b/code/nel/tools/misc/rcerror/rcerror_widget.ui @@ -14,7 +14,7 @@ - Ryzom Core error report + NeL Error Report From 97de06bff27a607df229b3eb4131d2573a5cff99 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:28:02 +0100 Subject: [PATCH 294/344] renamed directory. --HG-- branch : feature-crashreport --- code/nel/tools/misc/CMakeLists.txt | 2 +- code/nel/tools/misc/{rcerror => crash_report}/CMakeLists.txt | 0 code/nel/tools/misc/{rcerror => crash_report}/rcerror.cpp | 0 code/nel/tools/misc/{rcerror => crash_report}/rcerror_data.h | 0 .../nel/tools/misc/{rcerror => crash_report}/rcerror_socket.cpp | 0 code/nel/tools/misc/{rcerror => crash_report}/rcerror_socket.h | 0 .../nel/tools/misc/{rcerror => crash_report}/rcerror_widget.cpp | 0 code/nel/tools/misc/{rcerror => crash_report}/rcerror_widget.h | 0 code/nel/tools/misc/{rcerror => crash_report}/rcerror_widget.ui | 0 9 files changed, 1 insertion(+), 1 deletion(-) rename code/nel/tools/misc/{rcerror => crash_report}/CMakeLists.txt (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror.cpp (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_data.h (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_socket.cpp (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_socket.h (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_widget.cpp (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_widget.h (100%) rename code/nel/tools/misc/{rcerror => crash_report}/rcerror_widget.ui (100%) diff --git a/code/nel/tools/misc/CMakeLists.txt b/code/nel/tools/misc/CMakeLists.txt index 1cda7e8e6..c9bbcd058 100644 --- a/code/nel/tools/misc/CMakeLists.txt +++ b/code/nel/tools/misc/CMakeLists.txt @@ -3,7 +3,7 @@ SUBDIRS(bnp_make disp_sheet_id extract_filename lock make_sheet_id xml_packer) IF(WITH_QT) ADD_SUBDIRECTORY(words_dic_qt) ADD_SUBDIRECTORY(message_box_qt) - ADD_SUBDIRECTORY(rcerror) + ADD_SUBDIRECTORY(crash_report) ENDIF(WITH_QT) IF(WIN32) diff --git a/code/nel/tools/misc/rcerror/CMakeLists.txt b/code/nel/tools/misc/crash_report/CMakeLists.txt similarity index 100% rename from code/nel/tools/misc/rcerror/CMakeLists.txt rename to code/nel/tools/misc/crash_report/CMakeLists.txt diff --git a/code/nel/tools/misc/rcerror/rcerror.cpp b/code/nel/tools/misc/crash_report/rcerror.cpp similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror.cpp rename to code/nel/tools/misc/crash_report/rcerror.cpp diff --git a/code/nel/tools/misc/rcerror/rcerror_data.h b/code/nel/tools/misc/crash_report/rcerror_data.h similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_data.h rename to code/nel/tools/misc/crash_report/rcerror_data.h diff --git a/code/nel/tools/misc/rcerror/rcerror_socket.cpp b/code/nel/tools/misc/crash_report/rcerror_socket.cpp similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_socket.cpp rename to code/nel/tools/misc/crash_report/rcerror_socket.cpp diff --git a/code/nel/tools/misc/rcerror/rcerror_socket.h b/code/nel/tools/misc/crash_report/rcerror_socket.h similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_socket.h rename to code/nel/tools/misc/crash_report/rcerror_socket.h diff --git a/code/nel/tools/misc/rcerror/rcerror_widget.cpp b/code/nel/tools/misc/crash_report/rcerror_widget.cpp similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_widget.cpp rename to code/nel/tools/misc/crash_report/rcerror_widget.cpp diff --git a/code/nel/tools/misc/rcerror/rcerror_widget.h b/code/nel/tools/misc/crash_report/rcerror_widget.h similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_widget.h rename to code/nel/tools/misc/crash_report/rcerror_widget.h diff --git a/code/nel/tools/misc/rcerror/rcerror_widget.ui b/code/nel/tools/misc/crash_report/rcerror_widget.ui similarity index 100% rename from code/nel/tools/misc/rcerror/rcerror_widget.ui rename to code/nel/tools/misc/crash_report/rcerror_widget.ui From 6be70dd39c090d1d80ff80d08695f51cd726fce8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:33:12 +0100 Subject: [PATCH 295/344] Renames. --HG-- branch : feature-crashreport --- .../tools/misc/crash_report/CMakeLists.txt | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/code/nel/tools/misc/crash_report/CMakeLists.txt b/code/nel/tools/misc/crash_report/CMakeLists.txt index 51522cf0c..0e2d2a9bc 100644 --- a/code/nel/tools/misc/crash_report/CMakeLists.txt +++ b/code/nel/tools/misc/crash_report/CMakeLists.txt @@ -1,14 +1,14 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SRC_DIR} ${QT_INCLUDES}) -FILE(GLOB RCERROR_SRC *.cpp) -FILE(GLOB RCERROR_HDR *h) +FILE(GLOB CRASHREPORT_SRC *.cpp) +FILE(GLOB CRASHREPORT_HDR *h) -SET(RCERROR_MOC_HDR -rcerror_socket.h -rcerror_widget.h +SET(CRASHREPORT_MOC_HDR +crash_report_socket.h +crash_report_widget.h ) -SET(RCERROR_UI -rcerror_widget.ui +SET(CRASHREPORT_UI +crash_report_widget.ui ) SET(QT_USE_QTGUI TRUE) @@ -20,20 +20,20 @@ SET(QT_USE_QTXML FALSE) INCLUDE(${QT_USE_FILE}) ADD_DEFINITIONS(${QT_DEFINITIONS}) -QT4_WRAP_CPP(RCERROR_MOC_SRC ${RCERROR_MOC_HDR}) -QT4_WRAP_UI(RCERROR_UI_HDR ${RCERROR_UI}) +QT4_WRAP_CPP(CRASHREPORT_MOC_SRC ${CRASHREPORT_MOC_HDR}) +QT4_WRAP_UI(CRASHREPORT_UI_HDR ${CRASHREPORT_UI}) -SOURCE_GROUP(QtResources FILES ${RCERROR_UI}) -SOURCE_GROUP(QtGeneratedUiHdr FILES ${RCERROR_UI_HDR}) -SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${RCERROR_MOC_SRC}) -SOURCE_GROUP("source files" FILES ${RCERROR_SRC}) -SOURCE_GROUP("header files" FILES ${RCERROR_HDR}) +SOURCE_GROUP(QtResources FILES ${CRASHREPORT_UI}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${CRASHREPORT_UI_HDR}) +SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${CRASHREPORT_MOC_SRC}) +SOURCE_GROUP("source files" FILES ${CRASHREPORT_SRC}) +SOURCE_GROUP("header files" FILES ${CRASHREPORT_HDR}) -ADD_EXECUTABLE(rcerror WIN32 MACOSX_BUNDLE ${RCERROR_SRC} ${RCERROR_MOC_HDR} ${RCERROR_MOC_SRC} ${RCERROR_UI_HDR}) -TARGET_LINK_LIBRARIES(rcerror ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) +ADD_EXECUTABLE(crash_report WIN32 MACOSX_BUNDLE ${CRASHREPORT_SRC} ${CRASHREPORT_MOC_HDR} ${CRASHREPORT_MOC_SRC} ${CRASHREPORT_UI_HDR}) +TARGET_LINK_LIBRARIES(crash_report ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) -NL_DEFAULT_PROPS(rcerror "Ryzom Core Error Reporter") -NL_ADD_RUNTIME_FLAGS(rcerror) +NL_DEFAULT_PROPS(crash_report "NeL, Tools, Misc: Crash Report") +NL_ADD_RUNTIME_FLAGS(crash_report) -INSTALL(TARGETS rcerror RUNTIME DESTINATION ${NL_BIN_PREFIX}) +INSTALL(TARGETS crash_report RUNTIME DESTINATION ${NL_BIN_PREFIX}) From 39879717926f8bfdc06fefe1f0158bad1cf31165 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:33:38 +0100 Subject: [PATCH 296/344] Renames. --HG-- branch : feature-crashreport --- .../nel/tools/misc/crash_report/{rcerror.cpp => crash_report.cpp} | 0 .../misc/crash_report/{rcerror_data.h => crash_report_data.h} | 0 .../crash_report/{rcerror_socket.cpp => crash_report_socket.cpp} | 0 .../misc/crash_report/{rcerror_socket.h => crash_report_socket.h} | 0 .../crash_report/{rcerror_widget.cpp => crash_report_widget.cpp} | 0 .../misc/crash_report/{rcerror_widget.h => crash_report_widget.h} | 0 .../crash_report/{rcerror_widget.ui => crash_report_widget.ui} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename code/nel/tools/misc/crash_report/{rcerror.cpp => crash_report.cpp} (100%) rename code/nel/tools/misc/crash_report/{rcerror_data.h => crash_report_data.h} (100%) rename code/nel/tools/misc/crash_report/{rcerror_socket.cpp => crash_report_socket.cpp} (100%) rename code/nel/tools/misc/crash_report/{rcerror_socket.h => crash_report_socket.h} (100%) rename code/nel/tools/misc/crash_report/{rcerror_widget.cpp => crash_report_widget.cpp} (100%) rename code/nel/tools/misc/crash_report/{rcerror_widget.h => crash_report_widget.h} (100%) rename code/nel/tools/misc/crash_report/{rcerror_widget.ui => crash_report_widget.ui} (100%) diff --git a/code/nel/tools/misc/crash_report/rcerror.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror.cpp rename to code/nel/tools/misc/crash_report/crash_report.cpp diff --git a/code/nel/tools/misc/crash_report/rcerror_data.h b/code/nel/tools/misc/crash_report/crash_report_data.h similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_data.h rename to code/nel/tools/misc/crash_report/crash_report_data.h diff --git a/code/nel/tools/misc/crash_report/rcerror_socket.cpp b/code/nel/tools/misc/crash_report/crash_report_socket.cpp similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_socket.cpp rename to code/nel/tools/misc/crash_report/crash_report_socket.cpp diff --git a/code/nel/tools/misc/crash_report/rcerror_socket.h b/code/nel/tools/misc/crash_report/crash_report_socket.h similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_socket.h rename to code/nel/tools/misc/crash_report/crash_report_socket.h diff --git a/code/nel/tools/misc/crash_report/rcerror_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_widget.cpp rename to code/nel/tools/misc/crash_report/crash_report_widget.cpp diff --git a/code/nel/tools/misc/crash_report/rcerror_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_widget.h rename to code/nel/tools/misc/crash_report/crash_report_widget.h diff --git a/code/nel/tools/misc/crash_report/rcerror_widget.ui b/code/nel/tools/misc/crash_report/crash_report_widget.ui similarity index 100% rename from code/nel/tools/misc/crash_report/rcerror_widget.ui rename to code/nel/tools/misc/crash_report/crash_report_widget.ui From cfe2d603503d7da01e87dc8e14a90942e7544843 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 19:52:01 +0100 Subject: [PATCH 297/344] More renames... --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 4 +-- .../tools/misc/crash_report/crash_report.cpp | 4 +-- .../misc/crash_report/crash_report_data.h | 2 +- .../misc/crash_report/crash_report_socket.cpp | 14 +++++----- .../misc/crash_report/crash_report_socket.h | 14 +++++----- .../misc/crash_report/crash_report_widget.cpp | 26 +++++++++---------- .../misc/crash_report/crash_report_widget.h | 14 +++++----- .../misc/crash_report/crash_report_widget.ui | 4 +-- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index d761373fd..09cfc1178 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -115,9 +115,9 @@ static void doSendReport() f.close(); #ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "rcerror.exe", filename ); + NLMISC::launchProgram( "crash_report.exe", filename ); #else - NLMISC::launchProgram( "rcerror", filename ); + NLMISC::launchProgram( "crash_report", filename ); #endif } diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index f26886735..d04928d21 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -17,7 +17,7 @@ // along with this program. If not, see . -#include "rcerror_widget.h" +#include "crash_report_widget.h" #include #include @@ -25,7 +25,7 @@ int main( int argc, char **argv ) { QApplication app( argc, argv ); - CRCErrorWidget w; + CCrashReportWidget w; w.setFileName( "rcerrorlog.txt" ); w.show(); diff --git a/code/nel/tools/misc/crash_report/crash_report_data.h b/code/nel/tools/misc/crash_report/crash_report_data.h index 8accc75a3..5884e7eb4 100644 --- a/code/nel/tools/misc/crash_report/crash_report_data.h +++ b/code/nel/tools/misc/crash_report/crash_report_data.h @@ -23,7 +23,7 @@ #include -struct SRCErrorData +struct SCrashReportData { QString description; QString report; diff --git a/code/nel/tools/misc/crash_report/crash_report_socket.cpp b/code/nel/tools/misc/crash_report/crash_report_socket.cpp index 720cb792b..209ea89e8 100644 --- a/code/nel/tools/misc/crash_report/crash_report_socket.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_socket.cpp @@ -16,7 +16,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include "rcerror_socket.h" +#include "crash_report_socket.h" #include #include #include @@ -27,26 +27,26 @@ namespace static const char *BUG_URL = "http://192.168.2.66/dfighter/r.php"; } -class CRCErrorSocketPvt +class CCrashReportSocketPvt { public: QNetworkAccessManager mgr; }; -CRCErrorSocket::CRCErrorSocket( QObject *parent ) : +CCrashReportSocket::CCrashReportSocket( QObject *parent ) : QObject( parent ) { - m_pvt = new CRCErrorSocketPvt(); + m_pvt = new CCrashReportSocketPvt(); connect( &m_pvt->mgr, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( onFinished( QNetworkReply* ) ) ); } -CRCErrorSocket::~CRCErrorSocket() +CCrashReportSocket::~CCrashReportSocket() { delete m_pvt; } -void CRCErrorSocket::sendReport( const SRCErrorData &data ) +void CCrashReportSocket::sendReport( const SCrashReportData &data ) { QUrl params; params.addQueryItem( "report", data.report ); @@ -60,7 +60,7 @@ void CRCErrorSocket::sendReport( const SRCErrorData &data ) m_pvt->mgr.post( request, params.encodedQuery() ); } -void CRCErrorSocket::onFinished( QNetworkReply *reply ) +void CCrashReportSocket::onFinished( QNetworkReply *reply ) { if( reply->error() != QNetworkReply::NoError ) Q_EMIT reportFailed(); diff --git a/code/nel/tools/misc/crash_report/crash_report_socket.h b/code/nel/tools/misc/crash_report/crash_report_socket.h index 95092a250..24bf6c451 100644 --- a/code/nel/tools/misc/crash_report/crash_report_socket.h +++ b/code/nel/tools/misc/crash_report/crash_report_socket.h @@ -21,20 +21,20 @@ #define RCERROR_SOCKET #include -#include "rcerror_data.h" +#include "crash_report_data.h" -class CRCErrorSocketPvt; +class CCrashReportSocketPvt; class QNetworkReply; -class CRCErrorSocket : public QObject +class CCrashReportSocket : public QObject { Q_OBJECT public: - CRCErrorSocket( QObject *parent ); - ~CRCErrorSocket(); + CCrashReportSocket( QObject *parent ); + ~CCrashReportSocket(); - void sendReport( const SRCErrorData &data ); + void sendReport( const SCrashReportData &data ); Q_SIGNALS: void reportSent(); @@ -44,7 +44,7 @@ private Q_SLOTS: void onFinished( QNetworkReply *reply ); private: - CRCErrorSocketPvt *m_pvt; + CCrashReportSocketPvt *m_pvt; }; #endif diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 04d06ff94..49925765d 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -17,20 +17,20 @@ // along with this program. If not, see . -#include "rcerror_widget.h" -#include "rcerror_socket.h" -#include "rcerror_data.h" +#include "crash_report_widget.h" +#include "crash_report_socket.h" +#include "crash_report_data.h" #include #include #include #include -CRCErrorWidget::CRCErrorWidget( QWidget *parent ) : +CCrashReportWidget::CCrashReportWidget( QWidget *parent ) : QWidget( parent ) { m_ui.setupUi( this ); - m_socket = new CRCErrorSocket( this ); + m_socket = new CCrashReportSocket( this ); QTimer::singleShot( 1, this, SLOT( onLoad() ) ); @@ -42,12 +42,12 @@ QWidget( parent ) connect( m_socket, SIGNAL( reportFailed() ), this, SLOT( onReportFailed() ) ); } -CRCErrorWidget::~CRCErrorWidget() +CCrashReportWidget::~CCrashReportWidget() { m_socket = NULL; } -void CRCErrorWidget::onLoad() +void CCrashReportWidget::onLoad() { QFile f( m_fileName ); bool b = f.open( QFile::ReadOnly | QFile::Text ); @@ -64,12 +64,12 @@ void CRCErrorWidget::onLoad() f.close(); } -void CRCErrorWidget::onSendClicked() +void CCrashReportWidget::onSendClicked() { m_ui.sendButton->setEnabled( false ); QApplication::setOverrideCursor( Qt::WaitCursor ); - SRCErrorData data; + SCrashReportData data; data.description = m_ui.descriptionEdit->toPlainText(); data.report = m_ui.reportEdit->toPlainText(); data.email = m_ui.emailEdit->text(); @@ -77,17 +77,17 @@ void CRCErrorWidget::onSendClicked() m_socket->sendReport( data ); } -void CRCErrorWidget::onCancelClicked() +void CCrashReportWidget::onCancelClicked() { close(); } -void CRCErrorWidget::onCBClicked() +void CCrashReportWidget::onCBClicked() { m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } -void CRCErrorWidget::onReportSent() +void CCrashReportWidget::onReportSent() { QApplication::setOverrideCursor( Qt::ArrowCursor ); @@ -98,7 +98,7 @@ void CRCErrorWidget::onReportSent() close(); } -void CRCErrorWidget::onReportFailed() +void CCrashReportWidget::onReportFailed() { QApplication::setOverrideCursor( Qt::ArrowCursor ); diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index 1d016fa52..47d16ad77 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -21,16 +21,16 @@ #define RCERROR_WIDGET -#include "ui_rcerror_widget.h" +#include "ui_crash_report_widget.h" -class CRCErrorSocket; +class CCrashReportSocket; -class CRCErrorWidget : public QWidget +class CCrashReportWidget : public QWidget { Q_OBJECT public: - CRCErrorWidget( QWidget *parent = NULL ); - ~CRCErrorWidget(); + CCrashReportWidget( QWidget *parent = NULL ); + ~CCrashReportWidget(); void setFileName( const char *fn ){ m_fileName = fn; } @@ -44,9 +44,9 @@ private Q_SLOTS: void onReportFailed(); private: - Ui::RCErrorWidget m_ui; + Ui::CrashReportWidget m_ui; QString m_fileName; - CRCErrorSocket *m_socket; + CCrashReportSocket *m_socket; }; #endif diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.ui b/code/nel/tools/misc/crash_report/crash_report_widget.ui index b92ac65a6..589810578 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.ui +++ b/code/nel/tools/misc/crash_report/crash_report_widget.ui @@ -1,7 +1,7 @@ - RCErrorWidget - + CrashReportWidget + Qt::ApplicationModal From 955ef484608242126953099a8c5935f263143e96 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 21:51:17 +0100 Subject: [PATCH 298/344] Parametrize crash reporter. --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 21 ++++--- .../tools/misc/crash_report/crash_report.cpp | 61 ++++++++++++++++++- .../misc/crash_report/crash_report_socket.cpp | 7 +-- .../misc/crash_report/crash_report_socket.h | 4 ++ .../misc/crash_report/crash_report_widget.cpp | 56 ++++++++++++++++- .../misc/crash_report/crash_report_widget.h | 7 +++ 6 files changed, 139 insertions(+), 17 deletions(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 09cfc1178..58740ce28 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -92,18 +92,21 @@ static bool CanSendMailReport= false; static bool DebugDefaultBehavior, QuitDefaultBehavior; +static std::string URL = "FILL_IN_CRASH_REPORT_HOSTNAME_HERE"; + static void doSendReport() { std::string filename; - // Unfortunately Qt 4.8.5 on Windows messes up arguments. - // As a workaround the report filename is hardcoded for now. - // - //filename = "report_"; - //filename += NLMISC::toString( time( NULL ) ); - //filename += ".txt"; + filename = "report_"; + filename += NLMISC::toString( time( NULL ) ); + filename += ".txt"; - filename = "rcerrorlog.txt"; + std::string params; + params = "-log "; + params += filename; + params += " -host "; + params += URL; std::ofstream f; f.open( filename.c_str() ); @@ -115,9 +118,9 @@ static void doSendReport() f.close(); #ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "crash_report.exe", filename ); + NLMISC::launchProgram( "crash_report.exe", params ); #else - NLMISC::launchProgram( "crash_report", filename ); + NLMISC::launchProgram( "crash_report", params ); #endif } diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index d04928d21..e083de126 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -21,12 +21,71 @@ #include #include +#include +#include +#include + +class CCmdLineParser +{ +public: + static void parse( int argc, char **argv, std::vector< std::pair< std::string, std::string > > &v ) + { + std::stack< std::string > stack; + std::string key; + std::string value; + + for( int i = argc - 1 ; i >= 0; i-- ) + { + stack.push( std::string( argv[ i ] ) ); + } + + while( !stack.empty() ) + { + key = stack.top(); + stack.pop(); + + // If not a real parameter ( they start with '-' ), discard. + if( key[ 0 ] != '-' ) + continue; + + // Remove the '-' + key = key.substr( 1 ); + + // No more parameters + if( stack.empty() ) + { + v.push_back( std::make_pair( key, "" ) ); + break; + } + + value = stack.top(); + + // If next parameter is a key, process it in the next iteration + if( value[ 0 ] == '-' ) + { + v.push_back( std::make_pair( key, "" ) ); + continue; + } + // Otherwise store the pair + else + { + v.push_back( std::make_pair( key, value ) ); + stack.pop(); + } + } + } +}; + int main( int argc, char **argv ) { QApplication app( argc, argv ); + std::vector< std::pair< std::string, std::string > > params; + + CCmdLineParser::parse( argc, argv, params ); + CCrashReportWidget w; - w.setFileName( "rcerrorlog.txt" ); + w.setup( params ); w.show(); return app.exec(); diff --git a/code/nel/tools/misc/crash_report/crash_report_socket.cpp b/code/nel/tools/misc/crash_report/crash_report_socket.cpp index 209ea89e8..5f8720e05 100644 --- a/code/nel/tools/misc/crash_report/crash_report_socket.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_socket.cpp @@ -22,11 +22,6 @@ #include #include -namespace -{ - static const char *BUG_URL = "http://192.168.2.66/dfighter/r.php"; -} - class CCrashReportSocketPvt { public: @@ -53,7 +48,7 @@ void CCrashReportSocket::sendReport( const SCrashReportData &data ) params.addQueryItem( "descr", data.description ); params.addQueryItem( "email", data.email ); - QUrl url( BUG_URL ); + QUrl url( m_url ); QNetworkRequest request( url ); request.setRawHeader( "Connection", "close" ); diff --git a/code/nel/tools/misc/crash_report/crash_report_socket.h b/code/nel/tools/misc/crash_report/crash_report_socket.h index 24bf6c451..32ccc5da0 100644 --- a/code/nel/tools/misc/crash_report/crash_report_socket.h +++ b/code/nel/tools/misc/crash_report/crash_report_socket.h @@ -34,6 +34,9 @@ public: CCrashReportSocket( QObject *parent ); ~CCrashReportSocket(); + void setURL( const char *URL ){ m_url = URL; } + QString url() const{ return m_url; } + void sendReport( const SCrashReportData &data ); Q_SIGNALS: @@ -45,6 +48,7 @@ private Q_SLOTS: private: CCrashReportSocketPvt *m_pvt; + QString m_url; }; #endif diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 49925765d..ff0028223 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -47,8 +47,39 @@ CCrashReportWidget::~CCrashReportWidget() m_socket = NULL; } +void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std::string > > ¶ms ) +{ + for( int i = 0; i < params.size(); i++ ) + { + const std::pair< std::string, std::string > &p = params[ i ]; + const std::string &k = p.first; + const std::string &v = p.second; + + if( k == "log" ) + { + m_fileName = v.c_str(); + } + else + if( k == "host" ) + { + m_socket->setURL( v.c_str() ); + } + else + if( k == "title" ) + { + setWindowTitle( v.c_str() ); + } + } +} + void CCrashReportWidget::onLoad() { + if( !checkSettings() ) + { + close(); + return; + } + QFile f( m_fileName ); bool b = f.open( QFile::ReadOnly | QFile::Text ); if( !b ) @@ -57,6 +88,7 @@ void CCrashReportWidget::onLoad() tr( "No log file found" ), tr( "There was no log file found, therefore nothing to report. Exiting..." ) ); close(); + return; } QTextStream ss( &f ); @@ -107,4 +139,26 @@ void CCrashReportWidget::onReportFailed() tr( "Failed to send the report..." ) ); close(); -} \ No newline at end of file +} + +bool CCrashReportWidget::checkSettings() +{ + if( m_fileName.isEmpty() ) + { + QMessageBox::information( this, + tr( "No log file specified." ), + tr( "No log file specified. Exiting..." ) ); + return false; + } + + if( m_socket->url().isEmpty() ) + { + QMessageBox::information( this, + tr( "No host specified." ), + tr( "No host specified. Exiting..." ) ); + return false; + } + + return true; +} + diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index 47d16ad77..0baf2521d 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -22,6 +22,8 @@ #include "ui_crash_report_widget.h" +#include +#include class CCrashReportSocket; @@ -34,6 +36,8 @@ public: void setFileName( const char *fn ){ m_fileName = fn; } + void setup( const std::vector< std::pair< std::string, std::string > > ¶ms ); + private Q_SLOTS: void onLoad(); void onSendClicked(); @@ -44,6 +48,9 @@ private Q_SLOTS: void onReportFailed(); private: + bool checkSettings(); + + Ui::CrashReportWidget m_ui; QString m_fileName; CCrashReportSocket *m_socket; From 2bb5e8e9ba6be80184635505cc570176b1a153b7 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 22 Feb 2015 22:34:07 +0100 Subject: [PATCH 299/344] Remove generated log file when quitting the reporter. --HG-- branch : feature-crashreport --- .../tools/misc/crash_report/crash_report_widget.cpp | 13 ++++++++++--- .../tools/misc/crash_report/crash_report_widget.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index ff0028223..968978f94 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -24,6 +24,7 @@ #include #include #include +#include CCrashReportWidget::CCrashReportWidget( QWidget *parent ) : QWidget( parent ) @@ -111,7 +112,7 @@ void CCrashReportWidget::onSendClicked() void CCrashReportWidget::onCancelClicked() { - close(); + removeAndQuit(); } void CCrashReportWidget::onCBClicked() @@ -127,7 +128,7 @@ void CCrashReportWidget::onReportSent() tr( "Report sent" ), tr( "The report has been sent." ) ); - close(); + removeAndQuit(); } void CCrashReportWidget::onReportFailed() @@ -138,7 +139,7 @@ void CCrashReportWidget::onReportFailed() tr( "Report failed" ), tr( "Failed to send the report..." ) ); - close(); + removeAndQuit(); } bool CCrashReportWidget::checkSettings() @@ -162,3 +163,9 @@ bool CCrashReportWidget::checkSettings() return true; } +void CCrashReportWidget::removeAndQuit() +{ + QFile::remove( m_fileName ); + close(); +} + diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index 0baf2521d..61b56e340 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -49,7 +49,7 @@ private Q_SLOTS: private: bool checkSettings(); - + void removeAndQuit(); Ui::CrashReportWidget m_ui; QString m_fileName; From 8bf372056f1290301b75e38eac367eb74306383d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 23 Feb 2015 01:36:50 +0100 Subject: [PATCH 300/344] Use CMsgBoxDisplayer on non-windows platforms as well. --HG-- branch : feature-crashreport --- code/nel/src/misc/debug.cpp | 2 +- code/nel/src/misc/displayer.cpp | 4 +- code/nel/src/misc/report.cpp | 79 ++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 3f0c26f69..86752a412 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -1197,10 +1197,10 @@ void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) #ifdef NL_OS_WINDOWS if (TrapCrashInDebugger || !IsDebuggerPresent ()) +#endif { DefaultMsgBoxDisplayer = new CMsgBoxDisplayer ("DEFAULT_MBD"); } -#endif #if LOG_IN_FILE if (logInFile) diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index d48c44d02..86fc1d726 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,7 +529,7 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { -#ifdef NL_OS_WINDOWS +//#ifdef NL_OS_WINDOWS bool needSpace = false; // stringstream ss; @@ -720,7 +720,7 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m } */ } -#endif +//#endif } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 58740ce28..784f49a9a 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -63,19 +63,61 @@ void setReportEmailFunction (void *emailFunction) #endif } +static string Body; +static std::string URL = "FILL_IN_CRASH_REPORT_HOSTNAME_HERE"; + + +static void doSendReport() +{ + std::string filename; + + filename = "report_"; + filename += NLMISC::toString( int( time( NULL ) ) ); + filename += ".txt"; + + std::string params; + params = "-log "; + params += filename; + params += " -host "; + params += URL; + + std::ofstream f; + f.open( filename.c_str() ); + if( !f.good() ) + return; + + f << Body; + + f.close(); + +#ifdef NL_OS_WINDOWS + NLMISC::launchProgram( "crash_report.exe", params ); +#else + NLMISC::launchProgram( "crash_report", params ); +#endif + + // Added because NLSMIC::launcProgram needs time to launch + nlSleep( 2 * 1000 ); + +} + #ifndef NL_OS_WINDOWS // GNU/Linux, do nothing -void report () +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { + Body = addSlashR( body ); + + doSendReport(); + + return ReportQuit; } #else // Windows specific version -static string Body; static string Subject; static string AttachedFile; @@ -92,39 +134,6 @@ static bool CanSendMailReport= false; static bool DebugDefaultBehavior, QuitDefaultBehavior; -static std::string URL = "FILL_IN_CRASH_REPORT_HOSTNAME_HERE"; - -static void doSendReport() -{ - std::string filename; - - filename = "report_"; - filename += NLMISC::toString( time( NULL ) ); - filename += ".txt"; - - std::string params; - params = "-log "; - params += filename; - params += " -host "; - params += URL; - - std::ofstream f; - f.open( filename.c_str() ); - if( !f.good() ) - return; - - f << Body; - - f.close(); - -#ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "crash_report.exe", params ); -#else - NLMISC::launchProgram( "crash_report", params ); -#endif - -} - static void sendEmail() { if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) From a912fa49ac1e133738b90157872e2026edaf2565 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:25:23 +0100 Subject: [PATCH 301/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- code/ryzom/server/src/pd_lib/db_description_parser.cpp | 2 +- code/ryzom/server/src/pd_lib/pd_lib.cpp | 2 +- code/ryzom/server/src/pd_lib/pd_messages.cpp | 6 +++--- code/ryzom/server/src/pd_lib/pd_string_mapper.cpp | 2 +- code/ryzom/server/src/pd_lib/pd_utils.h | 10 +++++++--- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/code/ryzom/server/src/pd_lib/db_description_parser.cpp b/code/ryzom/server/src/pd_lib/db_description_parser.cpp index 175000cf2..55eb4a3d6 100644 --- a/code/ryzom/server/src/pd_lib/db_description_parser.cpp +++ b/code/ryzom/server/src/pd_lib/db_description_parser.cpp @@ -260,7 +260,7 @@ bool CDBDescriptionParser::loadType(xmlNodePtr node) return false; } - typeNode.EnumValues.push_back(make_pair(name, value)); + typeNode.EnumValues.push_back(std::pair(name, value)); if (typeNode.Dimension <= value) typeNode.Dimension = value; diff --git a/code/ryzom/server/src/pd_lib/pd_lib.cpp b/code/ryzom/server/src/pd_lib/pd_lib.cpp index f57a4be62..1a2cda9ba 100644 --- a/code/ryzom/server/src/pd_lib/pd_lib.cpp +++ b/code/ryzom/server/src/pd_lib/pd_lib.cpp @@ -571,7 +571,7 @@ void CPDSLib::update() CMessage* msgupd = new CMessage("PD_UPDATE"); msgupd->serial(_DatabaseId); msgupd->serial(_UpdateId); - _QueuedMessages.push_back(make_pair(_UpdateId, msgupd)); + _QueuedMessages.push_back(std::pair(_UpdateId, msgupd)); ++_UpdateId; // serial queue diff --git a/code/ryzom/server/src/pd_lib/pd_messages.cpp b/code/ryzom/server/src/pd_lib/pd_messages.cpp index 253855d46..b5e731d95 100644 --- a/code/ryzom/server/src/pd_lib/pd_messages.cpp +++ b/code/ryzom/server/src/pd_lib/pd_messages.cpp @@ -504,7 +504,7 @@ bool CUpdateLog::selectMessages(const CDBDescriptionParser& description, const N if (message.getType() == CDbMessage::PushContext) { - contextsStart.push_back(std::make_pair(msg, false)); + contextsStart.push_back(std::pair(msg, false)); } else if (message.getType() == CDbMessage::PopContext) { @@ -561,7 +561,7 @@ bool CUpdateLog::selectMessages(const CDBDescriptionParser& description, const s if (message.getType() == CDbMessage::PushContext) { - contextsStart.push_back(std::make_pair(msg, false)); + contextsStart.push_back(std::pair(msg, false)); } else if (message.getType() == CDbMessage::PopContext) { @@ -644,7 +644,7 @@ bool CUpdateLog::selectMessages(const CDBDescriptionParser& description, const N if (message.getType() == CDbMessage::PushContext) { - contextsStart.push_back(std::make_pair(msg, false)); + contextsStart.push_back(std::pair(msg, false)); } else if (message.getType() == CDbMessage::PopContext) { diff --git a/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp b/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp index 184d4bb7f..7a326dc67 100644 --- a/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp +++ b/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp @@ -64,7 +64,7 @@ void CPDStringMapper::setMapping(const std::string& str, uint32 id) return; } - its = _StringMap.insert(std::make_pair(lowMapStr, id)).first; + its = _StringMap.insert(std::pair(lowMapStr, id)).first; _IdMap[id] = its; } diff --git a/code/ryzom/server/src/pd_lib/pd_utils.h b/code/ryzom/server/src/pd_lib/pd_utils.h index 73a0268d8..0f0ab46d5 100644 --- a/code/ryzom/server/src/pd_lib/pd_utils.h +++ b/code/ryzom/server/src/pd_lib/pd_utils.h @@ -494,9 +494,13 @@ struct CColumnIndexHashMapTraits static const size_t min_buckets = 8; CColumnIndexHashMapTraits() { } size_t operator() (const CColumnIndex &id) const - { - return id.hash(); - } + { + return id.hash(); + } + bool operator()(const CColumnIndex &left, const CColumnIndex &right) + { + return left.hash() < right.hash(); + } }; class CSetMap From 4cb42c6de0ff6820390cc3cd47d4498ae3466509 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:28:13 +0100 Subject: [PATCH 302/344] Visual Studio 2013 compilation support for Ryzom Tools --HG-- branch : develop --- code/ryzom/server/src/ai_share/16x16_layer.cpp | 2 +- code/ryzom/server/src/ai_share/world_map.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/ryzom/server/src/ai_share/16x16_layer.cpp b/code/ryzom/server/src/ai_share/16x16_layer.cpp index c820e4f7b..4e78cf54e 100644 --- a/code/ryzom/server/src/ai_share/16x16_layer.cpp +++ b/code/ryzom/server/src/ai_share/16x16_layer.cpp @@ -100,7 +100,7 @@ I16x16Layer *I16x16Layer::compress(I16x16Layer *layer, sint32 blank) map::iterator it = count.find(val); if (it == count.end()) - count.insert(make_pair(val, 1)); + count.insert(std::pair(val, 1)); else ++((*it).second); } diff --git a/code/ryzom/server/src/ai_share/world_map.cpp b/code/ryzom/server/src/ai_share/world_map.cpp index eae84acbf..f468c1144 100644 --- a/code/ryzom/server/src/ai_share/world_map.cpp +++ b/code/ryzom/server/src/ai_share/world_map.cpp @@ -1469,7 +1469,7 @@ bool CWorldMap::findAStarPath(CWorldPosition const& start, CWorldPosition const& uint father = (uint)nodes.size()-1; // Add start topology to visited nodes (father holds start topo node index for the moment) - visited.insert(make_pair(startTopo, father)); + visited.insert(std::pair(startTopo, father)); // Push start node in the heap with a zero cost heap.push(0.0f, father); @@ -1562,7 +1562,7 @@ bool CWorldMap::findAStarPath(CWorldPosition const& start, CWorldPosition const& // Add node to heap with a computed f(n)=g(n)+h(n) heap.push(distance + heuristic, child); // Add node to visited - visited.insert(make_pair(next, child)); + visited.insert(std::pair(next, child)); } } @@ -1633,7 +1633,7 @@ bool CWorldMap::findAStarPath(const CTopology::TTopologyId &start, const CTopolo uint father = (uint)nodes.size()-1; // add current to visited nodes - visited.insert(make_pair(startTopo, father)); + visited.insert(std::pair(startTopo, father)); heap.push(0.0f, father); bool found=false; @@ -1699,7 +1699,7 @@ bool CWorldMap::findAStarPath(const CTopology::TTopologyId &start, const CTopolo // add node to visited and to heap heap.push(heuristic, child); - visited.insert(make_pair(next, child)); + visited.insert(std::pair(next, child)); } } @@ -1767,7 +1767,7 @@ bool CWorldMap::findInsideAStarPath(CWorldPosition const& start, CWorldPosition uint father = (uint)nodes.size()-1; // Add start node to visited nodes (father holds start node index for the moment) - visited.insert(make_pair(startNode, father)); + visited.insert(std::pair(startNode, father)); // Push start node in the heap with a zero cost heap.push(0.0f, father); @@ -1854,7 +1854,7 @@ bool CWorldMap::findInsideAStarPath(CWorldPosition const& start, CWorldPosition // Add node to heap with a computed f(n)=g(n)+h(n) heap.push(distance + heuristic, child); // Add node to visited - visited.insert(make_pair(next, child)); + visited.insert(std::pair(next, child)); } } From 389bde2e110a513877620a98cec8cf15c1dbfa70 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:37:51 +0100 Subject: [PATCH 303/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- .../server/src/ai_data_service/pacs_scan.cpp | 6 +++--- .../server/src/ai_service/event_manager.h | 2 ++ .../src/backup_service/backup_service.cpp | 2 +- .../src/backup_service/web_connection.cpp | 18 +++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp index 9b5af1d5b..e52b97573 100644 --- a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp +++ b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp @@ -1651,7 +1651,7 @@ public: first.flags = (topNode.isInWater() ? 1 : 0) + (topNode.isInNogo() ? 2 : 0); // push first position - stacks[first.flags].insert(make_pair(first.flags, stwp)); + stacks[first.flags].insert(std::pair(first.flags, stwp)); while (true) { @@ -1750,11 +1750,11 @@ public: } if (tmp.getTopologyNode().Id == topNode.Id) { - stacks[0].insert(make_pair(ndist, tmp)); + stacks[0].insert(std::pair(ndist, tmp)); } else { - stacks[tmpflags+1].insert(make_pair(ndist, tmp)); + stacks[tmpflags + 1].insert(std::pair(ndist, tmp)); } } } diff --git a/code/ryzom/server/src/ai_service/event_manager.h b/code/ryzom/server/src/ai_service/event_manager.h index ab49b8d68..731539051 100644 --- a/code/ryzom/server/src/ai_service/event_manager.h +++ b/code/ryzom/server/src/ai_service/event_manager.h @@ -17,6 +17,8 @@ #ifndef RYAI_EVENT_MANAGER_H #define RYAI_EVENT_MANAGER_H +#include + #include "event_reaction.h" #include "states.h" diff --git a/code/ryzom/server/src/backup_service/backup_service.cpp b/code/ryzom/server/src/backup_service/backup_service.cpp index aed50a32c..95c11d07a 100644 --- a/code/ryzom/server/src/backup_service/backup_service.cpp +++ b/code/ryzom/server/src/backup_service/backup_service.cpp @@ -718,7 +718,7 @@ void CBackupService::init() BSIsSlave = true; FileManager.forbidStall(); // I'm a slave, try to contact master - string host = MasterBSHost; + string host = MasterBSHost.get(); if (host.find (":") == string::npos) host += ":49990"; diff --git a/code/ryzom/server/src/backup_service/web_connection.cpp b/code/ryzom/server/src/backup_service/web_connection.cpp index 86a62902d..6afa8f885 100644 --- a/code/ryzom/server/src/backup_service/web_connection.cpp +++ b/code/ryzom/server/src/backup_service/web_connection.cpp @@ -209,10 +209,10 @@ void cbGetSaveList(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); - string incrementalDir = IncrementalBackupDirectory; - string saveShardRoot = SaveShardRoot; - string templatePath = SaveTemplatePath; - string extList = SaveExtList; + string incrementalDir = IncrementalBackupDirectory.get(); + string saveShardRoot = SaveShardRoot.get(); + string templatePath = SaveTemplatePath.get(); + string extList = SaveExtList.get(); string shard; string userid; @@ -293,8 +293,8 @@ void cbRestoreSave(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); - string saveShardRoot = SaveShardRoot; - string templatePath = SaveTemplatePath; + string saveShardRoot = SaveShardRoot.get(); + string templatePath = SaveTemplatePath.get(); string shard; string userid; @@ -368,9 +368,9 @@ void cbCopyOverSave(CMemStream &msgin, TSockId host) explode(str, string("%%"), params, true); - string saveShardRoot = SaveShardRoot; - string templatePath = SaveTemplatePath; - string extList = SaveExtList; + string saveShardRoot = SaveShardRoot.get(); + string templatePath = SaveTemplatePath.get(); + string extList = SaveExtList.get(); string shard; string userid; From aede54925f8946919cad60fef2650e3bfa3465f9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:38:43 +0100 Subject: [PATCH 304/344] Visual Studio 2013 compilation support for Ryzom Tools --HG-- branch : develop --- code/ryzom/tools/pd_parser/parser.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/ryzom/tools/pd_parser/parser.cpp b/code/ryzom/tools/pd_parser/parser.cpp index 733bad4df..4b5e9f5c1 100644 --- a/code/ryzom/tools/pd_parser/parser.cpp +++ b/code/ryzom/tools/pd_parser/parser.cpp @@ -1189,7 +1189,7 @@ bool CEnumSimpleValueNode::prolog() uint i; for (i=0; iValues.push_back(make_pair(Names[i], CurrentValue)); + CurrentEnumNode->Values.push_back(std::pair(Names[i], CurrentValue)); } if (parent != NULL) ++(parent->CurrentValue); @@ -1214,7 +1214,7 @@ bool CEnumRangeNode::prolog() CurrentValue = 0; } - CurrentEnumNode->Values.push_back(make_pair(Name, CurrentValue)); + CurrentEnumNode->Values.push_back(std::pair(Name, CurrentValue)); return true; } @@ -1238,7 +1238,7 @@ bool CEnumRangeNode::epilog() if (!EndRange.empty()) { - CurrentEnumNode->Values.push_back(make_pair(EndRange, CurrentValue)); + CurrentEnumNode->Values.push_back(std::pair(EndRange, CurrentValue)); } return true; @@ -4709,7 +4709,7 @@ void CLogMsgNode::generateContent() CClassNode *cnd; if ( (tnd = getTypeNode(type, false)) ) { - pair::iterator, bool> res = params.insert(make_pair(name, tnd)); + pair::iterator, bool> res = params.insert(std::pair(name, tnd)); if (!res.second) error("log parameter '"+name+"' already defined"); @@ -4723,7 +4723,7 @@ void CLogMsgNode::generateContent() } else if ( (cnd = getClassNode(type, false)) ) { - pair::iterator, bool> res = params.insert(make_pair(name, cnd)); + pair::iterator, bool> res = params.insert(std::pair(name, cnd)); if (!res.second) error("log parameter '"+name+"' already defined"); @@ -4739,7 +4739,7 @@ void CLogMsgNode::generateContent() { CExtLogTypeNode* extnd = new CExtLogTypeNode(); extnd->ExtLogType = "string"; - pair::iterator, bool> res = params.insert(make_pair(name, extnd)); + pair::iterator, bool> res = params.insert(std::pair(name, extnd)); if (!res.second) error("log parameter '"+name+"' already defined"); From 883d69942871b81684fa980fcc328303e4d20a25 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:48:41 +0100 Subject: [PATCH 305/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- .../entities_game_service/player_manager/db_string_updater.h | 2 ++ .../entities_game_service/player_manager/player_manager.h | 5 +++-- .../player_manager/player_manager_interface.h | 5 +++-- .../src/frontend_service/client_entity_id_translator.h | 5 +++-- code/ryzom/server/src/frontend_service/vision_provider.h | 2 ++ code/ryzom/server/src/gpm_service/world_position_manager.h | 5 +++-- code/ryzom/server/src/pd_lib/pd_utils.h | 2 +- 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h index 059e7d765..ec8e8041f 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h @@ -53,6 +53,8 @@ class CDBStringUpdater : public NLMISC::CSingleton // hasher for the identifier struct THashDBStringLeaf { + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator()(const TBDStringLeaf &stringLeaf) const { return ((size_t)stringLeaf.ClientDB>>4) ^ ((size_t)stringLeaf.Node>>4); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h index 9f1643e84..9f159fd01 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h @@ -48,9 +48,10 @@ namespace NLNET extern CGenericXmlMsgHeaderManager GenericMsgManager; -class CServiceIdHash +struct CServiceIdHash { -public: + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator () ( const NLNET::TServiceId &sid ) const { return sid.get(); } }; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h index a18e1645a..a76e9656a 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h @@ -41,9 +41,10 @@ public: }; - class CUint32Hash + struct CUint32Hash { - public: + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator () ( const uint32 &i ) const { return i; } }; diff --git a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h index 0f18698c5..f6b79e42d 100644 --- a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h +++ b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h @@ -89,9 +89,10 @@ public: private: - class CHash + struct CHash { - public: + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator () ( const TEntityIndex& index ) const { return index.getIndex(); } }; diff --git a/code/ryzom/server/src/frontend_service/vision_provider.h b/code/ryzom/server/src/frontend_service/vision_provider.h index 39d84fb2f..aaca90869 100644 --- a/code/ryzom/server/src/frontend_service/vision_provider.h +++ b/code/ryzom/server/src/frontend_service/vision_provider.h @@ -84,6 +84,8 @@ class CClientIdLookup; // Hash function: ClientId * 256 + CeId struct CHash { + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator() ( TPairClientSlot pair ) const { return (pair.ClientId << 8) + pair.Slot; } }; diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.h b/code/ryzom/server/src/gpm_service/world_position_manager.h index 75ea9ead5..f3a285a2e 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.h +++ b/code/ryzom/server/src/gpm_service/world_position_manager.h @@ -137,9 +137,10 @@ public: //friend void CWorldEntity::createPrimitive(NLPACS::UMoveContainer *pMoveContainer, uint8 worldImage); friend void CWorldEntity::removePrimitive(); - class CEntityIdHash + struct CEntityIdHash { - public: + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; size_t operator () ( const NLMISC::CEntityId &id ) const { return (uint32)id.getShortId(); } }; diff --git a/code/ryzom/server/src/pd_lib/pd_utils.h b/code/ryzom/server/src/pd_lib/pd_utils.h index 0f0ab46d5..e6dbb15fc 100644 --- a/code/ryzom/server/src/pd_lib/pd_utils.h +++ b/code/ryzom/server/src/pd_lib/pd_utils.h @@ -499,7 +499,7 @@ struct CColumnIndexHashMapTraits } bool operator()(const CColumnIndex &left, const CColumnIndex &right) { - return left.hash() < right.hash(); + return left < right; } }; From 3ac5c4c5c3a7d2972fcc996e5f27bd8c5d111567 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:52:01 +0100 Subject: [PATCH 306/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- .../src/entities_game_service/deposit.cpp | 1 + .../src/entities_game_service/fame_pd.cpp | 2 +- .../game_event_manager.cpp | 4 ++-- .../guild_container_pd.cpp | 2 +- .../src/entities_game_service/guild_pd.cpp | 2 +- .../mission_manager/mission_queue_manager.cpp | 4 ++-- .../src/entities_game_service/mission_pd.cpp | 18 +++++++++--------- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/deposit.cpp b/code/ryzom/server/src/entities_game_service/deposit.cpp index 7d8000f4d..d4cd560ad 100644 --- a/code/ryzom/server/src/entities_game_service/deposit.cpp +++ b/code/ryzom/server/src/entities_game_service/deposit.cpp @@ -16,6 +16,7 @@ #include "stdpch.h" +#include #include "deposit.h" #include "player_manager/character.h" #include "player_manager/player_manager.h" diff --git a/code/ryzom/server/src/entities_game_service/fame_pd.cpp b/code/ryzom/server/src/entities_game_service/fame_pd.cpp index db2104c5d..2e201412a 100644 --- a/code/ryzom/server/src/entities_game_service/fame_pd.cpp +++ b/code/ryzom/server/src/entities_game_service/fame_pd.cpp @@ -516,7 +516,7 @@ void CFameContainerPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; NLMISC::CSheetId __k; data.serial(__k); - _Entries.insert(std::make_pair(__k, CFameContainerEntryPD())); + _Entries.insert(std::pair(__k, CFameContainerEntryPD())); CFameContainerEntryPD* __o = &(_Entries[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); diff --git a/code/ryzom/server/src/entities_game_service/game_event_manager.cpp b/code/ryzom/server/src/entities_game_service/game_event_manager.cpp index 5346809a3..b95fb1ad4 100644 --- a/code/ryzom/server/src/entities_game_service/game_event_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/game_event_manager.cpp @@ -59,7 +59,7 @@ CGameEventManager::CGameEventManager() // ---------------------------------------------------------------------------- void CGameEventManager::init() { - string sFilename = GameEventFile; + string sFilename = GameEventFile.get(); sFilename = CPath::standardizePath(IService::getInstance()->WriteFilesDirectory) + sFilename; if (CFile::fileExists(sFilename)) @@ -302,7 +302,7 @@ void CGameEventManager::saveGameEventFile() { if( _InitOk ) { - string sFilename = GameEventFile; + string sFilename = GameEventFile.get(); sFilename = CPath::standardizePath(IService::getInstance()->WriteFilesDirectory) + sFilename; static CPersistentDataRecordRyzomStore pdr; diff --git a/code/ryzom/server/src/entities_game_service/guild_container_pd.cpp b/code/ryzom/server/src/entities_game_service/guild_container_pd.cpp index dea4e2a1d..7e025acdf 100644 --- a/code/ryzom/server/src/entities_game_service/guild_container_pd.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_container_pd.cpp @@ -298,7 +298,7 @@ void CGuildContainerPD::pds__fetch(RY_PDS::CPData &data) TGuildId __k; data.serial(__k); CGuildPD* __o = static_cast(PDSLib.create(tableIndex)); - _Guilds.insert(std::make_pair(__k, __o)); + _Guilds.insert(std::pair(__k, __o)); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); __o->pds__setParentUnnotified(this); diff --git a/code/ryzom/server/src/entities_game_service/guild_pd.cpp b/code/ryzom/server/src/entities_game_service/guild_pd.cpp index 819ae72ad..1da40c221 100644 --- a/code/ryzom/server/src/entities_game_service/guild_pd.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_pd.cpp @@ -470,7 +470,7 @@ void CGuildPD::pds__fetch(RY_PDS::CPData &data) TCharacterId __k; data.serial(__k); CGuildMemberPD* __o = static_cast(PDSLib.create(tableIndex)); - _Members.insert(std::make_pair(__k, __o)); + _Members.insert(std::pair(__k, __o)); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); __o->pds__setParentUnnotified(this); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_queue_manager.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_queue_manager.cpp index bab69042a..a821eef45 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_queue_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_queue_manager.cpp @@ -48,7 +48,7 @@ CMissionQueueManager::CMissionQueueManager() // ---------------------------------------------------------------------------- void CMissionQueueManager::init() { - string sFilename = MissionQueueFile; + string sFilename = MissionQueueFile.get(); sFilename = Bsi.getLocalPath() + sFilename; if (CFile::fileExists(sFilename)) @@ -141,7 +141,7 @@ void CMissionQueueManager::saveToFile() if( _InitOk ) { - string sFilename = MissionQueueFile; + string sFilename = MissionQueueFile.get(); // save file via Backup Service (BS) try diff --git a/code/ryzom/server/src/entities_game_service/mission_pd.cpp b/code/ryzom/server/src/entities_game_service/mission_pd.cpp index ffa8855a9..1d5903687 100644 --- a/code/ryzom/server/src/entities_game_service/mission_pd.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_pd.cpp @@ -328,7 +328,7 @@ void CActiveStepPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _States.insert(std::make_pair(__k, CActiveStepStatePD())); + _States.insert(std::pair(__k, CActiveStepStatePD())); CActiveStepStatePD* __o = &(_States[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2353,7 +2353,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _Steps.insert(std::make_pair(__k, CActiveStepPD())); + _Steps.insert(std::pair(__k, CActiveStepPD())); CActiveStepPD* __o = &(_Steps[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2367,7 +2367,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _Compass.insert(std::make_pair(__k, CMissionCompassPD())); + _Compass.insert(std::pair(__k, CMissionCompassPD())); CMissionCompassPD* __o = &(_Compass[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2381,7 +2381,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _StepsDone.insert(std::make_pair(__k, CDoneStepPD())); + _StepsDone.insert(std::pair(__k, CDoneStepPD())); CDoneStepPD* __o = &(_StepsDone[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2395,7 +2395,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _Teleports.insert(std::make_pair(__k, CMissionTeleportPD())); + _Teleports.insert(std::pair(__k, CMissionTeleportPD())); CMissionTeleportPD* __o = &(_Teleports[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2409,7 +2409,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _InsidePlaces.insert(std::make_pair(__k, CMissionInsidePlacePD())); + _InsidePlaces.insert(std::pair(__k, CMissionInsidePlacePD())); CMissionInsidePlacePD* __o = &(_InsidePlaces[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2423,7 +2423,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _OutsidePlaces.insert(std::make_pair(__k, CMissionOutsidePlacePD())); + _OutsidePlaces.insert(std::pair(__k, CMissionOutsidePlacePD())); CMissionOutsidePlacePD* __o = &(_OutsidePlaces[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -2437,7 +2437,7 @@ void CMissionPD::pds__fetch(RY_PDS::CPData &data) if (rowIndex == RY_PDS::INVALID_ROW_INDEX || tableIndex == RY_PDS::INVALID_TABLE_INDEX) break; uint32 __k; data.serial(__k); - _HandledAIGroups.insert(std::make_pair(__k, CHandledAIGroupPD())); + _HandledAIGroups.insert(std::pair(__k, CHandledAIGroupPD())); CHandledAIGroupPD* __o = &(_HandledAIGroups[__k]); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); @@ -3276,7 +3276,7 @@ void CMissionContainerPD::pds__fetch(RY_PDS::CPData &data) uint32 __k; data.serial(__k); CMissionPD* __o = static_cast(PDSLib.create(tableIndex)); - _Missions.insert(std::make_pair(__k, __o)); + _Missions.insert(std::pair(__k, __o)); PDSLib.setRowIndex(rowIndex, __o); __o->pds__fetch(data); __o->pds__setParentUnnotified(this); From 77d17265eb4578beb0bc88fff09af74d725d4580 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 12:58:43 +0100 Subject: [PATCH 307/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- code/nel/include/nel/gui/lua_object.h | 3 +-- code/nel/include/nel/misc/class_id.h | 3 +-- code/nel/include/nel/misc/entity_id.h | 3 +-- code/nel/include/nel/misc/sheet_id.h | 3 +-- code/nel/include/nel/misc/string_mapper.h | 3 +-- code/nel/include/nel/misc/ucstring.h | 3 +-- code/nel/include/nel/sound/containers.h | 3 +-- code/nel/include/nel/sound/context_sound.h | 3 +-- code/nel/samples/net/udp/bench_service.cpp | 3 +-- code/nel/tools/pacs/build_rbank/build_surf.cpp | 3 +-- code/ryzom/client/src/actions.h | 3 +-- code/ryzom/client/src/network_connection.h | 10 ++-------- code/ryzom/common/src/game_share/base_types.h | 3 +-- .../player_manager/db_string_updater.h | 3 +-- .../player_manager/player_manager.h | 3 +-- .../player_manager/player_manager_interface.h | 3 +-- .../src/frontend_service/client_entity_id_translator.h | 3 +-- .../server/src/frontend_service/client_id_lookup.h | 5 ++--- code/ryzom/server/src/frontend_service/fe_types.h | 6 ++---- .../server/src/gpm_service/world_position_manager.cpp | 8 ++++---- .../server/src/gpm_service/world_position_manager.h | 3 +-- .../src/input_output_service/string_manager_parser.cpp | 2 +- code/ryzom/server/src/monitor_service/client.cpp | 2 +- code/ryzom/server/src/pd_lib/pd_utils.h | 3 +-- 24 files changed, 30 insertions(+), 57 deletions(-) diff --git a/code/nel/include/nel/gui/lua_object.h b/code/nel/include/nel/gui/lua_object.h index 1564df080..2360f1609 100644 --- a/code/nel/include/nel/gui/lua_object.h +++ b/code/nel/include/nel/gui/lua_object.h @@ -285,8 +285,7 @@ namespace NLGUI class CLuaHashMapTraits { public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CLuaHashMapTraits() {} diff --git a/code/nel/include/nel/misc/class_id.h b/code/nel/include/nel/misc/class_id.h index 0628e8030..d02fc5646 100644 --- a/code/nel/include/nel/misc/class_id.h +++ b/code/nel/include/nel/misc/class_id.h @@ -61,8 +61,7 @@ public: class CClassIdHashMapTraits { public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; inline size_t operator() ( const CClassId& classId ) const { return ((((uint64)classId >> 32)|0xFFFFFFFF) ^ (((uint64)classId|0xFFFFFFFF) & 0xFFFFFFFF)); diff --git a/code/nel/include/nel/misc/entity_id.h b/code/nel/include/nel/misc/entity_id.h index 027fe28c7..b4e40909e 100644 --- a/code/nel/include/nel/misc/entity_id.h +++ b/code/nel/include/nel/misc/entity_id.h @@ -575,8 +575,7 @@ public: // Traits for hash_map using CEntityId struct CEntityIdHashMapTraits { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CEntityIdHashMapTraits() { } size_t operator() (const NLMISC::CEntityId &id ) const { diff --git a/code/nel/include/nel/misc/sheet_id.h b/code/nel/include/nel/misc/sheet_id.h index 869a61af6..b11e97188 100644 --- a/code/nel/include/nel/misc/sheet_id.h +++ b/code/nel/include/nel/misc/sheet_id.h @@ -248,8 +248,7 @@ private : class CSheetIdHashMapTraits { public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; inline size_t operator() ( const CSheetId& sheetId ) const { return sheetId.asInt() >> 5; diff --git a/code/nel/include/nel/misc/string_mapper.h b/code/nel/include/nel/misc/string_mapper.h index 36a73ed4d..1f62dd123 100644 --- a/code/nel/include/nel/misc/string_mapper.h +++ b/code/nel/include/nel/misc/string_mapper.h @@ -39,8 +39,7 @@ typedef const std::string *TStringId; // Traits for hash_map using CStringId struct CStringIdHashMapTraits { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CStringIdHashMapTraits() { } size_t operator() (const NLMISC::TStringId &stringId) const { diff --git a/code/nel/include/nel/misc/ucstring.h b/code/nel/include/nel/misc/ucstring.h index e6d7544b1..88e599c1a 100644 --- a/code/nel/include/nel/misc/ucstring.h +++ b/code/nel/include/nel/misc/ucstring.h @@ -355,8 +355,7 @@ namespace NLMISC // Traits for hash_map using CEntityId struct CUCStringHashMapTraits { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CUCStringHashMapTraits() { } size_t operator() (const ucstring &id ) const { diff --git a/code/nel/include/nel/sound/containers.h b/code/nel/include/nel/sound/containers.h index 63e134077..57387e91e 100644 --- a/code/nel/include/nel/sound/containers.h +++ b/code/nel/include/nel/sound/containers.h @@ -42,8 +42,7 @@ namespace NLSOUND { template struct THashPtr : public std::unary_function { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () (const Pointer &ptr) const { //CHashSet::hasher h; diff --git a/code/nel/include/nel/sound/context_sound.h b/code/nel/include/nel/sound/context_sound.h index 13683ac56..8424ee087 100644 --- a/code/nel/include/nel/sound/context_sound.h +++ b/code/nel/include/nel/sound/context_sound.h @@ -82,8 +82,7 @@ struct CContextMatcher struct CHash : public std::unary_function { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () (const CContextMatcher &patternMatcher) const { return patternMatcher.getHashValue(); diff --git a/code/nel/samples/net/udp/bench_service.cpp b/code/nel/samples/net/udp/bench_service.cpp index 981a0dd0a..190347d4b 100644 --- a/code/nel/samples/net/udp/bench_service.cpp +++ b/code/nel/samples/net/udp/bench_service.cpp @@ -98,8 +98,7 @@ struct CClient struct TInetAddressHash { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; inline bool operator() (const NLNET::CInetAddress &x1, const NLNET::CInetAddress &x2) const { diff --git a/code/nel/tools/pacs/build_rbank/build_surf.cpp b/code/nel/tools/pacs/build_rbank/build_surf.cpp index 9546e19f1..10d4c6a19 100644 --- a/code/nel/tools/pacs/build_rbank/build_surf.cpp +++ b/code/nel/tools/pacs/build_rbank/build_surf.cpp @@ -201,8 +201,7 @@ template class CHashPtr { public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; typedef A *ptrA; size_t operator() (const ptrA &a) const diff --git a/code/ryzom/client/src/actions.h b/code/ryzom/client/src/actions.h index cdc3f200a..b177c1818 100644 --- a/code/ryzom/client/src/actions.h +++ b/code/ryzom/client/src/actions.h @@ -281,8 +281,7 @@ public: // HashMapTraits for NLMISC::TKey struct CTKeyHashMapTraits { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CTKeyHashMapTraits() { } size_t operator() (NLMISC::TKey key) const { diff --git a/code/ryzom/client/src/network_connection.h b/code/ryzom/client/src/network_connection.h index 3eb5cd95b..da47f925e 100644 --- a/code/ryzom/client/src/network_connection.h +++ b/code/ryzom/client/src/network_connection.h @@ -776,16 +776,10 @@ protected: /// @name NLMISC::CEntityId handling (for gamedev) //@{ - class CHash + struct CHash { - public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - - CHash() {} - + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () (const CLFECOMMON::TSheetId &id) const { return id; } - inline bool operator() (const CLFECOMMON::TSheetId &id1, const CLFECOMMON::TSheetId &id2) const { return (size_t)id1 < (size_t)id2; } }; diff --git a/code/ryzom/common/src/game_share/base_types.h b/code/ryzom/common/src/game_share/base_types.h index 250e5f5e4..5330537b7 100644 --- a/code/ryzom/common/src/game_share/base_types.h +++ b/code/ryzom/common/src/game_share/base_types.h @@ -238,8 +238,7 @@ public: CHashCode() {} - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( const TDataSetRow &index ) const { return index.getHashCode(); } diff --git a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h index ec8e8041f..7603c92e9 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/db_string_updater.h @@ -53,8 +53,7 @@ class CDBStringUpdater : public NLMISC::CSingleton // hasher for the identifier struct THashDBStringLeaf { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator()(const TBDStringLeaf &stringLeaf) const { return ((size_t)stringLeaf.ClientDB>>4) ^ ((size_t)stringLeaf.Node>>4); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h index 9f159fd01..ba0d1c306 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager.h @@ -50,8 +50,7 @@ extern CGenericXmlMsgHeaderManager GenericMsgManager; struct CServiceIdHash { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( const NLNET::TServiceId &sid ) const { return sid.get(); } }; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h index a76e9656a..3e5de3130 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_manager_interface.h @@ -43,8 +43,7 @@ public: struct CUint32Hash { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( const uint32 &i ) const { return i; } }; diff --git a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h index f6b79e42d..957774f39 100644 --- a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h +++ b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h @@ -91,8 +91,7 @@ private: struct CHash { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( const TEntityIndex& index ) const { return index.getIndex(); } }; diff --git a/code/ryzom/server/src/frontend_service/client_id_lookup.h b/code/ryzom/server/src/frontend_service/client_id_lookup.h index 3d6db560e..9db039a12 100644 --- a/code/ryzom/server/src/frontend_service/client_id_lookup.h +++ b/code/ryzom/server/src/frontend_service/client_id_lookup.h @@ -114,10 +114,9 @@ private: typedef std::vector TEntityIndexToClient; - class CIdHash + struct CIdHash { - public: - + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( NLMISC::CEntityId id ) const { return (uint32)id.getShortId(); } }; diff --git a/code/ryzom/server/src/frontend_service/fe_types.h b/code/ryzom/server/src/frontend_service/fe_types.h index 747fd6f9e..08a12eb5a 100644 --- a/code/ryzom/server/src/frontend_service/fe_types.h +++ b/code/ryzom/server/src/frontend_service/fe_types.h @@ -69,11 +69,9 @@ typedef uint32 TUid; /** * CInetAddress hash function */ -class CInetAddressHashMapTraits +struct CInetAddressHashMapTraits { -public: - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; inline size_t operator() ( const NLNET::CInetAddress& x ) const { //return x.port(); diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.cpp b/code/ryzom/server/src/gpm_service/world_position_manager.cpp index 2c10878a6..9674541fc 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.cpp +++ b/code/ryzom/server/src/gpm_service/world_position_manager.cpp @@ -504,7 +504,7 @@ void CWorldPositionManager::triggerSubscribe(NLNET::TServiceId serviceId, const STOP_IF(IsRingShard,"Illegal use of CWorldPositionManager on ring shard"); if (_PatatSubscribeManager.exist(name)) { - _PatatSubscribeManager.subscribe(serviceId, make_pair(name, id)); + _PatatSubscribeManager.subscribe(serviceId, std::pair(name, id)); } } @@ -2113,7 +2113,7 @@ void CWorldPositionManager::movePlayer(CWorldEntity *entity, sint32 x, sint32 y, { if (entity->PlayerInfos->DistanceHistory.size() >= 20) entity->PlayerInfos->DistanceHistory.pop_back(); - entity->PlayerInfos->DistanceHistory.push_front(make_pair(CVectorD(x*0.001, y*0.001, z*0.001), tick)); + entity->PlayerInfos->DistanceHistory.push_front(std::pair(CVectorD(x*0.001, y*0.001, z*0.001), tick)); } #endif @@ -3227,7 +3227,7 @@ void CWorldPositionManager::visionRequest(sint32 x, sint32 y, sint32 range, vect if (abs(x - entity->X) < range && abs(y - entity->Y) < range && (rrange = sqrt(sqr((x - entity->X)*0.001) + sqr((y - entity->Y)*0.001))) < frange) { - entities.push_back(make_pair(entity->Id, (sint32)(rrange*1000))); + entities.push_back(std::pair(entity->Id, (sint32)(rrange * 1000))); } } @@ -3240,7 +3240,7 @@ void CWorldPositionManager::visionRequest(sint32 x, sint32 y, sint32 range, vect if (abs(x - entity->X) < range && abs(y - entity->Y) < range && (rrange = sqrt(sqr((x - entity->X)*0.001) + sqr((y - entity->Y)*0.001))) < frange) { - entities.push_back(make_pair(entity->Id, (sint32)(rrange*1000))); + entities.push_back(std::pair(entity->Id, (sint32)(rrange * 1000))); } } } diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.h b/code/ryzom/server/src/gpm_service/world_position_manager.h index f3a285a2e..18645d8ca 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.h +++ b/code/ryzom/server/src/gpm_service/world_position_manager.h @@ -139,8 +139,7 @@ public: struct CEntityIdHash { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; size_t operator () ( const NLMISC::CEntityId &id ) const { return (uint32)id.getShortId(); } }; diff --git a/code/ryzom/server/src/input_output_service/string_manager_parser.cpp b/code/ryzom/server/src/input_output_service/string_manager_parser.cpp index 0cbfbf595..2aa3c896b 100644 --- a/code/ryzom/server/src/input_output_service/string_manager_parser.cpp +++ b/code/ryzom/server/src/input_output_service/string_manager_parser.cpp @@ -1356,7 +1356,7 @@ void CStringManager::mergeEntityWords(CEntityWords& dest, const CEntityWords& so std::map::const_iterator iti; for (iti=source._ColumnInfo.begin(); iti!=source._ColumnInfo.end(); ++iti) if (dest._ColumnInfo.find((*iti).first) == dest._ColumnInfo.end()) - extraColumns.push_back(std::make_pair((*iti).first, osz+(uint32)extraColumns.size())); + extraColumns.push_back(std::pair((*iti).first, osz + (uint32)extraColumns.size())); for (iti=source._RowInfo.begin(); iti!=source._RowInfo.end(); ++iti) if (dest._RowInfo.find((*iti).first) == dest._RowInfo.end()) diff --git a/code/ryzom/server/src/monitor_service/client.cpp b/code/ryzom/server/src/monitor_service/client.cpp index 6d761ba3e..ce2fdc5dc 100644 --- a/code/ryzom/server/src/monitor_service/client.cpp +++ b/code/ryzom/server/src/monitor_service/client.cpp @@ -273,7 +273,7 @@ void CMonitorClient::update () TYPE_NAME_STRING_ID id = Str[i]; std::map::iterator ite = StringMap.find (id); nlassert (ite != StringMap.end()); - strToSend.push_back( make_pair(id, &((*ite).second)) ); + strToSend.push_back(std::pair(id, &((*ite).second))); strTotalSize += 4+4+(uint)(*ite).second.size(); } diff --git a/code/ryzom/server/src/pd_lib/pd_utils.h b/code/ryzom/server/src/pd_lib/pd_utils.h index e6dbb15fc..85a183753 100644 --- a/code/ryzom/server/src/pd_lib/pd_utils.h +++ b/code/ryzom/server/src/pd_lib/pd_utils.h @@ -490,8 +490,7 @@ typedef std::vector TIndexList; struct CColumnIndexHashMapTraits { - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; + enum { bucket_size = 4, min_buckets = 8, }; CColumnIndexHashMapTraits() { } size_t operator() (const CColumnIndex &id) const { From 609fbbc9c38726a80dd5b329c6b233ea3d3f74d3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 13:08:03 +0100 Subject: [PATCH 308/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- .../server/src/frontend_service/client_entity_id_translator.h | 3 ++- code/ryzom/server/src/frontend_service/client_id_lookup.h | 3 ++- code/ryzom/server/src/frontend_service/fe_types.h | 1 + code/ryzom/server/src/frontend_service/frontend_service.cpp | 2 +- code/ryzom/server/src/gpm_service/world_position_manager.h | 3 ++- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h index 957774f39..f80fbe983 100644 --- a/code/ryzom/server/src/frontend_service/client_entity_id_translator.h +++ b/code/ryzom/server/src/frontend_service/client_entity_id_translator.h @@ -92,7 +92,8 @@ private: struct CHash { enum { bucket_size = 4, min_buckets = 8, }; - size_t operator () ( const TEntityIndex& index ) const { return index.getIndex(); } + size_t operator () (const TEntityIndex& index) const { return index.getIndex(); } + bool operator() (const TEntityIndex& left, const TEntityIndex& right) { return left < right; } }; // table to map CEntityId to TCLEntityId diff --git a/code/ryzom/server/src/frontend_service/client_id_lookup.h b/code/ryzom/server/src/frontend_service/client_id_lookup.h index 9db039a12..9c63a60a6 100644 --- a/code/ryzom/server/src/frontend_service/client_id_lookup.h +++ b/code/ryzom/server/src/frontend_service/client_id_lookup.h @@ -117,7 +117,8 @@ private: struct CIdHash { enum { bucket_size = 4, min_buckets = 8, }; - size_t operator () ( NLMISC::CEntityId id ) const { return (uint32)id.getShortId(); } + size_t operator () (NLMISC::CEntityId id) const { return (uint32)id.getShortId(); } + bool operator() (const NLMISC::CEntityId& left, const NLMISC::CEntityId& right) { return left < right; } }; typedef CHashMap TIdToClientMap; diff --git a/code/ryzom/server/src/frontend_service/fe_types.h b/code/ryzom/server/src/frontend_service/fe_types.h index 08a12eb5a..d63ef1e42 100644 --- a/code/ryzom/server/src/frontend_service/fe_types.h +++ b/code/ryzom/server/src/frontend_service/fe_types.h @@ -77,6 +77,7 @@ struct CInetAddressHashMapTraits //return x.port(); return x.internalIPAddress(); } + bool operator() (const NLNET::CInetAddress& left, const NLNET::CInetAddress& right) { return left < right; } // bool operator() (const NLNET::CInetAddress &x1, const NLNET::CInetAddress &x2) const // { // return classId1 < classId2; diff --git a/code/ryzom/server/src/frontend_service/frontend_service.cpp b/code/ryzom/server/src/frontend_service/frontend_service.cpp index cbf4a5610..c973ebcfd 100644 --- a/code/ryzom/server/src/frontend_service/frontend_service.cpp +++ b/code/ryzom/server/src/frontend_service/frontend_service.cpp @@ -1862,7 +1862,7 @@ NLMISC_COMMAND( dumpImpulseStats, "Dump Impulse stat to XML log", " [[- if (reverse) comp = -comp; - result.push_back(std::make_pair(comp, client)); + result.push_back(std::pair(comp, client)); } if (ucriterion != 0 && !result.empty()) diff --git a/code/ryzom/server/src/gpm_service/world_position_manager.h b/code/ryzom/server/src/gpm_service/world_position_manager.h index 18645d8ca..81209357c 100644 --- a/code/ryzom/server/src/gpm_service/world_position_manager.h +++ b/code/ryzom/server/src/gpm_service/world_position_manager.h @@ -140,7 +140,8 @@ public: struct CEntityIdHash { enum { bucket_size = 4, min_buckets = 8, }; - size_t operator () ( const NLMISC::CEntityId &id ) const { return (uint32)id.getShortId(); } + size_t operator () (const NLMISC::CEntityId &id) const { return (uint32)id.getShortId(); } + size_t operator () (const NLMISC::CEntityId &left, const NLMISC::CEntityId &right) const { return left < right; } }; /// Container of entities (all entities are referenced by this container From ca3243782b15165df5b1a3136d9fc8a1e357dc17 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 13:13:11 +0100 Subject: [PATCH 309/344] Visual Studio 2013 compilation support for Ryzom Tools --HG-- branch : develop --- code/ryzom/tools/client/client_patcher/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/ryzom/tools/client/client_patcher/CMakeLists.txt b/code/ryzom/tools/client/client_patcher/CMakeLists.txt index e5b845e43..70857105e 100644 --- a/code/ryzom/tools/client/client_patcher/CMakeLists.txt +++ b/code/ryzom/tools/client/client_patcher/CMakeLists.txt @@ -12,6 +12,7 @@ ADD_EXECUTABLE(ryzom_client_patcher ${SRC}) INCLUDE_DIRECTORIES( ${LIBXML2_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/ryzom/client/src ) @@ -20,6 +21,7 @@ TARGET_LINK_LIBRARIES(ryzom_client_patcher nelnet ryzom_gameshare ryzom_sevenzip + ${ZLIB_LIBRARIES} ${CURL_LIBRARIES}) IF(APPLE) From 55d0c3282d86ff27df4d250bc3f92d0bc2c67955 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 13:16:50 +0100 Subject: [PATCH 310/344] Visual Studio 2013 compilation support for Ryzom Server --HG-- branch : develop --- code/ryzom/server/src/monitor_service/service_main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index 84bbcbe86..bf092bbae 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -418,7 +418,9 @@ void clientAuthentication(CMessage &msgin, TSockId from, CCallbackNetBase &netba // fail the authentication // Do not send result immediatly to avoid a potential hacker // to try a dictionnary or that dort of things - BadLoginClients.insert(std::make_pair(NLMISC::CTime::getLocalTime() + LOGIN_RETRY_DELAY_IN_MILLISECONDS, Clients[i])); + BadLoginClients.insert(std::pair >( + NLMISC::CTime::getLocalTime() + LOGIN_RETRY_DELAY_IN_MILLISECONDS, + (NLMISC::CRefPtr)Clients[i])); Clients[i]->BadLogin =true; return; } From 6ae954326d761cc0b176ec83212afcd6c534095c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 19:23:15 +0100 Subject: [PATCH 311/344] GCC/Linux version of NLMISC_BREAKPOINT --HG-- branch : feature-crashreport --- code/nel/include/nel/misc/debug.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/misc/debug.h b/code/nel/include/nel/misc/debug.h index 690d340a3..8d2483e4e 100644 --- a/code/nel/include/nel/misc/debug.h +++ b/code/nel/include/nel/misc/debug.h @@ -350,8 +350,10 @@ void setCrashAlreadyReported(bool state); */ // removed because we always check assert (even in release mode) #if defined (NL_OS_WINDOWS) && defined (NL_DEBUG) -#if defined (NL_OS_WINDOWS) -#define NLMISC_BREAKPOINT __debugbreak(); +#if defined(NL_OS_WINDOWS) +#define NLMISC_BREAKPOINT __debugbreak() +#elif defined(NL_OS_UNIX) && defined(NL_COMP_GCC) +#define NLMISC_BREAKPOINT __builtin_trap() #else #define NLMISC_BREAKPOINT abort() #endif From e4e3f2019b427f862d34a5dce39746a889a7b7e2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 20:01:20 +0100 Subject: [PATCH 312/344] Add function to set custom host url. Deprecate email callback function. Add some comments --HG-- branch : feature-crashreport --- code/nel/include/nel/misc/report.h | 13 ++- code/nel/src/misc/report.cpp | 174 +++++++++++++---------------- 2 files changed, 86 insertions(+), 101 deletions(-) diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index 11745b6e3..c492f4aa2 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,9 +21,11 @@ namespace NLMISC { +enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; + /** Display a custom message box. * - * \param title set the title of the report. If empty, it'll display "NeL report". + * \param title set the title of the report. If empty, it'll display "NeL Crash Report" or the default title set by setReportWindowTitle. * \param header message displayed before the edit text box. If empty, it displays the default message. * \param body message displayed in the edit text box. This string will be sent by email. * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior @@ -32,14 +34,15 @@ namespace NLMISC { * * \return the button clicked or error */ +TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); -enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); +/// Set the Url of the web service used to post crash reports to +void setReportPostUrl(const std::string &postUrl); +/// DEPRECATED /** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); */ -void setReportEmailFunction (void *emailFunction); +void setReportEmailFunction(void *emailFunction); } // NLMISC diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 784f49a9a..69ce40544 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -16,6 +16,8 @@ #include "stdmisc.h" +#include + #include "nel/misc/common.h" #include "nel/misc/ucstring.h" @@ -42,125 +44,126 @@ using namespace std; namespace NLMISC { -#ifdef NL_OS_WINDOWS -static HWND sendReport=NULL; -#endif - -//old doesn't work on visual c++ 7.1 due to default parameter typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile = "", bool onlyCheck = false); -typedef bool (*TEmailFunction) (const std::string &smtpServer, const std::string &from, const std::string &to, const std::string &subject, const std::string &body, const std::string &attachedFile, bool onlyCheck); - -#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } - -static TEmailFunction EmailFunction = NULL; - -void setReportEmailFunction (void *emailFunction) +void setReportEmailFunction(void *emailFunction) { - EmailFunction = (TEmailFunction)emailFunction; - -#ifdef NL_OS_WINDOWS - if (sendReport) - EnableWindow(sendReport, FALSE); -#endif + // DEPRECATED + // no-op } -static string Body; -static std::string URL = "FILL_IN_CRASH_REPORT_HOSTNAME_HERE"; +// Contents of crash report +static string ReportBody; +// Host url for crash report +static std::string ReportPostUrl = ""; +// Title for the crash report window +static std::string ReportWindowTitle = ""; +void setReportPostUrl(const std::string &postUrl) +{ + ReportPostUrl = postUrl; +} +// Launch the crash report application static void doSendReport() { std::string filename; - filename = "report_"; + filename = /*getLogDirectory() + */ "report_"; // FIXME: Should use log directory filename += NLMISC::toString( int( time( NULL ) ) ); filename += ".txt"; - std::string params; - params = "-log "; - params += filename; - params += " -host "; - params += URL; + std::stringstream params; + params << "-log "; + params << filename; // FIXME: Escape the filepath with quotes + if (!ReportPostUrl.empty()) + { + params << " -host "; + params << ReportPostUrl; + } + if (!ReportWindowTitle.empty()) + { + params << " -title "; + params << ReportWindowTitle; // FIXME: Escape the title with quotes and test + } std::ofstream f; f.open( filename.c_str() ); if( !f.good() ) return; - f << Body; + f << ReportBody; f.close(); #ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "crash_report.exe", params ); + NLMISC::launchProgram( "crash_report.exe", params.str() ); #else - NLMISC::launchProgram( "crash_report", params ); + NLMISC::launchProgram( "crash_report", params.str() ); #endif // Added because NLSMIC::launcProgram needs time to launch nlSleep( 2 * 1000 ); - + } -#ifndef NL_OS_WINDOWS +#if defined(FINAL_VERSION) || !defined(NL_OS_WINDOWS) -// GNU/Linux, do nothing - -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +// For FINAL_VERSION, simply launch the crash report and exit the application +TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { - Body = addSlashR( body ); - - doSendReport(); + ReportWindowTitle = title; + ReportBody = addSlashR(body); + + doSendReport(); + +# if 1 // TODO: This behaviour is used in the old report code when Quitting the application is the default crash report behaviour. Needs testing. +# ifdef NL_OS_WINDOWS +# ifndef NL_COMP_MINGW + // disable the Windows popup telling that the application aborted and disable the dr watson report. + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +# endif +# endif + // quit without calling atexit or static object dtors. + abort(); +# endif - return ReportQuit; + return ReportQuit; } #else -// Windows specific version +// Windows specific version for DEV builds, first shows a dialog box for debugging -static string Subject; -static string AttachedFile; +static HWND sendReport=NULL; +#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } -static HWND checkIgnore=NULL; -static HWND debug=NULL; -static HWND ignore=NULL; -static HWND quit=NULL; -static HWND dialog=NULL; +static HWND checkIgnore = NULL; +static HWND debug = NULL; +static HWND ignore = NULL; +static HWND quit = NULL; +static HWND dialog = NULL; static bool NeedExit; static TReportResult Result; static bool IgnoreNextTime; -static bool CanSendMailReport= false; +static bool CanSendMailReport = false; static bool DebugDefaultBehavior, QuitDefaultBehavior; -static void sendEmail() +static void maybeSendReport() { if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - // EnableWindow(sendReport, FALSE); - // MessageBox (dialog, "The email was successfully sent", "email", MB_OK); + doSendReport(); #ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_sent"); + CFile::createEmptyFile(getLogDirectory() + "report_sent"); #endif - } - else - { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_failed"); -#endif - // MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } } else { #ifndef NL_NO_DEBUG_FILES CFile::createEmptyFile(getLogDirectory() + "report_refused"); #endif - } +- } } static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -175,7 +178,7 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM } else if ((HWND) lParam == debug) { - doSendReport(); + maybeSendReport(); NeedExit = true; Result = ReportDebug; if (DebugDefaultBehavior) @@ -185,13 +188,13 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM } else if ((HWND) lParam == ignore) { - doSendReport(); + maybeSendReport(); NeedExit = true; Result = ReportIgnore; } else if ((HWND) lParam == quit) { - doSendReport(); + maybeSendReport(); NeedExit = true; Result = ReportQuit; @@ -210,43 +213,26 @@ static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM abort(); } } - /*else if ((HWND) lParam == sendReport) - { - if (EmailFunction != NULL) - { - bool res = EmailFunction ("", "", "", Subject, Body, AttachedFile, false); - if (res) - { - EnableWindow(sendReport, FALSE); - MessageBox (dialog, "The email was successfully sent", "email", MB_OK); - CFile::createEmptyFile(getLogDirectory() + "report_sent"); - } - else - { - MessageBox (dialog, "Failed to send the email", "email", MB_OK | MB_ICONERROR); - } - } - }*/ } else if (message == WM_CHAR) { if (wParam == 27) { // ESC -> ignore - doSendReport(); + maybeSendReport(); NeedExit = true; Result = ReportIgnore; } } - return DefWindowProc (hWnd, message, wParam, lParam); + return DefWindowProc(hWnd, message, wParam, lParam); } -TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { // register the window static bool AlreadyRegister = false; - if(!AlreadyRegister) + if (!AlreadyRegister) { WNDCLASSW wc; memset (&wc,0,sizeof(wc)); @@ -264,8 +250,8 @@ TReportResult report (const std::string &title, const std::string &header, const AlreadyRegister = true; } - ucstring formatedTitle = title.empty() ? ucstring("NeL report") : ucstring(title); - + ReportWindowTitle = title.empty() ? "Nel Crash Report" : title; + ucstring formatedTitle = ucstring::makeFromUtf8(ReportWindowTitle); // create the window dialog = CreateWindowW (L"NLReportWindow", (LPCWSTR)formatedTitle.c_str(), WS_DLGFRAME | WS_CAPTION /*| WS_THICKFRAME*/, CW_USEDEFAULT, CW_USEDEFAULT, 456, 400, NULL, NULL, GetModuleHandle(NULL), NULL); @@ -273,9 +259,6 @@ TReportResult report (const std::string &title, const std::string &header, const // create the font HFONT font = CreateFont (-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); - Subject = subject; - AttachedFile = attachedFile; - // create the edit control HWND edit = CreateWindowW (L"EDIT", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_READONLY | ES_LEFT | ES_MULTILINE, 7, 70, 429, 212, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); SendMessage (edit, WM_SETFONT, (WPARAM) font, TRUE); @@ -283,10 +266,10 @@ TReportResult report (const std::string &title, const std::string &header, const // set the edit text limit to lot of :) SendMessage (edit, EM_LIMITTEXT, ~0U, 0); - Body = addSlashR (body); + ReportBody = addSlashR(body); // set the message in the edit text - SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)Body.c_str()); + SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)ReportBody.c_str()); if (enableCheckIgnore) { @@ -336,8 +319,7 @@ TReportResult report (const std::string &title, const std::string &header, const } // ace don't do that because it s slow to try to send a mail - //CanSendMailReport = sendReportButton && EmailFunction != NULL && EmailFunction("", "", "", "", "", true); - CanSendMailReport = sendReportButton && EmailFunction != NULL; + CanSendMailReport = sendReportButton && !ReportPostUrl.empty(); if (CanSendMailReport) formatedHeader += " Send report will only email the contents of the box below. Please, send it to help us (it could take few minutes to send the email, be patient)."; From fc950e08e020ae7f3fa993f793ff34a38bde9c60 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 20:07:29 +0100 Subject: [PATCH 313/344] Move crash report web application to appropriate directory --HG-- branch : feature-crashreport --- .../crash_report}/config.inc.php | 0 .../crash_report}/log.inc.php | 0 .../crash_report/submit.php} | 0 code/web/rcerror_web/rcerror_test.htm | 19 ------------------- 4 files changed, 19 deletions(-) rename code/web/{rcerror_web => public_php/crash_report}/config.inc.php (100%) rename code/web/{rcerror_web => public_php/crash_report}/log.inc.php (100%) rename code/web/{rcerror_web/rcerror.php => public_php/crash_report/submit.php} (100%) delete mode 100644 code/web/rcerror_web/rcerror_test.htm diff --git a/code/web/rcerror_web/config.inc.php b/code/web/public_php/crash_report/config.inc.php similarity index 100% rename from code/web/rcerror_web/config.inc.php rename to code/web/public_php/crash_report/config.inc.php diff --git a/code/web/rcerror_web/log.inc.php b/code/web/public_php/crash_report/log.inc.php similarity index 100% rename from code/web/rcerror_web/log.inc.php rename to code/web/public_php/crash_report/log.inc.php diff --git a/code/web/rcerror_web/rcerror.php b/code/web/public_php/crash_report/submit.php similarity index 100% rename from code/web/rcerror_web/rcerror.php rename to code/web/public_php/crash_report/submit.php diff --git a/code/web/rcerror_web/rcerror_test.htm b/code/web/rcerror_web/rcerror_test.htm deleted file mode 100644 index eb314d3f7..000000000 --- a/code/web/rcerror_web/rcerror_test.htm +++ /dev/null @@ -1,19 +0,0 @@ - -Ryzom Core Error Report Web application test harness - -
    - - - - - - - - - -
    Description
    Report
    Email
    - -
    -
    - - From a548940b8c30276a0066581b279936798c46e5bf Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 20:09:51 +0100 Subject: [PATCH 314/344] Default window title --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 69ce40544..ca06d1077 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -110,7 +110,7 @@ static void doSendReport() // For FINAL_VERSION, simply launch the crash report and exit the application TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { - ReportWindowTitle = title; + ReportWindowTitle = title.empty() ? "Nel Crash Report" : title; ReportBody = addSlashR(body); doSendReport(); From 68120a53e7c6a6fcbcaeb997a6ef820f81265e2b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 23 Feb 2015 20:33:31 +0100 Subject: [PATCH 315/344] Only in FINAL_VERSION --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index ca06d1077..7323716e3 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -115,7 +115,7 @@ TReportResult report(const std::string &title, const std::string &header, const doSendReport(); -# if 1 // TODO: This behaviour is used in the old report code when Quitting the application is the default crash report behaviour. Needs testing. +# if defined(FINAL_VERSION) // TODO: This behaviour is used in the old report code when Quitting the application is the default crash report behaviour. Needs testing. # ifdef NL_OS_WINDOWS # ifndef NL_COMP_MINGW // disable the Windows popup telling that the application aborted and disable the dr watson report. From 02e8100ea4b77dea376d36f1ca21696f1288bfb6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 12:47:32 +0100 Subject: [PATCH 317/344] Fix sstream include --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 7323716e3..8c58234cf 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -16,7 +16,7 @@ #include "stdmisc.h" -#include +#include #include "nel/misc/common.h" #include "nel/misc/ucstring.h" From e2dcc3b0354825bc24556c799439a2e98549dd30 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 12:47:54 +0100 Subject: [PATCH 318/344] Categorize NLMISC project source files --HG-- branch : develop --- code/nel/src/misc/CMakeLists.txt | 170 +++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/code/nel/src/misc/CMakeLists.txt b/code/nel/src/misc/CMakeLists.txt index 2d3ef9066..f40517f5b 100644 --- a/code/nel/src/misc/CMakeLists.txt +++ b/code/nel/src/misc/CMakeLists.txt @@ -1,6 +1,176 @@ FILE(GLOB SRC *.cpp *.h config_file/*.cpp config_file/*.h) FILE(GLOB HEADERS ../../include/nel/misc/*.h) +FILE(GLOB NLMISC_CDB + cdb.cpp ../../include/nel/misc/cdb.h + cdb_*.cpp ../../include/nel/misc/cdb_*.h +) + +FILE(GLOB NLMISC_EVENT + events.cpp ../../include/nel/misc/events.h + event_*.cpp ../../include/nel/misc/event_*.h + *_event_*.cpp ../../include/nel/misc/*_event_*.h +) + +FILE(GLOB NLMISC_DEBUG + debug.cpp ../../include/nel/misc/debug.h + report.cpp ../../include/nel/misc/report.h + log.cpp ../../include/nel/misc/log.h +) + +FILE(GLOB NLMISC_FILESYSTEM + async_file_manager.cpp ../../include/nel/misc/async_file_manager.h + file.cpp ../../include/nel/misc/file.h + path.cpp ../../include/nel/misc/path.h + big_file.cpp ../../include/nel/misc/big_file.h + *_xml.cpp ../../include/nel/misc/*_xml.h + xml_*.cpp ../../include/nel/misc/xml_*.h +) + +FILE(GLOB NLMISC_STREAM + *_stream.cpp ../../include/nel/misc/*_stream.h + stream.cpp ../../include/nel/misc/stream.h + stream_*.cpp ../../include/nel/misc/stream_*.h +) + +FILE(GLOB NLMISC_DISPLAYER + displayer.cpp ../../include/nel/misc/displayer.h + *_displayer.cpp ../../include/nel/misc/*_displayer.h +) + +FILE(GLOB NLMISC_MATH + plane.cpp ../../include/nel/misc/plane.h + ../../include/nel/misc/plane_inline.h + polygon.cpp ../../include/nel/misc/polygon.h + quad.cpp ../../include/nel/misc/quad.h + quat.cpp ../../include/nel/misc/quat.h + rect.cpp ../../include/nel/misc/rect.h + rgba.cpp ../../include/nel/misc/rgba.h + triangle.cpp ../../include/nel/misc/triangle.h + uv.cpp ../../include/nel/misc/uv.h + vector*.cpp ../../include/nel/misc/vector*.h + aabbox.cpp ../../include/nel/misc/aabbox.h + algo.cpp ../../include/nel/misc/algo.h + bsphere.cpp ../../include/nel/misc/bsphere.h + fast_floor.cpp ../../include/nel/misc/fast_floor.h + geom_ext.cpp ../../include/nel/misc/geom_ext.h + line.cpp ../../include/nel/misc/line.h + matrix.cpp ../../include/nel/misc/matrix.h +) + +FILE(GLOB NLMISC_PLATFORM + *_nl.cpp ../../include/nel/misc/*_nl.h + common.cpp ../../include/nel/misc/common.h + app_context.cpp ../../include/nel/misc/app_context.h + check_fpu.cpp ../../include/nel/misc/check_fpu.h + cpu_time_stat.cpp ../../include/nel/misc/cpu_time_stat.h + dummy_window.cpp ../../include/nel/misc/dummy_window.h + dynloadlib.cpp ../../include/nel/misc/dynloadlib.h + fast_mem.cpp ../../include/nel/misc/fast_mem.h + inter_window_msg_queue.cpp ../../include/nel/misc/inter_window_msg_queue.h + system_*.cpp ../../include/nel/misc/system_*.h + win32_util.cpp ../../include/nel/misc/win32_util.h + win_tray.cpp ../../include/nel/misc/win_tray.h +) + +FILE(GLOB NLMISC_GENERIC + ../../include/nel/misc/array_2d.h + *_memory.cpp ../../include/nel/misc/*_memory.h + buf_fifo.cpp ../../include/nel/misc/buf_fifo.h + ../../include/nel/misc/callback.h + *_allocator.cpp ../../include/nel/misc/*_allocator.h + ../../include/nel/misc/enum_bitset.h + fast_id_map.cpp ../../include/nel/misc/fast_id_map.h + hierarchical_timer.cpp ../../include/nel/misc/hierarchical_timer.h + ../../include/nel/misc/historic.h + ../../include/nel/misc/mutable_container.h + ../../include/nel/misc/random.h + smart_ptr.cpp ../../include/nel/misc/smart_ptr.h + ../../include/nel/misc/smart_ptr_inline.h + ../../include/nel/misc/resource_ptr.h + ../../include/nel/misc/resource_ptr_inline.h + bit_set.cpp ../../include/nel/misc/bit_set.h + stop_watch.cpp ../../include/nel/misc/stop_watch.h + ../../include/nel/misc/twin_map.h + object_vector.cpp ../../include/nel/misc/object_vector.h + ../../include/nel/misc/singleton.h + speaker_listener.cpp ../../include/nel/misc/speaker_listener.h + ../../include/nel/misc/static_map.h + stl_block_list.cpp ../../include/nel/misc/stl_block_list.h +) + +FILE(GLOB NLMISC_UTILITY + config_file.cpp ../../include/nel/misc/config_file.h + cf_*.cpp ../../include/nel/misc/cf_*.h + config_file/config_file.cpp config_file/config_file.h + config_file/cf_*.cpp config_file/cf_*.h + class_id.cpp ../../include/nel/misc/class_id.h + class_registry.cpp ../../include/nel/misc/class_registry.h + cmd_args.cpp ../../include/nel/misc/cmd_args.h + command.cpp ../../include/nel/misc/command.h + eid_translator.cpp ../../include/nel/misc/eid_translator.h + entity_id.cpp ../../include/nel/misc/entity_id.h + eval_num_expr.cpp ../../include/nel/misc/eval_num_expr.h + factory.cpp ../../include/nel/misc/factory.h + grid_traversal.cpp ../../include/nel/misc/grid_traversal.h + mouse_smoother.cpp ../../include/nel/misc/mouse_smoother.h + noise_value.cpp ../../include/nel/misc/noise_value.h + progress_callback.cpp ../../include/nel/misc/progress_callback.h + sheet_id.cpp ../../include/nel/misc/sheet_id.h + variable.cpp ../../include/nel/misc/variable.h + value_smoother.cpp ../../include/nel/misc/value_smoother.h +) + +FILE(GLOB NLMISC_STRING + string_*.cpp ../../include/nel/misc/string_*.h + ../../include/nel/misc/ucstring.h + unicode.cpp + sstring.cpp ../../include/nel/misc/sstring.h +) + +FILE(GLOB NLMISC_I18N + diff_tool.cpp ../../include/nel/misc/diff_tool.h + i18n.cpp ../../include/nel/misc/i18n.h + words_dictionary.cpp ../../include/nel/misc/words_dictionary.h +) + +FILE(GLOB NLMISC_THREAD + co_task.cpp ../../include/nel/misc/co_task.h + mutex.cpp ../../include/nel/misc/mutex.h + *_thread.cpp ../../include/nel/misc/*_thread.h + task_*.cpp ../../include/nel/misc/task_*.h + reader_writer.cpp ../../include/nel/misc/reader_writer.h + tds.cpp ../../include/nel/misc/tds.h + thread.cpp ../../include/nel/misc/thread.h +) + +FILE(GLOB NLMISC_BITMAP + bitmap.cpp ../../include/nel/misc/bitmap.h + bitmap_*.cpp +) + +FILE(GLOB NLMISC_CRYPT + md5.cpp ../../include/nel/misc/md5.h + sha1.cpp ../../include/nel/misc/sha1.h +) + +SOURCE_GROUP("" FILES ${SRC} ${HEADERS}) +SOURCE_GROUP("cdb" FILES ${NLMISC_CDB}) +SOURCE_GROUP("event" FILES ${NLMISC_EVENT}) +SOURCE_GROUP("debug" FILES ${NLMISC_DEBUG}) +SOURCE_GROUP("platform" FILES ${NLMISC_PLATFORM}) +SOURCE_GROUP("filesystem" FILES ${NLMISC_FILESYSTEM}) +SOURCE_GROUP("stream" FILES ${NLMISC_STREAM}) +SOURCE_GROUP("displayer" FILES ${NLMISC_DISPLAYER}) +SOURCE_GROUP("math" FILES ${NLMISC_MATH}) +SOURCE_GROUP("generic" FILES ${NLMISC_GENERIC}) +SOURCE_GROUP("utility" FILES ${NLMISC_UTILITY}) +SOURCE_GROUP("bitmap" FILES ${NLMISC_BITMAP}) +SOURCE_GROUP("thread" FILES ${NLMISC_THREAD}) +SOURCE_GROUP("i18n" FILES ${NLMISC_I18N}) +SOURCE_GROUP("crypt" FILES ${NLMISC_CRYPT}) +SOURCE_GROUP("string" FILES ${NLMISC_STRING}) + NL_TARGET_LIB(nelmisc ${HEADERS} ${SRC}) IF(WITH_GTK) From e201c909379b8a70b24e16c6b3f45d9297178814 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 12:47:54 +0100 Subject: [PATCH 319/344] Remove redundant windows.h includes in NLMISC --HG-- branch : develop --- code/nel/include/nel/misc/dummy_window.h | 12 ++++++++++++ .../nel/include/nel/misc/inter_window_msg_queue.h | 12 ++++++++++++ code/nel/include/nel/misc/win_displayer.h | 12 ++++++++++-- code/nel/src/misc/co_task.cpp | 15 +-------------- code/nel/src/misc/common.cpp | 4 ---- code/nel/src/misc/log.cpp | 4 ---- code/nel/src/misc/mem_displayer.cpp | 4 ---- code/nel/src/misc/path.cpp | 4 ---- code/nel/src/misc/report.cpp | 4 ---- code/nel/src/misc/shared_memory.cpp | 7 +------ code/nel/src/misc/stdmisc.h | 1 + code/nel/src/misc/system_info.cpp | 4 ---- code/nel/src/misc/system_utils.cpp | 5 ----- code/nel/src/misc/time_nl.cpp | 7 +------ code/nel/src/misc/win32_util.cpp | 2 -- code/nel/src/misc/win_displayer.cpp | 4 ---- code/nel/src/misc/win_event_emitter.cpp | 4 ---- 17 files changed, 38 insertions(+), 67 deletions(-) diff --git a/code/nel/include/nel/misc/dummy_window.h b/code/nel/include/nel/misc/dummy_window.h index bd205f0a0..66d9345ba 100644 --- a/code/nel/include/nel/misc/dummy_window.h +++ b/code/nel/include/nel/misc/dummy_window.h @@ -22,6 +22,18 @@ #ifdef NL_OS_WINDOWS // for win32 os only +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#ifndef _WIN32_WINDOWS +# define _WIN32_WINDOWS 0x0410 +#endif +#ifndef WINVER +# define WINVER 0x0400 +#endif +#ifndef NOMINMAX +# define NOMINMAX +#endif #include diff --git a/code/nel/include/nel/misc/inter_window_msg_queue.h b/code/nel/include/nel/misc/inter_window_msg_queue.h index 02867f8b4..4ab5bef4e 100644 --- a/code/nel/include/nel/misc/inter_window_msg_queue.h +++ b/code/nel/include/nel/misc/inter_window_msg_queue.h @@ -27,6 +27,18 @@ #include "nel/misc/mem_stream.h" #include "nel/misc/dummy_window.h" +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#ifndef _WIN32_WINDOWS +# define _WIN32_WINDOWS 0x0410 +#endif +#ifndef WINVER +# define WINVER 0x0400 +#endif +#ifndef NOMINMAX +# define NOMINMAX +#endif #include namespace NLMISC diff --git a/code/nel/include/nel/misc/win_displayer.h b/code/nel/include/nel/misc/win_displayer.h index 934a6e990..f7a5e55e1 100644 --- a/code/nel/include/nel/misc/win_displayer.h +++ b/code/nel/include/nel/misc/win_displayer.h @@ -21,8 +21,16 @@ #ifdef NL_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#ifndef NL_COMP_MINGW +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#ifndef _WIN32_WINDOWS +# define _WIN32_WINDOWS 0x0410 +#endif +#ifndef WINVER +# define WINVER 0x0400 +#endif +#ifndef NOMINMAX # define NOMINMAX #endif #include diff --git a/code/nel/src/misc/co_task.cpp b/code/nel/src/misc/co_task.cpp index d238b4853..97a9e1e23 100644 --- a/code/nel/src/misc/co_task.cpp +++ b/code/nel/src/misc/co_task.cpp @@ -43,20 +43,7 @@ #else //NL_USE_THREAD_COTASK // some platform specifics #if defined (NL_OS_WINDOWS) -//# define _WIN32_WINNT 0x0500 -# define NL_WIN_CALLBACK CALLBACK -// Visual .NET won't allow Fibers for a Windows version older than 2000. However the basic features are sufficient for us, we want to compile them for all Windows >= 95 -# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400) -# ifdef _WIN32_WINNT -# undef _WIN32_WINNT -# endif -# define _WIN32_WINNT 0x0400 -# endif - -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include +# define NL_WIN_CALLBACK CALLBACK #elif defined (NL_OS_UNIX) # define NL_WIN_CALLBACK # include diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp index 31ad7edb0..e8bec1e92 100644 --- a/code/nel/src/misc/common.cpp +++ b/code/nel/src/misc/common.cpp @@ -20,10 +20,6 @@ #include "nel/misc/common.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include # include # include #elif defined NL_OS_UNIX diff --git a/code/nel/src/misc/log.cpp b/code/nel/src/misc/log.cpp index 478a5e338..f0e3e36f8 100644 --- a/code/nel/src/misc/log.cpp +++ b/code/nel/src/misc/log.cpp @@ -19,11 +19,7 @@ #include "nel/misc/log.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif # include -# include #else # include #endif diff --git a/code/nel/src/misc/mem_displayer.cpp b/code/nel/src/misc/mem_displayer.cpp index fc5681657..0aaac26cc 100644 --- a/code/nel/src/misc/mem_displayer.cpp +++ b/code/nel/src/misc/mem_displayer.cpp @@ -24,10 +24,6 @@ #include "nel/misc/debug.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include # include # pragma comment(lib, "imagehlp.lib") # ifdef NL_OS_WIN64 diff --git a/code/nel/src/misc/path.cpp b/code/nel/src/misc/path.cpp index f593f695d..71d57104a 100644 --- a/code/nel/src/misc/path.cpp +++ b/code/nel/src/misc/path.cpp @@ -25,10 +25,6 @@ #include "nel/misc/xml_pack.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include # include # include # include diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 20b2b1c11..15d8a8287 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -23,10 +23,6 @@ #include "nel/misc/path.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include # include # include #endif // NL_OS_WINDOWS diff --git a/code/nel/src/misc/shared_memory.cpp b/code/nel/src/misc/shared_memory.cpp index 7b11fea52..3afe795f1 100644 --- a/code/nel/src/misc/shared_memory.cpp +++ b/code/nel/src/misc/shared_memory.cpp @@ -19,12 +19,7 @@ #include "nel/misc/shared_memory.h" #include "nel/misc/debug.h" -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include -#else +#ifndef NL_OS_WINDOWS # include # include # include diff --git a/code/nel/src/misc/stdmisc.h b/code/nel/src/misc/stdmisc.h index 37284511c..186a0fccd 100644 --- a/code/nel/src/misc/stdmisc.h +++ b/code/nel/src/misc/stdmisc.h @@ -43,6 +43,7 @@ #include #ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN # define _WIN32_WINDOWS 0x0410 # ifndef NL_COMP_MINGW # define WINVER 0x0400 diff --git a/code/nel/src/misc/system_info.cpp b/code/nel/src/misc/system_info.cpp index 31cde5283..8524939c8 100644 --- a/code/nel/src/misc/system_info.cpp +++ b/code/nel/src/misc/system_info.cpp @@ -19,10 +19,6 @@ #include "nel/misc/system_info.h" #ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include # include # include # include diff --git a/code/nel/src/misc/system_utils.cpp b/code/nel/src/misc/system_utils.cpp index a66eed02f..f53f6822e 100644 --- a/code/nel/src/misc/system_utils.cpp +++ b/code/nel/src/misc/system_utils.cpp @@ -18,11 +18,6 @@ #include "nel/misc/system_utils.h" #ifdef NL_OS_WINDOWS - #ifndef NL_COMP_MINGW - #define NOMINMAX - #endif - #include - #ifdef _WIN32_WINNT_WIN7 // only supported by Windows 7 Platform SDK #include diff --git a/code/nel/src/misc/time_nl.cpp b/code/nel/src/misc/time_nl.cpp index 8aacbd002..821e4b397 100644 --- a/code/nel/src/misc/time_nl.cpp +++ b/code/nel/src/misc/time_nl.cpp @@ -20,12 +20,7 @@ #include "nel/misc/sstring.h" #include "nel/misc/thread.h" -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include -#elif defined (NL_OS_UNIX) +#if defined (NL_OS_UNIX) # include # include #endif diff --git a/code/nel/src/misc/win32_util.cpp b/code/nel/src/misc/win32_util.cpp index 63315e1b2..6085e98e5 100644 --- a/code/nel/src/misc/win32_util.cpp +++ b/code/nel/src/misc/win32_util.cpp @@ -20,8 +20,6 @@ #ifdef NL_OS_WINDOWS -#include - #ifdef DEBUG_NEW #define new DEBUG_NEW #endif diff --git a/code/nel/src/misc/win_displayer.cpp b/code/nel/src/misc/win_displayer.cpp index 95b6b34cf..a91f64b4d 100644 --- a/code/nel/src/misc/win_displayer.cpp +++ b/code/nel/src/misc/win_displayer.cpp @@ -18,10 +18,6 @@ #include "nel/misc/win_displayer.h" #ifdef NL_OS_WINDOWS -#ifndef NL_COMP_MINGW -# define NOMINMAX -#endif -#include #include #include #include diff --git a/code/nel/src/misc/win_event_emitter.cpp b/code/nel/src/misc/win_event_emitter.cpp index 01da89564..67e426f1e 100644 --- a/code/nel/src/misc/win_event_emitter.cpp +++ b/code/nel/src/misc/win_event_emitter.cpp @@ -22,10 +22,6 @@ #include "nel/misc/event_server.h" #ifdef NL_OS_WINDOWS -#ifndef NL_COMP_MINGW -#define NOMINMAX -#endif -#include #include /** From 50e11b05367e96934e650e13d65e00abcf7bce64 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 12:47:54 +0100 Subject: [PATCH 320/344] Add _WIN32_WINNT fallback define --HG-- branch : develop --- code/nel/include/nel/misc/dummy_window.h | 3 +++ code/nel/include/nel/misc/inter_window_msg_queue.h | 3 +++ code/nel/include/nel/misc/win_displayer.h | 3 +++ code/nel/src/misc/stdmisc.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/code/nel/include/nel/misc/dummy_window.h b/code/nel/include/nel/misc/dummy_window.h index 66d9345ba..81ef078f9 100644 --- a/code/nel/include/nel/misc/dummy_window.h +++ b/code/nel/include/nel/misc/dummy_window.h @@ -28,6 +28,9 @@ #ifndef _WIN32_WINDOWS # define _WIN32_WINDOWS 0x0410 #endif +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif #ifndef WINVER # define WINVER 0x0400 #endif diff --git a/code/nel/include/nel/misc/inter_window_msg_queue.h b/code/nel/include/nel/misc/inter_window_msg_queue.h index 4ab5bef4e..c23a52412 100644 --- a/code/nel/include/nel/misc/inter_window_msg_queue.h +++ b/code/nel/include/nel/misc/inter_window_msg_queue.h @@ -33,6 +33,9 @@ #ifndef _WIN32_WINDOWS # define _WIN32_WINDOWS 0x0410 #endif +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif #ifndef WINVER # define WINVER 0x0400 #endif diff --git a/code/nel/include/nel/misc/win_displayer.h b/code/nel/include/nel/misc/win_displayer.h index f7a5e55e1..b4a56178c 100644 --- a/code/nel/include/nel/misc/win_displayer.h +++ b/code/nel/include/nel/misc/win_displayer.h @@ -27,6 +27,9 @@ #ifndef _WIN32_WINDOWS # define _WIN32_WINDOWS 0x0410 #endif +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif #ifndef WINVER # define WINVER 0x0400 #endif diff --git a/code/nel/src/misc/stdmisc.h b/code/nel/src/misc/stdmisc.h index 186a0fccd..de7df693c 100644 --- a/code/nel/src/misc/stdmisc.h +++ b/code/nel/src/misc/stdmisc.h @@ -45,6 +45,9 @@ #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # define _WIN32_WINDOWS 0x0410 +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif # ifndef NL_COMP_MINGW # define WINVER 0x0400 # define NOMINMAX From d9dd425dc6e6f0c8843173dc67caee93c2ebba3d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 12:47:54 +0100 Subject: [PATCH 321/344] Cleanup Windows includes --HG-- branch : develop --- code/nel/src/misc/common.cpp | 1 + code/nel/src/misc/stdmisc.h | 6 ++++-- code/nel/src/misc/system_utils.cpp | 9 +++++---- code/nel/src/misc/time_nl.cpp | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp index e8bec1e92..671879f2e 100644 --- a/code/nel/src/misc/common.cpp +++ b/code/nel/src/misc/common.cpp @@ -20,6 +20,7 @@ #include "nel/misc/common.h" #ifdef NL_OS_WINDOWS +# include # include # include #elif defined NL_OS_UNIX diff --git a/code/nel/src/misc/stdmisc.h b/code/nel/src/misc/stdmisc.h index de7df693c..b24a74616 100644 --- a/code/nel/src/misc/stdmisc.h +++ b/code/nel/src/misc/stdmisc.h @@ -42,7 +42,9 @@ #include #include -#ifdef _WIN32 +#include + +#ifdef NL_OS_WINDOWS # define WIN32_LEAN_AND_MEAN # define _WIN32_WINDOWS 0x0410 # ifndef _WIN32_WINNT @@ -53,7 +55,7 @@ # define NOMINMAX # endif # include -# include +# include #endif #endif // NL_STDMISC_H diff --git a/code/nel/src/misc/system_utils.cpp b/code/nel/src/misc/system_utils.cpp index f53f6822e..e298f941c 100644 --- a/code/nel/src/misc/system_utils.cpp +++ b/code/nel/src/misc/system_utils.cpp @@ -18,11 +18,12 @@ #include "nel/misc/system_utils.h" #ifdef NL_OS_WINDOWS - #ifdef _WIN32_WINNT_WIN7 +# include +# ifdef _WIN32_WINNT_WIN7 // only supported by Windows 7 Platform SDK - #include - #define TASKBAR_PROGRESS 1 - #endif +# include +# define TASKBAR_PROGRESS 1 +# endif #endif #ifdef DEBUG_NEW diff --git a/code/nel/src/misc/time_nl.cpp b/code/nel/src/misc/time_nl.cpp index 821e4b397..70b7b3807 100644 --- a/code/nel/src/misc/time_nl.cpp +++ b/code/nel/src/misc/time_nl.cpp @@ -20,7 +20,9 @@ #include "nel/misc/sstring.h" #include "nel/misc/thread.h" -#if defined (NL_OS_UNIX) +#ifdef NL_OS_WINDOWS +# include +#elif defined (NL_OS_UNIX) # include # include #endif From 54ae2da0a62882a64b4814a7cc8c04326043125c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:17:45 +0100 Subject: [PATCH 323/344] Fix _MSC_VER typo --HG-- branch : develop --- code/nel/include/nel/misc/types_nl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h index 7091f4905..cd733d732 100644 --- a/code/nel/include/nel/misc/types_nl.h +++ b/code/nel/include/nel/misc/types_nl.h @@ -53,7 +53,7 @@ # endif # ifdef _MSC_VER # define NL_COMP_VC -# if _MSC_VER >= 1700 +# if _MSC_VER >= 1800 # define NL_COMP_VC12 # define NL_COMP_VC_VERSION 120 # elif _MSC_VER >= 1700 From cb52c7ee7e4c22e4189763a20c9d56dc73c1c966 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:17:45 +0100 Subject: [PATCH 324/344] Use ULL suffix for unsigned 64bit integer constants with Visual Studio 2013 --HG-- branch : develop --- code/nel/include/nel/misc/types_nl.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h index cd733d732..2461cb5e6 100644 --- a/code/nel/include/nel/misc/types_nl.h +++ b/code/nel/include/nel/misc/types_nl.h @@ -463,7 +463,11 @@ typedef uint16 ucchar; // To define a 64bits constant; ie: UINT64_CONSTANT(0x123456781234) #ifdef NL_COMP_VC -# if (NL_COMP_VC_VERSION >= 80) +# if (NL_COMP_VC_VERSION >= 120) +# define INT64_CONSTANT(c) (c##LL) +# define SINT64_CONSTANT(c) (c##LL) +# define UINT64_CONSTANT(c) (c##ULL) +# elif (NL_COMP_VC_VERSION >= 80) # define INT64_CONSTANT(c) (c##LL) # define SINT64_CONSTANT(c) (c##LL) # define UINT64_CONSTANT(c) (c##LL) From a66204a03a615d7735e314b5712749abc48c42f3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:17:45 +0100 Subject: [PATCH 325/344] Add isWindowedApplication to INeLContext --HG-- branch : develop --- code/nel/include/nel/misc/app_context.h | 7 +++++++ code/nel/include/nel/misc/gtk_displayer.h | 6 +----- code/nel/include/nel/misc/win_displayer.h | 6 +----- code/nel/src/misc/app_context.cpp | 21 +++++++++++++++++++ code/nel/src/misc/debug.cpp | 5 +++++ code/nel/src/misc/gtk_displayer.cpp | 9 ++++++++ code/nel/src/misc/win_displayer.cpp | 8 +++++++ code/ryzom/client/src/client.cpp | 2 ++ .../client/src/snowballs_client.cpp | 1 + 9 files changed, 55 insertions(+), 10 deletions(-) diff --git a/code/nel/include/nel/misc/app_context.h b/code/nel/include/nel/misc/app_context.h index 46d2a15c7..df9165baf 100644 --- a/code/nel/include/nel/misc/app_context.h +++ b/code/nel/include/nel/misc/app_context.h @@ -88,6 +88,8 @@ namespace NLMISC virtual void setNoAssert(bool noAssert) =0; virtual bool getAlreadyCreateSharedAmongThreads() =0; virtual void setAlreadyCreateSharedAmongThreads(bool b) =0; + virtual bool isWindowedApplication() = 0; + virtual void setWindowedApplication(bool b = true) = 0; //@} protected: /// Called by derived class to finalize initialisation of context @@ -131,6 +133,8 @@ namespace NLMISC virtual void setNoAssert(bool noAssert); virtual bool getAlreadyCreateSharedAmongThreads(); virtual void setAlreadyCreateSharedAmongThreads(bool b); + virtual bool isWindowedApplication(); + virtual void setWindowedApplication(bool b); private: /// Singleton registry @@ -147,6 +151,7 @@ namespace NLMISC bool DebugNeedAssert; bool NoAssert; bool AlreadyCreateSharedAmongThreads; + bool WindowedApplication; }; /** This class implements the context interface for the a library module. @@ -183,6 +188,8 @@ namespace NLMISC virtual void setNoAssert(bool noAssert); virtual bool getAlreadyCreateSharedAmongThreads(); virtual void setAlreadyCreateSharedAmongThreads(bool b); + virtual bool isWindowedApplication(); + virtual void setWindowedApplication(bool b); private: /// Pointer to the application context. diff --git a/code/nel/include/nel/misc/gtk_displayer.h b/code/nel/include/nel/misc/gtk_displayer.h index 88dd3acc8..e2d35c83c 100644 --- a/code/nel/include/nel/misc/gtk_displayer.h +++ b/code/nel/include/nel/misc/gtk_displayer.h @@ -42,11 +42,7 @@ class CGtkDisplayer : public NLMISC::CWindowDisplayer { public: - CGtkDisplayer (const char *displayerName = "") : CWindowDisplayer(displayerName) - { - needSlashR = false; - createLabel ("@Clear|CLEAR"); - } + CGtkDisplayer (const char *displayerName = ""); virtual ~CGtkDisplayer (); diff --git a/code/nel/include/nel/misc/win_displayer.h b/code/nel/include/nel/misc/win_displayer.h index b4a56178c..f450055a9 100644 --- a/code/nel/include/nel/misc/win_displayer.h +++ b/code/nel/include/nel/misc/win_displayer.h @@ -57,11 +57,7 @@ class CWinDisplayer : public NLMISC::CWindowDisplayer { public: - CWinDisplayer (const char *displayerName = "") : CWindowDisplayer(displayerName), Exit(false) - { - needSlashR = true; - createLabel ("@Clear|CLEAR"); - } + CWinDisplayer(const char *displayerName = ""); virtual ~CWinDisplayer (); diff --git a/code/nel/src/misc/app_context.cpp b/code/nel/src/misc/app_context.cpp index 32b981bb3..2383fcda5 100644 --- a/code/nel/src/misc/app_context.cpp +++ b/code/nel/src/misc/app_context.cpp @@ -114,6 +114,7 @@ CApplicationContext::CApplicationContext() DebugNeedAssert = false; NoAssert = false; AlreadyCreateSharedAmongThreads = false; + WindowedApplication = false; contextReady(); } @@ -242,6 +243,16 @@ void CApplicationContext::setAlreadyCreateSharedAmongThreads(bool b) AlreadyCreateSharedAmongThreads = b; } +bool CApplicationContext::isWindowedApplication() +{ + return WindowedApplication; +} + +void CApplicationContext::setWindowedApplication(bool b) +{ + WindowedApplication = b; +} + CLibraryContext::CLibraryContext(INelContext &applicationContext) : _ApplicationContext(&applicationContext) { @@ -430,6 +441,16 @@ void CLibraryContext::setAlreadyCreateSharedAmongThreads(bool b) _ApplicationContext->setAlreadyCreateSharedAmongThreads(b); } +bool CLibraryContext::isWindowedApplication() +{ + return _ApplicationContext->isWindowedApplication(); +} + +void CLibraryContext::setWindowedApplication(bool b) +{ + _ApplicationContext->setWindowedApplication(b); +} + void initNelLibrary(NLMISC::CLibrary &lib) { nlassert(lib.isLibraryLoaded()); diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 2a9c5282a..01aa148dc 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -1222,6 +1222,11 @@ void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) #endif // LOG_IN_FILE DefaultMemDisplayer = new CMemDisplayer ("DEFAULT_MD"); +#ifdef NL_OS_WINDOWS + if (GetConsoleWindow() == NULL) + INelContext::getInstance().setWindowedApplication(true); +#endif + initDebug2(logInFile); INelContext::getInstance().setAlreadyCreateSharedAmongThreads(true); diff --git a/code/nel/src/misc/gtk_displayer.cpp b/code/nel/src/misc/gtk_displayer.cpp index c2e04e67e..0c581b2e5 100644 --- a/code/nel/src/misc/gtk_displayer.cpp +++ b/code/nel/src/misc/gtk_displayer.cpp @@ -32,6 +32,7 @@ #pragma comment(lib, "gthread-1.3.lib") #endif +#include "nel/misc/app_context.h" #include "nel/misc/path.h" #include "nel/misc/command.h" #include "nel/misc/thread.h" @@ -59,6 +60,14 @@ static GtkWidget *hrootbox = NULL, *scrolled_win2 = NULL; // Functions // +CGtkDisplayer (const char *displayerName) : CWindowDisplayer(displayerName) +{ + needSlashR = false; + createLabel ("@Clear|CLEAR"); + + INelContext::getInstance().setWindowedApplication(true); +} + CGtkDisplayer::~CGtkDisplayer () { if (_Init) diff --git a/code/nel/src/misc/win_displayer.cpp b/code/nel/src/misc/win_displayer.cpp index a91f64b4d..5da7db65b 100644 --- a/code/nel/src/misc/win_displayer.cpp +++ b/code/nel/src/misc/win_displayer.cpp @@ -26,6 +26,7 @@ #include #include +#include "nel/misc/app_context.h" #include "nel/misc/path.h" #include "nel/misc/command.h" #include "nel/misc/thread.h" @@ -41,6 +42,13 @@ namespace NLMISC { static CHARFORMAT2 CharFormat; +CWinDisplayer::CWinDisplayer(const char *displayerName) : CWindowDisplayer(displayerName), Exit(false) +{ + needSlashR = true; + createLabel("@Clear|CLEAR"); + + INelContext::getInstance().setWindowedApplication(true); +} CWinDisplayer::~CWinDisplayer () { diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index fb6e2dca5..1b4285dd5 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -365,6 +365,8 @@ int main(int argc, char **argv) createDebug(); + INelContext::getInstance().setWindowedApplication(true); + #ifndef NL_DEBUG INelContext::getInstance().getDebugLog()->removeDisplayer("DEFAULT_SD"); INelContext::getInstance().getInfoLog()->removeDisplayer("DEFAULT_SD"); diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 7e019412b..059960922 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -1264,6 +1264,7 @@ sint main(int argc, char **argv) { // use log.log if NEL_LOG_IN_FILE and SBCLIENT_USE_LOG_LOG defined as 1 createDebug(NULL, SBCLIENT_USE_LOG_LOG, false); + INelContext::getInstance().setWindowedApplication(true); #if SBCLIENT_USE_LOG // create snowballs_client.log From 72475cf7194e8f9c288f3428ca9c68927855c484 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:17:45 +0100 Subject: [PATCH 326/344] Fix FindLibOVR cmake script --HG-- branch : develop --- code/CMakeModules/FindLibOVR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/CMakeModules/FindLibOVR.cmake b/code/CMakeModules/FindLibOVR.cmake index 1403a4b2c..707949613 100644 --- a/code/CMakeModules/FindLibOVR.cmake +++ b/code/CMakeModules/FindLibOVR.cmake @@ -38,7 +38,7 @@ ELSEIF(WIN32) ENDIF(UNIX) FIND_LIBRARY(LIBOVR_LIBRARY - NAMES ovr + NAMES ovr libovr PATHS $ENV{LIBOVR_DIR}/${LIBOVR_LIBRARY_BUILD_PATH} /usr/local/lib From c5ec0a9223c87d7f64af6fc7753d51f011df0eec Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:18:26 +0100 Subject: [PATCH 327/344] Qt5 compile settings for crash report tool --HG-- branch : feature-crashreport+qt5 --- code/nel/tools/misc/CMakeLists.txt | 4 +- .../tools/misc/crash_report/CMakeLists.txt | 72 +++++++++++++------ 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/code/nel/tools/misc/CMakeLists.txt b/code/nel/tools/misc/CMakeLists.txt index c9bbcd058..f7f1b9a39 100644 --- a/code/nel/tools/misc/CMakeLists.txt +++ b/code/nel/tools/misc/CMakeLists.txt @@ -3,8 +3,10 @@ SUBDIRS(bnp_make disp_sheet_id extract_filename lock make_sheet_id xml_packer) IF(WITH_QT) ADD_SUBDIRECTORY(words_dic_qt) ADD_SUBDIRECTORY(message_box_qt) - ADD_SUBDIRECTORY(crash_report) ENDIF(WITH_QT) +IF(WITH_QT OR WITH_QT5) + ADD_SUBDIRECTORY(crash_report) +ENDIF(WITH_QT OR WITH_QT5) IF(WIN32) ADD_SUBDIRECTORY(exec_timeout) diff --git a/code/nel/tools/misc/crash_report/CMakeLists.txt b/code/nel/tools/misc/crash_report/CMakeLists.txt index 0e2d2a9bc..fe063f6d0 100644 --- a/code/nel/tools/misc/crash_report/CMakeLists.txt +++ b/code/nel/tools/misc/crash_report/CMakeLists.txt @@ -1,39 +1,65 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SRC_DIR} ${QT_INCLUDES}) FILE(GLOB CRASHREPORT_SRC *.cpp) -FILE(GLOB CRASHREPORT_HDR *h) +FILE(GLOB CRASHREPORT_HDR *.h) +FILE(GLOB CRASHREPORT_UI *.ui) -SET(CRASHREPORT_MOC_HDR -crash_report_socket.h -crash_report_widget.h +FILE(GLOB CRASHREPORT_MOC_HDR + crash_report_socket.h + crash_report_widget.h ) -SET(CRASHREPORT_UI -crash_report_widget.ui -) +find_package(Qt5Network) -SET(QT_USE_QTGUI TRUE) -SET(QT_USE_QTNETWORK TRUE) -SET(QT_USE_QTMAIN TRUE) -SET(QT_USE_QTOPENGL FALSE) -SET(QT_USE_QTXML FALSE) +IF(!WITH_QT5) + SET(QT_USE_QTGUI TRUE) + SET(QT_USE_QTNETWORK TRUE) + SET(QT_USE_QTMAIN TRUE) + SET(QT_USE_QTOPENGL FALSE) + SET(QT_USE_QTXML FALSE) + INCLUDE(${QT_USE_FILE}) +ENDIF(!WITH_QT5) -INCLUDE(${QT_USE_FILE}) ADD_DEFINITIONS(${QT_DEFINITIONS}) -QT4_WRAP_CPP(CRASHREPORT_MOC_SRC ${CRASHREPORT_MOC_HDR}) -QT4_WRAP_UI(CRASHREPORT_UI_HDR ${CRASHREPORT_UI}) +IF(WITH_QT5) + SET(CMAKE_AUTOMOC ON) + QT5_WRAP_CPP(CRASHREPORT_MOC_SRC ${CRASHREPORT_MOC_HDR}) + QT5_WRAP_UI(CRASHREPORT_UI_HDR ${CRASHREPORT_UI}) +ELSE(WITH_QT5) + QT4_WRAP_CPP(CRASHREPORT_MOC_SRC ${CRASHREPORT_MOC_HDR}) + QT4_WRAP_UI(CRASHREPORT_UI_HDR ${CRASHREPORT_UI}) +ENDIF(WITH_QT5) + +SOURCE_GROUP(resources FILES ${CRASHREPORT_UI}) +IF(!WITH_QT5) + SOURCE_GROUP(generated FILES ${CRASHREPORT_UI_HDR} ${CRASHREPORT_MOC_SRC}) +ENDIF(!WITH_QT5) +SOURCE_GROUP("" FILES ${CRASHREPORT_SRC} ${CRASHREPORT_HDR}) -SOURCE_GROUP(QtResources FILES ${CRASHREPORT_UI}) -SOURCE_GROUP(QtGeneratedUiHdr FILES ${CRASHREPORT_UI_HDR}) -SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${CRASHREPORT_MOC_SRC}) -SOURCE_GROUP("source files" FILES ${CRASHREPORT_SRC}) -SOURCE_GROUP("header files" FILES ${CRASHREPORT_HDR}) +IF(WITH_QT5) + ADD_EXECUTABLE(crash_report WIN32 MACOSX_BUNDLE + ${CRASHREPORT_SRC} + ${CRASHREPORT_HDR} + ${CRASHREPORT_UI} + ) +ELSE(WITH_QT5) + ADD_EXECUTABLE(crash_report WIN32 MACOSX_BUNDLE + ${CRASHREPORT_SRC} + ${CRASHREPORT_MOC_HDR} + ${CRASHREPORT_MOC_SRC} + ${CRASHREPORT_UI_HDR} + ) +ENDIF(WITH_QT5) -ADD_EXECUTABLE(crash_report WIN32 MACOSX_BUNDLE ${CRASHREPORT_SRC} ${CRASHREPORT_MOC_HDR} ${CRASHREPORT_MOC_SRC} ${CRASHREPORT_UI_HDR}) -TARGET_LINK_LIBRARIES(crash_report ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) +IF(WITH_QT5) + TARGET_LINK_LIBRARIES(crash_report + Qt5::Widgets + Qt5::Network) +ELSE(WITH_QT5) + TARGET_LINK_LIBRARIES(crash_report ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY}) +ENDIF(WITH_QT5) NL_DEFAULT_PROPS(crash_report "NeL, Tools, Misc: Crash Report") NL_ADD_RUNTIME_FLAGS(crash_report) INSTALL(TARGETS crash_report RUNTIME DESTINATION ${NL_BIN_PREFIX}) - From 826907c8ddae52451398c4daff421f673e93d419 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 24 Feb 2015 17:18:48 +0100 Subject: [PATCH 328/344] Qt5 compile fix for crash report tool --HG-- branch : feature-crashreport --- .../misc/crash_report/crash_report_socket.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_socket.cpp b/code/nel/tools/misc/crash_report/crash_report_socket.cpp index 5f8720e05..f2a14e84b 100644 --- a/code/nel/tools/misc/crash_report/crash_report_socket.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_socket.cpp @@ -21,6 +21,9 @@ #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +# include +#endif class CCrashReportSocketPvt { @@ -43,16 +46,26 @@ CCrashReportSocket::~CCrashReportSocket() void CCrashReportSocket::sendReport( const SCrashReportData &data ) { +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QUrlQuery params; +#else QUrl params; +#endif params.addQueryItem( "report", data.report ); params.addQueryItem( "descr", data.description ); - params.addQueryItem( "email", data.email ); + params.addQueryItem("email", data.email); QUrl url( m_url ); QNetworkRequest request( url ); request.setRawHeader( "Connection", "close" ); - m_pvt->mgr.post( request, params.encodedQuery() ); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QByteArray postData = params.query(QUrl::FullyEncoded).toUtf8(); +#else + QByteArray postData = params.encodedQuery(); +#endif + + m_pvt->mgr.post(request, postData); } void CCrashReportSocket::onFinished( QNetworkReply *reply ) From 9d92e2d0d3ae191bcc9431a86dd8c002ea9a1f9b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Mar 2015 19:52:39 +0100 Subject: [PATCH 329/344] GUI changes as per requested by Kaetemi. --HG-- branch : feature-crashreport --- .../misc/crash_report/crash_report_widget.cpp | 74 ++++++++++++++++++- .../misc/crash_report/crash_report_widget.h | 8 ++ .../misc/crash_report/crash_report_widget.ui | 38 +++------- 3 files changed, 91 insertions(+), 29 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 968978f94..889606d99 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -25,18 +25,21 @@ #include #include #include +#include +#include CCrashReportWidget::CCrashReportWidget( QWidget *parent ) : QWidget( parent ) { + m_developerMode = false; + m_forceSend = false; + m_ui.setupUi( this ); m_socket = new CCrashReportSocket( this ); QTimer::singleShot( 1, this, SLOT( onLoad() ) ); - connect( m_ui.sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); - connect( m_ui.canceButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.emailCB, SIGNAL( stateChanged( int ) ), this, SLOT( onCBClicked() ) ); connect( m_socket, SIGNAL( reportSent() ), this, SLOT( onReportSent() ) ); @@ -70,11 +73,60 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: { setWindowTitle( v.c_str() ); } + else + if( k == "dev" ) + { + m_developerMode = true; + } + else + if( k == "sendreport" ) + { + m_forceSend = true; + } + } + + QHBoxLayout *hbl = new QHBoxLayout( this ); + + if( m_developerMode ) + { + QPushButton *alwaysIgnoreButton = new QPushButton( tr( "Always Ignore" ), this ); + QPushButton *ignoreButton = new QPushButton( tr( "Ignore" ), this ); + QPushButton *abortButton = new QPushButton( tr( "Abort" ), this ); + QPushButton *breakButton = new QPushButton( tr( "Break" ), this ); + + hbl->addWidget( alwaysIgnoreButton ); + hbl->addWidget( ignoreButton ); + hbl->addWidget( abortButton ); + hbl->addWidget( breakButton ); + + m_ui.gridLayout->addLayout( hbl, 6, 0, 1, 3 ); + + connect( alwaysIgnoreButton, SIGNAL( clicked( bool ) ), this, SLOT( onAlwaysIgnoreClicked() ) ); + connect( ignoreButton, SIGNAL( clicked( bool ) ), this, SLOT( onIgnoreClicked() ) ); + connect( abortButton, SIGNAL( clicked( bool ) ), this, SLOT( onAbortClicked() ) ); + connect( breakButton, SIGNAL( clicked( bool ) ), this, SLOT( onBreakClicked() ) ); + } + else + { + QPushButton *sendButton = new QPushButton( tr( "Send report" ), this ); + connect( sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); + hbl->addWidget( sendButton ); + + if( !m_forceSend ) + { + QPushButton *cancelButton = new QPushButton( tr( "Don't send report" ), this ); + connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + hbl->addWidget( cancelButton ); + } + + m_ui.gridLayout->addLayout( hbl, 6, 0, 1, 3 ); } } void CCrashReportWidget::onLoad() { + return; + if( !checkSettings() ) { close(); @@ -99,7 +151,6 @@ void CCrashReportWidget::onLoad() void CCrashReportWidget::onSendClicked() { - m_ui.sendButton->setEnabled( false ); QApplication::setOverrideCursor( Qt::WaitCursor ); SCrashReportData data; @@ -120,6 +171,23 @@ void CCrashReportWidget::onCBClicked() m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } +void CCrashReportWidget::onAlwaysIgnoreClicked() +{ +} + +void CCrashReportWidget::onIgnoreClicked() +{ +} + +void CCrashReportWidget::onAbortClicked() +{ +} + +void CCrashReportWidget::onBreakClicked() +{ +} + + void CCrashReportWidget::onReportSent() { QApplication::setOverrideCursor( Qt::ArrowCursor ); diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index 61b56e340..b0039e0e2 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -43,6 +43,11 @@ private Q_SLOTS: void onSendClicked(); void onCancelClicked(); void onCBClicked(); + + void onAlwaysIgnoreClicked(); + void onIgnoreClicked(); + void onAbortClicked(); + void onBreakClicked(); void onReportSent(); void onReportFailed(); @@ -54,6 +59,9 @@ private: Ui::CrashReportWidget m_ui; QString m_fileName; CCrashReportSocket *m_socket; + bool m_developerMode; + bool m_forceSend; + }; #endif diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.ui b/code/nel/tools/misc/crash_report/crash_report_widget.ui index 589810578..ed252eb07 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.ui +++ b/code/nel/tools/misc/crash_report/crash_report_widget.ui @@ -9,8 +9,8 @@ 0 0 - 400 - 407 + 406 + 430 @@ -24,9 +24,6 @@
    - - - @@ -34,24 +31,17 @@ - - - - true - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - + + - + Email me if you have further questions, or updates on this issue - + false @@ -61,17 +51,13 @@ - - - - Send + + + + true - - - - - - Cancel + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From d6662403438d22b79cfdd8ae6fb4f4fada172d1f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Mar 2015 20:12:09 +0100 Subject: [PATCH 330/344] Added return codes as requested. --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report.cpp | 8 +++++++- .../tools/misc/crash_report/crash_report_widget.cpp | 8 ++++++++ .../tools/misc/crash_report/crash_report_widget.h | 13 +++++++++++++ code/ryzom/client/src/init.cpp | 2 ++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index e083de126..0c9e4fc93 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -88,5 +88,11 @@ int main( int argc, char **argv ) w.setup( params ); w.show(); - return app.exec(); + int ret = app.exec(); + + if( ret != EXIT_SUCCESS ) + return ret; + else + return w.getReturnValue(); + } \ No newline at end of file diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 889606d99..609c58562 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -173,18 +173,26 @@ void CCrashReportWidget::onCBClicked() void CCrashReportWidget::onAlwaysIgnoreClicked() { + m_returnValue = ERET_ALWAYS_IGNORE; + close(); } void CCrashReportWidget::onIgnoreClicked() { + m_returnValue = ERET_IGNORE; + close(); } void CCrashReportWidget::onAbortClicked() { + m_returnValue = ERET_ABORT; + close(); } void CCrashReportWidget::onBreakClicked() { + m_returnValue = ERET_BREAK; + close(); } diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index b0039e0e2..db3d85b47 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -31,12 +31,24 @@ class CCrashReportWidget : public QWidget { Q_OBJECT public: + + enum EReturnValue + { + ERET_NULL = 0, + ERET_ALWAYS_IGNORE = 21, + ERET_IGNORE = 22, + ERET_ABORT = 23, + ERET_BREAK = 24 + }; + CCrashReportWidget( QWidget *parent = NULL ); ~CCrashReportWidget(); void setFileName( const char *fn ){ m_fileName = fn; } void setup( const std::vector< std::pair< std::string, std::string > > ¶ms ); + + EReturnValue getReturnValue() const{ return m_returnValue; } private Q_SLOTS: void onLoad(); @@ -62,6 +74,7 @@ private: bool m_developerMode; bool m_forceSend; + EReturnValue m_returnValue; }; #endif diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index f0fd40dae..2ffc6e8e0 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -538,6 +538,8 @@ void checkDriverVersion() void checkDriverDepth () { + nlassert( false ); + // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From 374d966069911a3daf60f551937aed308aac9173 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Mar 2015 21:06:01 +0100 Subject: [PATCH 331/344] Some more GUI changes. --HG-- branch : feature-crashreport --- .../misc/crash_report/crash_report_widget.cpp | 98 ++++++++++++------- .../misc/crash_report/crash_report_widget.h | 4 +- .../misc/crash_report/crash_report_widget.ui | 4 +- 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 609c58562..350a35ff8 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -27,6 +27,7 @@ #include #include #include +#include CCrashReportWidget::CCrashReportWidget( QWidget *parent ) : QWidget( parent ) @@ -85,10 +86,38 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: } } + if( m_fileName.isEmpty() ) + { + m_ui.reportLabel->hide(); + m_ui.reportEdit->hide(); + } + + // When no -host specified no custom entry and email fields + if( m_socket->url().isEmpty() ) + { + m_ui.descriptionEdit->hide(); + m_ui.emailCB->hide(); + m_ui.emailEdit->hide(); + m_ui.descrLabel->hide(); + } + QHBoxLayout *hbl = new QHBoxLayout( this ); if( m_developerMode ) { + if( !m_socket->url().isEmpty() ) + { + m_ui.emailCB->setEnabled( false ); + + QCheckBox *cb = new QCheckBox( tr( "Send report" ), this ); + m_ui.gridLayout->addWidget( cb, 4, 0, 1, 1 ); + + m_ui.gridLayout->addWidget( m_ui.emailCB, 5, 0, 1, 1 ); + m_ui.gridLayout->addWidget( m_ui.emailEdit, 6, 0, 1, 1 ); + + connect( cb, SIGNAL( stateChanged( int ) ), this, SLOT( onSendCBClicked() ) ); + } + QPushButton *alwaysIgnoreButton = new QPushButton( tr( "Always Ignore" ), this ); QPushButton *ignoreButton = new QPushButton( tr( "Ignore" ), this ); QPushButton *abortButton = new QPushButton( tr( "Abort" ), this ); @@ -99,7 +128,7 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: hbl->addWidget( abortButton ); hbl->addWidget( breakButton ); - m_ui.gridLayout->addLayout( hbl, 6, 0, 1, 3 ); + m_ui.gridLayout->addLayout( hbl, 7, 0, 1, 3 ); connect( alwaysIgnoreButton, SIGNAL( clicked( bool ) ), this, SLOT( onAlwaysIgnoreClicked() ) ); connect( ignoreButton, SIGNAL( clicked( bool ) ), this, SLOT( onIgnoreClicked() ) ); @@ -108,15 +137,26 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: } else { - QPushButton *sendButton = new QPushButton( tr( "Send report" ), this ); - connect( sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); - hbl->addWidget( sendButton ); - - if( !m_forceSend ) + // If -host is specified, offer the send function + if( !m_socket->url().isEmpty() ) { - QPushButton *cancelButton = new QPushButton( tr( "Don't send report" ), this ); - connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); - hbl->addWidget( cancelButton ); + QPushButton *sendButton = new QPushButton( tr( "Send report" ), this ); + connect( sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); + hbl->addWidget( sendButton ); + + if( !m_forceSend ) + { + QPushButton *cancelButton = new QPushButton( tr( "Don't send report" ), this ); + connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + hbl->addWidget( cancelButton ); + } + } + // Otherwise only offer exit + else + { + QPushButton *exitButton = new QPushButton( tr( "Exit" ), this ); + connect( exitButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + hbl->addWidget( exitButton ); } m_ui.gridLayout->addLayout( hbl, 6, 0, 1, 3 ); @@ -125,13 +165,8 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: void CCrashReportWidget::onLoad() { - return; - - if( !checkSettings() ) - { - close(); + if( m_fileName.isEmpty() ) return; - } QFile f( m_fileName ); bool b = f.open( QFile::ReadOnly | QFile::Text ); @@ -171,6 +206,18 @@ void CCrashReportWidget::onCBClicked() m_ui.emailEdit->setEnabled( m_ui.emailCB->isChecked() ); } +void CCrashReportWidget::onSendCBClicked() +{ + bool b = m_ui.emailCB->isEnabled(); + + if( b ) + { + m_ui.emailCB->setChecked( false ); + } + + m_ui.emailCB->setEnabled( !b ); +} + void CCrashReportWidget::onAlwaysIgnoreClicked() { m_returnValue = ERET_ALWAYS_IGNORE; @@ -218,27 +265,6 @@ void CCrashReportWidget::onReportFailed() removeAndQuit(); } -bool CCrashReportWidget::checkSettings() -{ - if( m_fileName.isEmpty() ) - { - QMessageBox::information( this, - tr( "No log file specified." ), - tr( "No log file specified. Exiting..." ) ); - return false; - } - - if( m_socket->url().isEmpty() ) - { - QMessageBox::information( this, - tr( "No host specified." ), - tr( "No host specified. Exiting..." ) ); - return false; - } - - return true; -} - void CCrashReportWidget::removeAndQuit() { QFile::remove( m_fileName ); diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index db3d85b47..a0468a565 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -49,12 +49,13 @@ public: void setup( const std::vector< std::pair< std::string, std::string > > ¶ms ); EReturnValue getReturnValue() const{ return m_returnValue; } - + private Q_SLOTS: void onLoad(); void onSendClicked(); void onCancelClicked(); void onCBClicked(); + void onSendCBClicked(); void onAlwaysIgnoreClicked(); void onIgnoreClicked(); @@ -65,7 +66,6 @@ private Q_SLOTS: void onReportFailed(); private: - bool checkSettings(); void removeAndQuit(); Ui::CrashReportWidget m_ui; diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.ui b/code/nel/tools/misc/crash_report/crash_report_widget.ui index ed252eb07..dec7e74ca 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.ui +++ b/code/nel/tools/misc/crash_report/crash_report_widget.ui @@ -18,14 +18,14 @@ - + What were you doing when the crash occured? - + Contents of the report ( automatically generated ) From 3108e5e013c1d3ceee91234409e22bfe799f010f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 3 Mar 2015 02:30:39 +0100 Subject: [PATCH 332/344] Send report in dev mode if the CB is checked. --HG-- branch : feature-crashreport --- .../misc/crash_report/crash_report_widget.cpp | 40 +++++++++++++------ .../misc/crash_report/crash_report_widget.h | 1 + 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 350a35ff8..e176bb2be 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -34,6 +34,7 @@ QWidget( parent ) { m_developerMode = false; m_forceSend = false; + m_devSendReport = false; m_ui.setupUi( this ); @@ -63,6 +64,8 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: if( k == "log" ) { m_fileName = v.c_str(); + if( !QFile::exists( m_fileName ) ) + m_fileName.clear(); } else if( k == "host" ) @@ -92,8 +95,8 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: m_ui.reportEdit->hide(); } - // When no -host specified no custom entry and email fields - if( m_socket->url().isEmpty() ) + + if( m_socket->url().isEmpty() || m_fileName.isEmpty() ) { m_ui.descriptionEdit->hide(); m_ui.emailCB->hide(); @@ -105,7 +108,7 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: if( m_developerMode ) { - if( !m_socket->url().isEmpty() ) + if( !m_socket->url().isEmpty() && !m_fileName.isEmpty() ) { m_ui.emailCB->setEnabled( false ); @@ -172,10 +175,7 @@ void CCrashReportWidget::onLoad() bool b = f.open( QFile::ReadOnly | QFile::Text ); if( !b ) { - QMessageBox::information( this, - tr( "No log file found" ), - tr( "There was no log file found, therefore nothing to report. Exiting..." ) ); - close(); + m_fileName.clear(); return; } @@ -186,6 +186,18 @@ void CCrashReportWidget::onLoad() void CCrashReportWidget::onSendClicked() { + if( m_developerMode && !m_devSendReport ) + { + close(); + return; + } + + if( m_socket->url().isEmpty() || m_fileName.isEmpty() ) + { + close(); + return; + } + QApplication::setOverrideCursor( Qt::WaitCursor ); SCrashReportData data; @@ -216,30 +228,32 @@ void CCrashReportWidget::onSendCBClicked() } m_ui.emailCB->setEnabled( !b ); + + m_devSendReport = !m_devSendReport; } void CCrashReportWidget::onAlwaysIgnoreClicked() { m_returnValue = ERET_ALWAYS_IGNORE; - close(); + onSendClicked(); } void CCrashReportWidget::onIgnoreClicked() { m_returnValue = ERET_IGNORE; - close(); + onSendClicked(); } void CCrashReportWidget::onAbortClicked() { m_returnValue = ERET_ABORT; - close(); + onSendClicked(); } void CCrashReportWidget::onBreakClicked() { m_returnValue = ERET_BREAK; - close(); + onSendClicked(); } @@ -267,7 +281,9 @@ void CCrashReportWidget::onReportFailed() void CCrashReportWidget::removeAndQuit() { - QFile::remove( m_fileName ); + if( !m_fileName.isEmpty() ) + QFile::remove( m_fileName ); + close(); } diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.h b/code/nel/tools/misc/crash_report/crash_report_widget.h index a0468a565..f40e40854 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.h +++ b/code/nel/tools/misc/crash_report/crash_report_widget.h @@ -73,6 +73,7 @@ private: CCrashReportSocket *m_socket; bool m_developerMode; bool m_forceSend; + bool m_devSendReport; EReturnValue m_returnValue; }; From d561a7078c35898f936ca0c34606016a151f91c3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 3 Mar 2015 02:33:04 +0100 Subject: [PATCH 333/344] Only send email if the email CB is checked. --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report_widget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index e176bb2be..9c23b793a 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -203,7 +203,9 @@ void CCrashReportWidget::onSendClicked() SCrashReportData data; data.description = m_ui.descriptionEdit->toPlainText(); data.report = m_ui.reportEdit->toPlainText(); - data.email = m_ui.emailEdit->text(); + + if( m_ui.emailCB->isChecked() ) + data.email = m_ui.emailEdit->text(); m_socket->sendReport( data ); } From 7ca008ba86ef29c9479de4b3a27af6ec147f54c3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 3 Mar 2015 02:37:51 +0100 Subject: [PATCH 334/344] Don't offer send in non-dev mode when there's no log file specified. --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report_widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 9c23b793a..07ec7cd6f 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -141,7 +141,7 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: else { // If -host is specified, offer the send function - if( !m_socket->url().isEmpty() ) + if( !m_socket->url().isEmpty() && !m_fileName.isEmpty() ) { QPushButton *sendButton = new QPushButton( tr( "Send report" ), this ); connect( sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); From baa5273eaa9ff939f22c6c33590775b2da245f04 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 3 Mar 2015 03:10:28 +0100 Subject: [PATCH 335/344] Default return value. --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report_widget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 07ec7cd6f..00b4c33bf 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -35,6 +35,7 @@ QWidget( parent ) m_developerMode = false; m_forceSend = false; m_devSendReport = false; + m_returnValue = ERET_NULL; m_ui.setupUi( this ); From 74cb91d460bbd8e7ae6afe3e5808b02144299a4a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 3 Mar 2015 03:10:59 +0100 Subject: [PATCH 336/344] This was left here unintentionally. --HG-- branch : feature-crashreport --- code/ryzom/client/src/init.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 2ffc6e8e0..f0fd40dae 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -538,8 +538,6 @@ void checkDriverVersion() void checkDriverDepth () { - nlassert( false ); - // Check desktop is in 32 bit else no window mode allowed. if (ClientCfg.Windowed) { From 9d50210e6ba9ae10199122308b100af652e54409 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 337/344] Enable crash report tool in debugging sample application --HG-- branch : feature-crashreport --- code/nel/samples/misc/debug/main.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/code/nel/samples/misc/debug/main.cpp b/code/nel/samples/misc/debug/main.cpp index 6ee31754f..85cd4edc9 100644 --- a/code/nel/samples/misc/debug/main.cpp +++ b/code/nel/samples/misc/debug/main.cpp @@ -18,11 +18,9 @@ #include // contains all debug features -#include "nel/misc/debug.h" +#include -using namespace NLMISC; - -int main (int /* argc */, char ** /* argv */) +int main(int /* argc */, char ** /* argv */) { // all debug functions have different behaviors in debug and in release mode. // in general, in debug mode, all debug functions are active, they display @@ -36,20 +34,23 @@ int main (int /* argc */, char ** /* argv */) // in release mode, this function does nothing by default. you have to add a displayer // manually, or put true in the parameter to say to the function that you want it to // add the default displayers - createDebug (); + NLMISC::createDebug(); + + // enable the crash report tool + NLMISC::INelContext::getInstance().setWindowedApplication(true); // display debug information, that will be skipped in release mode. - nldebug ("nldebug() %d", 1); + nldebug("nldebug() %d", 1); // display the string - nlinfo ("nlinfo() %d", 2); + nlinfo("nlinfo() %d", 2); // when something not normal, but that the program can manage, occurs, call nlwarning() - nlwarning ("nlwarning() %d", 3); + nlwarning("nlwarning() %d", 3); // nlassert() is like assert but do more powerful things. in release mode, the test is // not executed and nothing will happen. (Press F5 in Visual C++ to continue the execution) - nlassert (true == false); + nlassert(true == false); // in a switch case or when you want that the program never executes a part of code, use stop. // in release, nlstop does nothing. in debug mode, @@ -61,16 +62,16 @@ int main (int /* argc */, char ** /* argv */) // occurs. (In Visual C++ press F5 to continue) try { - nlerror ("nlerror() %d", 4); + nlerror("nlerror() %d", 4); } - catch(const EFatalError &) + catch (const NLMISC::EFatalError &) { // just continue... - nlinfo ("nlerror() generated an EFatalError exception, just ignore it"); + nlinfo("nlerror() generated an EFatalError exception, just ignore it"); } printf("\nPress to exit\n"); - getchar (); + getchar(); return EXIT_SUCCESS; } From 699e1644e71ddd760313ba9b12985abec541f7af Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 338/344] Use proper style sheet for crash report under Cinnamon --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index 0c9e4fc93..c42f1ae6f 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -78,6 +78,19 @@ public: int main( int argc, char **argv ) { +#ifndef WIN32 + // Workaround to default -style=gtk+ on recent Cinnamon versions + char *currentDesktop = getenv("XDG_CURRENT_DESKTOP"); + if (currentDesktop) + { + printf("XDG_CURRENT_DESKTOP: %s\n", currentDesktop); + if (!strcmp(currentDesktop, "X-Cinnamon")) + { + setenv("XDG_CURRENT_DESKTOP", "gnome", 1); + } + } +#endif + QApplication app( argc, argv ); std::vector< std::pair< std::string, std::string > > params; From b896405b3dd13c83c746e097aad0dee917cc7479 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 339/344] Adjust layout --HG-- branch : feature-crashreport --- .../misc/crash_report/crash_report_widget.cpp | 25 ++++++++++++------- .../misc/crash_report/crash_report_widget.ui | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 00b4c33bf..7ca723f44 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -122,10 +122,13 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: connect( cb, SIGNAL( stateChanged( int ) ), this, SLOT( onSendCBClicked() ) ); } + hbl->addStretch(); + QPushButton *alwaysIgnoreButton = new QPushButton( tr( "Always Ignore" ), this ); QPushButton *ignoreButton = new QPushButton( tr( "Ignore" ), this ); QPushButton *abortButton = new QPushButton( tr( "Abort" ), this ); - QPushButton *breakButton = new QPushButton( tr( "Break" ), this ); + QPushButton *breakButton = new QPushButton(tr("Break"), this); + breakButton->setAutoDefault(true); hbl->addWidget( alwaysIgnoreButton ); hbl->addWidget( ignoreButton ); @@ -141,26 +144,30 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: } else { + hbl->addStretch(); + // If -host is specified, offer the send function if( !m_socket->url().isEmpty() && !m_fileName.isEmpty() ) { + if (!m_forceSend) + { + QPushButton *cancelButton = new QPushButton(tr("Don't send report"), this); + connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(onCancelClicked())); + hbl->addWidget(cancelButton); + } + QPushButton *sendButton = new QPushButton( tr( "Send report" ), this ); + sendButton->setAutoDefault(true); connect( sendButton, SIGNAL( clicked( bool ) ), this, SLOT( onSendClicked() ) ); hbl->addWidget( sendButton ); - - if( !m_forceSend ) - { - QPushButton *cancelButton = new QPushButton( tr( "Don't send report" ), this ); - connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); - hbl->addWidget( cancelButton ); - } } // Otherwise only offer exit else { QPushButton *exitButton = new QPushButton( tr( "Exit" ), this ); connect( exitButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); - hbl->addWidget( exitButton ); + hbl->addWidget(exitButton); + exitButton->setAutoDefault(true); } m_ui.gridLayout->addLayout( hbl, 6, 0, 1, 3 ); diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.ui b/code/nel/tools/misc/crash_report/crash_report_widget.ui index dec7e74ca..da1e38618 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.ui +++ b/code/nel/tools/misc/crash_report/crash_report_widget.ui @@ -14,7 +14,7 @@ - NeL Error Report + NeL report From 230be4d64b6d3a86c4443a7185877626bb6c065f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 340/344] Extend debugging sample --HG-- branch : feature-crashreport --- code/nel/samples/misc/debug/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/nel/samples/misc/debug/main.cpp b/code/nel/samples/misc/debug/main.cpp index 85cd4edc9..66217ac1d 100644 --- a/code/nel/samples/misc/debug/main.cpp +++ b/code/nel/samples/misc/debug/main.cpp @@ -20,6 +20,11 @@ // contains all debug features #include +void repeatederror() +{ + nlassert(false && "hit always ignore"); +} + int main(int /* argc */, char ** /* argv */) { // all debug functions have different behaviors in debug and in release mode. @@ -70,6 +75,9 @@ int main(int /* argc */, char ** /* argv */) nlinfo("nlerror() generated an EFatalError exception, just ignore it"); } + for (int i = 0; i < 32; ++i) + repeatederror(); + printf("\nPress to exit\n"); getchar(); From a9dc1a4c6800b22fcdece31f5f42db5b8de206a7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 341/344] Fix checkbox behaviour --HG-- branch : feature-crashreport --- code/nel/tools/misc/crash_report/crash_report_widget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/misc/crash_report/crash_report_widget.cpp b/code/nel/tools/misc/crash_report/crash_report_widget.cpp index 7ca723f44..218b3545c 100644 --- a/code/nel/tools/misc/crash_report/crash_report_widget.cpp +++ b/code/nel/tools/misc/crash_report/crash_report_widget.cpp @@ -119,7 +119,9 @@ void CCrashReportWidget::setup( const std::vector< std::pair< std::string, std:: m_ui.gridLayout->addWidget( m_ui.emailCB, 5, 0, 1, 1 ); m_ui.gridLayout->addWidget( m_ui.emailEdit, 6, 0, 1, 1 ); - connect( cb, SIGNAL( stateChanged( int ) ), this, SLOT( onSendCBClicked() ) ); + connect(cb, SIGNAL(stateChanged(int)), this, SLOT(onSendCBClicked())); + if (m_forceSend) + cb->setChecked(true); } hbl->addStretch(); From bbfc15c07af812f91d384d5065709b17ea4b5fda Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:10 +0100 Subject: [PATCH 342/344] Extend debugging sample --HG-- branch : feature-crashreport --- code/nel/samples/misc/debug/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/samples/misc/debug/main.cpp b/code/nel/samples/misc/debug/main.cpp index 66217ac1d..5850cb2b3 100644 --- a/code/nel/samples/misc/debug/main.cpp +++ b/code/nel/samples/misc/debug/main.cpp @@ -19,9 +19,11 @@ // contains all debug features #include +#include void repeatederror() { + // hit always ignore to surpress this error for the duration of the program nlassert(false && "hit always ignore"); } @@ -43,6 +45,7 @@ int main(int /* argc */, char ** /* argv */) // enable the crash report tool NLMISC::INelContext::getInstance().setWindowedApplication(true); + NLMISC::setReportPostUrl("http://ryzomcore.org/crash_report/"); // display debug information, that will be skipped in release mode. nldebug("nldebug() %d", 1); @@ -75,6 +78,7 @@ int main(int /* argc */, char ** /* argv */) nlinfo("nlerror() generated an EFatalError exception, just ignore it"); } + // keep repeating the same error for (int i = 0; i < 32; ++i) repeatederror(); From 5a307cfa206a9a362ebb8faa6432a1cb36ef0f53 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:06:11 +0100 Subject: [PATCH 343/344] Replace report functionality --HG-- branch : feature-crashreport --- code/nel/include/nel/misc/report.h | 46 ++++++++++++++++++------------ code/nel/src/misc/debug.cpp | 4 +-- code/nel/src/misc/displayer.cpp | 42 ++++++++++++--------------- code/nel/src/misc/report.cpp | 1 + code/nel/src/net/service.cpp | 2 +- 5 files changed, 51 insertions(+), 44 deletions(-) diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index c492f4aa2..55a1c2dbf 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,28 +21,38 @@ namespace NLMISC { -enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; - -/** Display a custom message box. - * - * \param title set the title of the report. If empty, it'll display "NeL Crash Report" or the default title set by setReportWindowTitle. - * \param header message displayed before the edit text box. If empty, it displays the default message. - * \param body message displayed in the edit text box. This string will be sent by email. - * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior - * +#if FINAL_VERSION +#define NL_REPORT_SYNCHRONOUS false +#define NL_REPORT_DEFAULT NLMISC::ReportAbort +#else +#define NL_REPORT_SYNCHRONOUS true +#define NL_REPORT_DEFAULT NLMISC::ReportBreak +#endif + +enum TReportResult +{ + // See also crash_report_widget.h EReturnValue + ReportAlwaysIgnore = 21, + ReportIgnore = 22, + ReportAbort = 23, + ReportBreak = 24 +}; + +/** Display a crash report * + * \param title set the title of the report. If empty, it'll display "NeL report" + * \param subject extended title of the report + * \param body message displayed in the edit text box. This string will be sent to the crash report tool + * \param attachment binary file to attach. This is a filename + * \param synchronous use system() and wait for the crash tool exit code, passes -dev flag; otherwise return defaultResult immediately + * \param sendReport hide 'dont send' button, or auto enable 'send report' checkbox * - * \return the button clicked or error + * \return the button clicked or defaultResult */ -TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); +TReportResult report(const std::string &title, const std::string &subject, const std::string &body, const std::string &attachment, bool synchronous, bool sendReport, TReportResult defaultResult); -/// Set the Url of the web service used to post crash reports to -void setReportPostUrl(const std::string &postUrl); - -/// DEPRECATED -/** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); - */ -void setReportEmailFunction(void *emailFunction); +/// Set the Url of the web service used to post crash reports to. String is copied +void setReportPostUrl(const char *postUrl); } // NLMISC diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 86752a412..96372d124 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -553,8 +553,8 @@ public: { // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). - bool i = false; - report (progname+shortExc, "", subject, _Reason, true, 1, true, 1, !isCrashAlreadyReported(), i, NL_CRASH_DUMP_FILE); + report(progname + shortExc, subject, _Reason, NL_CRASH_DUMP_FILE, true, !isCrashAlreadyReported(), ReportAbort); + // TODO: Does this need to be synchronous? Why does this not handle the report result? // no more sent mail for crash setCrashAlreadyReported(true); diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 86fc1d726..273ebf111 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -688,37 +688,33 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; + + TReportResult reportResult = report(args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), + subject, body, filename, NL_REPORT_SYNCHRONOUS, !isCrashAlreadyReported(), NL_REPORT_DEFAULT); - if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) + switch (reportResult) { + case ReportAlwaysIgnore: + IgnoreNextTime = true; + break; + case ReportBreak: INelContext::getInstance().setDebugNeedAssert(true); + break; + case ReportAbort: +# ifdef NL_OS_WINDOWS +# ifndef NL_COMP_MINGW + // disable the Windows popup telling that the application aborted and disable the dr watson report. + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +# endif +# endif + abort(); + break; } // no more sent mail for crash setCrashAlreadyReported(true); } - -/* // Check the envvar NEL_IGNORE_ASSERT - if (getenv ("NEL_IGNORE_ASSERT") == NULL) - { - // Ask the user to continue, debug or ignore - int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); - if (result == IDABORT) - { - // Exit the program now - exit (EXIT_FAILURE); - } - else if (result == IDRETRY) - { - // Give the debugger a try - DebugNeedAssert = true; - } - else if (result == IDIGNORE) - { - // Continue, do nothing - } - } -*/ } + } //#endif } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 8c58234cf..96ad2fac9 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -16,6 +16,7 @@ #include "stdmisc.h" +#include #include #include "nel/misc/common.h" diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp index f42806245..a37370b17 100644 --- a/code/nel/src/net/service.cpp +++ b/code/nel/src/net/service.cpp @@ -606,7 +606,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, ListeningPort = servicePort; - setReportEmailFunction ((void*)sendEmail); + // setReportEmailFunction ((void*)sendEmail); // setDefaultEmailParams ("gw.nevrax.com", "", "cado@nevrax.com"); From ee32b56d8704d59f5622a1d9012f08c841f6c239 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 6 Mar 2015 19:07:25 +0100 Subject: [PATCH 344/344] Replace report functionality --HG-- branch : feature-crashreport --- code/nel/src/misc/report.cpp | 457 +++++++++++------------------------ 1 file changed, 146 insertions(+), 311 deletions(-) diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 96ad2fac9..b388dfb31 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -24,363 +24,198 @@ #include "nel/misc/report.h" #include "nel/misc/path.h" - -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW -# define NOMINMAX -# endif -# include -# include -# include -#endif // NL_OS_WINDOWS - -#define NL_NO_DEBUG_FILES 1 - -using namespace std; +#include "nel/misc/file.h" #ifdef DEBUG_NEW #define new DEBUG_NEW #endif -namespace NLMISC -{ - -void setReportEmailFunction(void *emailFunction) -{ - // DEPRECATED - // no-op -} - -// Contents of crash report -static string ReportBody; -// Host url for crash report -static std::string ReportPostUrl = ""; -// Title for the crash report window -static std::string ReportWindowTitle = ""; +#define NL_REPORT_POST_URL_ENVVAR "NL_REPORT_POST_URL" +#ifdef NL_OS_WINDOWS +#define NL_CRASH_REPORT_TOOL "crash_report.exe" +#else +#define NL_CRASH_REPORT_TOOL "crash_report" +#endif +#define NL_DEBUG_REPORT 0 +// Set to 1 if you want command line report tool +#define NL_REPORT_CONSOLE 0 +// Set to 1 if you want command line report tool even when the debugger is present +#define NL_REPORT_CONSOLE_DEBUGGER 1 -void setReportPostUrl(const std::string &postUrl) +namespace NLMISC { - ReportPostUrl = postUrl; -} -// Launch the crash report application -static void doSendReport() +void setReportPostUrl(const char *postUrl) { - std::string filename; - - filename = /*getLogDirectory() + */ "report_"; // FIXME: Should use log directory - filename += NLMISC::toString( int( time( NULL ) ) ); - filename += ".txt"; - - std::stringstream params; - params << "-log "; - params << filename; // FIXME: Escape the filepath with quotes - if (!ReportPostUrl.empty()) - { - params << " -host "; - params << ReportPostUrl; - } - if (!ReportWindowTitle.empty()) - { - params << " -title "; - params << ReportWindowTitle; // FIXME: Escape the title with quotes and test - } - - std::ofstream f; - f.open( filename.c_str() ); - if( !f.good() ) - return; - - f << ReportBody; - - f.close(); - +#if NL_DEBUG_REPORT + if (INelContext::isContextInitialised()) + nldebug("Set report post url to '%s'", postUrl); +#endif #ifdef NL_OS_WINDOWS - NLMISC::launchProgram( "crash_report.exe", params.str() ); + SetEnvironmentVariableA(NL_REPORT_POST_URL_ENVVAR, postUrl); #else - NLMISC::launchProgram( "crash_report", params.str() ); + setenv(NL_REPORT_POST_URL_ENVVAR, postUrl, 1); #endif - - // Added because NLSMIC::launcProgram needs time to launch - nlSleep( 2 * 1000 ); - } -#if defined(FINAL_VERSION) || !defined(NL_OS_WINDOWS) - -// For FINAL_VERSION, simply launch the crash report and exit the application -TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) +inline const char *getReportPostURL() { - ReportWindowTitle = title.empty() ? "Nel Crash Report" : title; - ReportBody = addSlashR(body); - - doSendReport(); - -# if defined(FINAL_VERSION) // TODO: This behaviour is used in the old report code when Quitting the application is the default crash report behaviour. Needs testing. -# ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW - // disable the Windows popup telling that the application aborted and disable the dr watson report. - _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); -# endif -# endif - // quit without calling atexit or static object dtors. - abort(); -# endif - - return ReportQuit; -} - +#ifdef NL_OS_WINDOWS + static char buf[512]; + buf[0] = '\0'; + int res = GetEnvironmentVariableA(NL_REPORT_POST_URL_ENVVAR, buf, sizeof(buf)); + if (res <= 0 || res > 511) return NULL; + if (buf[0] == '\0') return NULL; + return buf; #else - -// Windows specific version for DEV builds, first shows a dialog box for debugging - -static HWND sendReport=NULL; -#define DELETE_OBJECT(a) if((a)!=NULL) { DeleteObject (a); a = NULL; } - -static HWND checkIgnore = NULL; -static HWND debug = NULL; -static HWND ignore = NULL; -static HWND quit = NULL; -static HWND dialog = NULL; - -static bool NeedExit; -static TReportResult Result; -static bool IgnoreNextTime; -static bool CanSendMailReport = false; - -static bool DebugDefaultBehavior, QuitDefaultBehavior; - -static void maybeSendReport() -{ - if (CanSendMailReport && SendMessage(sendReport, BM_GETCHECK, 0, 0) != BST_CHECKED) - { - doSendReport(); -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_sent"); -#endif - } - else - { -#ifndef NL_NO_DEBUG_FILES - CFile::createEmptyFile(getLogDirectory() + "report_refused"); + char *res = getenv(NL_REPORT_POST_URL_ENVVAR); + if (res == NULL || res[0] == '\0') return NULL; + return res; #endif -- } } -static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +TReportResult report(const std::string &title, const std::string &subject, const std::string &body, const std::string &attachment, bool synchronous, bool sendReport, TReportResult defaultResult) { - //MSGFILTER *pmf; - - if (message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) + std::string reportPath; + if (!body.empty()) { - if ((HWND) lParam == checkIgnore) - { - IgnoreNextTime = !IgnoreNextTime; - } - else if ((HWND) lParam == debug) - { - maybeSendReport(); - NeedExit = true; - Result = ReportDebug; - if (DebugDefaultBehavior) - { - NLMISC_BREAKPOINT; - } - } - else if ((HWND) lParam == ignore) - { - maybeSendReport(); - NeedExit = true; - Result = ReportIgnore; - } - else if ((HWND) lParam == quit) + std::stringstream reportFile; + reportFile << getLogDirectory(); + reportFile << "nel_report_"; + reportFile << (int)time(NULL); + reportFile << ".log"; + reportPath = CFile::findNewFile(reportFile.str()); + std::ofstream f; + f.open(reportPath.c_str()); + if (!f.good()) { - maybeSendReport(); - NeedExit = true; - Result = ReportQuit; - - if (QuitDefaultBehavior) - { - // ace: we cannot call exit() because it's call the static object dtor and can crash the application - // if the dtor call order is not good. - //exit(EXIT_SUCCESS); -#ifdef NL_OS_WINDOWS -#ifndef NL_COMP_MINGW - // disable the Windows popup telling that the application aborted and disable the dr watson report. - _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); -#endif +#if NL_DEBUG_REPORT + if (INelContext::isContextInitialised()) + nldebug("Failed to write report log to '%s'", reportPath.c_str()); #endif - // quit without calling atexit or static object dtors. - abort(); - } + reportPath.clear(); } - } - else if (message == WM_CHAR) - { - if (wParam == 27) + else { - // ESC -> ignore - maybeSendReport(); - NeedExit = true; - Result = ReportIgnore; + f << body; + f.close(); } } - return DefWindowProc(hWnd, message, wParam, lParam); -} - -TReportResult report(const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) -{ - // register the window - static bool AlreadyRegister = false; - if (!AlreadyRegister) + if (INelContext::isContextInitialised() + && INelContext::getInstance().isWindowedApplication() + && CFile::isExists(NL_CRASH_REPORT_TOOL)) { - WNDCLASSW wc; - memset (&wc,0,sizeof(wc)); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"NLReportWindow"; - wc.lpszMenuName = NULL; - if (!RegisterClassW(&wc)) return ReportError; - AlreadyRegister = true; - } + std::stringstream params; + params << NL_CRASH_REPORT_TOOL; - ReportWindowTitle = title.empty() ? "Nel Crash Report" : title; - ucstring formatedTitle = ucstring::makeFromUtf8(ReportWindowTitle); + if (!reportPath.empty()) + params << " -log \"" << reportPath << "\""; - // create the window - dialog = CreateWindowW (L"NLReportWindow", (LPCWSTR)formatedTitle.c_str(), WS_DLGFRAME | WS_CAPTION /*| WS_THICKFRAME*/, CW_USEDEFAULT, CW_USEDEFAULT, 456, 400, NULL, NULL, GetModuleHandle(NULL), NULL); + if (!subject.empty()) + params << " -attachment \"" << attachment << "\""; - // create the font - HFONT font = CreateFont (-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); + if (!title.empty()) + params << " -title \"" << title << "\""; - // create the edit control - HWND edit = CreateWindowW (L"EDIT", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_READONLY | ES_LEFT | ES_MULTILINE, 7, 70, 429, 212, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (edit, WM_SETFONT, (WPARAM) font, TRUE); + if (!subject.empty()) + params << " -subject \"" << subject << "\""; - // set the edit text limit to lot of :) - SendMessage (edit, EM_LIMITTEXT, ~0U, 0); + const char *reportPostUrl = getReportPostURL(); + if (reportPostUrl) + params << " -host \"" << reportPostUrl << "\""; - ReportBody = addSlashR(body); + if (synchronous) + params << " -dev"; - // set the message in the edit text - SendMessage (edit, WM_SETTEXT, (WPARAM)0, (LPARAM)ReportBody.c_str()); + if (sendReport) + params << " -sendreport"; - if (enableCheckIgnore) - { - // create the combo box control - checkIgnore = CreateWindowW (L"BUTTON", L"Don't display this report again", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_CHECKBOX, 7, 290, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (checkIgnore, WM_SETFONT, (WPARAM) font, TRUE); + std::string paramsStr = params.str(); - if(ignoreNextTime) + if (synchronous) { - SendMessage (checkIgnore, BM_SETCHECK, BST_CHECKED, 0); + TReportResult result = (TReportResult)::system(paramsStr.c_str()); + if (result != ReportAlwaysIgnore + && result != ReportIgnore + && result != ReportAbort + && result != ReportBreak) + { +#if NL_DEBUG_REPORT + if (INelContext::isContextInitialised()) + nldebug("Return default result, invalid return code %i", (int)result); +#endif + return defaultResult; + } + return result; + } + else + { + NLMISC::launchProgram(NL_CRASH_REPORT_TOOL, paramsStr); // FIXME: Don't use this function, it uses logging, etc, so may loop infinitely! + return defaultResult; } - } - - // create the debug button control - debug = CreateWindowW (L"BUTTON", L"Debug", WS_CHILD | WS_VISIBLE, 7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (debug, WM_SETFONT, (WPARAM) font, TRUE); - - if (debugButton == 0) - EnableWindow(debug, FALSE); - - // create the ignore button control - ignore = CreateWindowW (L"BUTTON", L"Ignore", WS_CHILD | WS_VISIBLE, 75+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (ignore, WM_SETFONT, (WPARAM) font, TRUE); - - if (ignoreButton == 0) - EnableWindow(ignore, FALSE); - - // create the quit button control - quit = CreateWindowW (L"BUTTON", L"Quit", WS_CHILD | WS_VISIBLE, 75+75+7+7+7, 315, 75, 25, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (quit, WM_SETFONT, (WPARAM) font, TRUE); - - if (quitButton == 0) - EnableWindow(quit, FALSE); - - // create the debug button control - sendReport = CreateWindowW (L"BUTTON", L"Don't send the report", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 7, 315+32, 429, 18, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (sendReport, WM_SETFONT, (WPARAM) font, TRUE); - - string formatedHeader; - if (header.empty()) - { - formatedHeader = "This application stopped to display this report."; } else { - formatedHeader = header; - } - - // ace don't do that because it s slow to try to send a mail - CanSendMailReport = sendReportButton && !ReportPostUrl.empty(); - - if (CanSendMailReport) - formatedHeader += " Send report will only email the contents of the box below. Please, send it to help us (it could take few minutes to send the email, be patient)."; - else - EnableWindow(sendReport, FALSE); - - ucstring uc = ucstring::makeFromUtf8(formatedHeader); - - // create the label control - HWND label = CreateWindowW (L"STATIC", (LPCWSTR)uc.c_str(), WS_CHILD | WS_VISIBLE /*| SS_WHITERECT*/, 7, 7, 429, 51, dialog, (HMENU) NULL, (HINSTANCE) GetWindowLongPtr(dialog, GWLP_HINSTANCE), NULL); - SendMessage (label, WM_SETFONT, (WPARAM) font, TRUE); - - - DebugDefaultBehavior = debugButton==1; - QuitDefaultBehavior = quitButton==1; - - IgnoreNextTime = ignoreNextTime; - - // show until the cursor really show :) - while (ShowCursor(TRUE) < 0) - ; - - SetWindowPos (dialog, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - - SetFocus(dialog); - SetForegroundWindow(dialog); - - NeedExit = false; - - while(!NeedExit) - { - MSG msg; - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) +#if NL_DEBUG_REPORT + if (INelContext::isContextInitialised() && !CFile::isExists(NL_CRASH_REPORT_TOOL)) + nldebug("Crash report tool '%s' does not exist", NL_CRASH_REPORT_TOOL); +#endif +#if defined(NL_OS_WINDOWS) && !FINAL_VERSION && !NL_REPORT_CONSOLE_DEBUGGER + if (IsDebuggerPresent()) + { + return defaultResult; + } + else +#endif + if (synchronous) + { +#if NL_REPORT_CONSOLE + // An interactive console based report + printf("\n"); + if (!title.empty()) + printf("%s\n", title.c_str()); + else + printf("NeL report\n"); + printf("\n"); + if (!subject.empty()) + printf("\tsubject: '%s'\n", subject.c_str()); + if (!body.empty()) + printf("\tbody: '%s'\n", reportPath.c_str()); + if (!attachment.empty()) + printf("\tattachment: '%s'\n", attachment.c_str()); + for (;;) + { + printf("\n"); + printf("Always Ignore (S), Ignore (I), Abort (A), Break (B)?\n"); // S for Surpress + printf("> "); + int c = getchar(); + getchar(); + switch (c) + { + case 'S': + case 's': + return ReportAlwaysIgnore; + case 'I': + case 'i': + return ReportIgnore; + case 'A': + case 'a': + return ReportAbort; + case 'B': + case 'b': + return ReportBreak; + } + } +#else + return defaultResult; +#endif + } + else { - TranslateMessage(&msg); - DispatchMessageW(&msg); + return defaultResult; } - nlSleep (1); } - - // set the user result - ignoreNextTime = IgnoreNextTime; - - ShowWindow(dialog, SW_HIDE); - - - - DELETE_OBJECT(sendReport) - DELETE_OBJECT(quit) - DELETE_OBJECT(ignore) - DELETE_OBJECT(debug) - DELETE_OBJECT(checkIgnore) - DELETE_OBJECT(edit) - DELETE_OBJECT(label) - DELETE_OBJECT(dialog) - - return Result; } -#endif - - } // NLMISC