This commit is contained in:
Mike 2014-01-18 17:16:44 -06:00
commit 0807d490ad
21 changed files with 1088 additions and 38 deletions

9
.gitignore vendored
View File

@ -7,6 +7,11 @@
*.un~ *.un~
Session.vim Session.vim
MegaGlest.kdev4 MegaGlest.kdev4
/mk/linux/mydata
/mk/linux/release
/mk/linux/linux_symbols
/mk/linux/core
/mk/linux/core.bak
## OSX ## OSX
Icon Icon
@ -70,10 +75,6 @@ $RECYCLE.BIN/
/source/windows_deps_2010 /source/windows_deps_2010
/source/windows_deps_2010_old /source/windows_deps_2010_old
/mk/linux/mydata
/mk/linux/release
/mk/linux/linux_symbols
# Coverity # Coverity
/cov-int /cov-int
/cov-int/.* /cov-int/.*

@ -1 +1 @@
Subproject commit 4338c735393e942cefd983b5bdffd92adf6a542d Subproject commit 35d6e48036cd987fac66de9a2b92c8d5c818483d

View File

@ -14,6 +14,7 @@ PACKAGE="$RELEASENAME-$VERSION.tar.xz"
CURRENTDIR="$(dirname $(readlink -f $0))" CURRENTDIR="$(dirname $(readlink -f $0))"
RELEASEDIR="$CURRENTDIR/release/$RELEASENAME-$VERSION/megaglest-$VERSION" RELEASEDIR="$CURRENTDIR/release/$RELEASENAME-$VERSION/megaglest-$VERSION"
SOURCEDIR="$CURRENTDIR/../../source/" SOURCEDIR="$CURRENTDIR/../../source/"
# Below we assume you have the data source contents root in a folder called: git-data-source/
REPODIR="$CURRENTDIR/../../../git-data-source/" REPODIR="$CURRENTDIR/../../../git-data-source/"
echo "Creating data package in $RELEASEDIR" echo "Creating data package in $RELEASEDIR"
@ -36,7 +37,7 @@ fi
mkdir -p "$RELEASEDIR/data-source" mkdir -p "$RELEASEDIR/data-source"
cd "$RELEASEDIR/data-source" cd "$RELEASEDIR/data-source"
#svn export --force "$CURRENTDIR/../../../git-data-source" "$RELEASEDIR/data-source/" #svn export --force "$CURRENTDIR/../../../git-data-source" "$RELEASEDIR/data-source/"
git archive --remote ${REPODIR}/megaglest-data-source/ HEAD: | tar x git archive --remote ${REPODIR}/ HEAD: | tar x
cd "$CURRENTDIR" cd "$CURRENTDIR"
echo "creating $PACKAGE" echo "creating $PACKAGE"

View File

@ -6,7 +6,7 @@
OLD_MG_VERSION=3.9.0 OLD_MG_VERSION=3.9.0
OLD_MG_VERSION_BINARY=3.9.0 OLD_MG_VERSION_BINARY=3.9.0
MG_VERSION=3.9.1-dev MG_VERSION=3.9.1
if [ "$1" = "--oldversion" ]; then if [ "$1" = "--oldversion" ]; then
echo "$OLD_MG_VERSION" echo "$OLD_MG_VERSION"

View File

@ -270,9 +270,11 @@ if [ $REPACKONLY -eq 0 ]; then
copyGlestDeptsCmd="${INSTALL_ROOTDIR}makedeps_folder.sh megaglest" copyGlestDeptsCmd="${INSTALL_ROOTDIR}makedeps_folder.sh megaglest"
$copyGlestDeptsCmd $copyGlestDeptsCmd
cd "$CURRENTDIR"
cd data
LIBVLC_DIR_CHECK=$( ldd megaglest | grep "libvlc\." | sort -u | awk '{print $3}' ) LIBVLC_DIR_CHECK=$( ldd megaglest | grep "libvlc\." | sort -u | awk '{print $3}' )
if [ "$LIBVLC_DIR_CHECK" != '' ]; then if [ "$LIBVLC_DIR_CHECK" != '' ]; then
LIBVLC_DIR=$( $LIBVLC_DIR_CHECK | xargs dirname ) LIBVLC_DIR=$( dirname $LIBVLC_DIR_CHECK )
fi fi
echo LibVLC installed in [$LIBVLC_DIR] copying to lib/ echo LibVLC installed in [$LIBVLC_DIR] copying to lib/

View File

@ -1,5 +1,5 @@
local GAME_INSTALL_SIZE = 700000000; local GAME_INSTALL_SIZE = 730000000;
local GAME_VERSION = "3.9.0"; local GAME_VERSION = "3.9.1";
local _ = MojoSetup.translate local _ = MojoSetup.translate

View File

@ -3,8 +3,8 @@
!define APNAME MegaGlest !define APNAME MegaGlest
!define APNAME_OLD Mega-Glest !define APNAME_OLD Mega-Glest
!define APVER_OLD 3.7.1 !define APVER_OLD 3.9.0
!define APVER 3.9.0 !define APVER 3.9.1
Name "${APNAME} ${APVER}" Name "${APNAME} ${APVER}"
SetCompressor /FINAL /SOLID lzma SetCompressor /FINAL /SOLID lzma
@ -285,6 +285,7 @@ Section "Start Menu Shortcuts"
CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} Map Editor.lnk" "$INSTDIR\megaglest_editor.exe" "" "$INSTDIR\megaglest_editor.exe" 0 "" "" "${APNAME} MegaGlest Map Editor" CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} Map Editor.lnk" "$INSTDIR\megaglest_editor.exe" "" "$INSTDIR\megaglest_editor.exe" 0 "" "" "${APNAME} MegaGlest Map Editor"
CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} G3D Viewer.lnk" "$INSTDIR\megaglest_g3dviewer.exe" "" "$INSTDIR\megaglest_g3dviewer.exe" 0 "" "" "${APNAME} MegaGlest G3D Viewer" CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} G3D Viewer.lnk" "$INSTDIR\megaglest_g3dviewer.exe" "" "$INSTDIR\megaglest_g3dviewer.exe" 0 "" "" "${APNAME} MegaGlest G3D Viewer"
CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} Main.lnk" "$INSTDIR" "" "" 0 "" "" "This folder is the ${APNAME} installation folder"
CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} User Data.lnk" "$APPDATA\megaglest" "" "" 0 "" "" "This folder contains downloaded data (such as mods) and your personal ${APNAME} configuration" CreateShortCut "$SMPROGRAMS\${APNAME}\${APNAME} User Data.lnk" "$APPDATA\megaglest" "" "" 0 "" "" "This folder contains downloaded data (such as mods) and your personal ${APNAME} configuration"
SectionEnd SectionEnd

View File

@ -2,10 +2,10 @@
; General Attributes ; General Attributes
!define APNAME MegaGlest !define APNAME MegaGlest
!define APVER 3.9.0 !define APVER 3.9.1
!define APNAME_OLD Mega-Glest !define APNAME_OLD Mega-Glest
!define APVER_OLD 3.7.1 !define APVER_OLD 3.9.0
!define APVER_UPDATE 3.9.0 !define APVER_UPDATE 3.9.1
Name "${APNAME} ${APVER_UPDATE}" Name "${APNAME} ${APVER_UPDATE}"
SetCompressor /FINAL /SOLID lzma SetCompressor /FINAL /SOLID lzma

View File

@ -9,6 +9,7 @@ cd /d "%~dp0"
ECHO Checking for windows binary runtime tools... ECHO Checking for windows binary runtime tools...
if NOT EXIST ..\..\data\glest_game\7z.exe call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\7z.exe call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\7z.dll call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\7z.dll call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\tar.exe call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\wget.exe call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\wget.exe call cscript getTools.vbs
set depfolder=windows_deps set depfolder=windows_deps
@ -72,6 +73,7 @@ rem Update from GIT to latest rev
ECHO -------------------------------- ECHO --------------------------------
Echo Updating Code from GIT to latest Revision... Echo Updating Code from GIT to latest Revision...
cd ..\..\ cd ..\..\
git submodule update
git pull git pull
git submodule foreach git pull git submodule foreach git pull

View File

@ -16,6 +16,7 @@ cd /d "%~dp0"
ECHO Checking for windows binary runtime tools... ECHO Checking for windows binary runtime tools...
if NOT EXIST ..\..\data\glest_game\7z.exe call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\7z.exe call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\7z.dll call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\7z.dll call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\tar.exe call cscript getTools.vbs
if NOT EXIST ..\..\data\glest_game\wget.exe call cscript getTools.vbs if NOT EXIST ..\..\data\glest_game\wget.exe call cscript getTools.vbs
set depfolder=windows_deps_2012 set depfolder=windows_deps_2012
@ -96,6 +97,7 @@ rem Update from GIT to latest rev
ECHO -------------------------------- ECHO --------------------------------
Echo Updating Code from GIT to latest Revision... Echo Updating Code from GIT to latest Revision...
cd ..\..\ cd ..\..\
git submodule update
git pull git pull
git submodule foreach git pull git submodule foreach git pull

View File

@ -106,3 +106,38 @@ If objXMLHTTP.Status = 200 Then
End if End if
Set objXMLHTTP = Nothing Set objXMLHTTP = Nothing
' Set your settings
strFileURL = "http://www.soft-haus.com/glest/tools/tar.exe"
strHDLocation = "..\..\data\glest_game\tar.exe"
WScript.Echo "----------------------------------------"
WScript.Echo "About to download tar.exe from:"
WScript.Echo strFileURL & ", please wait..."
' Fetch the file
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP")
objXMLHTTP.open "GET", strFileURL, false
objXMLHTTP.send()
If objXMLHTTP.Status = 200 Then
Set objADOStream = CreateObject("ADODB.Stream")
objADOStream.Open
objADOStream.Type = 1 'adTypeBinary
objADOStream.Write objXMLHTTP.ResponseBody
objADOStream.Position = 0 'Set the stream position to the start
Set objFSO = Createobject("Scripting.FileSystemObject")
If objFSO.Fileexists(strHDLocation) Then objFSO.DeleteFile strHDLocation
Set objFSO = Nothing
objADOStream.SaveToFile strHDLocation
objADOStream.Close
Set objADOStream = Nothing
WScript.Echo "tar.exe has been downloaded successfully to: "
WScript.Echo strHDLocation
WScript.Echo "----------------------------------------"
End if
Set objXMLHTTP = Nothing

View File

@ -31,37 +31,91 @@ set RELEASENAME=megaglest-standalone-data
set PACKAGE=%RELEASENAME%-%mg_version%.7z set PACKAGE=%RELEASENAME%-%mg_version%.7z
set RELEASEDIR=release-data\%RELEASENAME%-%mg_version% set RELEASEDIR=release-data\%RELEASENAME%-%mg_version%
set PROJDIR=..\..\ set PROJDIR=..\..\
set REPODIR=%~dp0\..\..\
set PATH=%path%;%~dp0..\..\data\glest_game
rem to debug creating the archive only rem to debug creating the archive only
rem goto make_archive rem goto make_archive
echo Creating data package in [%RELEASEDIR%] echo Creating data package in [%RELEASEDIR%]
if exist %RELEASEDIR% echo Cleaning previous release folder [%RELEASEDIR%]
if exist %RELEASEDIR% rd /s /q %RELEASEDIR% if exist %RELEASEDIR% rd /s /q %RELEASEDIR%
mkdir %RELEASEDIR% mkdir %RELEASEDIR%
rem copy data rem copy data
echo copying data ... echo Copying data ...
mkdir %RELEASEDIR%\data\ mkdir %RELEASEDIR%\data\
svn export --force ..\..\data\glest_game\data %RELEASEDIR%\data\ cd /d %RELEASEDIR%\data\
rem svn export --force ..\..\data\glest_game\data %RELEASEDIR%\data\
echo GIT ARCHIVE data ...
git archive --remote %REPODIR%\data\glest_game\ HEAD:data | tar -x
cd /d "%~dp0"
rem pause
mkdir %RELEASEDIR%\docs\ mkdir %RELEASEDIR%\docs\
svn export --force ..\..\data\glest_game\docs %RELEASEDIR%\docs\ cd /d %RELEASEDIR%\docs\
svn export --force ..\..\data\glest_game\docs\CHANGELOG.txt %RELEASEDIR%\docs\CHANGELOG.txt rem svn export --force ..\..\data\glest_game\docs %RELEASEDIR%\docs\
svn export --force ..\..\data\glest_game\docs\README.txt %RELEASEDIR%\docs\README.txt echo GIT ARCHIVE docs ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:docs | tar -x
cd /d "%~dp0"
cd /d %RELEASEDIR%\docs\
rem svn export --force ..\..\data\glest_game\docs\CHANGELOG.txt %RELEASEDIR%\docs\CHANGELOG.txt
echo GIT ARCHIVE CHANGELOG.txt ...
git archive --remote %REPODIR% HEAD:docs/ CHANGELOG.txt | tar -x
cd /d "%~dp0"
rem pause
cd /d %RELEASEDIR%\docs\
rem svn export --force ..\..\data\glest_game\docs\README.txt %RELEASEDIR%\docs\README.txt
echo GIT ARCHIVE README.txt ...
git archive --remote %REPODIR% HEAD:docs/ README.txt | tar -x
cd /d "%~dp0"
rem pause
mkdir %RELEASEDIR%\maps\ mkdir %RELEASEDIR%\maps\
svn export --force ..\..\data\glest_game\maps %RELEASEDIR%\maps\ cd /d %RELEASEDIR%\maps\
rem svn export --force ..\..\data\glest_game\maps %RELEASEDIR%\maps\
echo GIT ARCHIVE maps ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:maps | tar -x
cd /d "%~dp0"
mkdir %RELEASEDIR%\scenarios\ mkdir %RELEASEDIR%\scenarios\
svn export --force ..\..\data\glest_game\scenarios %RELEASEDIR%\scenarios\ cd /d %RELEASEDIR%\scenarios\
rem svn export --force ..\..\data\glest_game\scenarios %RELEASEDIR%\scenarios\
echo GIT ARCHIVE scenarios ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:scenarios | tar -x
cd /d "%~dp0"
mkdir %RELEASEDIR%\techs\ mkdir %RELEASEDIR%\techs\
svn export --force ..\..\data\glest_game\techs %RELEASEDIR%\techs\ cd /d %RELEASEDIR%\techs\
rem svn export --force ..\..\data\glest_game\techs %RELEASEDIR%\techs\
echo GIT ARCHIVE techs ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:techs | tar -x
cd /d "%~dp0"
mkdir %RELEASEDIR%\tilesets\ mkdir %RELEASEDIR%\tilesets\
svn export --force ..\..\data\glest_game\tilesets %RELEASEDIR%\tilesets\ cd /d %RELEASEDIR%\tilesets\
rem svn export --force ..\..\data\glest_game\tilesets %RELEASEDIR%\tilesets\
echo GIT ARCHIVE tilesets ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:tilesets | tar -x
cd /d "%~dp0"
mkdir %RELEASEDIR%\tutorials\ mkdir %RELEASEDIR%\tutorials\
svn export --force ..\..\data\glest_game\tutorials %RELEASEDIR%\tutorials\ cd /d %RELEASEDIR%\tutorials\
rem svn export --force ..\..\data\glest_game\tutorials %RELEASEDIR%\tutorials\
echo GIT ARCHIVE tutorials ...
git archive --remote %REPODIR%/data/glest_game/ HEAD:tutorials | tar -x
cd /d "%~dp0"
rem special export for flag images rem special export for flag images
mkdir %RELEASEDIR%\data\core\misc_textures\flags\ mkdir %RELEASEDIR%\data\core\misc_textures\flags\
svn export --force ..\..\source\masterserver\flags %RELEASEDIR%\data\core\misc_textures\flags\ cd /d %RELEASEDIR%\data\core\misc_textures\flags\
rem svn export --force ..\..\source\masterserver\flags %RELEASEDIR%\data\core\misc_textures\flags\
echo GIT ARCHIVE flags ...
git archive --remote %REPODIR% HEAD:source/masterserver/flags | tar -x
cd /d "%~dp0"
rem START rem START
rem remove embedded data rem remove embedded data

View File

@ -27,7 +27,7 @@ using namespace Shared::Platform;
namespace Glest { namespace Game { namespace Glest { namespace Game {
const char *mailString = " http://bugs.megaglest.org"; const char *mailString = " http://bugs.megaglest.org";
const string glestVersionString = "v3.9.1-dev"; const string glestVersionString = "v3.9.1";
#if defined(GITVERSION) #if defined(GITVERSION)
const string GIT_RawRev = string(GITVERSION); const string GIT_RawRev = string(GITVERSION);
const string GIT_Rev = string("Rev: ") + string(GITVERSION); const string GIT_Rev = string("Rev: ") + string(GITVERSION);

View File

@ -4638,7 +4638,7 @@ int glestMain(int argc, char** argv) {
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_DEBUG]) == true) { if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_DEBUG]) == true) {
printf("Forcing LUA debugging enabled!\n"); printf("Forcing LUA debugging enabled!\n");
config.setBool("DebugLUA","true", true); config.setBool("DebugLUA",true, true);
} }
// Setup debug logging etc // Setup debug logging etc

View File

@ -1033,8 +1033,11 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
} }
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(callingThread->getMutexThreadObjectAccessor(),string(__FILE__) + "_" + intToStr(__LINE__));
tilesetListRemote.clear(); tilesetListRemote.clear();
Tokenize(tilesetsMetaData,tilesetListRemote,"\n"); Tokenize(tilesetsMetaData,tilesetListRemote,"\n");
safeMutex.ReleaseLock(true);
for(unsigned int i=0; i < tilesetListRemote.size(); i++) { for(unsigned int i=0; i < tilesetListRemote.size(); i++) {
@ -1043,7 +1046,9 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
return; return;
} }
safeMutex.Lock();
string result=refreshTilesetModInfo(tilesetListRemote[i]); string result=refreshTilesetModInfo(tilesetListRemote[i]);
safeMutex.ReleaseLock(true);
} }
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
@ -1060,8 +1065,10 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.Lock();
techListRemote.clear(); techListRemote.clear();
Tokenize(techsMetaData,techListRemote,"\n"); Tokenize(techsMetaData,techListRemote,"\n");
safeMutex.ReleaseLock(true);
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1075,7 +1082,9 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
return; return;
} }
safeMutex.Lock();
string result=refreshTechModInfo(techListRemote[i]); string result=refreshTechModInfo(techListRemote[i]);
safeMutex.ReleaseLock(true);
} }
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
@ -1092,8 +1101,10 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.Lock();
mapListRemote.clear(); mapListRemote.clear();
Tokenize(mapsMetaData,mapListRemote,"\n"); Tokenize(mapsMetaData,mapListRemote,"\n");
safeMutex.ReleaseLock(true);
for(unsigned int i=0; i < mapListRemote.size(); i++) { for(unsigned int i=0; i < mapListRemote.size(); i++) {
@ -1102,7 +1113,9 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata
return; return;
} }
safeMutex.Lock();
string result=refreshMapModInfo(mapListRemote[i]); string result=refreshMapModInfo(mapListRemote[i]);
safeMutex.ReleaseLock(true);
} }
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
@ -1218,7 +1231,10 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){
if(ftpClientThread != NULL) { if(ftpClientThread != NULL) {
if(button == 0 && ftpMessageBox.getButtonCount() == 3) { if(button == 0 && ftpMessageBox.getButtonCount() == 3) {
string mapName = getMissingMapFromFTPServer; string mapName = getMissingMapFromFTPServer;
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
string mapURL = mapCacheList[mapName].url; string mapURL = mapCacheList[mapName].url;
safeMutexThread.ReleaseLock();
if(ftpClientThread != NULL) ftpClientThread->addMapToRequests(mapName,mapURL); if(ftpClientThread != NULL) ftpClientThread->addMapToRequests(mapName,mapURL);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
@ -1253,7 +1269,10 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){
if(ftpClientThread != NULL) { if(ftpClientThread != NULL) {
if(button == 0 && ftpMessageBox.getButtonCount() == 3) { if(button == 0 && ftpMessageBox.getButtonCount() == 3) {
string tilesetName = getMissingTilesetFromFTPServer; string tilesetName = getMissingTilesetFromFTPServer;
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
string tilesetURL = tilesetCacheList[tilesetName].url; string tilesetURL = tilesetCacheList[tilesetName].url;
safeMutexThread.ReleaseLock();
if(ftpClientThread != NULL) ftpClientThread->addTilesetToRequests(tilesetName,tilesetURL); if(ftpClientThread != NULL) ftpClientThread->addTilesetToRequests(tilesetName,tilesetURL);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
@ -1288,7 +1307,10 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){
if(ftpClientThread != NULL) { if(ftpClientThread != NULL) {
if(button == 0 && ftpMessageBox.getButtonCount() == 3) { if(button == 0 && ftpMessageBox.getButtonCount() == 3) {
string techName = getMissingTechtreeFromFTPServer; string techName = getMissingTechtreeFromFTPServer;
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
string techURL = techCacheList[techName].url; string techURL = techCacheList[techName].url;
safeMutexThread.ReleaseLock();
if(ftpClientThread != NULL) ftpClientThread->addTechtreeToRequests(techName,techURL); if(ftpClientThread != NULL) ftpClientThread->addTechtreeToRequests(techName,techURL);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
@ -4372,6 +4394,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingTilesetQuestion").c_str(),gameSettings->getTileset().c_str()); snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingTilesetQuestion").c_str(),gameSettings->getTileset().c_str());
// Is the item in the mod center? // Is the item in the mod center?
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(tilesetCacheList.find(getMissingMapFromFTPServer) == tilesetCacheList.end()) { if(tilesetCacheList.find(getMissingMapFromFTPServer) == tilesetCacheList.end()) {
ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload")); ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload"));
} }
@ -4379,6 +4402,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost")); ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost"));
ftpMessageBox.addButton(lang.getString("NoDownload")); ftpMessageBox.addButton(lang.getString("NoDownload"));
} }
safeMutexThread.ReleaseLock();
ftpMissingDataType = ftpmsg_MissingTileset; ftpMissingDataType = ftpmsg_MissingTileset;
showFTPMessageBox(szBuf, lang.getString("Question"), false); showFTPMessageBox(szBuf, lang.getString("Question"), false);
@ -4443,6 +4467,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingTechtreeQuestion").c_str(),gameSettings->getTech().c_str()); snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingTechtreeQuestion").c_str(),gameSettings->getTech().c_str());
// Is the item in the mod center? // Is the item in the mod center?
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(techCacheList.find(getMissingTechtreeFromFTPServer) == techCacheList.end()) { if(techCacheList.find(getMissingTechtreeFromFTPServer) == techCacheList.end()) {
ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload")); ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload"));
} }
@ -4450,6 +4475,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost")); ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost"));
ftpMessageBox.addButton(lang.getString("NoDownload")); ftpMessageBox.addButton(lang.getString("NoDownload"));
} }
safeMutexThread.ReleaseLock();
ftpMissingDataType = ftpmsg_MissingTechtree; ftpMissingDataType = ftpmsg_MissingTechtree;
showFTPMessageBox(szBuf, lang.getString("Question"), false); showFTPMessageBox(szBuf, lang.getString("Question"), false);
@ -4534,6 +4560,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingMapQuestion").c_str(),currentMap.c_str()); snprintf(szBuf,8096,"%s %s ?",lang.getString("DownloadMissingMapQuestion").c_str(),currentMap.c_str());
// Is the item in the mod center? // Is the item in the mod center?
MutexSafeWrapper safeMutexThread((modHttpServerThread != NULL ? modHttpServerThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(mapCacheList.find(getMissingTechtreeFromFTPServer) == mapCacheList.end()) { if(mapCacheList.find(getMissingTechtreeFromFTPServer) == mapCacheList.end()) {
ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload")); ftpMessageBox.init(lang.getString("Yes"),lang.getString("NoDownload"));
} }
@ -4541,6 +4568,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost")); ftpMessageBox.init(lang.getString("ModCenter"),lang.getString("GameHost"));
ftpMessageBox.addButton(lang.getString("NoDownload")); ftpMessageBox.addButton(lang.getString("NoDownload"));
} }
safeMutexThread.ReleaseLock();
ftpMissingDataType = ftpmsg_MissingMap; ftpMissingDataType = ftpmsg_MissingMap;
showFTPMessageBox(szBuf, lang.getString("Question"), false); showFTPMessageBox(szBuf, lang.getString("Question"), false);

View File

@ -1069,9 +1069,10 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
void ServerInterface::checkForAutoPauseForLaggingClient(int index,ConnectionSlot* connectionSlot) { void ServerInterface::checkForAutoPauseForLaggingClient(int index,ConnectionSlot* connectionSlot) {
if (this->clientsAutoPausedDueToLag == false) { if (gameSettings.getNetworkPauseGameForLaggedClients() == true &&
this->clientsAutoPausedDueToLag == false) {
if (connectionSlot != NULL && connectionSlot->isConnected() == true) { if (connectionSlot != NULL && connectionSlot->isConnected() == true) {
if (connectionSlot->getAutoPauseGameCountForLag()< MAX_CLIENT_PAUSE_FOR_LAG_COUNT) { if (connectionSlot->getAutoPauseGameCountForLag() < MAX_CLIENT_PAUSE_FOR_LAG_COUNT) {
if (this->clientLagCallbackInterface != NULL) { if (this->clientLagCallbackInterface != NULL) {
if (this->clientsAutoPausedDueToLagTimer.isStarted() == false || if (this->clientsAutoPausedDueToLagTimer.isStarted() == false ||
@ -1438,7 +1439,8 @@ void ServerInterface::dispatchPendingUnMarkCellMessages(std::vector <string> &er
} }
void ServerInterface::checkForAutoResumeForLaggingClients() { void ServerInterface::checkForAutoResumeForLaggingClients() {
if (this->clientsAutoPausedDueToLag == true && if (gameSettings.getNetworkPauseGameForLaggedClients() == true &&
this->clientsAutoPausedDueToLag == true &&
this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) { this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) {
//printf("this->clientsAutoPausedDueToLag: %d [%lld]\n",this->clientsAutoPausedDueToLag,(long long)this->clientsAutoPausedDueToLagTimer.getMillis()); //printf("this->clientsAutoPausedDueToLag: %d [%lld]\n",this->clientsAutoPausedDueToLag,(long long)this->clientsAutoPausedDueToLagTimer.getMillis());

View File

@ -129,6 +129,7 @@ UnitType::UnitType() : ProducibleType() {
armor=0; armor=0;
sight=0; sight=0;
size=0; size=0;
renderSize=0;
height=0; height=0;
addItemToVault(&(this->maxHp),this->maxHp); addItemToVault(&(this->maxHp),this->maxHp);

View File

@ -8,7 +8,7 @@
define( 'PRODUCT_NAME', 'MegaGlest' ); define( 'PRODUCT_NAME', 'MegaGlest' );
define( 'PRODUCT_URL', 'http://megaglest.org' ); define( 'PRODUCT_URL', 'http://megaglest.org' );
define( 'MYSQL_HOST', '127.0.0.1' ); define( 'MYSQL_HOST', 'localhost' );
define( 'MYSQL_DATABASE', 'megaglest_master' ); define( 'MYSQL_DATABASE', 'megaglest_master' );
define( 'MYSQL_USER', 'not_root' ); define( 'MYSQL_USER', 'not_root' );
define( 'MYSQL_PASSWORD', 'your_pwd' ); define( 'MYSQL_PASSWORD', 'your_pwd' );

View File

@ -1163,7 +1163,7 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
if(meshName!="" && unitModel!=NULL){ if(meshName!="" && unitModel!=NULL){
//printf("meshName set unitModel given\n"); //printf("meshName set unitModel given\n");
bool foundMesh=false; bool foundMesh=false;
for(uint i=0; i<unitModel->getMeshCount() ; i++){ for(unsigned int i=0; i<unitModel->getMeshCount() ; i++){
//printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str());
if(unitModel->getMesh(i)->getName()==meshName){ if(unitModel->getMesh(i)->getName()==meshName){
const InterpolationData *data=unitModel->getMesh(i)->getInterpolationData(); const InterpolationData *data=unitModel->getMesh(i)->getInterpolationData();
@ -1178,7 +1178,7 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
} }
if( foundMesh == false ) { if( foundMesh == false ) {
string meshesFound=""; string meshesFound="";
for(uint i=0; i<unitModel->getMeshCount() ; i++){ for(unsigned i=0; i<unitModel->getMeshCount() ; i++){
meshesFound+= unitModel->getMesh(i)->getName()+", "; meshesFound+= unitModel->getMesh(i)->getName()+", ";
} }

View File

@ -449,7 +449,8 @@ void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugT
} }
char szBuf2[100]=""; char szBuf2[100]="";
if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { //if (type != debugPathFinder && type != debugError && type != debugWorldSynch) {
if (type != debugPathFinder && type != debugWorldSynch) {
// Get the current time. // Get the current time.
// time_t curtime = time (NULL); // time_t curtime = time (NULL);
// Convert it to local time representation. // Convert it to local time representation.
@ -581,7 +582,7 @@ void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugT
(*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << debugEntry.c_str(); (*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << debugEntry.c_str();
} }
else if (type == debugError) { else if (type == debugError) {
(*currentDebugLog.fileStream) << " *ERROR* " << debugEntry.c_str(); (*currentDebugLog.fileStream) << "[" << szBuf2 << "] *ERROR* " << debugEntry.c_str();
} }
else { else {
(*currentDebugLog.fileStream) << debugEntry.c_str(); (*currentDebugLog.fileStream) << debugEntry.c_str();
@ -602,7 +603,7 @@ void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugT
printf("[%s] %s", szBuf2, debugEntry.c_str()); printf("[%s] %s", szBuf2, debugEntry.c_str());
} }
else if (type == debugError) { else if (type == debugError) {
printf("*ERROR* %s", debugEntry.c_str()); printf("*ERROR* [%s] %s", szBuf2,debugEntry.c_str());
} }
else { else {
printf("%s", debugEntry.c_str()); printf("%s", debugEntry.c_str());

View File

@ -0,0 +1,920 @@
# -*- coding: utf-8 -*-
###########################################################################
# Glest Model / Texture / UV / Animation Importer and Exporter
# for the Game Glest that u can find http://www.glest.org
# copyright 2005 By Andreas Becker (seltsamuel@yahoo.de)
#
# 2011/05/25: v0.1 alpha1
# modified by William Zheng for Blender 2.57(loveheaven_zhengwei@hotmail.com)
#
# corrected by MrPostiga for Blender 2.58
#
# extended by Yggdrasil
#
# Started Date: 07 June 2005 Put Public 20 June 2005
# Distributed under the GNU PUBLIC LICENSE
#"""
#Here an explanation of the V4 Format found at www.glest.org
#================================
#1. DATA TYPES
#================================
#G3D files use the following data types:
#uint8: 8 bit unsigned integer
#uint16: 16 bit unsigned integer
#uint32: 32 bit unsigned integer
#float32: 32 bit floating point
#================================
#2. OVERALL STRUCTURE
#================================
#- File header
#- Model header
#- Mesh header
#- Texture names
#- Mesh data
#================================
#2. FILE HEADER
#================================
#Code:
#struct FileHeader{
# uint8 id[3];
# uint8 version;
#};
#This header is shared among all the versions of G3D, it identifies this file as a G3D model and provides information of the version.
#id: must be "G3D"
#version: must be 4, in binary (not '4')
#================================
#3. MODEL HEADER
#================================
#Code:
#struct ModelHeader{
# uint16 meshCount;
# uint8 type;
#};
#meshCount: number of meshes in this model
#type: must be 0
#================================
#4. MESH HEADER
#================================
#There is a mesh header for each mesh, there must be "meshCount" headers in a file but they are not consecutive, texture names and mesh data are stored in between.
#Code:
#struct MeshHeader{
# uint8 name[64];
# uint32 frameCount;
# uint32 vertexCount;
# uint32 indexCount;
# float32 diffuseColor[3];
# float32 specularColor[3];
# float32 specularPower;
# float32 opacity;
# uint32 properties;
# uint32 textures;
#};
#name: name of the mesh
#frameCount: number of keyframes in this mesh
#vertexCount: number of vertices in each frame
#indexCount: number of indices in this mesh (the number of triangles is indexCount/3)
#diffuseColor: RGB diffuse color
#specularColor: RGB specular color (currently unused)
#specularPower: specular power (currently unused)
##properties: property flags
#Code:
#enum MeshPropertyFlag{
# mpfCustomColor= 1,
# mpfTwoSided= 2,
# mpfNoSelect= 4
#};
#mpfTwoSided: meshes in this mesh are rendered by both sides, if this flag is not present only "counter clockwise" faces are rendered
#mpfCustomColor: alpha in this model is replaced by a custom color, usually the player color
#textures: texture flags
#Code:
#enum MeshTexture{
# diffuse = 1,
# specular = 2,
# normal = 4
#};
#================================
#4. TEXTURE NAMES
#================================
#A list of uint8[64] texture name values. One for each texture in the mesh. If there are no textures in the mesh no texture names are present.
#================================
#5. MESH DATA
#================================
#After each mesh header and texture names the mesh data is placed.
#vertices: frameCount * vertexCount * 3, float32 values representing the x, y, z vertex coords for all frames
#normals: frameCount * vertexCount * 3, float32 values representing the x, y, z normal coords for all frames
#texture coords: vertexCount * 2, float32 values representing the s, t tex coords for all frames (only present if the mesh has 1 texture at least)
#indices: indexCount, uint32 values representing the indices
###########################################################################
bl_info = {
"name": "G3D Mesh Import/Export",
"description": "Import/Export .g3d file (Glest 3D)",
"author": "various, see head of script",
"version": (0, 11, 1),
"blender": (2, 65, 0),
"location": "File > Import-Export",
"warning": "always keep .blend files",
"wiki_url": "http://glest.wikia.com/wiki/G3D_support",
"tracker_url": "https://forum.megaglest.org/index.php?topic=6596",
"category": "Import-Export"}
###########################################################################
# Importing Structures needed (must later verify if i need them really all)
###########################################################################
import bpy
from bpy.props import StringProperty
from bpy_extras.image_utils import load_image
from bpy_extras.io_utils import ImportHelper, ExportHelper
import bmesh
import sys, struct, string, types
from types import *
import os
from os import path
from os.path import dirname, abspath
import subprocess
from mathutils import Matrix
from math import radians
###########################################################################
# Variables that are better Global to handle
###########################################################################
imported = [] #List of all imported Objects
toexport = [] #List of Objects to export (actually only meshes)
sceneID = None #Points to the active Blender Scene
def unpack_list(list_of_tuples):
l = []
for t in list_of_tuples:
l.extend(t)
return l
###########################################################################
# Declaring Structures of G3D Format
###########################################################################
class G3DHeader: #Read first 4 Bytes of file should be G3D + Versionnumber
binary_format = "<3cB"
def __init__(self, fileID):
temp = fileID.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format,temp)
self.id = str(data[0]+data[1]+data[2], "utf-8")
self.version = data[3]
class G3DModelHeaderv3: #Read Modelheader in V3 there is only the number of Meshes in file
binary_format = "<I"
def __init__(self, fileID):
temp = fileID.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format,temp)
self.meshcount = data[0]
class G3DModelHeaderv4: #Read Modelheader: Number of Meshes and Meshtype (must be 0)
binary_format = "<HB"
def __init__(self, fileID):
temp = fileID.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format,temp)
self.meshcount = data[0]
self.mtype = data[1]
class G3DMeshHeaderv3: #Read Meshheader
binary_format = "<7I64c"
def __init__(self,fileID):
temp = fileID.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format,temp)
self.framecount = data[0] #Framecount = Number of Animationsteps
self.normalframecount= data[1] #Number of Normal Frames actualli equal to Framecount
self.texturecoordframecount= data[2]#Number of Frames of Texturecoordinates seems everytime to be 1
self.colorframecount= data[3] #Number of Frames of Colors seems everytime to be 1
self.vertexcount= data[4] #Number of Vertices in each Frame
self.indexcount= data[5] #Number of Indices in Mesh (Triangles = Indexcount/3)
self.properties= data[6] #Property flags
if self.properties & 1: #PropertyBit is Mesh Textured ?
self.hastexture = False
self.diffusetexture = None
else:
self.diffusetexture = "".join([str(x, "ascii") for x in data[7:-1] if x[0]< 127 ])
self.hastexture = True
if self.properties & 2: #PropertyBit is Mesh TwoSided ?
self.istwosided = True
else:
self.istwosided = False
if self.properties & 4: #PropertyBit is Mesh Alpha Channel custom Color in Game ?
self.customalpha = True
else:
self.customalpha = False
class G3DMeshHeaderv4: #Read Meshheader
binary_format = "<64c3I8f2I"
texname_format = "<64c"
def _readtexname(self,fileID):
temp = fileID.read(struct.calcsize(self.texname_format))
data = struct.unpack(self.texname_format,temp)
return "".join([str(x, "ascii") for x in data[0:-1] if x[0] < 127 ])
def __init__(self,fileID):
temp = fileID.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format,temp)
self.meshname = "".join([str(x, "ascii") for x in data[0:64] if x[0] < 127 ]) #Name of Mesh every Char is a String on his own
self.framecount = data[64] #Framecount = Number of Animationsteps
self.vertexcount = data[65] #Number of Vertices in each Frame
self.indexcount = data[66] #Number of Indices in Mesh (Triangles = Indexcount/3)
self.diffusecolor = data[67:70] #RGB diffuse color
self.specularcolor = data[70:73] #RGB specular color (unused)
self.specularpower = data[73] #Specular power (unused)
self.opacity = data[74] #Opacity
self.properties = data[75] #Property flags
self.textures = data[76] #Texture flags
self.customalpha = bool(self.properties & 1)
self.istwosided = bool(self.properties & 2)
self.noselect = bool(self.properties & 4)
self.hastexture = False
self.diffusetexture = None
self.speculartexture = None
self.normaltexture = None
if self.textures: #PropertyBit is Mesh Textured ?
if self.textures & 1: # diffuse
self.diffusetexture = self._readtexname(fileID)
if self.textures & 2: # specular
self.speculartexture = self._readtexname(fileID)
if self.textures & 4: # normal
self.normaltexture = self._readtexname(fileID)
self.hastexture = True
# read all texture slots, otherwise it's read as data
tex = self.textures >> 3
while tex:
tex &= tex - 1 # set rightmost 1-bit to 0
# discard texture name, as we don't know what to do with it
fileID.seek(struct.calcsize(self.texname_format))
print("warning: ignored texture in undefined texture slot")
class G3DMeshdataV3: #Calculate and read the Mesh Datapack
def __init__(self,fileID,header):
#Calculation of the Meshdatasize to load because its variable
#Animationframes * Vertices per Animation * 3 (Each Point are 3 Float X Y Z Coordinates)
vertex_format = "<%if" % int(header.framecount * header.vertexcount * 3)
#The same for Normals
normals_format = "<%if" % int(header.normalframecount * header.vertexcount * 3)
#Same here but Textures are 2D so only 2 Floats needed for Position inside Texture Bitmap
texturecoords_format = "<%if" % int(header.texturecoordframecount * header.vertexcount * 2)
#Colors in format RGBA
colors_format = "<%if" % int(header.colorframecount * 4)
#Indices
indices_format = "<%iI" % int(header.indexcount)
#Load the Meshdata as calculated above
self.vertices = struct.unpack(vertex_format,fileID.read(struct.calcsize(vertex_format)))
self.normals = struct.unpack(normals_format,fileID.read(struct.calcsize(normals_format)))
self.texturecoords = struct.unpack(texturecoords_format,fileID.read(struct.calcsize(texturecoords_format)))
self.colors = struct.unpack(colors_format,fileID.read(struct.calcsize(colors_format)))
self.indices = struct.unpack(indices_format ,fileID.read(struct.calcsize(indices_format)))
class G3DMeshdataV4: #Calculate and read the Mesh Datapack
def __init__(self,fileID,header):
#Calculation of the Meshdatasize to load because its variable
#Animationframes * Points (Vertex) per Animation * 3 (Each Point are 3 Float X Y Z Coordinates)
vertex_format = "<%if" % int(header.framecount * header.vertexcount * 3)
#The same for Normals
normals_format = "<%if" % int(header.framecount * header.vertexcount * 3)
#Same here but Textures are 2D so only 2 Floats needed for Position inside Texture Bitmap
texturecoords_format = "<%if" % int(header.vertexcount * 2)
#Indices
indices_format = "<%iI" % int(header.indexcount)
#Load the Meshdata as calculated above
self.vertices = struct.unpack(vertex_format,fileID.read(struct.calcsize(vertex_format)))
self.normals = struct.unpack(normals_format,fileID.read(struct.calcsize(normals_format)))
if header.hastexture:
self.texturecoords = struct.unpack(texturecoords_format,fileID.read(struct.calcsize(texturecoords_format)))
self.indices = struct.unpack(indices_format ,fileID.read(struct.calcsize(indices_format)))
#Create a Mesh inside Blender
def createMesh(filename, header, data, toblender, operator):
mesh = bpy.data.meshes.new(header.meshname) #New Mesh
meshobj = bpy.data.objects.new(header.meshname+'Object', mesh) #New Object for the new Mesh
scene = bpy.context.scene
scene.objects.link(meshobj)
scene.update()
uvcoords = []
img_diffuse = None
img_specular = None
img_normal = None
if header.hastexture: #Load Texture when assigned
try:
texturefile = dirname(abspath(filename)) + os.sep + header.diffusetexture
img_diffuse = bpy.data.images.load(texturefile)
for x in range(0,len(data.texturecoords),2): #Prepare the UV
uvcoords.append([data.texturecoords[x],data.texturecoords[x+1]])
if header.isv4:
if header.speculartexture:
texturefile = dirname(abspath(filename)) + os.sep + header.speculartexture
img_specular = bpy.data.images.load(texturefile)
if header.normaltexture:
texturefile = dirname(abspath(filename)) + os.sep + header.normaltexture
img_normal = bpy.data.images.load(texturefile)
except:
import traceback
traceback.print_exc()
header.hastexture = False
operator.report({'WARNING'}, "Couldn't load texture. See console for details.")
vertsCO = []
vertsNormal = []
for x in range(0,header.vertexcount*3,3): #Get the Vertices and Normals into empty Mesh
vertsCO.extend([(data.vertices[x],data.vertices[x+1],data.vertices[x+2])])
vertsNormal.extend([(data.normals[x],data.normals[x+1],data.normals[x+2])])
#vertsCO.extend([(data.vertices[x+(header.framecount-1)*header.vertexcount*3],data.vertices[x+(header.framecount-1)*header.vertexcount*3+1],data.vertices[x+(header.framecount-1)*header.vertexcount*3+2])])
#vertsNormal.extend([(data.normals[x+(header.framecount-1)*header.vertexcount*3],data.normals[x+(header.framecount-1)*header.vertexcount*3+1],data.normals[x+(header.framecount-1)*header.vertexcount*3+2])])
mesh.vertices.add(len(vertsCO))
mesh.vertices.foreach_set("co", unpack_list(vertsCO))
mesh.vertices.foreach_set("normal", unpack_list(vertsNormal))
faces = []
faceuv = []
for i in range(0,len(data.indices),3): #Build Faces into Mesh
faces.extend([data.indices[i], data.indices[i+1], data.indices[i+2], 0])
if header.hastexture:
uv = []
u0 = uvcoords[data.indices[i]][0]
v0 = uvcoords[data.indices[i]][1]
uv.append([u0,v0])
u1 = uvcoords[data.indices[i+1]][0]
v1 = uvcoords[data.indices[i+1]][1]
uv.append([u1,v1])
u2 = uvcoords[data.indices[i+2]][0]
v2 = uvcoords[data.indices[i+2]][1]
uv.append([u2,v2])
faceuv.append([uv,0,0,0])
else:
uv = []
uv.append([0,0])
uv.append([0,0])
uv.append([0,0])
faceuv.append([uv,0,0,0])
mesh.tessfaces.add(len(faces)//4)
mesh.tessfaces.foreach_set("vertices_raw", faces)
mesh.tessfaces.foreach_set("use_smooth", [True] * len(mesh.tessfaces))
mesh.g3d_customColor = header.customalpha
mesh.show_double_sided = header.istwosided
if header.isv4:
mesh.g3d_noSelect = header.noselect
else:
mesh.g3d_noSelect = False
mesh.g3d_fullyOpaque = False
#===================================================================================================
#Material Setup
#===================================================================================================
def addtexslot(matdata,index,name,img):
texture = bpy.data.textures.new(name=name,type='IMAGE')
texture.image = img
slot = matdata.texture_slots.create(index)
slot.texture = texture
slot.texture_coords = 'UV'
if header.hastexture:
materialname = "pskmat"
materials = []
matdata = bpy.data.materials.new(materialname + '1')
addtexslot(matdata, 0, 'diffusetexture', img_diffuse)
if img_specular:
addtexslot(matdata, 1, 'speculartexture', img_specular)
if img_normal:
addtexslot(matdata, 2, 'normaltexture', img_normal)
if header.isv4:
matdata.diffuse_color = (header.diffusecolor[0], header.diffusecolor[1],header.diffusecolor[2])
matdata.alpha = header.opacity
matdata.specular_color = (header.specularcolor[0], header.specularcolor[1],header.specularcolor[2])
materials.append(matdata)
for material in materials:
#add material to the mesh list of materials
mesh.materials.append(material)
countm = 0
psktexname="psk" + str(countm)
mesh.tessface_uv_textures.new(name=psktexname)
if (len(faceuv) > 0):
for countm in range(len(mesh.tessface_uv_textures)):
uvtex = mesh.tessface_uv_textures[countm] #add one uv texture
for i, face in enumerate(mesh.tessfaces):
blender_tface = uvtex.data[i] #face
mfaceuv = faceuv[i]
if countm == faceuv[i][1]:
face.material_index = faceuv[i][1]
blender_tface.uv1 = mfaceuv[0][0] #uv = (0,0)
blender_tface.uv2 = mfaceuv[0][1] #uv = (0,0)
blender_tface.uv3 = mfaceuv[0][2] #uv = (0,0)
blender_tface.image = img_diffuse
else:
blender_tface.uv1 = [0,0]
blender_tface.uv2 = [0,0]
blender_tface.uv3 = [0,0]
imported.append(meshobj) #Add to Imported Objects
sk = meshobj.shape_key_add()
for x in range(1,header.framecount): #Put in Vertex Positions for Keyanimation
sk = meshobj.shape_key_add()
for i in range(0,header.vertexcount*3,3):
sk.data[i//3].co[0]= data.vertices[x*header.vertexcount*3 + i]
sk.data[i//3].co[1]= data.vertices[x*header.vertexcount*3 + i +1]
sk.data[i//3].co[2]= data.vertices[x*header.vertexcount*3 + i +2]
# activate one shapekey per frame
for i in range(1,header.framecount):
shape = mesh.shape_keys.key_blocks[i]
shape.value = 0.0
shape.keyframe_insert("value", frame=i)
shape.value = 1.0
shape.keyframe_insert("value", frame=(i+1))
shape.value = 0.0
shape.keyframe_insert("value", frame=(i+2))
meshobj.active_shape_key_index = 0
if toblender:
# rotate from glest to blender orientation
#mesh.transform( Matrix( ((1,0,0,0),(0,0,-1,0),(0,1,0,0),(0,0,0,1)) ) )
# doesn't work, maybe because of shape keys
# use object transformation instead
meshobj.rotation_euler = (radians(90), 0, 0)
# update polygon structures from tessfaces
mesh.update()
mesh.update_tag()
# remove duplicates
bm = bmesh.new()
bm.from_mesh(mesh)
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
bm.to_mesh(mesh)
bm.free()
return
###########################################################################
# Import
###########################################################################
def G3DLoader(filepath, toblender, operator): #Main Import Routine
global imported, sceneID
print ("\nNow Importing File: " + filepath)
fileID = open(filepath,"rb")
header = G3DHeader(fileID)
print ("\nHeader ID : " + header.id)
print ("Version : " + str(header.version))
if header.id != "G3D":
print ("ERROR: This is Not a G3D Model File")
operator.report({'ERROR'}, "This is Not a G3D Model File")
fileID.close
return
if header.version not in (3, 4):
print ("ERROR: The Version of this G3D File is not Supported")
operator.report({'ERROR'}, "The Version of this G3D File is not Supported")
fileID.close
return
#in_editmode = Blender.Window.EditMode() #Must leave Editmode when active
#if in_editmode: Blender.Window.EditMode(0)
sceneID = bpy.context.scene #Get active Scene
#scenecontext=sceneID.getRenderingContext() #To Access the Start/Endframe its so hidden i searched till i got angry :-)
basename=os.path.basename(filepath).split('.')[0] #Generate the Base Filename without Path + extension
imported = []
maxframe=0
if header.version == 3:
modelheader = G3DModelHeaderv3(fileID)
print ("Number of Meshes : " + str(modelheader.meshcount))
for x in range(modelheader.meshcount):
meshheader = G3DMeshHeaderv3(fileID)
meshheader.isv4 = False
print ("\nMesh Number : " + str(x+1))
print ("framecount : " + str(meshheader.framecount))
print ("normalframecount : " + str(meshheader.normalframecount))
print ("texturecoordframecount: " + str(meshheader.texturecoordframecount))
print ("colorframecount : " + str(meshheader.colorframecount))
print ("pointcount : " + str(meshheader.vertexcount))
print ("indexcount : " + str(meshheader.indexcount))
print ("texturename : " + str(meshheader.diffusetexture))
print ("hastexture : " + str(meshheader.hastexture))
print ("istwosided : " + str(meshheader.istwosided))
print ("customalpha : " + str(meshheader.customalpha))
meshheader.meshname = basename+str(x+1) #Generate Meshname because V3 has none
if meshheader.framecount > maxframe: maxframe = meshheader.framecount #Evaluate the maximal animationsteps
meshdata = G3DMeshdataV3(fileID,meshheader)
createMesh(filepath, meshheader, meshdata, toblender, operator)
fileID.close
bpy.context.scene.frame_start=1
bpy.context.scene.frame_end=maxframe
bpy.context.scene.frame_current=1
anchor = bpy.data.objects.new('Empty', None)
anchor.select = True
bpy.context.scene.objects.link(anchor)
for ob in imported:
ob.parent = anchor
bpy.context.scene.update()
return
if header.version == 4:
modelheader = G3DModelHeaderv4(fileID)
print ("Number of Meshes : " + str(modelheader.meshcount))
for x in range(modelheader.meshcount):
meshheader = G3DMeshHeaderv4(fileID)
meshheader.isv4 = True
print ("\nMesh Number : " + str(x+1))
print ("meshname : " + str(meshheader.meshname))
print ("framecount : " + str(meshheader.framecount))
print ("vertexcount : " + str(meshheader.vertexcount))
print ("indexcount : " + str(meshheader.indexcount))
print ("diffusecolor : %1.6f %1.6f %1.6f" %meshheader.diffusecolor)
print ("specularcolor : %1.6f %1.6f %1.6f" %meshheader.specularcolor)
print ("specularpower : %1.6f" %meshheader.specularpower)
print ("opacity : %1.6f" %meshheader.opacity)
print ("properties : " + str(meshheader.properties))
print ("textures : " + str(meshheader.textures))
print ("texturename : " + str(meshheader.diffusetexture))
if len(meshheader.meshname) ==0: #When no Meshname in File Generate one
meshheader.meshname = basename+str(x+1)
if meshheader.framecount > maxframe: maxframe = meshheader.framecount #Evaluate the maximal animationsteps
meshdata = G3DMeshdataV4(fileID,meshheader)
createMesh(filepath, meshheader, meshdata, toblender, operator)
fileID.close
bpy.context.scene.frame_start=1
bpy.context.scene.frame_end=maxframe
bpy.context.scene.frame_current=1
anchor = bpy.data.objects.new('Empty', None)
anchor.select = True
bpy.context.scene.objects.link(anchor)
for ob in imported:
ob.parent = anchor
bpy.context.scene.update()
print ("Created a empty Object as 'Grip' where all imported Objects are parented to")
print ("To move the complete Meshes only select this empty Object and move it")
print ("All Done, have a good Day :-)\n\n")
return
def G3DSaver(filepath, context, toglest, operator):
print ("\nNow Exporting File: " + filepath)
objs = context.selected_objects
if len(objs) == 0:
objs = bpy.data.objects
#get real meshcount as len(bpy.data.meshes) holds also old meshes
meshCount = 0
for obj in objs:
if obj.type == 'MESH':
meshCount += 1
if obj.mode != 'OBJECT': # we want to be in object mode
print("ERROR: mesh not in object mode")
operator.report({'ERROR'}, "mesh not in object mode")
return -1
if meshCount == 0:
print("ERROR: no meshes found")
operator.report({'ERROR'}, "no meshes found")
return -1
fileID = open(filepath,"wb")
# G3DHeader v4
fileID.write(struct.pack("<3cB", b'G', b'3', b'D', 4))
# G3DModelHeaderv4
fileID.write(struct.pack("<HB", meshCount, 0))
# meshes
#for mesh in bpy.data.meshes:
for obj in objs:
if obj.type != 'MESH':
continue
mesh = obj.data.copy()
diffuseColor = [1.0, 1.0, 1.0]
specularColor = [0.9, 0.9, 0.9]
opacity = 1.0
textures = 0
if len(mesh.materials) > 0:
# we have a texture, hopefully
material = mesh.materials[0]
slot = material.texture_slots[0]
# only look for other textures when we have diffuse
if slot and slot.texture.type=='IMAGE' and len(mesh.uv_textures)>0:
diffuseColor = material.diffuse_color
specularColor = material.specular_color
opacity = material.alpha
textures = 1
texnames = []
texnames.append(bpy.path.basename(slot.texture.image.filepath))
# specular and normal
for i in range(1, 3):
slot = material.texture_slots[i]
if slot and slot.texture.type=='IMAGE':
texnames.append(bpy.path.basename(slot.texture.image.filepath))
textures |= 1 << i
else:
print("WARNING: first texture slot in first material isn't of type IMAGE or it's not unwrapped, texture ignored")
operator.report({'WARNING'}, "first texture slot in first material isn't of type IMAGE or it's not unwrapped, texture ignored")
#continue without texture
meshname = mesh.name
frameCount = context.scene.frame_end - context.scene.frame_start +1
realFaceCount = 0 # real face count (triangles)
indices=[] # list of indices
newverts=[] # list of vertex indices which need to be duplicated
uvlist = [] # list of texcoords
mesh.update(calc_tessface=True) # tesselate n-polygons to triangles & quads
if textures:
uvtex = mesh.tessface_uv_textures[0]
uvlist[:] = [[0]*2 for i in range(len(mesh.vertices))]
# blender allows to have multiple texcoords per vertex,
# in g3d format every vertex can only have one texcoord
# -> duplicate vertex
# the dictionary/map vdict collects all the stuff
# index to "unique" vertices from blender
# -> tuple( list of texcoords, list of indices to the duplicated vertex )
vdict = dict()
nextIndex = len(mesh.vertices)
for face in mesh.tessfaces:
# when a vertex is duplicated it gets a new index, so the
# triple of indices describing the face is different too
faceindices = []
realFaceCount += 1
uvdata = uvtex.data[face.index]
for i in range(3):
#closure, got rid of copy&paste, still looking weird
def getTexCoords():
nonlocal nextIndex, vdict, uvlist, newverts
vindex = face.vertices[i]
if vindex not in vdict: # new vertex -> add it
vdict[vindex] = [uvdata.uv[i]], [vindex]
uvlist[vindex] = uvdata.uv[i] # that's a (s,t)-pair
else:
found = False
idx = 0
for ele in vdict[vindex][0]:
if uvdata.uv[i][0] == ele[0] and uvdata.uv[i][1] == ele[1]:
found = True
break
idx += 1
if found: # same vertex and texcoord before
# it could be a different index now, the index of a new
# duplicated vertex
#vindex = vdict[vindex][1][ vdict[vindex][0].index(uvdata.uv[i]) ]
vindex = vdict[vindex][1][idx]
else: # same vertex as before but with different texcoord -> duplicate
vdict[vindex][0].append(uvdata.uv[i])
vdict[vindex][1].append(nextIndex)
# duplicate vertex because it takes part in different faces
# with different texcoords
newverts.append(vindex)
uvlist.append(uvdata.uv[i])
# new index for the duplicated vertex
vindex = nextIndex
nextIndex += 1
faceindices.append(vindex)
getTexCoords()
indices.extend(faceindices)
if len(face.vertices) == 4:
faceindices = []
realFaceCount += 1
for i in [0,2,3]:
getTexCoords()
indices.extend(faceindices)
else:
for face in mesh.tessfaces:
realFaceCount += 1
indices.extend(face.vertices[0:3])
if len(face.vertices) == 4:
realFaceCount += 1
# new face because quad got split
indices.append(face.vertices[0])
indices.append(face.vertices[2])
indices.append(face.vertices[3])
# abort when no triangles as it crashs g3dviewer
if realFaceCount == 0:
print("ERROR: no triangles found")
operator.report({'ERROR'}, "no triangles found")
fileID.close()
return -1
indexCount = realFaceCount * 3
vertexCount = len(mesh.vertices) + len(newverts)
specularPower = 9.999999 # unused, same as old exporter
properties = 0
if mesh.g3d_customColor:
properties |= 1
if mesh.show_double_sided:
properties |= 2
if mesh.g3d_noSelect:
properties |= 4
#MeshData
vertices = []
normals = []
fcurrent = context.scene.frame_current
for i in range(context.scene.frame_start, context.scene.frame_end+1):
context.scene.frame_set(i)
#FIXME: not sure what's better: PREVIEW or RENDER settings
m = obj.to_mesh(context.scene, True, 'RENDER')
m.transform(obj.matrix_world) # apply object-mode transformations
if toglest:
# rotate from blender to glest orientation
m.transform( Matrix( ((1,0,0,0),(0,0,1,0),(0,-1,0,0),(0,0,0,1)) ) )
# transform normals too
m.calc_normals()
for vertex in m.vertices:
vertices.extend(vertex.co)
normals.extend(vertex.normal)
# duplicate vertices and corresponding normals, for every frame
for nv in newverts:
vertices.extend(m.vertices[nv].co)
normals.extend(m.vertices[nv].normal)
context.scene.frame_set(fcurrent)
if mesh.g3d_fullyOpaque:
opacity = 1.0
# MeshHeader
fileID.write(struct.pack("<64s3I8f2I",
bytes(meshname, "ascii"),
frameCount, vertexCount, indexCount,
diffuseColor[0], diffuseColor[1], diffuseColor[2],
specularColor[0], specularColor[1], specularColor[2],
specularPower, opacity,
properties, textures
))
#Texture names
if textures: # only when we have textures
for i in range(len(texnames)):
fileID.write(struct.pack("<64s", bytes(texnames[i], "ascii")))
# see G3DMeshdataV4
vertex_format = "<%if" % int(frameCount * vertexCount * 3)
normals_format = "<%if" % int(frameCount * vertexCount * 3)
texturecoords_format = "<%if" % int(vertexCount * 2)
indices_format = "<%iI" % int(indexCount)
fileID.write(struct.pack(vertex_format, *vertices))
fileID.write(struct.pack(normals_format, *normals))
# texcoords
if textures: # only when we have textures
texcoords = []
for uv in uvlist:
texcoords.extend(uv)
fileID.write(struct.pack(texturecoords_format, *texcoords))
fileID.write(struct.pack(indices_format, *indices))
fileID.close()
return 0
#---=== Register ===
class G3DPanel(bpy.types.Panel):
#bl_idname = "OBJECT_PT_G3DPanel"
bl_label = "G3D properties"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
return (context.object is not None and context.object.type == 'MESH')
def draw(self, context):
self.layout.prop(context.object.data, "g3d_customColor")
self.layout.prop(context.object.data, "show_double_sided", text="double sided")
self.layout.prop(context.object.data, "g3d_noSelect")
self.layout.prop(context.object.data, "g3d_fullyOpaque")
class ImportG3D(bpy.types.Operator, ImportHelper):
'''Load a G3D file'''
bl_idname = "importg3d.g3d"
bl_label = "Import G3D"
filename_ext = ".g3d"
filter_glob = StringProperty(default="*.g3d", options={'HIDDEN'})
toblender = bpy.props.BoolProperty(
name="rotate to Blender orientation",
description="Rotate meshes from Glest to Blender orientation",
default=True)
def execute(self, context):
try:
G3DLoader(self.filepath, self.toblender, self)
except:
import traceback
traceback.print_exc()
return {'CANCELLED'}
return {'FINISHED'}
class ExportG3D(bpy.types.Operator, ExportHelper):
'''Save a G3D file'''
bl_idname = "exportg3d.g3d"
bl_label = "Export G3D"
filename_ext = ".g3d"
filter_glob = StringProperty(default="*.g3d", options={'HIDDEN'})
#export options
showg3d = bpy.props.BoolProperty(
name="show G3D afterwards",
description=("Run g3dviewer to show G3D after export. "
"g3dviewer needs to be in the scripts directory, "
"otherwise the associated program of .g3d is run."),
default=False)
toglest = bpy.props.BoolProperty(
name="rotate to glest orientation",
description="Rotate meshes from Blender to Glest orientation",
default=True)
def execute(self, context):
try:
res = G3DSaver(self.filepath, context, self.toglest, self)
if res==0 and self.showg3d:
print("opening g3dviewer with " + self.filepath)
scriptsdir = bpy.utils.script_path_user()
dname = os.path.dirname(self.filepath)
found = False
for f in os.listdir(scriptsdir):
if "g3dviewer" in f:
f = os.path.join(scriptsdir, f)
if os.path.isfile(f) and os.access(f, os.X_OK):
cmd = [f, self.filepath]
print(cmd)
subprocess.Popen(cmd, cwd=dname)
found = True
# try default associated program
if not found:
if os.name == 'posix':
# xdg-open is only a shell script which delegates the job to a
# desktop specific program, e.g. if DE=kde than kde-open
# needs DE environment variable set, otherwise it just throws it
# at the browser, which is not very helpful
print("running xdg-open "+self.filepath)
subprocess.Popen(['xdg-open', self.filepath], cwd=dname)
elif os.name == 'mac':
subprocess.Popen(['open', self.filepath], cwd=dname)
elif os.name == 'nt':
#os.startfile(self.filepath) # no way to change dir
subprocess.Popen(['cmd', '/C', 'start', self.filepath], cwd=dname)
except:
import traceback
traceback.print_exc()
return {'CANCELLED'}
return {'FINISHED'}
def menu_func_import(self, context):
self.layout.operator(ImportG3D.bl_idname, text="Glest 3D File (.g3d)")
def menu_func_export(self, context):
self.layout.operator(ExportG3D.bl_idname, text="Glest 3D File (.g3d)")
def register():
# custom mesh properties
bpy.types.Mesh.g3d_customColor = bpy.props.BoolProperty(
name="team color",
description="replace alpha channel of texture with team color")
bpy.types.Mesh.g3d_noSelect = bpy.props.BoolProperty(
name="non-selectable",
description="click on mesh doesn't select unit")
bpy.types.Mesh.g3d_fullyOpaque = bpy.props.BoolProperty(
name="fully opaque",
description="sets opacity to 1.0, ignoring what's set in materials")
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func_import)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == '__main__':
register()
# main()
#for obj in bpy.data.objects:
# if obj.type == 'MESH':
# obj.select = True
# bpy.ops.object.delete()
#G3DLoader("import.g3d", True, None)
#for obj in bpy.context.selected_objects:
# obj.select = False # deselect everything, so we get it all
#G3DSaver("test.g3d", bpy.context)