Compare commits

..

23 Commits

Author SHA1 Message Date
James Turner
8cc607b25a Initial bump for 3.0.1
- includes Maclauncher work-around for bug 1377
2014-02-25 15:51:54 +00:00
Clément de l'Hamaide
223941a09a bump FG revision 2014-02-15 00:23:45 +01:00
Clement de l'Hamaide
f5f09611a6 uncheck 32 bits install by default + add info page 2014-02-14 22:51:31 +01:00
Clement de l'Hamaide
8d021e6f53 Bump FG revision 2014-02-14 22:23:46 +01:00
Clément de l'Hamaide
acf6d62fbc Bump FGRun revision 2014-02-14 14:16:35 +01:00
James Turner
0a00d898b7 Bump for SG+FG fixes. 2014-02-10 18:08:12 +00:00
Gijs de Rooy
c99ea4c0ed Update fgmeta for fgrun console fix 2014-02-04 17:47:19 +01:00
James Turner
4ae520beed And bump FGRun too. 2014-02-01 12:36:32 +00:00
James Turner
61eee4de8a Bump for RC2 point
flightgear, simgear and mac-launcher tweaks
2014-02-01 09:45:25 +00:00
Clément de l'Hamaide
e45c26e648 Bump FGRun revision 2014-01-23 19:45:22 +01:00
James Turner
f16c99683e Bump for material-reload crash fix. 2014-01-23 09:19:37 +00:00
James Turner
004f7ad904 Remove references to SVN in Mac release. 2014-01-23 09:04:33 +00:00
James Turner
bfa7a4a35a Fix CrashRpt install
(Wrong name for CrashSender helper)
2014-01-23 09:04:15 +00:00
James Turner
7729f3eb4a Bump for FG change. 2014-01-22 22:37:14 +00:00
James Turner
2c6d4e2aa7 Bump for FG tweak 2014-01-21 09:26:08 +00:00
Clément de l'Hamaide
f577196ace bump maclauncher revision 2014-01-20 13:36:01 +01:00
James Turner
416e22b6e1 Bump for CrashRpt in FG 2014-01-20 10:41:43 +00:00
James Turner
029d5d81ef Bump for CameraViewportListener change
(Should fix Mac release build)
2014-01-18 18:50:59 +00:00
James Turner
62dd9bc458 Switch Windows SG+FG builds to RelWithDebInfo
This means PDB files will be generated, suitable for post-hoc
minidump assembly.
2014-01-18 14:53:48 +00:00
James Turner
187a29f1b9 ISS rules for CrashRpt 2014-01-18 14:45:44 +00:00
James Turner
52c0f90d16 Switch 3.0 Mac release build to use Release mode. 2014-01-18 14:38:06 +00:00
Clément de l'Hamaide
698342ebce Switch on release/3.0.0 for fgrun submodule 2014-01-18 10:45:39 +01:00
James Turner
ca076b78ff Create 3.0 branch head. 2014-01-17 21:29:26 +00:00
53 changed files with 2401 additions and 6097 deletions

4
.gitignore vendored
View File

@@ -2,7 +2,6 @@ dist
.DS_Store
install
3rdParty
3rdParty.x64
boost_1_44_0
InstallConfig.iss
Output
@@ -12,6 +11,7 @@ sgBuild
image
build
macflightgear
fgdata
src
tmp
Makefile
@@ -19,5 +19,3 @@ CMakeFiles
archivebuild
osgbuild
CMakeCache.txt
*.pyc
build-*

16
.gitmodules vendored
View File

@@ -1,20 +1,16 @@
[submodule "simgear"]
path = simgear
url = https://git.code.sf.net/p/flightgear/simgear
url = git://gitorious.org/fg/simgear.git
branch = next
[submodule "flightgear"]
path = flightgear
url = https://git.code.sf.net/p/flightgear/flightgear
url = git://gitorious.org/fg/flightgear.git
branch = next
[submodule "fgrun"]
path = fgrun
url = https://git.code.sf.net/p/flightgear/fgrun
url = git://gitorious.org/fg/fgrun.git
branch = next
[submodule "fgdata"]
path = fgdata
url = git://git.code.sf.net/p/flightgear/fgdata
branch = next
[submodule "windows-3rd-party"]
path = windows-3rd-party
url = https://git.code.sf.net/p/flightgear/windows-3rd-party
[submodule "maclauncher"]
path = maclauncher
url = git://gitorious.org/fg/maclauncher.git
branch = master

View File

@@ -1,41 +1,65 @@
cmake_minimum_required (VERSION 2.8.0)
cmake_minimum_required (VERSION 2.6.4)
include (ExternalProject)
project(FlightGear-Meta)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
message(STATUS "Default install dir set to ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Default install dir to ${CMAKE_INSTALL_PREFIX}")
endif()
if (UNIX)
set(BOOST_BOOTSTRAP "./bootstrap.sh" --prefix=${CMAKE_INSTALL_PREFIX})
else()
set(BOOST_BOOTSTRAP "bootstrap.bat")
endif()
set(SG_DEPS OSG)
set(FG_DEPS SimGear)
set(SG_CMAKE_ARGS "")
set(FG_CMAKE_ARGS "")
set(FGRUN_CMAKE_ARGS "")
if(APPLE)
set(BOOST_ARGS link=static stage --with-system)
ExternalProject_Add(Boost
PREFIX ${CMAKE_BINARY_DIR}
SVN_REPOSITORY http://svn.boost.org/svn/boost/tags/release/Boost_1_52_0
UPDATE_COMMAND ${BOOST_BOOTSTRAP}
CONFIGURE_COMMAND ""
BUILD_COMMAND ./bjam ${BOOST_ARGS}
BUILD_IN_SOURCE 1
INSTALL_COMMAND ./b2 install ${BOOST_ARGS})
list(APPEND SG_DEPS Boost)
endif() # of Apple
set(OSG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(SG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(FG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(PLIB_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(RTI_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(FGRUN_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
# OpenSceneGraph configuration
#set(OSG_SOURCE http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
set(OSG_SOURCE https://github.com/openscenegraph/osg.git)
set(OSG_TAG OpenSceneGraph-3.2)
set(OSG_SOURCE http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
if (APPLE)
# force disable Qt and Jasper
set(OSG_CMAKE_ARGS
set(SDKROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk)
# force disable Qt and Jasper, and ensure an SDKROOT is set, or
# osgViewer system detection goes wrongh
set(OSG_CMAKE_ARGS -DCMAKE_OSX_SYSROOT=${SDKROOT}
-DOSG_USE_QT=0
-DJASPER_LIBRARY=
-DSDL_LIBRARY:FILEPATH=
-DCMAKE_OSX_ARCHITECTURES=x86_64
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7
)
# OSG with some patches applied for Mac
set(OSG_SOURCE https://github.com/zakalawe/osg.git)
set(OSG_TAG fgfs-osg-32)
# set(OSG_SOURCE GIT_REPOSITORY git://gitorious.org/+flightgear-developers/openscenegraph/mac-release-osg.git)
# set(OSG_SOURCE URL http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
elseif(MSVC)
set(OSG_MSVC "msvc")
if (${MSVC_VERSION} EQUAL 1700)
@@ -54,20 +78,12 @@ elseif(MSVC)
endif (CMAKE_CL_64)
SET(OSG_CMAKE_ARGS
-DOSG_USE_QT:BOOL=OFF
-DACTUAL_3RDPARTY_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}
-DBUILD_OSG_APPLICATIONS:BOOL=ON
-DOSG_PLUGIN_SEARCH_INSTALL_DIR_FOR_PLUGINS:BOOL=OFF
-DACTUAL_3RDPARTY_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}
-DCMAKE_LIBRARY_PATH:STRING=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib
-DCMAKE_INCLUDE_PATH:STRING=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include;${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include/freetype
-DCURL_INCLUDE_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include
-DTIFF_INCLUDE_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include
-DGDAL_INCLUDE_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include
-DGDAL_LIBRARY:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/gdal_i.lib
-DTIFF_LIBRARY:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/libtiff.lib
-DCURL_LIBRARY:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/libcurl_imp.lib
-DFREETYPE_LIBRARY:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/freetype.lib
-DFREETYPE_INCLUDE_DIR:PATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include;${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/include/freetype
-DFREETYPE_LIBRARY:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/freetype243.lib
-DGDAL_INCLUDE_DIR:PATH=
-DGDAL_LIBRARY:FILEPATH=
)
# for compatability with MSVC directory layout
@@ -80,31 +96,63 @@ else()
# normal OSG
endif()
if (MSVC)
# download 3rdparty dependencies zip, including boost
ExternalProject_Add(WinDeps
SVN_REPOSITORY http://fgfs.goneabitbursar.com/fgwin3rdparty/trunk/msvc100/${RDPARTY_DIR}
# extract to current root
SOURCE_DIR ${CMAKE_BINARY_DIR}/winDeps/${RDPARTY_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMAKE_SOURCE_DIR}/installWinDeps.bat
INSTALL_COMMAND ""
)
set(BOOST_ARGS link=static stage --with-system)
set(Boost_Version 1.54.0)
string(REPLACE "." "_" Boost_Version_Underscore ${Boost_Version})
ExternalProject_Add(Boost
PREFIX ${CMAKE_BINARY_DIR}
URL http://downloads.sourceforge.net/project/boost/boost/${Boost_Version}/boost_${Boost_Version_Underscore}.zip
URL_MD5 78a35834c45220a6164310e280abe675
UPDATE_COMMAND ""
CONFIGURE_COMMAND ${BOOST_BOOTSTRAP}
BUILD_COMMAND bjam --with-program_options ${BOOST_ARGS}
BUILD_IN_SOURCE 1
INSTALL_COMMAND ""
)
list(APPEND SG_DEPS Boost)
list(APPEND SG_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
list(APPEND FG_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
list(APPEND FGRUN_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
endif(MSVC) # of Windows
ExternalProject_Add(OSG
DEPENDS ${OSG_DEPS}
PREFIX ${CMAKE_BINARY_DIR}
GIT_REPOSITORY ${OSG_SOURCE}
GIT_TAG ${OSG_TAG}
URL ${OSG_SOURCE}
URL_HASH MD5=4980f8692712a24d4c99f363f80c6814
BINARY_DIR osgbuild
CMAKE_ARGS ${OSG_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=${OSG_INSTALL_PREFIX}
)
# Because OSG install the libraries in lib64/ instead of lib/
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
ExternalProject_Add_Step(OSG after_install
COMMAND ${CMAKE_COMMAND} -E create_symlink ${OSG_INSTALL_PREFIX}/lib64 ${OSG_INSTALL_PREFIX}/lib
COMMAND ${CMAKE_COMMAND} -E copy_directory ${OSG_INSTALL_PREFIX}/lib64 ${OSG_INSTALL_PREFIX}/lib
COMMAND ${CMAKE_COMMAND} -E remove_directory ${OSG_INSTALL_PREFIX}/lib64
DEPENDEES install
)
endif()
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# FIXME install of OpenRTI is failing on Windows, files in PREFIX/share which
# are ending up in C:/Program Files/OpenRTI
if (FALSE)
if (NOT MSVC)
ExternalProject_Add(OpenRTI
PREFIX ${CMAKE_BINARY_DIR}
DOWNLOAD_COMMAND GIT_REPOSITORY git://git.code.sf.net/p/openrti/OpenRTI
DOWNLOAD_COMMAND GIT_REPOSITORY git://gitorious.org/openrti/openrti.git
BINARY_DIR rtibuild
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${RTI_INSTALL_PREFIX}
)
@@ -148,6 +196,23 @@ if (NOT WIN32)
list(APPEND FG_DEPS PLIB)
endif()
# Only compile FGRun for Windows
if (MSVC)
list(APPEND FGRUN_CMAKE_ARGS -DMSVC_3RDPARTY_ROOT:PATH=${CMAKE_BINARY_DIR})
list(APPEND FGRUN_CMAKE_ARGS -DFLTK_FLUID_EXECUTABLE:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/fluid.exe)
list(APPEND FGRUN_CMAKE_ARGS -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH==${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/msgfmt.exe)
list(APPEND FGRUN_CMAKE_ARGS -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/msgmerge.exe)
ExternalProject_Add(FGRun
PREFIX ${CMAKE_BINARY_DIR}
DEPENDS ${FG_DEPS}
DOWNLOAD_COMMAND "" # no need to download
UPDATE_COMMAND "" # or update.
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/fgrun
BINARY_DIR fgrunbuild
CMAKE_ARGS ${FGRUN_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=${FGRUN_INSTALL_PREFIX} -DCMAKE_PREFIX_PATH=${OSG_INSTALL_PREFIX} -DADDITIONAL_LIBRARY_PATHS=${SG_INSTALL_PREFIX}
)
endif()
ExternalProject_Add(FlightGear
PREFIX ${CMAKE_BINARY_DIR}
DEPENDS ${FG_DEPS}

View File

@@ -1,362 +1,311 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
;
; This script creates an installable FlightGear package for Win32 using the
; "Inno Setup" package builder. Inno Setup is free (but probably not open
; source?.) The official web site for this package building software is:
;
; http://www.jrsoftware.org/isinfo.php
;
; Note: the files must appear in the X: drive.
; You can do this with the command below:
;
; subst X: path_to_files
;
; For example:
;
; C:\> subst X: F:\Path\to\FlightGear\root
; C:\> subst X: F:\
;
#include "InstallConfig.iss"
#if GetEnv("VSINSTALLDIR") == ""
#define VSInstallDir "C:\Program Files (x86)\Microsoft Visual Studio 14.0"
#else
#define VSInstallDir GetEnv("VSINSTALLDIR")
#endif
#define VCInstallDir VSInstallDir + "\VC"
#define InstallDir32 "X:\install\msvc140"
#define OSGInstallDir InstallDir32 + "\OpenSceneGraph"
#define OSGPluginsDir OSGInstallDir + "\bin\osgPlugins-" + OSGVersion
#define InstallDir64 "X:\install\msvc140-64"
#define OSG64InstallDir InstallDir64 + "\OpenSceneGraph"
#define OSG64PluginsDir OSG64InstallDir + "\bin\osgPlugins-" + OSGVersion
#define ThirdPartyDir "X:\windows-3rd-party\msvc140"
; we copy everything in install/<arch>/bin except these, which aren't
; useful to the end-user to ship
#define ExcludedBinaries "*smooth.exe,metar.exe,js_demo.exe"
[Setup]
AppId=FlightGear
AppName=FlightGear
AppPublisher=The FlightGear Team
OutputBaseFilename=FlightGear-{#FGVersion}{#FGDetails}
AppVerName=FlightGear v{#FGVersion}
AppPublisherURL=http://www.flightgear.org
AppSupportURL=http://www.flightgear.org
AppUpdatesURL=http://www.flightgear.org
DefaultDirName={pf}\FlightGear {#FGVersion}
UsePreviousAppDir=no
DefaultGroupName=FlightGear {#FGVersion}
UsePreviousGroup=no
LicenseFile=X:\flightgear\COPYING
Uninstallable=yes
SetupIconFile=X:\flightgear\package\flightgear.ico
VersionInfoVersion={#FGVersion}.0
InfoBeforeFile=X:\flightgear\package\windows\infobefore.txt
WizardImageFile=X:\flightgear\package\windows\setupimg.bmp
WizardImageStretch=No
WizardSmallImageFile=X:\flightgear\package\windows\setupsmall.bmp
VersionInfoCompany=The FlightGear Team
UninstallDisplayIcon={app}\bin\fgfs.exe
ArchitecturesInstallIn64BitMode=x64
ArchitecturesAllowed=x86 x64
; Sign tool must be defined in the Inno Setup GUI, to avoid
; exposing the certificate password
; SignTool=fg_code_sign1
[Tasks]
; NOTE: The following entry contains English phrases ("Create a desktop icon" and "Additional icons"). You are free to translate them into another language if required.
Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"
[Files]
; NOTE: run subst X: F:\ (or whatever path the expanded tree resides at)
;Source: "X:\*.txt"; DestDir: "{app}"; Flags: ignoreversion
; 32 bits install
Source: "{#InstallDir32}\bin\*.*"; DestDir: "{app}\bin"; Excludes: "{#ExcludedBinaries}"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
;locale only exists for fgrun - which has been disabled
;Source: "{#InstallDir32}\share\locale\*"; DestDir: "{app}\bin\locale"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\zlib.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\OpenAL32.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\libpng.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\libcurl.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\CrashRpt1403.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\CrashSender1403.exe"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#VCInstallDir}\redist\x86\Microsoft.VC140.CRT\*.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
; 64 bits install
Source: "{#InstallDir64}\bin\*.*"; DestDir: "{app}\bin"; Excludes: "{#ExcludedBinaries}"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
;locale only exists for fgrun - which has been disabled
;Source: "{#InstallDir64}\share\locale\*"; DestDir: "{app}\bin\locale"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\zlib.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\OpenAL32.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libpng.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libcurl.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\CrashRpt1403.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\CrashSender1403.exe"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#VCInstallDir}\redist\x64\Microsoft.VC140.CRT\*.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
; Include the base package
#if IncludeData == "TRUE"
Source: "X:\fgdata\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
#endif
; 32 bits install
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osg.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgDB.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgGA.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgParticle.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgText.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgUtil.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgViewer.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgSim.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgFX.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGInstallDir}\bin\ot{#OTSoNumber}-OpenThreads.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_ac.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_osga.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_3ds.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_mdl.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_jpeg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_rgb.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_png.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_dds.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_txf.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_tiff.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
Source: "{#OSGPluginsDir}\osgdb_freetype.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osganimation.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgfx.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgmanipulator.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgparticle.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgshadow.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgsim.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgterrain.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgtext.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_serializers_osgvolume.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_deprecated_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
;Source: "{#OSGPluginsDir}\osgdb_deprecated_osgparticle.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode
; 64 bits install
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osg.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgDB.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgGA.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgParticle.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgText.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgUtil.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgViewer.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgSim.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgFX.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64InstallDir}\bin\ot{#OTSoNumber}-OpenThreads.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_ac.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_osga.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_3ds.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_mdl.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_jpeg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_rgb.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_png.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_dds.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_txf.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_tiff.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
Source: "{#OSG64PluginsDir}\osgdb_freetype.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osganimation.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgfx.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgmanipulator.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgparticle.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgshadow.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgsim.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgterrain.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgtext.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_serializers_osgvolume.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_deprecated_osg.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
;Source: "{#OSG64PluginsDir}\osgdb_deprecated_osgparticle.dll"; DestDir: "{app}\bin\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
[Dirs]
; Make the user installable scenery directory
Name: "{userdocs}\FlightGear\Aircraft"; Permissions: everyone-modify; Check: not DirExists(ExpandConstant('{userdocs}\FlightGear\Aircraft'))
Name: "{userdocs}\FlightGear\TerraSync"; Permissions: everyone-modify; Check: not DirExists(ExpandConstant('{userdocs}\FlightGear\TerraSync'))
Name: "{userdocs}\FlightGear\Custom Scenery"; Permissions: everyone-modify; Check: not DirExists(ExpandConstant('{userdocs}\FlightGear\Custom Scenery'))
[Icons]
Name: "{userdesktop}\FlightGear {#FGVersion}"; Filename: "{app}\bin\fgfs.exe"; Parameters: "--launcher"; WorkingDir: "{app}\bin"; Tasks: desktopicon;
Name: "{group}\FlightGear"; Filename: "{app}\bin\fgfs.exe"; Parameters: "--launcher"; WorkingDir: "{app}\bin";
Name: "{group}\FlightGear Manual"; Filename: "{app}\data\Docs\getstart.pdf"
Name: "{group}\FlightGear Documentation"; Filename: "{app}\data\Docs\index.html"
Name: "{group}\Flightgear Wiki"; Filename: "http://wiki.flightgear.org"
Name: "{group}\Tools\Uninstall FlightGear"; Filename: "{uninstallexe}"
Name: "{group}\Tools\fgjs"; Filename: "cmd"; Parameters: "/k fgjs.exe ""--fg-root={app}\data"""; WorkingDir: "{app}\bin"
Name: "{group}\Tools\yasim"; Filename: "cmd"; Parameters: "/k ""{app}\bin\yasim.exe"" -h"; WorkingDir: "{app}\bin"
Name: "{group}\Tools\fgpanel"; Filename: "cmd"; Parameters: "/k ""{app}\bin\fgpanel.exe"" -h"; WorkingDir: "{app}\bin"
Name: "{group}\Tools\FGCom"; Filename: "{app}\bin\fgcom.exe"; WorkingDir: "{app}\bin"
Name: "{group}\Tools\FGCom-testing"; Filename: "{app}\bin\fgcom.exe"; Parameters: "--frequency=910"; WorkingDir: "{app}\bin"
Name: "{group}\Tools\Explore Documentation Folder"; Filename: "{app}\data\Docs"
[Code]
const
NET_FW_SCOPE_ALL = 0;
NET_FW_IP_VERSION_ANY = 2;
NET_FW_ACTION_ALLOW = 1;
NET_FW_RULE_DIR_ALL = 0;
NET_FW_RULE_DIR_IN = 1;
NET_FW_RULE_DIR_OUT = 2;
NET_FW_IP_PROTOCOL_ALL = 0;
NET_FW_IP_PROTOCOL_TCP = 6;
NET_FW_IP_PROTOCOL_UDP = 17;
NET_FW_PROFILE2_DOMAIN = 1;
NET_FW_PROFILE2_PRIVATE = 2;
NET_FW_PROFILE2_PUBLIC = 4;
procedure URLLabelOnClick(Sender: TObject);
var
ErrorCode: Integer;
begin
ShellExec('open', 'http://www.flightgear.org', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
procedure CreateURLLabel(ParentForm: TSetupForm; CancelButton: TNewButton);
var
URLLabel: TNewStaticText;
begin
URLLabel := TNewStaticText.Create(ParentForm);
URLLabel.Caption := 'www.flightgear.org';
URLLabel.Cursor := crHand;
URLLabel.OnClick := @URLLabelOnClick;
URLLabel.Parent := ParentForm;
{ Alter Font *after* setting Parent so the correct defaults are inherited first }
URLLabel.Font.Style := URLLabel.Font.Style + [fsUnderline];
URLLabel.Font.Color := clBlue;
URLLabel.Top := CancelButton.Top + CancelButton.Height - URLLabel.Height - 2;
URLLabel.Left := ScaleX(20);
end;
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
S: String;
begin
S := '';
S := S + MemoDirInfo + NewLine + NewLine;
S := S + MemoGroupInfo + NewLine + NewLine;
S := S + MemoTasksInfo + NewLine + NewLine;
Result := S;
end;
procedure AddBasicFirewallException(AppName, FileName: String);
var
FirewallObject: variant;
RuleObject: variant;
begin
try
FirewallObject := CreateOleObject('HNetCfg.FwMgr');
RuleObject := CreateOleObject('HNetCfg.FwAuthorizedApplication');
RuleObject.ProcessImageFileName := FileName;
RuleObject.Name := AppName;
RuleObject.Scope := NET_FW_SCOPE_ALL;
RuleObject.IpVersion := NET_FW_IP_VERSION_ANY;
RuleObject.Enabled := true;
FirewallObject.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(RuleObject);
except
end;
end;
procedure AddAdvancedFirewallException(AppName, AppDescription, FileName: String; Protocol: Integer; LocalPorts, RemotePorts: String; Direction: Integer);
var
FirewallObject: variant;
RuleObject: variant;
begin
try
FirewallObject := CreateOleObject('HNetCfg.FwPolicy2');
RuleObject := CreateOleObject('HNetCfg.FWRule');
RuleObject.Name := AppName;
RuleObject.Description := AppDescription;
RuleObject.ApplicationName := FileName;
if (Protocol <> NET_FW_IP_PROTOCOL_ALL) then
RuleObject.Protocol := Protocol;
if (LocalPorts <> '') then
RuleObject.LocalPorts := LocalPorts;
if (RemotePorts <> '') then
RuleObject.RemotePorts := RemotePorts;
if (Direction <> NET_FW_RULE_DIR_ALL) then
RuleObject.Direction := Direction;
RuleObject.Enabled := true;
RuleObject.Grouping := 'FlightGear';
RuleObject.Profiles := NET_FW_PROFILE2_DOMAIN + NET_FW_PROFILE2_PRIVATE + NET_FW_PROFILE2_PUBLIC;
RuleObject.Action := NET_FW_ACTION_ALLOW;
RuleObject.RemoteAddresses := '*';
FirewallObject.Rules.Add(RuleObject);
except
end;
end;
procedure RemoveFirewallException(AppName, FileName: String);
var
FirewallObject: variant;
Version: TWindowsVersion;
begin
GetWindowsVersionEx(Version);
try
if (Version.Major >= 6) then
begin
FirewallObject := CreateOleObject('HNetCfg.FwPolicy2');
FirewallObject.Rules.Remove(AppName);
end
else if (Version.Major = 5) and (((Version.Minor = 1) and (Version.ServicePackMajor >= 2)) or ((Version.Minor = 2) and (Version.ServicePackMajor >= 1))) then
begin
FirewallObject := CreateOleObject('HNetCfg.FwMgr');
FirewallObject.LocalPolicy.CurrentProfile.AuthorizedApplications.Remove(FileName);
end;
except
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
Version: TWindowsVersion;
begin
if CurStep = ssPostInstall then
begin
GetWindowsVersionEx(Version);
if (Version.Major >= 6) then
begin
{ IN and OUT rules must be specified separately, otherwise the firewall will create only the IN rule }
AddAdvancedFirewallException('FlightGear', 'Allows FlightGear to send and receive data over the multiplayer network and to get METARs.', ExpandConstant('{app}') + '\bin\fgfs.exe', NET_FW_IP_PROTOCOL_ALL, '', '', NET_FW_RULE_DIR_IN);
AddAdvancedFirewallException('FlightGear', 'Allows FlightGear to send and receive data over the multiplayer network and to get METARs.', ExpandConstant('{app}') + '\bin\fgfs.exe', NET_FW_IP_PROTOCOL_ALL, '', '', NET_FW_RULE_DIR_OUT);
AddAdvancedFirewallException('FlightGear FGCom', 'Allows FGCom to establish a connection to FlightGear and the VoIP server for voice ATC communication.', ExpandConstant('{app}') + '\bin\fgcom.exe', NET_FW_IP_PROTOCOL_ALL, '', '', NET_FW_RULE_DIR_IN);
AddAdvancedFirewallException('FlightGear FGCom', 'Allows FGCom to establish a connection to FlightGear and the VoIP server for voice ATC communication.', ExpandConstant('{app}') + '\bin\fgcom.exe', NET_FW_IP_PROTOCOL_ALL, '', '', NET_FW_RULE_DIR_OUT);
end
else if (Version.Major = 5) and (((Version.Minor = 1) and (Version.ServicePackMajor >= 2)) or ((Version.Minor = 2) and (Version.ServicePackMajor >= 1))) then
begin
{ The Windows XP/Server 2003 firewall does not block outgoing connections at all, so only listening processes should be added }
AddBasicFirewallException('FlightGear', ExpandConstant('{app}') + '\bin\fgfs.exe');
AddBasicFirewallException('FlightGear FGCom', ExpandConstant('{app}') + '\bin\fgcom.exe');
end;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then
begin
RemoveFirewallException('FlightGear', ExpandConstant('{app}') + '\bin\fgfs.exe');
RemoveFirewallException('FlightGear FGCom', ExpandConstant('{app}') + '\bin\fgcom.exe');
end;
end;
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
;
; This script creates an installable FlightGear package for Win32 using the
; "Inno Setup" package builder. Inno Setup is free (but probably not open
; source?.) The official web site for this package building software is:
;
; http://www.jrsoftware.org/isinfo.php
;
; Note: the files must appear in the X: drive.
; You can do this with the command below:
;
; subst X: path_to_files
;
; For example:
;
; C:\> subst X: F:\Path\to\FlightGear\root
; C:\> subst X: F:\
;
#include "InstallConfig.iss"
#if GetEnv("VSINSTALLDIR") == ""
#define VSInstallDir "C:\Program Files (x86)\Microsoft Visual Studio 10.0"
#else
#define VSInstallDir GetEnv("VSINSTALLDIR")
#endif
#define VCInstallDir VSInstallDir + "\VC"
#define OSGInstallDir "X:\install\msvc100\OpenSceneGraph"
#define OSGPluginsDir OSGInstallDir + "\bin\osgPlugins-" + OSGVersion
#define OSG64InstallDir "X:\install\msvc100-64\OpenSceneGraph"
#define OSG64PluginsDir OSG64InstallDir + "\bin\osgPlugins-" + OSGVersion
[Setup]
AppId=FlightGear
AppName=FlightGear
AppPublisher=The FlightGear Team
OutputBaseFilename=fgsetup-{#FGVersion}
AppVerName=FlightGear v{#FGVersion}
AppPublisherURL=http://www.flightgear.org
AppSupportURL=http://www.flightgear.org
AppUpdatesURL=http://www.flightgear.org
DefaultDirName={pf}\FlightGear
DefaultGroupName=FlightGear {#FGVersion}
LicenseFile=X:\flightgear\COPYING
Uninstallable=yes
SetupIconFile=X:\flightgear\package\flightgear.ico
VersionInfoVersion={#FGVersion}.0
InfoBeforeFile=X:\flightgear\package\Win32-Inno\infobefore.txt
WizardImageFile=X:\flightgear\package\Win32-Inno\setupimg.bmp
WizardImageStretch=No
WizardSmallImageFile=X:\flightgear\package\Win32-Inno\setupsmall.bmp
VersionInfoCompany=The FlightGear Team
UninstallDisplayIcon=X:\flightgear\projects\VC90\flightgear.ico
ArchitecturesInstallIn64BitMode=x64
ArchitecturesAllowed=x86 x64
[Tasks]
; NOTE: The following entry contains English phrases ("Create a desktop icon" and "Additional icons"). You are free to translate them into another language if required.
Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"
Name: "insoal"; Description: "Install OpenAL (the sound engine)"
Name: "force32"; Description: "Force 32bit install on 64bit system (Not recommended)"; Check: Is64BitInstallMode; Flags: unchecked
[Files]
; NOTE: run subst X: F:\ (or whatever path the expanded tree resides at)
;Source: "X:\*.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\fgfs.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "X:\install\msvc100-64\FlightGear\bin\fgfs.exe"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
;Unconditional install
Source: "X:\install\msvc100\FlightGear\bin\fgadmin.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\terrasync.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\js_demo.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\fgjs.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\fgpanel.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\GPSsmooth.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\UGsmooth.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\MIDGsmooth.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\metar.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\bin\yasim.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\3rdParty\bin\*.dll"; DestDir: "{app}\bin\Win32"
Source: "X:\install\msvc100\FlightGear\bin\fgcom.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion
Source: "X:\install\msvc100\FlightGear\share\flightgear\positions.txt"; DestDir: "{app}\share\flightgear"
Source: "X:\install\msvc100\FlightGear\share\flightgear\special_frequencies.txt"; DestDir: "{app}\share\flightgear"
Source: "X:\install\msvc100\FGRun\bin\fgrun.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion ; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "X:\install\msvc100\FGRun\share\locale\*"; DestDir: "{app}\bin\Win32\locale"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "X:\install\msvc100-64\FGRun\bin\fgrun.exe"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\install\msvc100-64\FGRun\share\locale\*"; DestDir: "{app}\bin\Win64\locale"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\3rdParty.x64\bin\*.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#VCInstallDir}\redist\x86\Microsoft.VC100.CRT\*.dll"; DestDir: "{app}\bin\Win32"
Source: "{#VCInstallDir}\redist\x64\Microsoft.VC100.CRT\*.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\3rdParty\bin\vcredist_x86.exe"; DestDir: "{app}\bin\Win32"; Flags: skipifsourcedoesntexist
Source: "X:\3rdParty.x64\bin\vcredist_x64.exe"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\3rdParty\bin\oalinst.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion skipifsourcedoesntexist
; CrashRpt DLLs are copied by the wildcard rule on *.dll above
Source: "X:\3rdParty\bin\CrashSender1402.exe"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion skipifsourcedoesntexist
Source: "X:\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin\Win32"; Flags: ignoreversion skipifsourcedoesntexist
Source: "X:\3rdParty.x64\bin\CrashSender1402.exe"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin\Win64"; Flags: ignoreversion skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "X:\data\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
; NOTE: tar.gz file uses name 'fgdata', to avoid renaming it, look for both names.
; assuming no setup has both names and hence we don't package twice :)
Source: "X:\fgdata\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osg.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgDB.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgGA.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgParticle.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgText.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgUtil.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgViewer.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgSim.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osgFX.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGInstallDir}\bin\ot{#OTSoNumber}-OpenThreads.dll"; DestDir: "{app}\bin\Win32"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_ac.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_osg.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_osga.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_3ds.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_mdl.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_jpeg.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_rgb.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_png.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_dds.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_txf.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_freetype.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osg.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osganimation.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgfx.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgmanipulator.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgparticle.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgshadow.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgsim.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgterrain.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgtext.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_serializers_osgvolume.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_deprecated_osg.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSGPluginsDir}\osgdb_deprecated_osgparticle.dll"; DestDir: "{app}\bin\Win32\osgPlugins-{#OSGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osg.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgDB.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgGA.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgParticle.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgText.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgUtil.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgViewer.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgSim.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\osg{#OSGSoNumber}-osgFX.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64InstallDir}\bin\ot{#OTSoNumber}-OpenThreads.dll"; DestDir: "{app}\bin\Win64"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_ac.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_osg.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_osga.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_3ds.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_mdl.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_jpeg.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_rgb.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_png.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_dds.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_txf.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_freetype.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osg.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osganimation.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgfx.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgmanipulator.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgparticle.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgshadow.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgsim.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgterrain.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgtext.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_serializers_osgvolume.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_deprecated_osg.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Source: "{#OSG64PluginsDir}\osgdb_deprecated_osgparticle.dll"; DestDir: "{app}\bin\Win64\osgPlugins-{#OSGVersion}"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode and not IsTaskSelected('force32')
[Dirs]
; Make the user installable scenery directory
Name: "{app}\scenery"; Permissions: everyone-modify
Name: "{code:TerrasyncDir}"; Permissions: everyone-modify
[Icons]
Name: "{group}\FlightGear Launcher"; Filename: "{app}\bin\Win32\fgrun.exe"; WorkingDir: "{app}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Name: "{group}\FlightGear Launcher"; Filename: "{app}\bin\Win64\fgrun.exe"; WorkingDir: "{app}"; Check: Is64BitInstallMode and not IsTaskSelected('force32')
; Name: "{group}\FlightGear"; Filename: "{app}\bin\Win32\fgfs.exe"; Parameters: "--fg-root=."; WorkingDir: "{app}";
Name: "{group}\FlightGear Manual"; Filename: "{app}\data\Docs\getstart.pdf"
Name: "{group}\FlightGear Documentation"; Filename: "{app}\data\Docs\index.html"
Name: "{group}\Flightgear Wiki"; Filename: "http://wiki.flightgear.org"
Name: "{userdesktop}\FlightGear {#FGVersion}"; Filename: "{app}\bin\Win32\fgrun.exe"; WorkingDir: "{app}"; Tasks: desktopicon; Check: not Is64BitInstallMode or IsTaskSelected('force32')
Name: "{userdesktop}\FlightGear {#FGVersion}"; Filename: "{app}\bin\Win64\fgrun.exe"; WorkingDir: "{app}"; Tasks: desktopicon; Check: Is64BitInstallMode and not IsTaskSelected('force32')
Name: "{group}\Tools\Install & Uninstall Scenery"; Filename: "{app}\bin\Win32\fgadmin.exe"; WorkingDir: "{app}"
Name: "{group}\Tools\TerraSync"; Filename: "{app}\bin\Win32\terrasync.exe"; Parameters: "-S -p 5505 -d ""{app}\terrasync"""; WorkingDir: "{app}"
Name: "{group}\Tools\Uninstall FlightGear"; Filename: "{uninstallexe}"
Name: "{group}\Tools\js_demo"; Filename: "{app}\bin\Win32\js_demo.exe"
Name: "{group}\Tools\fgjs"; Filename: "cmd"; Parameters: "/k fgjs.exe ""--fg-root={app}\data"""; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\GPSsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\GPSsmooth.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\UGsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\UGsmooth.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\MIDGsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\MIDGsmooth.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\metar"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\metar.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\yasim"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\yasim.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\fgpanel"; Filename: "cmd"; Parameters: "/k ""{app}\bin\Win32\fgpanel.exe"" -h"; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\FGCom"; Filename: "{app}\bin\Win32\fgcom.exe"; Parameters: "--positions=""{app}\share\flightgear\positions.txt"" --special=""{app}\share\flightgear\special_frequencies.txt"""; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\FGCom-testing"; Filename: "{app}\bin\Win32\fgcom.exe"; Parameters: "-f910 --positions=""{app}\share\flightgear\positions.txt"" --special=""{app}\share\flightgear\special_frequencies.txt"""; WorkingDir: "{app}\bin\Win32";
Name: "{group}\Tools\Explore Documentation Folder"; Filename: "{app}\data\Docs"
; For running flightgear directly
; Name: "{userdesktop}\FlightGear v2.0.0"; Filename: "{app}\bin\Win32\fgfs.exe"; Parameters: "--fg-root=."; WorkingDir: "{app}"; Tasks: desktopicon
[Run]
filename: "cmd.exe"; WorkingDir: "{app}\bin\Win32"; Parameters: "/C del msvc*.dll"; Check: FileExists(ExpandConstant('{app}\bin\Win32\vcredist_x86.exe'))
filename: "cmd.exe"; WorkingDir: "{app}\bin\Win64"; Parameters: "/C del msvc*.dll"; Check: FileExists(ExpandConstant('{app}\bin\Win64\vcredist_x64.exe'))
filename: "{app}\bin\Win32\vcredist_x86.exe"; WorkingDir: "{app}\bin\Win32"; Parameters: "/passive /norestart"; Description: "Installing MS Visual C++ runtime components"; Check: FileExists(ExpandConstant('{app}\bin\Win32\vcredist_x86.exe'))
filename: "{app}\bin\Win64\vcredist_x64.exe"; WorkingDir: "{app}\bin\Win64"; Parameters: "/passive /norestart"; Description: "Installing MS Visual C++ runtime components"; Check: Is64BitInstallMode and not IsTaskSelected('force32') and FileExists(ExpandConstant('{app}\bin\Win64\vcredist_x64.exe'))
filename: "{app}\bin\Win32\oalinst.exe"; WorkingDir: "{app}\bin\Win32"; Description: "Installing OpenAL"; Check: IsTaskSelected('insoal') and FileExists(ExpandConstant('{app}\bin\Win32\oalinst.exe'))
; Put installation directory into the fgrun.prefs
filename: "{app}\bin\Win32\fgrun.exe"; WorkingDir: "{app}\bin\Win32"; Parameters: "--silent ""--fg-exe={app}\bin\Win32\fgfs.exe"" ""--ts-exe={app}\bin\Win32\terrasync.exe"" ""--fg-root={app}\data"" ""--fg-scenery={app}\data\Scenery;{app}\scenery;{code:TerrasyncDir}"" --ts-dir=3 --version={#FGVersion}"; Check: not Is64BitInstallMode or IsTaskSelected('force32')
filename: "{app}\bin\Win64\fgrun.exe"; WorkingDir: "{app}\bin\Win64"; Parameters: "--silent ""--fg-exe={app}\bin\Win64\fgfs.exe"" ""--ts-exe={app}\bin\Win32\terrasync.exe"" ""--fg-root={app}\data"" ""--fg-scenery={app}\data\Scenery;{app}\scenery;{code:TerrasyncDir}"" --ts-dir=3 --version={#FGVersion}"; Check: Is64BitInstallMode and not IsTaskSelected('force32')
; Put installation and source directories into the fgadmin.prefs
filename: "{app}\bin\Win32\fgadmin.exe"; WorkingDir: "{app}\bin\Win32"; Parameters: "--silent ""--install-source={src}\..\Scenery"" ""--scenery-dest={app}\scenery"""
[Registry]
Root: HKLM; Subkey: "Software\flightgear.org"; ValueType: string; ValueName: "TerrasyncDir"; ValueData: "{code:TerrasyncDir}"
[Code]
var
TerrasyncDirPage: TInputDirWizardPage;
procedure URLLabelOnClick(Sender: TObject);
var
ErrorCode: Integer;
begin
ShellExec('open', 'http://www.flightgear.org', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
procedure CreateURLLabel(ParentForm: TSetupForm; CancelButton: TNewButton);
var
URLLabel: TNewStaticText;
begin
URLLabel := TNewStaticText.Create(ParentForm);
URLLabel.Caption := 'www.flightgear.org';
URLLabel.Cursor := crHand;
URLLabel.OnClick := @URLLabelOnClick;
URLLabel.Parent := ParentForm;
{ Alter Font *after* setting Parent so the correct defaults are inherited first }
URLLabel.Font.Style := URLLabel.Font.Style + [fsUnderline];
URLLabel.Font.Color := clBlue;
URLLabel.Top := CancelButton.Top + CancelButton.Height - URLLabel.Height - 2;
URLLabel.Left := ScaleX(20);
end;
procedure InitializeWizard();
begin
TerrasyncDirPage := CreateInputDirPage(wpSelectDir,
'Select Terrasync Directory', 'Where should scenery downloaded by Terrasync be put?',
'Select the folder in which Terrasync would download additional scenery, then click Next.',
False, 'Terrasync Folder');
TerrasyncDirPage.Add('');
CreateURLLabel(WizardForm, WizardForm.CancelButton);
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID = wpSelectDir then begin
TerrasyncDirPage.Values[0] := GetPreviousData( 'TerrasyncDir', ExpandConstant('{reg:HKLM\Software\flightgear.org,TerrasyncDir|{app}\terrasync}') );
end;
Result := True;
end;
function TerrasyncDir(Param: String): String;
begin
Result := TerrasyncDirPage.Values[0];
end;
procedure RegisterPreviousData(PreviousDataKey: Integer);
begin
{ Store the settings so we can restore them next time }
SetPreviousData(PreviousDataKey, 'TerrasyncDir', TerrasyncDirPage.Values[0]);
end;
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
S: String;
begin
S := '';
S := S + MemoDirInfo + NewLine + NewLine;
S := S + 'Terrasync folder:' + NewLine;
S := S + Space + TerrasyncDirPage.Values[0] + NewLine + NewLine;
S := S + MemoGroupInfo + NewLine + NewLine;
S := S + MemoTasksInfo + NewLine + NewLine;
Result := S;
end;

View File

@@ -13,7 +13,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>fgfs</string>
<string>FlightGear</string>
<key>CFBundleIdentifier</key>
<string>org.flightgear.FlightGear</string>
<key>CFBundleVersion</key>
@@ -21,20 +21,13 @@
<key>CFBundleShortVersionString</key>
<string><%= fgVersion %></string>
<key>LSMinimumSystemVersion</key>
<string>10.7.0</string>
<string>10.6.0</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
<string>©1996-<%= fgCurrentYear%>, The FlightGear Project</string>
<!-- when launched via LaunchServices, run the launcher GUI -->
<key>LSEnvironment</key>
<dict>
<key>FG_LAUNCHER</key>
<string>1</string>
</dict>
</dict>
</plist>

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -1,167 +0,0 @@
# Nasa2FGearthview
A bash-script to convert NASA satellite images to ready-to-use
textures for FG's EarthView using ImageMagick.
For info about FGearthview, see the forum thread:
https://forum.flightgear.org/viewtopic.php?f=6&t=15754
or this FG-wiki-page:
http://wiki.flightgear.org/Earthview
------------------------------------
About:
This script runs on Linux (maybe Mac also?) in a Bash
(Bourne Again Shell) - Windows is not supported (by the nature of the
script). Maybe it works on windows as well, I don't know, feel free
to try, and please let me know! :)
This will download the raw images from http://visibleearth.nasa.gov -
their server is not very fast, so I provide an alternative download
location: https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
This one is much quicker! If you really want the images directly from
NASA, then provide "nasa" to the script (see below)
In the end you will have 8 world-textures in .png and .dds format.
Generally .dds is better in performance, but it won't work on some
graphics cards. If this is the case for you, then try the .png files.
For further information see:
http://wiki.flightgear.org/index.php?title=DDS_Textures_in_FlightGear&redirect=no
If you also converted the clouds, then you'll also find 8 cloud-
textures in the format .png. Because the .dds-format has trouble with
rendering heavy alpha images, which is because of it's compression
algorythm [1], I think it's useless to also build faulty files.
However, this is not entirely true! It is possible to switch off the
.dds/DXT compression. But this results in huge files and is rather
heavy on the GPU's RAM.
Buckaroo has created a nice overview on dds-compression:
[1] http://www.buckarooshangar.com/flightgear/tut_dds.html
------------------------------------
Installation and usage:
Simply copy "convert.sh" into a folder of your liking and run it:
$ ./convert.sh
This will show a help text, since you didn't specify any target(s).
Possible targets are:
* world
* clouds
* all
Additionally, there are some options you could specify (further
explained below):
* 1k | 2k | 4k | 8k | 16k
* nasa
* no-download
* cleanup
* rebuild
* check
So your call could look sth like this:
$ ./convert.sh world no-download cleanup 8k
------------------------------------
Requirements:
WARNING!
This script uses a *lot* disk space! Make sure you have at least 90GB
available!
Also, this script will run for a *very long* time! It might be best to
let it run over night - your computer might become unresponsive from
time to time, due to the heavy CPU and memory load, which tends to
occur, when converting 54000x27000 images. ;-)
I also recommend to deactivate swapping!
$ sudo swapoff -a
To reactivate swapping do:
$ sudo swapon -a
This script relies on wget and imagemagick. Both are easily installed
by your systems package-management-system.
(On Debian/Ubuntu this is "apt-get")
So, on Debian for instance, you only need to put the following into
the console:
$ sudo apt-get install wget imagemagick
Depending on your distro, the package names might differ slightly! Use
a search engine of your choice to find out, how the packages are named
in your distro!
You may want to check:
$ apt search imagemagick
------------------------------------
Targets:
world
Generates the world tiles, needed to run FG with EarthView.
You will find the results in output/[$resolution]/*. Copy
these into $FGDATA/Models/Astro/*. More about the installation
of these textures can be found here:
http://wiki.flightgear.org/Earthview#Customization
clouds
Generates the cloud tiles, needed to run FG with EarthView.
The locations are the same as the other textures mentioned
above. Note that clouds are only available with up to 8k
resolution, due to the available data at NASA.
all
Converts everything needed for a full-blown earthview texture
set. Does the same as:
$ ./convert.sh world clouds
Options:
1k | 2k | 4k | 8k | 16k
Lets you specify a desired resolution of the textures.
Possible values are 1k, 2k, 4k, 8k and 16k. If nothing is
specified, the script will generate all of the resolutions.
16k is only available for earth textures.
nasa
Causes the script to download directly from
http://visibleearth.nasa.gov . If omitted the script will
download from
https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
which is much faster!
Uses wget either way.
no-download
Causes the script to skip the download function. If you
already have the source images, then you don't need to
re-download them. (About 2.4GB!)
If omitted, the script will download the source images from
https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
cleanup
Deletes the temporary files created during texture generation.
These can be found in tmp/
Note: if for some reason you later want some other resolution,
then it's good to have the data there. So only do this, when
you're quite sure that you're done.
Frees up a lot of disk-space! Which would have to be
regenerated if needed again.
rebuild
Deletes only the temporary files of the given target. So if
you call './convert.sh rebuild world' the script will delete
all corresponding temp-files of the target world, which will
trigger a complete regeneration of the relevant (instead of
skipping existing files)
check
Creates mosaics of the tiles, so you can look at them and see
if all went well.

File diff suppressed because it is too large Load Diff

38
base-package.rules Normal file
View File

@@ -0,0 +1,38 @@
- .git
- *.xcf
- *.tex
+ /fgdata/Aircraft/Generic
+ /fgdata/Aircraft/Instruments
+ /fgdata/Aircraft/Instruments-3d
+ /fgdata/Aircraft/UIUC
+ /fgdata/Aircraft/c172p
+ /fgdata/Aircraft/777
+ /fgdata/Aircraft/777-200
+ /fgdata/Aircraft/b1900d
+ /fgdata/Aircraft/ufo
+ /fgdata/Aircraft/CitationX
+ /fgdata/Aircraft/ZLT-NT
+ /fgdata/Aircraft/dhc2
+ /fgdata/Aircraft/Cub
+ /fgdata/Aircraft/sopwithCamel
+ /fgdata/Aircraft/f-14b
+ /fgdata/Aircraft/ASK13
+ /fgdata/Aircraft/bo105
+ /fgdata/Aircraft/Dragonfly
+ /fgdata/Aircraft/SenecaII
+ /fgdata/Aircraft/A6M2
- /fgdata/Aircraft/*
- /fgdata/Textures.high/*.new
- /fgdata/Textures.high/*.orig
- /fgdata/Textures.high/*.save
- /fgdata/Textures/Unused
- /fgdata/Textures/*.orig
- /fgdata/Docs/source
- /fgdata/Models/Airspace
- /fgdata/Models/MNUAV

View File

View File

@@ -1,136 +0,0 @@
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
IF %IS_NIGHTLY_BUILD% EQU 1 (
SET FGBUILDTYPE=Nightly
) ELSE (
SET FGBUILDTYPE=Release
)
REM following are for testing the script locally
REM SET PATH=%PATH%;%ProgramFiles%\CMake\bin;%ProgramFiles(x86)%\"Inno Setup 5"\
REM SET QT5SDK32=C:\Qt\5.6\msvc2015
REM SET QT5SDK64=C:\Qt\5.6\msvc2015_64
REM SET IS_NIGHTLY_BUILD=1
SET OSG32=%WORKSPACE%\install\msvc140\OpenSceneGraph
SET OSG64=%WORKSPACE%\install\msvc140-64\OpenSceneGraph
REM 32bits
md build-sg32
md build-fg32
cd build-sg32
cmake ..\simgear -G "Visual Studio 14" ^
-DMSVC_3RDPARTY_ROOT=%WORKSPACE%/windows-3rd-party/msvc140 ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_PREFIX_PATH:PATH=%OSG32% ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg32
cmake ..\flightgear -G "Visual Studio 14" ^
-DMSVC_3RDPARTY_ROOT=%WORKSPACE%/windows-3rd-party/msvc140 ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140 ^
-DCMAKE_PREFIX_PATH:PATH=%WORKSPACE%/install/msvc140/OpenSceneGraph ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_PREFIX_PATH=%QT5SDK32%;%OSG32% ^
-DFG_BUILD_TYPE=%FGBUILDTYPE%
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..
REM 64 bits
md build-sg64
md build-fg64
cd build-sg64
cmake ..\SimGear -G "Visual Studio 14 Win64" ^
-DMSVC_3RDPARTY_ROOT=%WORKSPACE%/windows-3rd-party/msvc140 ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_PREFIX_PATH:PATH=%OSG64% ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140-64
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg64
cmake ..\flightgear -G "Visual Studio 14 Win64" ^
-DMSVC_3RDPARTY_ROOT=%WORKSPACE%/windows-3rd-party/msvc140 ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140-64 ^
-DCMAKE_PREFIX_PATH=%QT5SDK64%;%OSG64% ^
-DFG_BUILD_TYPE=%FGBUILDTYPE%
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..
REM Qt5 deployment
%QT5SDK32%\bin\windeployqt --release --list target %WORKSPACE%/install/msvc140/bin/fgfs.exe
%QT5SDK64%\bin\windeployqt --release --list target %WORKSPACE%/install/msvc140-64/bin/fgfs.exe
REM build setup
ECHO Packaging root is %WORKSPACE%
subst X: /D
subst X: %WORKSPACE%.
REM ensure output dir is clean since we upload the entirety of it
rmdir /S /Q output
REM archiving PDB files
copy %WORKSPACE%\build-fg32\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x86-%BUILD_NUMBER%.pdb
copy %WORKSPACE%\build-fg64\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x64-%BUILD_NUMBER%.pdb
REM indirect way to get command output into an environment variable
set PATH=%OSG32%\bin;%PATH%
osgversion --so-number > %TEMP%\osg-so-number.txt
osgversion --version-number > %TEMP%\osg-version.txt
osgversion --openthreads-soversion-number > %TEMP%\openthreads-so-number.txt
SET /P FLIGHTGEAR_VERSION=<flightgear\version
SET /P OSG_VERSION=<%TEMP%\osg-version.txt
SET /P OSG_SO_NUMBER=<%TEMP%\osg-so-number.txt
SET /P OT_SO_NUMBER=<%TEMP%\openthreads-so-number.txt
IF %IS_NIGHTLY_BUILD% EQU 1 (
REM FlightGear nightly: with fgdata, output filename would be "FlightGear-x.x.x-nightly-full.exe"
CALL :writeBaseConfig
CALL :writeNightlyFullConfig
iscc /Q FlightGear.iss
REM FlightGear nightly: without fgdata, output filename would be "FlightGear-x.x.x-nightly.exe"
CALL :writeBaseConfig
CALL :writeNightlyDietConfig
iscc /Q FlightGear.iss
) ELSE (
REM FlightGear release: with fgdata, output filename would be "FlightGear-x.x.x.exe"
CALL :writeBaseConfig
CALL :writeReleaseConfig
iscc /Q FlightGear.iss
)
GOTO End
:writeBaseConfig
ECHO #define FGVersion "%FLIGHTGEAR_VERSION%" > InstallConfig.iss
ECHO #define OSGVersion "%OSG_VERSION%" >> InstallConfig.iss
ECHO #define OSGSoNumber "%OSG_SO_NUMBER%" >> InstallConfig.iss
ECHO #define OTSoNumber "%OT_SO_NUMBER%" >> InstallConfig.iss
GOTO End
:writeReleaseConfig
CALL :writeBaseConfig
ECHO #define FGDetails "" >> InstallConfig.iss
ECHO #define IncludeData "TRUE" >> InstallConfig.iss
GOTO End
:writeNightlyFullConfig
CALL :writeBaseConfig
ECHO #define FGDetails "-nightly-full" >> InstallConfig.iss
ECHO #define IncludeData "TRUE" >> InstallConfig.iss
GOTO End
:writeNightlyDietConfig
CALL :writeBaseConfig
ECHO #define FGDetails "-nightly" >> InstallConfig.iss
ECHO #define IncludeData "FALSE" >> InstallConfig.iss
GOTO End
:End

View File

@@ -1,83 +0,0 @@
aircraftTypeTags = [
"ga", "fighter", "helicopter", "glider", "spaceship", "bomber", "groundvehicle",
"tanker", "cargo", "transport", "bizjet", "trainer", "airship", "balloon"
]
manufacturerTags = [
"boeing", "cessna", "diamond", "douglas", "bell", "piper",
"airbus", "vickers", "lockheed", "fokker",
"embraer", "bombardier", "pilatus", "robin",
"eurocopter"
]
eraTags = [
"early-pioneers",
"ww1",
"1920s",
"1930s",
"golden-age",
"ww2",
"coldwar", "vietnam",
"1950s",
"1960s",
"1970s",
"1980s",
"1990s",
"2000s",
"gulfwar1",
"gulfwar2"
]
featureTags = [
"ifr",
"retractable-gear",
"fixed-gear",
"tail-dragger",
"seaplane",
"vtol",
"stol",
"experimental",
"prototype",
"fictional",
"biplane",
"triplane",
"supersonic",
"t-tail",
"v-tail",
"high-wing",
"cannard",
"tail-hook",
"refuel",
"delta",
"variable-geometry",
"glass-cockpit",
"hud",
"etops",
"floats",
"amphibious",
"airship",
"aerobatic"
]
propulsionTags = [
"piston", "radial",
"diesel",
"variable-pitch",
"supercharged",
"turboprop",
"jet", "afterburner", "rocket",
"electric",
"twin-engine",
"single-engine"
]
simFeatureTags = [
"tow",
"dual-controls",
"rembrandt"
]
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags
def isValidTag(maybeTag):
return maybeTag in tags

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Template catalog - copy and modify for your site as required-->
<PropertyList>
<local-output>/home/curt/Projects/FlightGear/ftp/Aircraft</local-output>
<download-url n="0">http://mirrors.ibiblio.org/flightgear/ftp/Aircraft/</download-url>
<thumbnail-url n="0">http://mirrors.ibiblio.org/flightgear/ftp/Aircraft/thumbnails</thumbnail-url>
<scm>
<type>svn</type>
<path>/home/curt/Projects/FlightGear/flightgear-fgaddon/Aircraft</path>
<skip>NTPS</skip>
<skip>c172</skip>
<skip>tu134</skip>
</scm>
<include-dir>/home/curt/Projects/FlightGear/flightgear-fgdata</include-dir>
<include-dir>/home/curt/Projects/FlightGear/flightgear-fgaddon</include-dir>
<!-- <scm>
<type>git</type>
<update type="bool">false</update>
<path>/Users/jmt/FGFS/fgdata</path>
<url>git://git.code.sf.net/p/flightgear/fgdata</url>
</scm> -->
<upload n="0">
<enabled type="bool">true</enabled>
<type>rsync-ssh</type>
<remote>fgfs:/home/fgfs/fgfs.goneabitbursar.com/official</remote>
</upload>
</PropertyList>

View File

@@ -1,516 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<aircraft_14bis>8a4ea48a3bb83b608386f942a85100c9</aircraft_14bis>
<aircraft_21>057bfdb3c3fcfba3f8d31723a77df277</aircraft_21>
<aircraft_707>088f6c3850d9c3f8e94ced2bfc2a65db</aircraft_707>
<aircraft_717>abc393890f7ab49f32c6a2adc01b7823</aircraft_717>
<aircraft_727-230>8e93ee83c42f77db9881f9ca0f00cf8b</aircraft_727-230>
<aircraft_737-100>45fc009e9323de75e477b2548c79cb9a</aircraft_737-100>
<aircraft_737-200>3fb8820c373e78bcd52981293e2d46e8</aircraft_737-200>
<aircraft_737-300>c974d9b2e7c5feba195563433a4c5bc2</aircraft_737-300>
<aircraft_737NG>dd9ab7cb3fb27a4acfc7b634fa9ec396</aircraft_737NG>
<aircraft_747>5779ec5bdab4e9405d0db447c5a73df4</aircraft_747>
<aircraft_747-200>e3565e459436a5e4dcdd260a095c28b2</aircraft_747-200>
<aircraft_747-400>ce6c904cb23df6337ed6bdc1dcf6d68e</aircraft_747-400>
<aircraft_747-8i>92161d0ef86048c0c859241abd64ffcd</aircraft_747-8i>
<aircraft_757-200>9f5841317f4ed65fc815517c6770affd</aircraft_757-200>
<aircraft_767-300>89c1b762b8b58fee4772a94d3c9b81d8</aircraft_767-300>
<aircraft_777>693bf6470439f876edced4bd558b69a1</aircraft_777>
<aircraft_787-8>f450b755c5bad640d8c2ef7312b1a6fb</aircraft_787-8>
<aircraft_A-10>4aaca65794466d8cbf8e9ab29ef1b47b</aircraft_A-10>
<aircraft_A-26-Invader>c57f1d877e851f2164f292997508dd36</aircraft_A-26-Invader>
<aircraft_A-6E>86b52be36911fd0ee5d0b93d4b70a087</aircraft_A-6E>
<aircraft_A24-Viking>904f23999e33d323d3f7a09c1807b71a</aircraft_A24-Viking>
<aircraft_A300>3ae04898384a6531fa2edac2fcd508e9</aircraft_A300>
<aircraft_A320-family>c9ec3df5ce80cbbbec9e39a849877ceb</aircraft_A320-family>
<aircraft_A340-600>f015a7d2c8bde1224298261ae34e04c2</aircraft_A340-600>
<aircraft_A380>4951432b9d39c142e891da3209e3ad32</aircraft_A380>
<aircraft_a4>f175e90ccf2c3ae5118cf6eb1a43867e</aircraft_a4>
<aircraft_A6M2>dfb5b7f4f7233d854dca45ae4521e080</aircraft_A6M2>
<aircraft_Aermacchi-MB-339>f6757f3a4f78364c0439fd7d488c4330</aircraft_Aermacchi-MB-339>
<aircraft_Aero-Commander>021be8bd26c7aa03093e5e356d8c7ef2</aircraft_Aero-Commander>
<aircraft_Aerocar>89c4f1663f6b65ca1f70184dd8886f8b</aircraft_Aerocar>
<aircraft_Aerostar-700>9049ec76bddd80abff57a837313771d8</aircraft_Aerostar-700>
<aircraft_AG-14>4f9c9c24e662036de1cd85ed528c3d4e</aircraft_AG-14>
<aircraft_Aichi-D3A>766eb03f38f36190de94422b5481ce4b</aircraft_Aichi-D3A>
<aircraft_Aichi-M6A>14219343b589d8610da96f7a8ec16cdc</aircraft_Aichi-M6A>
<aircraft_Airco-DH2>67689844de14068b7e95e675c0da6c17</aircraft_Airco-DH2>
<aircraft_AirCrane>44fd70dc27b3d36bbde5766ac528d095</aircraft_AirCrane>
<aircraft_Airspeed-Horsa>dae16af174310b492c4412e0c77593e8</aircraft_Airspeed-Horsa>
<aircraft_airwaveXtreme150>64c7f53c6dac1b4da3813661f7455faf</aircraft_airwaveXtreme150>
<aircraft_Albatros-BII>7ccb293d5808ca0b9c48271a6398de94</aircraft_Albatros-BII>
<aircraft_Albatross>61af35090bbc722076353d1496c2d82f</aircraft_Albatross>
<aircraft_Allegro-2000>edae78dee86c3c0cb741bc4ea8793162</aircraft_Allegro-2000>
<aircraft_Alouette-II>94d5008f7bbfb65a56cff0694983d8ff</aircraft_Alouette-II>
<aircraft_Alouette-III>c267be9f90def2460ff53649c6fee2f0</aircraft_Alouette-III>
<aircraft_Alphajet>3fd4701f2363c41de0374c4703b88e83</aircraft_Alphajet>
<aircraft_AN-225>87a1ad2288b56c71559549d55b93cccd</aircraft_AN-225>
<aircraft_an2>37ccf863b017f0b773885619a671f8f7</aircraft_an2>
<aircraft_an24b>3e26ca3bf5296630eebbcd82859d5ac4</aircraft_an24b>
<aircraft_ANT-20>add26dd267eca688d4a88b672749a155</aircraft_ANT-20>
<aircraft_Antoinette>75e69854bf9d09d16cbd5147926ba7fd</aircraft_Antoinette>
<aircraft_Antonov-An-12>457f71d5be8ec8c3e42c6919b226b549</aircraft_Antonov-An-12>
<aircraft_Antonov-An-22>4a27ba4bb53f82bf2a4b325cd3405a89</aircraft_Antonov-An-22>
<aircraft_apache>b7e3e73c98d17006e984e056442c29ce</aircraft_apache>
<aircraft_AR-234>c0c500c55706fc18d93817ebc3b6e83b</aircraft_AR-234>
<aircraft_Arsenal-VG33>c883cde7942cdcfb8cd69c135c4d29f7</aircraft_Arsenal-VG33>
<aircraft_Arup-S2>70db9ed1cb09e1442e22d020a9dc3069</aircraft_Arup-S2>
<aircraft_as332>c62f9ee3f78c98a6342a6a337089fd10</aircraft_as332>
<aircraft_ASK13>264d821437a558cf71c9209f466f6103</aircraft_ASK13>
<aircraft_ASK21>27923bdc9f0f3ae3449f5d7a17744da5</aircraft_ASK21>
<aircraft_ASK21-MI>023bbe168eb0babb4a68963edffc273b</aircraft_ASK21-MI>
<aircraft_asw20>0926a8a021c4e11fa2610cbb5f6f11b3</aircraft_asw20>
<aircraft_ATC>846d8156216e434e789f5d2b7432b68f</aircraft_ATC>
<aircraft_ATC-ML>887c1bc8ab679604031f983ab6c67974</aircraft_ATC-ML>
<aircraft_ATI-Resolution>915cd6323c113bb2a8b57e4c08900f3e</aircraft_ATI-Resolution>
<aircraft_ATR-72-500>c0fe4169db9a338f5beec102f1efe301</aircraft_ATR-72-500>
<aircraft_Avro-Arrow>4b2acc554752df97194e0da1a1c8638c</aircraft_Avro-Arrow>
<aircraft_AVRO-IV-Triplane>9d3c4b4b66a7140628b79c4f142cc0f4</aircraft_AVRO-IV-Triplane>
<aircraft_Avro-Lancaster>611d6172991766b32a43d19bfb06bbb2</aircraft_Avro-Lancaster>
<aircraft_B-17>7cf94e2ee2c76783bf17c845e12e48cb</aircraft_B-17>
<aircraft_B-1B>6407f6fd1bfe031b280639d20dfe100f</aircraft_B-1B>
<aircraft_B-2>04db71541bc7099383524080a2c64012</aircraft_B-2>
<aircraft_B-24-Liberator>2bdd09054c9c92088ff297d6358a05a8</aircraft_B-24-Liberator>
<aircraft_B-25>51c6e9397e1e8fff65eb1d1671d18067</aircraft_B-25>
<aircraft_B-36D-Peacemaker>3d1883d3213d2b5f7d39ec5221cd4eb2</aircraft_B-36D-Peacemaker>
<aircraft_B-52F>d172dc57ce4e2c15f7f550a5c0c734a8</aircraft_B-52F>
<aircraft_b1900d>db7301be7b428db2070e27a5fe7ee06e</aircraft_b1900d>
<aircraft_b26>a71912ae798780eba390f9b27638b139</aircraft_b26>
<aircraft_b29>7dd2ae465a7710921d11c6c18aa0c0e7</aircraft_b29>
<aircraft_BAC-TSR2>6aaa660040bd40facf28fc68220b3cfc</aircraft_BAC-TSR2>
<aircraft_BAe-125>2a3387f97647ad875060bac1284cfcbd</aircraft_BAe-125>
<aircraft_Beagle-Pup>46a6f17c638e177421d1afc559b9d66a</aircraft_Beagle-Pup>
<aircraft_beaufighter>50af4a2d301fafb2a3e13fe96e9215be</aircraft_beaufighter>
<aircraft_beech99>6395fcaf780d6e43b4dd9f215a24e718</aircraft_beech99>
<aircraft_Beechcraft-C18S>5a133a789694642b9f3e611ddf23d3d6</aircraft_Beechcraft-C18S>
<aircraft_Beechcraft-Staggerwing>b668b91e67ef10757839da013faee44b</aircraft_Beechcraft-Staggerwing>
<aircraft_Bell-222X>635dc4a39a43814f2885d59b1dda8a9d</aircraft_Bell-222X>
<aircraft_Bell-P-39>aba5e103f315014925dff3b39bd2d648</aircraft_Bell-P-39>
<aircraft_Bell-P-59>ba6e32553464e03fe6392303a2072631</aircraft_Bell-P-59>
<aircraft_Bell-X1>3c10ccdf2775cad485bb394d5b1e56eb</aircraft_Bell-X1>
<aircraft_Bell-XFL-1>167d03a6eafc1a3780f6fdf733fc7c6e</aircraft_Bell-XFL-1>
<aircraft_Bernard-HV220>0579472d3185c8beba310aef9bf65f5d</aircraft_Bernard-HV220>
<aircraft_bf109>cb732caa641493f07c4cc564018dd481</aircraft_bf109>
<aircraft_Bleriot-125>21b170a0f9dae055d5c1d1af9946515e</aircraft_Bleriot-125>
<aircraft_Bleriot-5190>4fdcfd3aa209318c07c779e408e81df2</aircraft_Bleriot-5190>
<aircraft_Bleriot-SPAD-S.510>aef8c5f5f68349a7ae804df1d6d07e3f</aircraft_Bleriot-SPAD-S.510>
<aircraft_bleriot-XI>e499504fcba1e95e0cca9c4418bfee23</aircraft_bleriot-XI>
<aircraft_bluebird>a9af2d04a1e7bf279d135a4a06b11181</aircraft_bluebird>
<aircraft_bo105>506a63476d00ef552b8adc3260ba1fa4</aircraft_bo105>
<aircraft_bocian>9a3fd12ef60228dca05efa4ff694a882</aircraft_bocian>
<aircraft_Boeing-247>152fcac32e4bb9f7fce5b6894b6da08b</aircraft_Boeing-247>
<aircraft_Boeing-P26>97a640a4f9eddc33ac626f78adfaecb9</aircraft_Boeing-P26>
<aircraft_Boeing314>f00599943616e14682c2baea90e6173a</aircraft_Boeing314>
<aircraft_Bombardier-415>787d13e37c31fbf894d5a25091e4befc</aircraft_Bombardier-415>
<aircraft_Br-761>78d4695d2466f50d3c45e0374809b386</aircraft_Br-761>
<aircraft_Brabazon>6d0e61e40af698ea72e2978ed50e3a49</aircraft_Brabazon>
<aircraft_Breda-B.Z.308>b3e9444c45cc9c445961b726429c0c7e</aircraft_Breda-B.Z.308>
<aircraft_Breguet-XIX>a230231691ebc4df86e7d645f31a0f07</aircraft_Breguet-XIX>
<aircraft_Buccaneer>84362d957e9dae0e5abc70ba4cb9816e</aircraft_Buccaneer>
<aircraft_Bugatti>311a00f90c55c01980688c1d5504df64</aircraft_Bugatti>
<aircraft_Burnelli-CBY-3>cb75a6990af600c666b02398cf77d6d1</aircraft_Burnelli-CBY-3>
<aircraft_BV-141>a191302bdfb1faff1c6f2dd8a5494381</aircraft_BV-141>
<aircraft_BV-170>258b971dd3041a49a816a2150d7e7125</aircraft_BV-170>
<aircraft_C-160-Transall>695ce9bf3221055eecd24be01acb57e2</aircraft_C-160-Transall>
<aircraft_C-2A>3c341ded96ce7c8832738c34c5c115f8</aircraft_C-2A>
<aircraft_C130>c954a3ab900676c0cbabb1bada93754b</aircraft_C130>
<aircraft_c150>270cabd6289080468d29a807f612cb4c</aircraft_c150>
<aircraft_c172r>60bb07c7cefe930145d4b199b63842a7</aircraft_c172r>
<aircraft_c182>fd61954ffdd247b47fec0fc9074aa40b</aircraft_c182>
<aircraft_c182rg>171f7d74d45a50804c8111f5fab29543</aircraft_c182rg>
<aircraft_c310>604cd9887e8f1c9011581348feca1e3c</aircraft_c310>
<aircraft_c310u3a>80756d598e81a6a09217da9025e6284f</aircraft_c310u3a>
<aircraft_C460>b465d263b244c5860ce010371032b5d3</aircraft_C460>
<aircraft_C561>60cb1a6effe4e0023edd1bfdc109aed3</aircraft_C561>
<aircraft_C684>e2881ea7546775db6847bb3890c04a03</aircraft_C684>
<aircraft_Campini-Caproni-N1>68ec43ed98164bef020452e3758ec22f</aircraft_Campini-Caproni-N1>
<aircraft_CanberraBI8>a865e922bec69cf8a6fe1f8d53dbc71b</aircraft_CanberraBI8>
<aircraft_Cap10B>4a7cb6a6f5f6d71d5eb2da025b42d71f</aircraft_Cap10B>
<aircraft_Cap10C>bd103f5fa8a8ac980b8c4ed3a041ff6b</aircraft_Cap10C>
<aircraft_Caproni-C22J>d4eb3933d210d1a8f1deaf8b43a65960</aircraft_Caproni-C22J>
<aircraft_Caproni-Ca3>0ad6cdbf91f37b6c71f94268914d2615</aircraft_Caproni-Ca3>
<aircraft_Caproni-Stipa>d94119914089db0f7b6d43ddf20cb302</aircraft_Caproni-Stipa>
<aircraft_Caravelle>826b017ad5bc1c77c65959367f41415f</aircraft_Caravelle>
<aircraft_Carreidas>4cc78b3c9c421c382b4e197de6589535</aircraft_Carreidas>
<aircraft_Caudron-G3>6c8b251c720301a00276f91db736ee85</aircraft_Caudron-G3>
<aircraft_Caudron-G4>28ebd3b1236a53a0b15bf9c6f5cc79d6</aircraft_Caudron-G4>
<aircraft_Cessna-208-Caravan>edbaa02c5b837b9522ad8d0fd7da81e8</aircraft_Cessna-208-Caravan>
<aircraft_Cessna-421-Golden-Eagle>e16b7b135dbe3fa75539931c950116b6</aircraft_Cessna-421-Golden-Eagle>
<aircraft_Cessna337>bf3b60a808daefd7b7374f934e7b10bf</aircraft_Cessna337>
<aircraft_ch47>d46d6e08cd90412088abffe2dbd03982</aircraft_ch47>
<aircraft_ch53e>55d564ff1b335a723d144e423b9a3c10</aircraft_ch53e>
<aircraft_Cirrus-SR22>a3bbd80a8c11bea16f567eafa898db8f</aircraft_Cirrus-SR22>
<aircraft_Citation>c6f74c5596f959608e1810004abba534</aircraft_Citation>
<aircraft_Citation-Bravo>a6743e193bb01776107fec98595555e4</aircraft_Citation-Bravo>
<aircraft_CitationX>8bf718df53a6af7777f087a302641061</aircraft_CitationX>
<aircraft_Coanda-1910>b66f175629a52396dd1db3f1718d2028</aircraft_Coanda-1910>
<aircraft_colditz>77100ce686eee7ae2b5950df44a38709</aircraft_colditz>
<aircraft_Commonwealth-Ca-12>f132805e11b1c1e60908080b9b6533ad</aircraft_Commonwealth-Ca-12>
<aircraft_ComperSwift>8b227cd83d5f1f3b3b44bb7b46714349</aircraft_ComperSwift>
<aircraft_Concorde>566f1dc35ae741cdeee125111f1e0c20</aircraft_Concorde>
<aircraft_Convair-XFY-1-Pogo>633550eae44633a9b23777ffab527f1b</aircraft_Convair-XFY-1-Pogo>
<aircraft_couzinet70>d8fa7f026fc404ad20b7c7f6a11619ee</aircraft_couzinet70>
<aircraft_cri-cri>bc2267347bc48ba2377926a7a6515274</aircraft_cri-cri>
<aircraft_CRJ-200>0d500b113ae2d633e5f0bf36a1d19fd9</aircraft_CRJ-200>
<aircraft_CRJ700-family>d935f718bed4a71069122fe5214ecd2e</aircraft_CRJ700-family>
<aircraft_Curtiss-Jenny>6062a91295fbf99801e65197a71451c5</aircraft_Curtiss-Jenny>
<aircraft_Curtiss-Model-F>8ca56323ab3db01ec034f231490a7702</aircraft_Curtiss-Model-F>
<aircraft_Curtiss-P40>a0d00a78d80e4a621a1cfb55c0658fe3</aircraft_Curtiss-P40>
<aircraft_D510>8b09cc7658164d311f4e70e36f463cde</aircraft_D510>
<aircraft_D520>b967ca884dd02b37ad9c247d31bdf1c7</aircraft_D520>
<aircraft_DaSH>f9c33778a3805892fbd0e6de35e54e91</aircraft_DaSH>
<aircraft_Dassault-Mystere-IV>387fd1c59b2e5934ffcd888df39b7174</aircraft_Dassault-Mystere-IV>
<aircraft_Dauphin>bdc3b2e695db1588827d000b55bbebda</aircraft_Dauphin>
<aircraft_DC-10-30>1d37211f993a920b0806b95db0f8ea7c</aircraft_DC-10-30>
<aircraft_dc2>77f9e6a9e1647dcd012966af7df1d4be</aircraft_dc2>
<aircraft_dc6>dbfd9548db8318098daa75733171a18e</aircraft_dc6>
<aircraft_dc8-63>70cff7394ced9ab348653ad82ece3c10</aircraft_dc8-63>
<aircraft_dc8-73>26883edc54c7a02e208ce51e7b964e2e</aircraft_dc8-73>
<aircraft_Deperdussin>00fc8120294619b97ccf0e04a6145c1f</aircraft_Deperdussin>
<aircraft_DerKleineUhu>9003650773fd4933b40089d146484045</aircraft_DerKleineUhu>
<aircraft_Deuche>033799e2157ac9ffc6ac04fcdfeafe04</aircraft_Deuche>
<aircraft_DG-101G>02e81c7a33551c2581f8d5767e464518</aircraft_DG-101G>
<aircraft_DH-106>f7ac35642502a83a265f7b6594650279</aircraft_DH-106>
<aircraft_DH-88>be3e5fcef3000c72a2d85fb9eb827793</aircraft_DH-88>
<aircraft_DH-89>c745759b0e259323b20ba2e535284e7d</aircraft_DH-89>
<aircraft_DH-91>8b24f65ff28f7c66e65bcf7025582575</aircraft_DH-91>
<aircraft_dhc1>14b8d09e2debfdfd9cac81b8b67c9498</aircraft_dhc1>
<aircraft_dhc2>ff6f3470289772182d931daa00f6057f</aircraft_dhc2>
<aircraft_dhc3>a0506714e972c2a58f745c6bd7cc4fe2</aircraft_dhc3>
<aircraft_dhc4>4a792858aa65aada7cb91a47a9cf8c5d</aircraft_dhc4>
<aircraft_dhc6>81fb6e7b8ff50d43180bb758d1a56121</aircraft_dhc6>
<aircraft_dhc8>cca58285c8c814dfe923aaec656b1d9c</aircraft_dhc8>
<aircraft_Diamond-Da40>26885d6e6a849ad9dd54829baa26daee</aircraft_Diamond-Da40>
<aircraft_Diamond-Da42>e9992fcecbc66640a932c1c8fb7e71ae</aircraft_Diamond-Da42>
<aircraft_DO-228>8915f9465c563740f9f8f2cf32f1dd74</aircraft_DO-228>
<aircraft_DO-26>80757f34ea04417b6b30d65092ce50ab</aircraft_DO-26>
<aircraft_DO-335>ba8bbc9e04405db298beb9c24c6200c3</aircraft_DO-335>
<aircraft_DO-X>41356deabb2cd689393f36b96123a330</aircraft_DO-X>
<aircraft_Douglas-Dc3>b57c14a1791a20bccbf23db826a22dbb</aircraft_Douglas-Dc3>
<aircraft_Douglas-Dolphin>578771e25e6d7d81e5574d8cd1d19de0</aircraft_Douglas-Dolphin>
<aircraft_DR400>01c814d7ddeb0adcee0ed58022ebf6a8</aircraft_DR400>
<aircraft_DR400-dauphin>259cd05cfbf4b80b2cb4be07cf4bf781</aircraft_DR400-dauphin>
<aircraft_Dragonfly>012f8917ef6d7ec50d8a73c0508e5b47</aircraft_Dragonfly>
<aircraft_Dromader>9f77b8fbf981c4d761d8c497b6ef0868</aircraft_Dromader>
<aircraft_Dunne-D.5>48795402cda50957be7b7504b4d82389</aircraft_Dunne-D.5>
<aircraft_E-2C>d015100dfb5381135d221f41b293584d</aircraft_E-2C>
<aircraft_E3B>894c16ccfa5aed2778c7be4873947b69</aircraft_E3B>
<aircraft_eastbourne_mono>a99c8114ca48074fea2c675a8e6908e0</aircraft_eastbourne_mono>
<aircraft_ec130>684d979f81bf15b2adf47b52d6ca21f7</aircraft_ec130>
<aircraft_ec135>39631381049db9e54655c499f91bfb31</aircraft_ec135>
<aircraft_Embraer-ERJ-145>ef5ed515fe8f93876137bb6b27f3b158</aircraft_Embraer-ERJ-145>
<aircraft_ercoupe>bdaa474d4be6e51b21266ce0c8782c2c</aircraft_ercoupe>
<aircraft_Etrich-Taube>f6ba735798172b43abf417c80c1c4db4</aircraft_Etrich-Taube>
<aircraft_eurofighter>0f915d06528b1cc2dcc16f7be3b9ab37</aircraft_eurofighter>
<aircraft_extra500>72a8b154cda42a2ec507b6a4c604afcb</aircraft_extra500>
<aircraft_F-106-dart>84bfa325c11d56920062e8516bfc146e</aircraft_F-106-dart>
<aircraft_F-117>ba904d06c2ddb28a7fd3f95ac344de7a</aircraft_F-117>
<aircraft_f-14b>3c0963e6203c4a6315155012bbbb8096</aircraft_f-14b>
<aircraft_F-15>43f556905826c6ad5c80af409eb8a76c</aircraft_F-15>
<aircraft_F-35B>e1875c6efdc7ffe1160d8e64ac5f5fd7</aircraft_F-35B>
<aircraft_F-86>ea67ec6bb6c981dbbd391003f997c6ef</aircraft_F-86>
<aircraft_F-8E-Crusader>41b4502a287018e27402925094324209</aircraft_F-8E-Crusader>
<aircraft_f16>25805162fbd9d4d00e09c814f0beef9b</aircraft_f16>
<aircraft_f18>45264d8293d22533f56f571283940754</aircraft_f18>
<aircraft_F4U>fb47e4425240141a45818dcdc8060a4b</aircraft_F4U>
<aircraft_F6F-Hellcat>b4fcbc6e73565001d25f3cd64fb85a77</aircraft_F6F-Hellcat>
<aircraft_F7F-Tigercat>0ea6ad997b8595f97530d9aed5529ec9</aircraft_F7F-Tigercat>
<aircraft_F80C>9a7c5ac1aabe992abf14fd4b53c1712c</aircraft_F80C>
<aircraft_F9F-Panther>305fc09e91c52fefd2b67d6925baff38</aircraft_F9F-Panther>
<aircraft_fa223>3746de4faf66266399a9273321088ce2</aircraft_fa223>
<aircraft_Fairchild-C119>ec397cdc0f61d78ecc28d2cc564becd6</aircraft_Fairchild-C119>
<aircraft_Fairchild-Metroliner>3248a3f496cc146fcd95c61ec2538ae7</aircraft_Fairchild-Metroliner>
<aircraft_Fairey-Gannet>96e43cd67c0c8b9fd6e158a3ee46fbdc</aircraft_Fairey-Gannet>
<aircraft_Falcon-50>6d78633d200d8f945be6400027116539</aircraft_Falcon-50>
<aircraft_Farman-III>3e0a4af617e2064e78cee25e1d8af653</aircraft_Farman-III>
<aircraft_Farman-IV>42f45908ac131a855f66e63c09279562</aircraft_Farman-IV>
<aircraft_Fiat-G55>15f03458e112d4d7d3ff674dc20286c2</aircraft_Fiat-G55>
<aircraft_Fiat-G91>a3854718af2cf6c4c0512a166e283b4c</aircraft_Fiat-G91>
<aircraft_FK9MK2>24144321fdadaf71e81f8b014ad0e16b</aircraft_FK9MK2>
<aircraft_fkdr1>2294512dc1cdb63a8b90a21ba48875c7</aircraft_fkdr1>
<aircraft_flash2a>c56ee7fbdb10b1ba979d019cc26972cf</aircraft_flash2a>
<aircraft_Focke-Wulf-F19-ente>8bd5f800b24dbfc37f59fe368a748af1</aircraft_Focke-Wulf-F19-ente>
<aircraft_Focke-Wulf-Ta.154>f926af126c01eabd3ceb0398b178519a</aircraft_Focke-Wulf-Ta.154>
<aircraft_Fokker-Eindecker-EIII>29cd9e7ea06489595979f3df518813dd</aircraft_Fokker-Eindecker-EIII>
<aircraft_Fokker-G1>ea6025e2b6cdffc86764c5ee5a949c9a</aircraft_Fokker-G1>
<aircraft_Fokker-S-11>c3f68417e01ab653e66131bd446f8940</aircraft_Fokker-S-11>
<aircraft_Fokker-Spin>2fc955ad2ecb4ba0a7899097e7e4b226</aircraft_Fokker-Spin>
<aircraft_fokker100>83874804ebae4b77f6ac92f55c19ba91</aircraft_fokker100>
<aircraft_fokker50>da5fc6e9761203e6dd26dc3f01a2fe68</aircraft_fokker50>
<aircraft_followme>6b17d6d7bc78b5424420d47c0d737fa9</aircraft_followme>
<aircraft_Ford-Trimotor>83743f288a09c89716ac2a2e212b11bc</aircraft_Ford-Trimotor>
<aircraft_Fouga-Magister>866329f60e90f3404a6bace54e733b73</aircraft_Fouga-Magister>
<aircraft_fw190>449953e8d06e61e78e94e520d8fbc3e3</aircraft_fw190>
<aircraft_Fw200>5179bd127ee44112ec06887e322725aa</aircraft_Fw200>
<aircraft_Fw61>049759aaa0c615f71b0e1e2d683cb3ba</aircraft_Fw61>
<aircraft_G-164>977f70220ecee03ef7367b940956122a</aircraft_G-164>
<aircraft_Gee-Bee>bf993f8a5499538d2b5f5f5ec0c7574d</aircraft_Gee-Bee>
<aircraft_Gloster-Gladiator>65223229f5f8adc17c534412fb1b2bc8</aircraft_Gloster-Gladiator>
<aircraft_Gloster-Meteor>9905dc7569bc1e9cf750e47cc138dbeb</aircraft_Gloster-Meteor>
<aircraft_Gloster-Whittle>ef530cb8d0f3b53b83d993f4284bc4c3</aircraft_Gloster-Whittle>
<aircraft_Gotha-G-V>d18ed659fb34df8e078b36d0156de731</aircraft_Gotha-G-V>
<aircraft_Grob-Astir>57ada6ce17e8dda569e49ef29a517b90</aircraft_Grob-Astir>
<aircraft_Grob-G109>65c28732f4909889ca9739953c7b2032</aircraft_Grob-G109>
<aircraft_Grob-G115>82ca3e94ee5a1ee711fbc73e7ab99645</aircraft_Grob-G115>
<aircraft_Grob-Gf200>b80921cb1ec91813ba6912abf8d3d73c</aircraft_Grob-Gf200>
<aircraft_Grumman-American-AA1>40f6523b7cc0aff71281820d54bdaa0f</aircraft_Grumman-American-AA1>
<aircraft_H-21C-Shawnee>515e08d2a12b2cc1891f23e086aa5933</aircraft_H-21C-Shawnee>
<aircraft_H1-Racer>d8250d2d9f842108ffed965ced81ab64</aircraft_H1-Racer>
<aircraft_H4-Hercules>34ea914ec8c9f7c85ba3c243c6d0f981</aircraft_H4-Hercules>
<aircraft_Handley-Page-Halifax>837d0bc1db372b8d18e251fb63aa13ea</aircraft_Handley-Page-Halifax>
<aircraft_Hansajet>98a417480a3126432d9214fe0efb83c9</aircraft_Hansajet>
<aircraft_harrier>568eeccd7ffc3b08937fdf2da81a972a</aircraft_harrier>
<aircraft_Harrier-GR1>8f90009d9f8c66ba0dafc1c05ff2c685</aircraft_Harrier-GR1>
<aircraft_Harrier-GR3>b3d6038ff416a64372b663e9f3ccc137</aircraft_Harrier-GR3>
<aircraft_Hawker-Siddeley-Nimrod>e78cd169d9423dc9a9126d51fbeeb91e</aircraft_Hawker-Siddeley-Nimrod>
<aircraft_He-111>febb50152f339e23040815432e8fd6d4</aircraft_He-111>
<aircraft_He162>a27b2dd3efe6a362d135d55eca70d134</aircraft_He162>
<aircraft_Heinkel-He-111>941ab65d0ee6a8c0578e87b8d881ffc0</aircraft_Heinkel-He-111>
<aircraft_Heinkel-He-177>3bc698cc3b8937609e715c12fb135ca0</aircraft_Heinkel-He-177>
<aircraft_Heinkel-He-178>8a646c02ac858485f683301e5d98adb5</aircraft_Heinkel-He-178>
<aircraft_Heinkel-He-280>f4656701178b9d1eea30aa73b6a96ea2</aircraft_Heinkel-He-280>
<aircraft_Heston-Type5>11ef72971dce2d4b47f9899fabc4e591</aircraft_Heston-Type5>
<aircraft_HM-14>aa1c16c7731e99ebc6cd536ce26daa14</aircraft_HM-14>
<aircraft_Hornet>5dacabf98fe85149246cd5fc9bae6c39</aircraft_Hornet>
<aircraft_Horsa>1ddf68bca0c4a97d263a2d1718f87d2e</aircraft_Horsa>
<aircraft_Horten-Ho-IX>e8e04eb1d9bd25e270944775d8cb4100</aircraft_Horten-Ho-IX>
<aircraft_HS-P-75>90f738b3a6362f787e2170cb3d7317f0</aircraft_HS-P-75>
<aircraft_Hughes-XF11>bcf549f662ba17ac5896ef38b824f13e</aircraft_Hughes-XF11>
<aircraft_Hunter>608118d1e8019c92a22c275b8ce02c4a</aircraft_Hunter>
<aircraft_HUP-Retriever>5a2683f3d5a170495dc0ed3ed8cfa3f2</aircraft_HUP-Retriever>
<aircraft_Hurricane>0f64845ba2b2a4bc6a5f5637d261b93b</aircraft_Hurricane>
<aircraft_Icaro_MRX13>5f873b418694a01d049664ae58ad69a8</aircraft_Icaro_MRX13>
<aircraft_IL-2>cdc9eeae48d8760204735cf3dfdfbec9</aircraft_IL-2>
<aircraft_j22>14d705864d455ec73ca9c373f6d61d58</aircraft_j22>
<aircraft_J3Cub>f978f4a979edc6b3ac3c6b0cbd631c83</aircraft_J3Cub>
<aircraft_j7w>b777fc0d1a2c85ce6c0a03dfd90df48b</aircraft_j7w>
<aircraft_JA37>ef141db8c2469b1421c8e74f018ee8a4</aircraft_JA37>
<aircraft_Jaguar>7a0a5d5f93e34dd40fcdce3f06848908</aircraft_Jaguar>
<aircraft_JAS39-Gripen>ed3685660909e7e831d7711a2cc7b7b0</aircraft_JAS39-Gripen>
<aircraft_jeep>59341e0675583a826c34c625ba277345</aircraft_jeep>
<aircraft_jetman>67a0cbf1e934dd6552cf3f231ed65964</aircraft_jetman>
<aircraft_Jodel-D140>0cfed1923e5d2b849760df5ced30a175</aircraft_Jodel-D140>
<aircraft_JT-5B>0650d1a62cce431fa07e64bf8845a904</aircraft_JT-5B>
<aircraft_Ju-87>91a6f9e779d641b451efa777b6f81e81</aircraft_Ju-87>
<aircraft_Ju-88>ebdd6f04edccd2205bcaed1e845b567d</aircraft_Ju-88>
<aircraft_ju52>ee7f03a89cabb1370183f8a88dad1e9d</aircraft_ju52>
<aircraft_Junkers-F13>f88670ae7d834818ba14d71a7e0036e3</aircraft_Junkers-F13>
<aircraft_Junkers-G.38ce>7ad891738873394a7626882fd86e2031</aircraft_Junkers-G.38ce>
<aircraft_Junkers-Ju-390>be9047b6412830adcf9a7d68cb4574d1</aircraft_Junkers-Ju-390>
<aircraft_Junkers-W34>b5e96c226c4a2277b34dee97efc1d960</aircraft_Junkers-W34>
<aircraft_K-7>cb160921e2c703bbbdafcb51d49c266f</aircraft_K-7>
<aircraft_K5Y1>f72439b0db6a44fde139cb7651c28207</aircraft_K5Y1>
<aircraft_Ka-50>96aae67efd76fb6bfce1a97b1fbdbefd</aircraft_Ka-50>
<aircraft_Katana>151fbc5f85a7acd78039d2f074901028</aircraft_Katana>
<aircraft_Kawasaki-Ki-61-Hien>4ab8429c7200f96c144439fe50cda12d</aircraft_Kawasaki-Ki-61-Hien>
<aircraft_KC135>28519bdf05d7b1c5601ebfe9b7d95c0d</aircraft_KC135>
<aircraft_Ki-84>fbee5f8f188262cf1e09c168dd1014db</aircraft_Ki-84>
<aircraft_KM>3031820f648fe2fb15f8c9d64c104387</aircraft_KM>
<aircraft_kodiak>947daecf702214b7708c8d7df872366b</aircraft_kodiak>
<aircraft_L-1011-500>14670bbba47068cc5914c399c51a20e3</aircraft_L-1011-500>
<aircraft_l39>1d42f9adf23bf70ef1f9ba1695b9f794</aircraft_l39>
<aircraft_La-5>75204b0421e9835bf3ac3d2a0d198163</aircraft_La-5>
<aircraft_Lancair-235>6fbd208db0830b462fe2d105d1924f1e</aircraft_Lancair-235>
<aircraft_LATE-29>5ad79d5b9a17f3ac79b71722547fb6ff</aircraft_LATE-29>
<aircraft_Late-631>421b4ec83fe86c82e0bb952d3ee08780</aircraft_Late-631>
<aircraft_Leduc-022>2d3c15a8151e86b497900f6873b1875b</aircraft_Leduc-022>
<aircraft_Lightning>b80a9a8c89b05c4fa22a314ea56b32ab</aircraft_Lightning>
<aircraft_Lionceau>93a573bcf722ce69de872674b3f9dd27</aircraft_Lionceau>
<aircraft_Lockheed-Martin-FA-22A-Raptor>97c2da3770e378b72637b09c0475156f</aircraft_Lockheed-Martin-FA-22A-Raptor>
<aircraft_Lockheed-NF104>572acc2315b077411699eba35c0655d1</aircraft_Lockheed-NF104>
<aircraft_Lockheed-NF104A>41347e33250b355077aba64c671a44ce</aircraft_Lockheed-NF104A>
<aircraft_Lockheed-P38>53cd0af0a81de17378a7d3201c31dbb9</aircraft_Lockheed-P38>
<aircraft_Lockheed-SR71>99485aa18c25c0e6537334d63ccfe2c6</aircraft_Lockheed-SR71>
<aircraft_Lockheed-U-2S>b00db640f9f0f490b0bfa7d6d8b40163</aircraft_Lockheed-U-2S>
<aircraft_Lockheed-Vega>04e530018ec557294dd90128fc0c4a56</aircraft_Lockheed-Vega>
<aircraft_Lockheed1049>99539707fa1c283b6513be48996d8d14</aircraft_Lockheed1049>
<aircraft_Lockheed1049h>8da4141b5716e4321d1d5dcf3cfd30e6</aircraft_Lockheed1049h>
<aircraft_Long-EZ>6e5a8b2abc701632f9b9ab7a839eee4d</aircraft_Long-EZ>
<aircraft_Lynx-WG13>9add8ac0325547a52fa53e03b06d23b9</aircraft_Lynx-WG13>
<aircraft_M-XE>1978498650f9f5ae335cfd702a6d16f6</aircraft_M-XE>
<aircraft_Macchi-Castoldi-MC72>6952026a71d24cf0b11baca0320ab087</aircraft_Macchi-Castoldi-MC72>
<aircraft_Macchi-M33>90dc0d1bce4c19822312f51be82e9c98</aircraft_Macchi-M33>
<aircraft_marchetti>b6959644da3e1acbdd2f63af0cc529f0</aircraft_marchetti>
<aircraft_Martin-Baker-MB5>5c21bdb968a38b57b911aa998b9db99d</aircraft_Martin-Baker-MB5>
<aircraft_MB326>1a61bc6d32a3ed512b51535c46dc6991</aircraft_MB326>
<aircraft_MD-312-Flamant>be65efca7b7d7fc246c373e391996978</aircraft_MD-312-Flamant>
<aircraft_MD11>e772e7fae851948c6f6b19c0191821aa</aircraft_MD11>
<aircraft_ME-209-V1>3de79c61240e8e04a24d95c707a61a2b</aircraft_ME-209-V1>
<aircraft_ME-262>9960374b772e64e5ad75e0d3b6e12f08</aircraft_ME-262>
<aircraft_ME-262HGIII>3dfa621d920cecce3585b0f1ccb6be72</aircraft_ME-262HGIII>
<aircraft_me163>687309052c27966bd4d3bbd023237c17</aircraft_me163>
<aircraft_me323>0d615e9e715d3d4e150e836fbf43f426</aircraft_me323>
<aircraft_Messerschmitt-BF110>39b9d8b0a4aafa4e1b25992520deb011</aircraft_Messerschmitt-BF110>
<aircraft_Messerschmitt-Libelle>ed7ad8c54b6c2d9d1727e85a1a198a31</aircraft_Messerschmitt-Libelle>
<aircraft_Messerschmitt-P1101>3b989b232dd121eff6b0b230e9e85f6c</aircraft_Messerschmitt-P1101>
<aircraft_MFI-9>a566bad5dc6de5bc8d782c4f292e34ed</aircraft_MFI-9>
<aircraft_MiG-15>9bb9d2c8983b99f4f74e063f3d1e3479</aircraft_MiG-15>
<aircraft_MiG-21bis>d749c64a1fa96fbb0f13fc3d41b646e9</aircraft_MiG-21bis>
<aircraft_Mig-29>c6b9271b94abdf0770612a5cf4555f91</aircraft_Mig-29>
<aircraft_Mil-Mi-12>e1d83cafee3b3cecfdc3e473913df264</aircraft_Mil-Mi-12>
<aircraft_Mil-Mi-24>9fe6b04de733a20290141310f02abdcf</aircraft_Mil-Mi-24>
<aircraft_Mirage-2000>7bf582dfc110cfe38d616b1cdeed91ee</aircraft_Mirage-2000>
<aircraft_mirage2000>faa0e38bdadaadb61fa28e968f8a2122</aircraft_mirage2000>
<aircraft_Mirage_F1>dc188baadc7e6b3033845cfd48a14163</aircraft_Mirage_F1>
<aircraft_MirageIII>9f814e7ec8180ca71bbaf721d9337e70</aircraft_MirageIII>
<aircraft_MirageIV>a969aedf03beddd8ee89367d6179e1a4</aircraft_MirageIV>
<aircraft_mosquito>15eac7459f9aeafabdce72df42a4ba69</aircraft_mosquito>
<aircraft_MPCarrier>280758b9c9b1ec90f2010f1b1ab06ba7</aircraft_MPCarrier>
<aircraft_MRJ>ad879791f1e9d0e2d719d6a4518bbe2c</aircraft_MRJ>
<aircraft_MS-406>4507e58972e6bc69ba4f46ea3db455ec</aircraft_MS-406>
<aircraft_Nakajima-B5N>02e681d40a2427610dd55c643e89b01d</aircraft_Nakajima-B5N>
<aircraft_Nieuport-11>701b0401fb152e87a40c8b5babe87798</aircraft_Nieuport-11>
<aircraft_Noratlas>b177adbf225feca2f7d39f80d5acc352</aircraft_Noratlas>
<aircraft_Nord-1405-Gerfaut-II>a862bcf397791708ef2e0441282b2b69</aircraft_Nord-1405-Gerfaut-II>
<aircraft_Nord-2502>c6f4dc65ba8177e50ef5742b3ecb52b7</aircraft_Nord-2502>
<aircraft_Nordstern>6df28cb4a7d5e8907391c3ed8e70b6e0</aircraft_Nordstern>
<aircraft_North-American-T28D-Trojan>5fee1165f23a11eeca4d24d766117377</aircraft_North-American-T28D-Trojan>
<aircraft_North-American-T6-Texan>7ee82c752779d1c51f7b92660006aad2</aircraft_North-American-T6-Texan>
<aircraft_Northrop-P61>23a394d7e36aa653bff9b32fc9548250</aircraft_Northrop-P61>
<aircraft_Northrop-xb35>e4ec374be03638c10a88f351e8f09bad</aircraft_Northrop-xb35>
<aircraft_ogel>26e51eabb21a9a71f1b5a685e3061843</aircraft_ogel>
<aircraft_OH-1>49259a0e7725bb2c6809e1aae15e8fac</aircraft_OH-1>
<aircraft_OH-58D>40801a1693b0b8bd33178d4a5bf67765</aircraft_OH-58D>
<aircraft_ornithopter>7b0c70f7b8de3e1a5c19d32c36fa7d00</aircraft_ornithopter>
<aircraft_OV10>74faff4f12efb353ccc61689fe96c46c</aircraft_OV10>
<aircraft_P-38-Lightning>43c98dfe30fecc4c2448dc51750154ee</aircraft_P-38-Lightning>
<aircraft_P130UL>ea0a540d06226687e3409c1226a1cc1d</aircraft_P130UL>
<aircraft_P180>ab8760c0219835fe97dcbbf698b39fa4</aircraft_P180>
<aircraft_P47>cc9b6238b260d924338d2c4ee2dafc95</aircraft_P47>
<aircraft_p51d>7caa4abbdb5dba23edbdc02cf2693909</aircraft_p51d>
<aircraft_pa22>da2990b33cef4afe7d629530b274632a</aircraft_pa22>
<aircraft_pa24-250>65a95dd87096e2377dff6fe917befb8a</aircraft_pa24-250>
<aircraft_pa28-161>02f4a01e218da00e8969d4ae52c84193</aircraft_pa28-161>
<aircraft_PaperAirplane>2b7fbfc1efdf6ab2663e8b3d7cd3daed</aircraft_PaperAirplane>
<aircraft_Parachutist>79da74f4e265f5290b4cf35b740663a7</aircraft_Parachutist>
<aircraft_paraglider>6531e09545716af63e4ef5cf8feb8ec1</aircraft_paraglider>
<aircraft_payen-pa100>2f86aa5353798f3a4202e403bfa12c02</aircraft_payen-pa100>
<aircraft_payen-pa350cd>b6e5e2bb9985effc63bdcb2177ec681b</aircraft_payen-pa350cd>
<aircraft_PBY-Catalina>937f55e89ec3df58c2d0339f9a1dd622</aircraft_PBY-Catalina>
<aircraft_PC-12>70352371bec5bee2af6bfa7fceb7da5e</aircraft_PC-12>
<aircraft_PC-21>a53d16394c2492eb0a713ecfd8dbaf8e</aircraft_PC-21>
<aircraft_PC-6>b4fbd66018b94d83d11e3e6e7e0fac1d</aircraft_PC-6>
<aircraft_PC-9M>7c90665c0c85a3e81b15a0ea69befeeb</aircraft_PC-9M>
<aircraft_pc7>6eea7be83224abc9a1c3da0ce2fe6c82</aircraft_pc7>
<aircraft_Percival-Mew-Gull>e2e0f33e2d38ad747f5c738230439ad6</aircraft_Percival-Mew-Gull>
<aircraft_Piaggio-P166>66de4194f057e4a5248d19c5d51f88ca</aircraft_Piaggio-P166>
<aircraft_Piaggio-Pegna-Pc-7>6944e2533d7ddca2752df6300a281b16</aircraft_Piaggio-Pegna-Pc-7>
<aircraft_Pioneer-200>8e89696bf062126e4fe969a65ea5da1f</aircraft_Pioneer-200>
<aircraft_Piper-PA-18>466c8c681f2c6c942668d769e79defba</aircraft_Piper-PA-18>
<aircraft_Piper-PA-28>f7f176d0ff24d09134c43f0e0bc57d5b</aircraft_Piper-PA-28>
<aircraft_Piper-PA-32>601545618b8fe3c210b4514a25242faf</aircraft_Piper-PA-32>
<aircraft_pittss1c>427efb1a07d99ca6c99698de322b7d74</aircraft_pittss1c>
<aircraft_Polikarpov-I16>3926f7b7e584ad63327a622dbac60564</aircraft_Polikarpov-I16>
<aircraft_Pond-Racer>46e6876c63888a593dd46307b7fe0965</aircraft_Pond-Racer>
<aircraft_Potez-630>228dab05bac8112a51265a509d28adc3</aircraft_Potez-630>
<aircraft_Pterodactyl>aa747cdb68e4ce5bcf3fcf3a7fa9b371</aircraft_Pterodactyl>
<aircraft_Pterosaur>fec9ddaa76f650624821341e07c32ef5</aircraft_Pterosaur>
<aircraft_pushback>8fa3ff17dbf4f5216d2b038af30b6d4b</aircraft_pushback>
<aircraft_Quickie>9e12e7ae2a644e77749efb5d5c4d0917</aircraft_Quickie>
<aircraft_R22>7c66503ed0253f16ad021be72e4abfa7</aircraft_R22>
<aircraft_R44>4db8a423cab299263b5139e0b44c4884</aircraft_R44>
<aircraft_RAF-S-E-5>267a979bb7fcadac5698365c158f8fbf</aircraft_RAF-S-E-5>
<aircraft_rah-66>14d8af5d3bc22ac49c5bdfcb8f63c9d8</aircraft_rah-66>
<aircraft_rallye-MS893>7afb876e7a2e7b7bfaa8619bf0c07265</aircraft_rallye-MS893>
<aircraft_Rascal>640eafc8068633c0e48ed3a569d18870</aircraft_Rascal>
<aircraft_RV-6A>27238520cd1123eb6e832489ed6d5a65</aircraft_RV-6A>
<aircraft_Ryan-Navion>e64d386ede9f5d1ab93bbe212246086f</aircraft_Ryan-Navion>
<aircraft_Ryan-PT22>dee77f1d0d3de7f0ce6859006e0ba642</aircraft_Ryan-PT22>
<aircraft_Ryan-SoSL>93e380e1b639a5d063be34521ef058a1</aircraft_Ryan-SoSL>
<aircraft_S-51-Dragonfly>fa4c3f5a64725039c6ac69dc817d0861</aircraft_S-51-Dragonfly>
<aircraft_SaabJ35F>d9c356d0f282204a451c7acb86a0df95</aircraft_SaabJ35F>
<aircraft_santa>cd6232d913be2a512d2e8fcae806afad</aircraft_santa>
<aircraft_Saunders-Roe-Princess>a6cef52c80b2fd0ebc43e26183d9a668</aircraft_Saunders-Roe-Princess>
<aircraft_seahawk>792aa8e491c51b10898600e5fce883fd</aircraft_seahawk>
<aircraft_SeaVixen>21e9817040f8a9ab9160745591915f28</aircraft_SeaVixen>
<aircraft_SenecaII>a769ea7ad74deb9a793966b98be001a0</aircraft_SenecaII>
<aircraft_sf25b>664ad64136e6958a39b292ec54607037</aircraft_sf25b>
<aircraft_sgs233>86308422b554356c850dffb9d0c90b2a</aircraft_sgs233>
<aircraft_Short-Stirling>96a0604d6e963d36a35e919f3ca01310</aircraft_Short-Stirling>
<aircraft_Short_Empire>868a7faef6fb3bca64a0bcb19b32840c</aircraft_Short_Empire>
<aircraft_shuttle>4e24a9c27d36afaec32256a211bef2c3</aircraft_shuttle>
<aircraft_SIAI-Marchetti-S.205R>2771caeaa310c1a6970e95c0ea403f3a</aircraft_SIAI-Marchetti-S.205R>
<aircraft_SIAI-Marchetti-SF.260>dcab556a830e493703640fd1fdad70eb</aircraft_SIAI-Marchetti-SF.260>
<aircraft_Sikorsky-76C>679c00028ac62b9aa3368840147170b5</aircraft_Sikorsky-76C>
<aircraft_Sikorsky-S38>3856921a90f947ec2f3e70fa23a1f6ea</aircraft_Sikorsky-S38>
<aircraft_Sikorsky-S58>9abb2fc4e373ab4431920fdaf45d8a87</aircraft_Sikorsky-S58>
<aircraft_Sky-sportster>d9b9c033f30335a81558a201810f862e</aircraft_Sky-sportster>
<aircraft_Skyranger>0a7450c02b7ff3de085087668ba975e7</aircraft_Skyranger>
<aircraft_Skyvan>712723a74eaa5f47d905c5938d1ecfa3</aircraft_Skyvan>
<aircraft_SM-55>dad894bca78456b5e2ba2e2005d2f29a</aircraft_SM-55>
<aircraft_sm79>626844492e56226455fa3a399f41c9e9</aircraft_sm79>
<aircraft_snowplow>e9eb491ec0bf4d3ad2c2690b94a9be95</aircraft_snowplow>
<aircraft_Socata-ST10>37b95c63434f398743ebbdfd2bee8089</aircraft_Socata-ST10>
<aircraft_sopwithCamel>7792f06b71703a39936f75eb1f0f1e05</aircraft_sopwithCamel>
<aircraft_SpaceShip-One>d082a2f287fc96ade10753e47cff2977</aircraft_SpaceShip-One>
<aircraft_SpaceShuttle>39c46f24941da46177122a83f119e8b7</aircraft_SpaceShuttle>
<aircraft_SPAD-VII>f250ae8d2a2b28eb4f736aa28e8f6abf</aircraft_SPAD-VII>
<aircraft_Spitfire>ca055bf7c4d39b07a40bb465ad635146</aircraft_Spitfire>
<aircraft_spitfireIX>690b3c6a74770738d2d5173fefb48e61</aircraft_spitfireIX>
<aircraft_sr20>cbecc0a364fbe6a7aa0c0ea683ce62ea</aircraft_sr20>
<aircraft_SR71-BlackBird>29a5495e10aa160cf94b0b9a06e94b48</aircraft_SR71-BlackBird>
<aircraft_Stampe-SV4>54ed408f46a6ae86d2b609c58caa2348</aircraft_Stampe-SV4>
<aircraft_Starship>078d68204b7b7d11103f97d6067693d2</aircraft_Starship>
<aircraft_Stearman>791b0a572eba95a6d0fcfdee605b284e</aircraft_Stearman>
<aircraft_Stieglitz>7c5d4939a29bbde445fa5a51a806a600</aircraft_Stieglitz>
<aircraft_Stiletto>f469bf3d05e34508c4644c9f21adde9b</aircraft_Stiletto>
<aircraft_Storch>987d5891ea899b92697b3dbae69f4290</aircraft_Storch>
<aircraft_Su-25>fc53b9f9e774bf455099a41e44f163e0</aircraft_Su-25>
<aircraft_SU-37>f0f2e74ef26520d16f11c26adcfa7244</aircraft_SU-37>
<aircraft_Submarine_Scout>57853593a2c72148f0de00faa70d67d4</aircraft_Submarine_Scout>
<aircraft_Super-Etendard>ea86ee06b4d358790036fe22ae8673a3</aircraft_Super-Etendard>
<aircraft_Super-Frelon>92a9c71fb1666816273b3283e7d02504</aircraft_Super-Frelon>
<aircraft_superguppySGT>86c50734cf3e657a4bb0646ae4848af3</aircraft_superguppySGT>
<aircraft_Supermarine-S.6B>b59d6790040c27853338b680067edc52</aircraft_Supermarine-S.6B>
<aircraft_Superwal>92158d7e55f4a892b3d3640cf0b254f0</aircraft_Superwal>
<aircraft_T-4>8518cfd8bec8278d0681f67dc7293906</aircraft_T-4>
<aircraft_T-50>2e45346a0f377bcb6adc59be3c05d72a</aircraft_T-50>
<aircraft_T37>7607a3732fee1ad3b43d44875764afe0</aircraft_T37>
<aircraft_T38>1039def0bf9d28ef2cc3a4b5649a9bcb</aircraft_T38>
<aircraft_TBM-Avenger>3118e96ceee1f63c4c5f916e48a62e3c</aircraft_TBM-Avenger>
<aircraft_Tecnam-P2006T>45daae280d68e757730051ce96933435</aircraft_Tecnam-P2006T>
<aircraft_Tecnam-P2010>d27cfef60c88f2785585db762aff50c0</aircraft_Tecnam-P2010>
<aircraft_Tecnam-P92>eefbe319cbc34fed4d63ace54f2fc1c8</aircraft_Tecnam-P92>
<aircraft_Tigre>806acc4c1616d1d940e61d27737e39f6</aircraft_Tigre>
<aircraft_TU-114>f6ce2c5a24ea1545e1d22956017e31b0</aircraft_TU-114>
<aircraft_Tu-134>66cee3c0d3e34c4bd97599c1a633c7db</aircraft_Tu-134>
<aircraft_TU-95>71c35b11bb1662bd612bc8e3e21232e5</aircraft_TU-95>
<aircraft_Tu-SB2bis-M103>50cd266f7a98b7d19ec75b9be804e715</aircraft_Tu-SB2bis-M103>
<aircraft_tu154>e5fd32dabb3412be5797805b5b00c002</aircraft_tu154>
<aircraft_tu154b>7a7bd91ea1d3c40e3f52a3453f6d5789</aircraft_tu154b>
<aircraft_UH-1>0c2692680244c3848e16c5f5cc6e525f</aircraft_UH-1>
<aircraft_UH-60>3126bd7f0dc24fb15fbaa6516bbc08d9</aircraft_UH-60>
<aircraft_V22-Osprey>1b1eb3803d01ea5dbfaee1836c9efb02</aircraft_V22-Osprey>
<aircraft_Velocity-XL>85770badb88a7a876bb828718cc4a30f</aircraft_Velocity-XL>
<aircraft_Vickers-Vanguard>1c9f328d29ee7e2453bf30a6b05939f4</aircraft_Vickers-Vanguard>
<aircraft_Vickers-Vimy>5d6709607fc95b3867fc491c0fe5e5e3</aircraft_Vickers-Vimy>
<aircraft_victor>ee0b3f5284765e02f1357f1cf7071ee1</aircraft_victor>
<aircraft_VMX22-Osprey>39f6e98033e45e3b599cdff5b72d7328</aircraft_VMX22-Osprey>
<aircraft_Vostok-1>9dc57923ec3e984723338db44460b4fe</aircraft_Vostok-1>
<aircraft_vulcanb2>f2eabbfcc31b0ab183fb4b91ba4f19c4</aircraft_vulcanb2>
<aircraft_Westland-Whirlwind>cce4ae63928058699f87b61a9604d1b1</aircraft_Westland-Whirlwind>
<aircraft_wrightFlyer1903>04d855def138064915a06781720d33cc</aircraft_wrightFlyer1903>
<aircraft_X15>a4e382d1493412f3d5cb1e06f9ec9b88</aircraft_X15>
<aircraft_x24b>c209d368e99561002a43697c0496d87d</aircraft_x24b>
<aircraft_XB-70>749a85a21354df350ddb8c50a5561b22</aircraft_XB-70>
<aircraft_XP-67>83cebd2f3cf663215a8bb97dcd38b13e</aircraft_XP-67>
<aircraft_Yak-130>b867555c6e06befe0715665c2a10931d</aircraft_Yak-130>
<aircraft_Yak-18T>e514c7719ac869a86ff466a22de3554d</aircraft_Yak-18T>
<aircraft_Yak-23>c1e1b2a685c99e73720bca83f0c01405</aircraft_Yak-23>
<aircraft_Yak-36>2db3c206f581c88c329567013d16aca3</aircraft_Yak-36>
<aircraft_yak3>62ff0d85b3b5d71c2854623bcad155cb</aircraft_yak3>
<aircraft_YardStik>44106df1f8f1145bb7f9d465a3d85233</aircraft_YardStik>
<aircraft_YF-23>bf82709deb10a369d7eaa23d623f631a</aircraft_YF-23>
<aircraft_YS-11>f32ab303e103ceeb6ca46926f2c1f510</aircraft_YS-11>
<aircraft_ZF_Navy_free_balloon>d6d11bb00006f7b6da2f4939ef06af23</aircraft_ZF_Navy_free_balloon>
<aircraft_ZivkoEdge>01893b6c69d97c42f223d95ff8595ff7</aircraft_ZivkoEdge>
<aircraft_Zlin-50lx>ec52deb7d44c5186c324ac0532ff2bc8</aircraft_Zlin-50lx>
<aircraft_ZLT-NT>60ffdd2bd30dc4a02dfca2ced49bbec5</aircraft_ZLT-NT>
<aircraft_IL-76>4a8d5a29427d179a6b0566d79555cbad</aircraft_IL-76>
<aircraft_SuperGuepard912>eedc5b614bac903c03dfdd287dc0123a</aircraft_SuperGuepard912>
<aircraft_Heinkel-He-111Z>e1f2b5c9d0a65366efd6f4840725d3c5</aircraft_Heinkel-He-111Z>
<aircraft_c182s>e307c8d98edfad2432ceea160a5b455d</aircraft_c182s>
<aircraft_Cessna-L19>3c40924714e6511a2c7c2e8d64a22e4c</aircraft_Cessna-L19>
<aircraft_Boomerang>e9c38c20924902a8cb168d69adf028c5</aircraft_Boomerang>
<aircraft_Arsenal-Delanne-10>e01bdd83f13783e98eae4d89d7c55405</aircraft_Arsenal-Delanne-10>
</PropertyList>

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Template catalog - copy and modify for your site as required-->
<PropertyList>
<template>
<version n="0">3.4.*</version>
<version n="1">3.5.*</version>
<version n="2">3.6.*</version>
<version n="3">3.7.*</version>
<version n="4">2016.1.*</version>
<version n="5">2016.*.*</version>
<version n="6">2017.*.*</version>
<id>org.flightgear.fgaddon</id>
<license>GPL</license>
<url>http://mirrors.ibiblio.org/flightgear/ftp/Aircraft/catalog.xml</url>
<name>FlightGear Aircraft Distribution From fgaddon</name>
<description>This hangar provides aircraft officially supported and maintained by the FlightGear project, under a free-software license.</description>
<de>
<description>Auf Deutsch</description>
</de>
<fr>
<description>En Francais</description>
</fr>
</template>
</PropertyList>

View File

@@ -1,5 +0,0 @@
*/.svn/*
*.xcf
*.blend
*.psd
*~

View File

@@ -1,303 +0,0 @@
# SAX for parsing
from xml.sax import make_parser, handler, expatreader
# ElementTree for writing
import xml.etree.cElementTree as ET
import re, os
class Node(object):
def __init__(self, name = '', index = 0, parent = None):
self._parent = parent
self._name = name
self._value = None
self._index = index
self._children = []
@property
def value(self):
return self._value
@value.setter
def value(self, v):
self._value = v
@property
def name(self):
return self._name
@property
def index(self):
return self._index
@property
def parent(self):
return self._parent
def getChild(self, n, i=None, create = False):
if i is None:
i = 0
# parse name as foo[999] if necessary
m = re.match(R"(\w+)\[(\d+)\]", n)
if m is not None:
n = m.group(1)
i = int(m.group(2))
for c in self._children:
if (c.name == n) and (c.index == i):
return c
if create:
c = Node(n, i, self)
self._children.append(c)
return c
else:
raise IndexError("no such child:" + str(n) + " index=" + str(i))
def addChild(self, n):
# adding an existing instance
if isinstance(n, Node):
n._parent = self
n._index = self.firstUnusedIndex(n.name)
self._children.append(n)
return n
i = self.firstUnusedIndex(n)
# create it via getChild
return self.getChild(n, i, create=True)
def firstUnusedIndex(self, n):
usedIndices = frozenset(c.index for c in self.getChildren(n))
i = 0
while i < 1000:
if i not in usedIndices:
return i
i += 1
raise RuntimeException("too many children with name:" + n)
def hasChild(self, nm):
for c in self._children:
if (c.name == nm):
return True
return False
def getChildren(self, n = None):
if n is None:
return self._children
return [c for c in self._children if c.name == n]
def getNode(self, path, cr = False):
axes = path.split('/')
nd = self
for ax in axes:
nd = nd.getChild(ax, create = cr)
return nd
def getValue(self, path, default = None):
try:
nd = self.getNode(path)
return nd.value
except:
return default
def write(self, path):
root = self._createXMLElement('PropertyList')
t = ET.ElementTree(root)
t.write(path, 'utf-8', xml_declaration = True)
def _createXMLElement(self, nm = None):
if nm is None:
nm = self.name
n = ET.Element(nm)
# value and type specification
try:
if self._value is not None:
if isinstance(self._value, basestring):
# don't call str() on strings, breaks the
# encoding
n.text = self._value
else:
# use str() to turn non-string types into text
n.text = str(self._value)
if isinstance(self._value, int):
n.set('type', 'int')
elif isinstance(self._value, float):
n.set('type', 'double')
elif isinstance(self._value, bool):
n.set('type', "bool")
except UnicodeEncodeError:
print "Encoding error with", self._value, type(self._value)
# index in parent
if (self.index != 0):
n.set('n', str(self.index))
# children
for c in self._children:
n.append(c._createXMLElement())
return n;
class ParseState:
def __init__(self):
self._counters = {}
def getNextIndex(self, name):
if name in self._counters:
self._counters[name] += 1
else:
self._counters[name] = 0
return self._counters[name]
def recordExplicitIndex(self, name, index):
if not name in self._counters:
self._counters[name] = index
else:
self._counters[name] = max(self._counters[name], index)
class PropsHandler(handler.ContentHandler):
def __init__(self, root = None, path = None, includePaths = []):
self._root = root
self._path = path
self._basePath = os.path.dirname(path)
self._includes = includePaths
self._locator = None
self._stateStack = [ParseState()]
if root is None:
# make a nameless root node
self._root = Node("", 0)
self._current = self._root
def setDocumentLocator(self, loc):
self._locator = loc
def startElement(self, name, attrs):
self._content = None
if (name == 'PropertyList'):
# still need to handle includes on the root element
if 'include' in attrs.keys():
self.handleInclude(attrs['include'])
return
currentState = self._stateStack[-1]
if 'n' in attrs.keys():
try:
index = int(attrs['n'])
except:
print "Invalid index at line:", self._locator.getLineNumber(), "of", self._path
raise IndexError("Invalid index at line:", self._locator.getLineNumber(), "of", self._path)
currentState.recordExplicitIndex(name, index)
self._current = self._current.getChild(name, index, create=True)
else:
index = currentState.getNextIndex(name)
# important we use getChild here, so that includes are resolved
# correctly
self._current = self._current.getChild(name, index, create=True)
self._stateStack.append(ParseState())
if 'include' in attrs.keys():
self.handleInclude(attrs['include'])
self._currentTy = None;
if 'type' in attrs.keys():
self._currentTy = attrs['type']
def handleInclude(self, includePath):
if includePath.startswith('/'):
includePath = includePath[1:]
p = os.path.join(self._basePath, includePath)
if not os.path.exists(p):
found = False
for i in self._includes:
p = os.path.join(i, includePath)
if os.path.exists(p):
found = True
break
if not found:
raise RuntimeError("include file not found", includePath, "at line", self._locator.getLineNumber())
readProps(p, self._current, self._includes)
def endElement(self, name):
if (name == 'PropertyList'):
return
try:
# convert and store value
self._current.value = self._content
if self._currentTy == "int":
self._current.value = int(self._content) if self._content is not None else 0
if self._currentTy == "bool":
self._current.value = self.parsePropsBool(self._content)
if self._currentTy == "double":
if self._content is None:
self._current.value = 0.0
else:
if self._content.endswith('f'):
self._content = self._content[:-1]
self._current.value = float(self._content)
except:
print "Parse error for value:", self._content, "at line:", self._locator.getLineNumber(), "of:", self._path
self._current = self._current.parent
self._content = None
self._currentTy = None
self._stateStack.pop()
def parsePropsBool(self, content):
if content == "True" or content == "true":
return True
if content == "False" or content == "false":
return False
try:
icontent = int(content)
if icontent is not None:
if icontent == 0:
return False
else:
return True;
except:
return False
def characters(self, content):
if self._content is None:
self._content = ''
self._content += content
def endDocument(self):
pass
@property
def root(self):
return self._root
def readProps(path, root = None, includePaths = []):
parser = make_parser()
locator = expatreader.ExpatLocator( parser )
h = PropsHandler(root, path, includePaths)
h.setDocumentLocator(locator)
parser.setContentHandler(h)
parser.parse(path)
return h.root
def copy(src, dest):
dest.value = src.value
# recurse over children
for c in src.getChildren() :
dc = dest.getChild(c.name, i = c.index, create = True)
copy(c, dc)

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<PropertyList>
<sim>
<!-- found in the F-15 XML -->
<uhf n="[0]">
<frequencies>
<selected-mhz type="int">225000</selected-mhz>
</frequencies>
</uhf>
</sim>
</PropertyList>

View File

@@ -1,25 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<value type="int">42</value>
<thing>
<value>apple</value>
</thing>
<thing>
<value>lemon</value>
</thing>
<thing>
<value>pear</value>
</thing>
<!-- ensure explicit indexing works -->
<sub>
<value n="1">a</value>
<value n="3">b</value>
<value n="99">c</value>
<value>d</value> <!-- should be assigned n=100 -->
</sub>
</PropertyList>

View File

@@ -1,20 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList include="root-include.xml">
<value type="int">33</value>
<thing>
<value>apple</value>
</thing>
<thing>
<value>lemon</value>
</thing>
<sub include ="sub-include.xml">
<!-- different index to avoid being included over -->
<widget n="100" type="int">99</widget>
</sub>
</PropertyList>

View File

@@ -1,22 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<value type="int">42</value>
<value type="int">43</value>
<value type="int">44</value>
<sim>
<views>
</views>
<preview>
</preview>
<preview>
</preview>
</sim>
<payload>
<weight>
</weight>
</payload>
</PropertyList>

View File

@@ -1,6 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<widget type="int">42</widget>
<widget type="int">43</widget>
<widget type="int">44</widget>
</PropertyList>

View File

@@ -1,61 +0,0 @@
import unittest
import types
import sgprops
class SGProps(unittest.TestCase):
def test_parse(self):
parsed = sgprops.readProps("testData/props1.xml")
self.assertEqual(parsed.getValue("value"), 42)
self.assertEqual(type(parsed.getValue("value")), types.IntType)
valNode = parsed.getChild("value")
self.assertEqual(valNode.parent, parsed)
self.assertEqual(valNode.name, "value")
self.assertEqual(valNode.value, 42)
self.assertEqual(type(valNode.value), types.IntType)
with self.assertRaises(IndexError):
missingNode = parsed.getChild("missing")
things = parsed.getChildren("thing")
self.assertEqual(len(things), 3)
self.assertEqual(things[0], parsed.getChild("thing", 0));
self.assertEqual(things[1], parsed.getChild("thing", 1));
self.assertEqual(things[2], parsed.getChild("thing", 2));
self.assertEqual(things[0].getValue("value"), "apple");
self.assertEqual(things[1].getValue("value"), "lemon");
self.assertEqual(things[2].getValue("value"), "pear");
def test_create(self):
pass
def test_invalidIndex(self):
with self.assertRaises(IndexError):
parsed = sgprops.readProps("testData/bad-index.xml")
def test_include(self):
parsed = sgprops.readProps("testData/props2.xml")
# test that value in main file over-rides the one in the include
self.assertEqual(parsed.getValue("value"), 33)
# but these come from the included file
self.assertEqual(parsed.getValue("value[1]"), 43)
self.assertEqual(parsed.getValue("value[2]"), 44)
subNode = parsed.getChild("sub")
widgets = subNode.getChildren("widget")
self.assertEqual(len(widgets), 4)
self.assertEqual(widgets[2].value, 44)
self.assertEqual(widgets[3].value, 99)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,479 +0,0 @@
#!/usr/bin/python
import argparse
import datetime
import hashlib # md5
import lxml.etree as ET
import os
import re
import shutil
import subprocess
import time
import sgprops
import sys
import catalogTags
CATALOG_VERSION = 4
parser = argparse.ArgumentParser()
parser.add_argument("--update", help="Update/pull SCM source",
action="store_true")
parser.add_argument("--no-update",
help="Disable updating from SCM source",
action="store_true")
parser.add_argument("--clean", help="Force regeneration of all zip files",
action="store_true")
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
includes = []
# xml node (robust) get text helper
def get_xml_text(e):
if e != None and e.text != None:
return e.text
else:
return ''
# create an xml node with text content
def make_xml_leaf(name, text):
leaf = ET.Element(name)
if text != None:
if isinstance(text, (int, long)):
leaf.text = str(text)
else:
leaf.text = text
else:
leaf.text = ''
return leaf
# return all available aircraft information from the set file as a
# dict
def scan_set_file(aircraft_dir, set_file):
global includes
base_file = os.path.basename(set_file)
base_id = base_file[:-8]
set_path = os.path.join(aircraft_dir, set_file)
local_includes = includes
local_includes.append(aircraft_dir)
root_node = sgprops.readProps(set_path, includePaths = local_includes)
if not root_node.hasChild("sim"):
return None
sim_node = root_node.getChild("sim")
if sim_node == None:
return None
variant = {}
variant['name'] = sim_node.getValue("description", None)
variant['status'] = sim_node.getValue("status", None)
variant['author'] = sim_node.getValue("author", None)
variant['description'] = sim_node.getValue("long-description", None)
variant['id'] = base_id
# allow -set.xml files to declare themselves as primary.
# we use this avoid needing a variant-of in every other -set.xml
variant['primary-set'] = sim_node.getValue('primary-set', False)
# extract and record previews for each variant
if sim_node.hasChild('previews'):
print "has previews ..."
variant['previews'] = extract_previews(sim_node.getChild('previews'), aircraft_dir)
if sim_node.hasChild('rating'):
rating_node = sim_node.getChild("rating")
variant['rating_FDM'] = rating_node.getValue("FDM", 0)
variant['rating_systems'] = rating_node.getValue("systems", 0)
variant['rating_cockpit'] = rating_node.getValue("cockpit", 0)
variant['rating_model'] = rating_node.getValue("model", 0)
if sim_node.hasChild('tags'):
variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file)
variant['variant-of'] = sim_node.getValue("variant-of", None)
#print ' ', variant
return variant
def extract_previews(previews_node, aircraft_dir):
result = []
for node in previews_node.getChildren("preview"):
previewType = node.getValue("type", None)
previewPath = node.getValue("path", None)
# check path exists in base-name-dir
fullPath = os.path.join(aircraft_dir, previewPath)
if not os.path.isfile(fullPath):
print "Bad preview path, skipping:" + fullPath
continue
result.append({'type':previewType, 'path':previewPath})
return result
def extract_tags(tags_node, set_path):
result = []
for node in tags_node.getChildren("tag"):
tag = node.value
# check tag is in the allowed list
if not catalogTags.isValidTag(tag):
print "Unknown tag value:", tag, " in ", set_path
result.append(tag)
return result
# scan all the -set.xml files in an aircraft directory. Returns a
# package dict and a list of variants.
def scan_aircraft_dir(aircraft_dir):
# old way of finding the master aircraft: it's the only one whose
# variant-of is empty. All the others have an actual value
# newer alternative is to specify one -set.xml as the primary. All the
# others are therefore variants.
setDicts = []
found_master = False
package = None
files = os.listdir(aircraft_dir)
for file in sorted(files, key=lambda s: s.lower()):
if file.endswith('-set.xml'):
try:
d = scan_set_file(aircraft_dir, file)
if d == None:
continue
except:
print "Skipping set file since couldn't be parsed:", os.path.join(aircraft_dir, file), sys.exc_info()[0]
continue
setDicts.append(d)
if d['primary-set']:
found_master = True
package = d
# didn't find a dict identified explicitly as the primary, look for one
# with an undefined variant-of
if not found_master:
for d in setDicts:
if d['variant-of'] == '':
found_master = True
package = d
break
if not found_master:
if len(setDicts) > 1:
print "Warning, no explicit primary set.xml in " + aircraft_dir
# use the first one
package = setDicts[0]
# variants is just all the set dicts except the master
variants = setDicts
variants.remove(package)
return (package, variants)
# use svn commands to report the last change date within dir
def last_change_date_svn(dir):
command = [ 'svn', 'info', dir ]
result = subprocess.check_output( command )
match = re.search('Last Changed Date: (\d+)\-(\d+)\-(\d+)', result)
if match:
rev_str = match.group(1) + match.group(2) + match.group(3)
return int(rev_str)
# find the most recent mtime within a directory subtree
def scan_dir_for_change_date_mtime(path):
maxsec = 0
names = os.listdir(path)
for name in names:
fullname = os.path.join(path, name)
if name == '.' or name == '..':
pass
elif os.path.isdir( fullname ):
mtime = scan_dir_for_change_date_mtime( fullname )
if mtime > maxsec:
maxsec = mtime
else:
mtime = os.path.getmtime( fullname )
if mtime > maxsec:
maxsec = mtime
return maxsec
def make_aircraft_zip(repo_path, name, zip_file):
print "Updating:", name + '.zip'
savedir = os.getcwd()
os.chdir(repo_path)
if os.path.exists(zip_file):
os.remove(zip_file)
command = ['zip', '-rq', '-9']
if os.path.exists(zip_excludes):
command += ['-x@' + zip_excludes]
else:
print "warning: no zip-excludes.lst file provided", zip_excludes
command += [zip_file, name]
subprocess.call(command)
os.chdir(savedir)
def get_md5sum(file):
f = open(file, 'r')
md5sum = hashlib.md5(f.read()).hexdigest()
f.close()
return md5sum
def append_preview_nodes(node, variant, download_base, package_name):
if not 'previews' in variant:
return
for preview in variant['previews']:
preview_node = ET.Element('preview')
preview_url = download_base + 'previews/' + package_name + '_' + preview['path']
preview_node.append( make_xml_leaf('type', preview['type']) )
preview_node.append( make_xml_leaf('url', preview_url) )
preview_node.append( make_xml_leaf('path', preview['path']) )
node.append(preview_node)
def copy_previews_for_variant(variant, package_name, package_dir, previews_dir):
if not 'previews' in variant:
return
for preview in variant['previews']:
preview_src = os.path.join(package_dir, preview['path'])
preview_dst = os.path.join(previews_dir, package_name + '_' + preview['path'])
#print preview_src, preview_dst, preview['path']
dir = os.path.dirname(preview_dst)
if not os.path.isdir(dir):
os.makedirs(dir)
if os.path.exists(preview_src):
shutil.copy2(preview_src, preview_dst)
def copy_previews_for_package(package, variants, package_name, package_dir, previews_dir):
copy_previews_for_variant(package, package_name, package_dir, previews_dir)
for v in variants:
copy_previews_for_variant(v, package_name, package_dir, previews_dir)
def append_tag_nodes(node, variant):
if not 'tags' in variant:
return
for tag in variant['tags']:
node.append(make_xml_leaf('tag', tag))
#def get_file_stats(file):
# f = open(file, 'r')
# md5 = hashlib.md5(f.read()).hexdigest()
# file_size = os.path.getsize(file)
# return (md5, file_size)
if not os.path.isdir(args.dir):
print "A valid catalog directory must be provided"
exit(0)
parser = ET.XMLParser(remove_blank_text=True)
config_file = os.path.join(args.dir, 'catalog.config.xml')
config = ET.parse(config_file, parser)
config_node = config.getroot()
template_file = os.path.join(args.dir, 'template.xml')
template = ET.parse(template_file, parser)
template_root = template.getroot()
template_node = template_root.find('template')
md5sum_file = os.path.join(args.dir, 'md5sum.xml')
if os.path.exists(md5sum_file):
md5sum_tree = ET.parse(md5sum_file, parser)
md5sum_root = md5sum_tree.getroot()
else:
md5sum_root = ET.Element('PropertyList')
md5sum_tree = ET.ElementTree(md5sum_root)
scm_list = config_node.findall('scm')
upload_node = config_node.find('upload')
download_base = get_xml_text(config_node.find('download-url'))
output_dir = get_xml_text(config_node.find('local-output'))
if output_dir == '':
output_dir = os.path.join(args.dir, 'output')
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
thumbnail_dir = os.path.join(output_dir, 'thumbnails')
if not os.path.isdir(thumbnail_dir):
os.mkdir(thumbnail_dir)
previews_dir = os.path.join(output_dir, 'previews')
if not os.path.isdir(previews_dir):
os.mkdir(previews_dir)
tmp = os.path.join(args.dir, 'zip-excludes.lst')
zip_excludes = os.path.realpath(tmp)
for i in config_node.findall("include-dir"):
path = get_xml_text(i)
if not os.path.exists(path):
print "Skipping missing include path:", path
continue
includes.append(path)
# freshen repositories
if args.no_update:
print 'Skipping repository updates.'
else:
cwd = os.getcwd()
for scm in scm_list:
repo_type = get_xml_text(scm.find('type'))
repo_path = get_xml_text(scm.find('path'))
includes.append(repo_path)
if repo_type == 'svn':
print 'SVN update:', repo_path
subprocess.call(['svn', 'update', repo_path])
elif repo_type == 'git':
print 'GIT pull:', repo_path
os.chdir(repo_path)
subprocess.call(['git','pull'])
elif repo_type == 'no-scm':
print "No update of unmannaged files:", repo_path
else:
print "Unknown scm type:", scm, repo_path
os.chdir(cwd)
# names of zip files we want (so we can identify/remove orphans)
valid_zips = []
# create the catalog tree
catalog_node = ET.Element('PropertyList')
catalog_root = ET.ElementTree(catalog_node)
# include the template configuration
for child in template_node:
catalog_node.append(child)
# scan repositories for catalog information
for scm in scm_list:
repo_type = get_xml_text(scm.find('type'))
repo_path = get_xml_text(scm.find('path'))
skip_nodes = scm.findall('skip')
skip_list = []
for s in skip_nodes:
skip_list.append(get_xml_text(s))
print 'skip list:', skip_list
names = os.listdir(repo_path)
for name in sorted(names, key=lambda s: s.lower()):
if name in skip_list:
print "skipping:", name
continue
aircraft_dir = os.path.join(repo_path, name)
if os.path.isdir(aircraft_dir):
print "%s:" % name,
(package, variants) = scan_aircraft_dir(aircraft_dir)
if package == None:
print "skipping:", name, "(no -set.xml files)"
continue
#print "package:", package
#print "variants:", variants
package_node = ET.Element('package')
package_node.append( make_xml_leaf('name', package['name']) )
package_node.append( make_xml_leaf('status', package['status']) )
package_node.append( make_xml_leaf('author', package['author']) )
package_node.append( make_xml_leaf('description', package['description']) )
if 'rating_FDM' in package or 'rating_systems' in package \
or 'rating_cockpit' in package or 'rating_model' in package:
rating_node = ET.Element('rating')
package_node.append(rating_node)
rating_node.append( make_xml_leaf('FDM',
package['rating_FDM']) )
rating_node.append( make_xml_leaf('systems',
package['rating_systems']) )
rating_node.append( make_xml_leaf('cockpit',
package['rating_cockpit']) )
rating_node.append( make_xml_leaf('model',
package['rating_model']) )
package_node.append( make_xml_leaf('id', package['id']) )
for variant in variants:
variant_node = ET.Element('variant')
package_node.append(variant_node)
variant_node.append( make_xml_leaf('id', variant['id']) )
variant_node.append( make_xml_leaf('name', variant['name']) )
if 'description' in variant:
variant_node.append( make_xml_leaf('description', variant['description']) )
if 'author' in variant:
variant_node.append( make_xml_leaf('author', variant['author']) )
append_preview_nodes(variant_node, variant, download_base, name)
append_tag_nodes(variant_node, variant)
package_node.append( make_xml_leaf('dir', name) )
if not download_base.endswith('/'):
download_base += '/'
download_url = download_base + name + '.zip'
thumbnail_url = download_base + 'thumbnails/' + name + '_thumbnail.jpg'
package_node.append( make_xml_leaf('url', download_url) )
package_node.append( make_xml_leaf('thumbnail', thumbnail_url) )
append_preview_nodes(package_node, package, download_base, name)
append_tag_nodes(package_node, package)
# todo: url (download), thumbnail (download url)
# get cached md5sum if it exists
md5sum = get_xml_text(md5sum_root.find(str('aircraft_' + name)))
# now do the packaging and rev number stuff
dir_mtime = scan_dir_for_change_date_mtime(aircraft_dir)
if repo_type == 'svn':
rev = last_change_date_svn(aircraft_dir)
else:
d = datetime.datetime.utcfromtimestamp(dir_mtime)
rev = d.strftime("%Y%m%d")
package_node.append( make_xml_leaf('revision', rev) )
#print "rev:", rev
#print "dir mtime:", dir_mtime
zipfile = os.path.join( output_dir, name + '.zip' )
valid_zips.append(name + '.zip')
if not os.path.exists(zipfile) \
or dir_mtime > os.path.getmtime(zipfile) \
or args.clean:
# rebuild zip file
print "updating:", zipfile
make_aircraft_zip(repo_path, name, zipfile)
md5sum = get_md5sum(zipfile)
else:
print "(no change)"
if md5sum == "":
md5sum = get_md5sum(zipfile)
filesize = os.path.getsize(zipfile)
package_node.append( make_xml_leaf('md5', md5sum) )
package_node.append( make_xml_leaf('file-size-bytes', filesize) )
# handle md5sum cache
node = md5sum_root.find('aircraft_' + name)
if node != None:
node.text = md5sum
else:
md5sum_root.append( make_xml_leaf('aircraft_' + name, md5sum) )
# handle thumbnails
thumbnail_src = os.path.join(aircraft_dir, 'thumbnail.jpg')
thumbnail_dst = os.path.join(thumbnail_dir, name + '_thumbnail.jpg')
if os.path.exists(thumbnail_src):
shutil.copy2(thumbnail_src, thumbnail_dst)
catalog_node.append(package_node)
package_node.append( make_xml_leaf('thumbnail-path', 'thumbnail.jpg') )
# copy previews for the package and variants into the
# output directory
copy_previews_for_package(package, variants, name, aircraft_dir, previews_dir)
# write out the master catalog file
cat_file = os.path.join(output_dir, 'catalog.xml')
catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True, pretty_print=True)
# write out the md5sum cache file
print md5sum_file
md5sum_tree.write(md5sum_file, encoding='utf-8', xml_declaration=True, pretty_print=True)
# look for orphaned zip files
files = os.listdir(output_dir)
for file in files:
if file.endswith('.zip')and not file in valid_zips:
print "orphaned zip:", file

View File

@@ -1,9 +0,0 @@
--- apt.dat 2016-12-08 18:43:50.000000000 +0100
+++ apt.dat-000 2016-12-08 18:56:02.310707492 +0100
@@ -1,5 +1,5 @@
I
-1000 Version - data cycle 2013.10, build 20131335, metadata AptXP1000. Copyright <20> 2013, Robin A. Peel (robin@x-plane.com). This data is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("AptNavGNULicence.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+1000 Version - data cycle 2013.10, build 20131335, metadata AptXP1000, further modified by the FlightGear team (cf. <https://sourceforge.net/p/flightgear/fgmeta/ci/next/tree/changes-in-dat-files/apt.dat>). Copyright <20> 2013, Robin A. Peel (robin@x-plane.com). This data is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("AptNavGNULicence.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
1 15 1 0 VHXX [X] CLOSED Kai Tak

View File

@@ -1,11 +0,0 @@
--- apt.dat 2016-12-08 18:56:02.310707492 +0100
+++ apt.dat-001 2016-12-08 19:01:00.082169377 +0100
@@ -926129,7 +926129,7 @@
19 45.98520090 -065.30815534 1 WS
19 45.98509598 -065.29620316 1 WS
19 45.98776000 -065.29826459 1 WS
-51 12320
+51 12320 CTAF/UNICOM
1 1000 0 1 3MN7 Haven
100 22.86 3 0 0.25 0 0 0 15 45.49243037 -094.12309108 0.00 0.00 1 0 0 0 33 45.48749963 -094.11966060 0.00 0.00 1 0 0 0

View File

@@ -1,21 +0,0 @@
This is the scripts I (James) use to maintain my builds on each platform.
They're much less clever than 'download and compile' but they do enough for me
and probably most other people, if you tweak the paths accordingly. The Mac
and Linux ones require Ruby (which is usually pre-installed). There are no
instructions - if you can't figure out what these do from reading the scripts,
you almost certainly should not be using them!
They all assume a top-level folder which contains
checkouts of simgear, flightgear, fgdata, OpenSceneGraph (into a dir named
'osg') and the windows-3rd-party dir in the case of Windows. It's assumed
you copy the script to that same dir, edit paths and run from there.
The Mac and Linux scripts will do the checkout for you - the Windows is not
so smart because Window batch scripts are not my friend.
On Mac you will need to grab the 3rdparty-dependency-build from Jenkins, or
build PLIB manually yourself, either should be straightforward. For all other
dependencies on Mac / Linux use your package manager / Homebrew.
Files will be installed into a subdir called 'dist'

View File

@@ -1,130 +0,0 @@
#!/usr/bin/ruby
require 'fileutils'
require 'optparse'
include FileUtils
baseDir = Dir.pwd
gitArgs = ""
qtPath = ""
doPull = false
doCMake = false
doInit = false
doClean = false
doPackage = false
cmakeCommonArgs = "-DCMAKE_INSTALL_PREFIX=#{baseDir}/dist -DSIMGEAR_SHARED=1"
cmakeFGArgs = ""
sfUser = "jmturner"
OptionParser.new do |opts|
opts.banner = "Usage: commands.rb [options]"
opts.on("", "--init", "Setup empty") do |v|
doInit = v
end
opts.on("-p", "--[no-]pull", "Pull from Git") do |v|
doPull = v
end
opts.on("-c", "--cmake", "Run Cmake") do |v|
doCMake = v
end
opts.on("", "--clean", "Clean build dirs") do |v|
doClean = v
end
opts.on("-r", "--rebase", "Rebase when pulling") do |v|
gitArgs += "--rebase"
end
opts.on("", "--qt=QTPATH", "Set Qt path when running cmake") do |v|
qtPath = v
end
end.parse!(ARGV)
def cloneEverything()
puts "Initialising"
if File.exist?("#{Dir.pwd}/simgear") or File.exist?("#{Dir.pwd}/flightgear")
puts "Checkout already exists"
return
end
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/simgear simgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/flightgear flightgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/fgdata fgdata`
`git clone https://github.com/openscenegraph/osg.git osg`
end
def createDirs()
`mkdir -p sgbuild`
`mkdir -p fgbuild`
`mkdir -p osg_release_build`
end
# path is needed for Cmake & running macdeployqt
if qtPath != ""
ENV['PATH'] = "#{ENV['PATH']}:#{qtPath}/bin"
end
if doClean
puts "Cleaning build dirs"
`rm -r sgbuild`
`rm -r fgbuild`
`rm -r osg_release_build`
createDirs()
end
if doInit
puts "Doing init"
cloneEverything()
createDirs();
end
if doPull
puts "Pulling from Git"
dataPull = Thread.new do
puts "Syncing FGData"
Dir.chdir "#{baseDir}/fgdata"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/simgear"
`git pull #{gitArgs}`
Dir.chdir "#{baseDir}/flightgear"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/osg_release_build"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../osg -DCMAKE_INSTALL_PREFIX=#{baseDir}/dist`
end
puts "Building OpenSceneGraph"
`make`
`make install`
Dir.chdir "#{baseDir}/sgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../simgear #{cmakeCommonArgs}`
end
puts "Building SimGear"
`make`
`make install`
Dir.chdir "#{baseDir}/fgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
if qtPath != ""
cmakeFGArgs = '-DENABLE_QT=1'
end
`cmake ../flightgear #{cmakeCommonArgs} #{cmakeFGArgs}`
end
puts "Building FlightGear"
`make`
`make install`
puts "All done."

View File

@@ -1,135 +0,0 @@
#!/usr/bin/ruby
require 'fileutils'
require 'optparse'
include FileUtils
baseDir = Dir.pwd
gitArgs = ""
qtPath = ""
doPull = false
doCMake = false
doInit = false
doClean = false
doPackage = false
cmakePlatformArgs = "-G Xcode"
cmakeCommonArgs = "-DCMAKE_INSTALL_PREFIX=#{baseDir}/dist"
cmakeSGArgs = "-DSIMGEAR_SHARED=1"
cmakeFGArgs = "-DSIMGEAR_SHARED=1"
sfUser = "jmturner"
OptionParser.new do |opts|
opts.banner = "Usage: commands.rb [options]"
opts.on("", "--init", "Setup empty") do |v|
doInit = v
end
opts.on("-p", "--[no-]pull", "Pull from Git") do |v|
doPull = v
end
opts.on("-c", "--cmake", "Run Cmake") do |v|
doCMake = v
end
opts.on("", "--clean", "Clean build dirs") do |v|
doClean = v
end
opts.on("-r", "--rebase", "Rebase when pulling") do |v|
gitArgs += "--rebase"
end
opts.on("", "--qt=QTPATH", "Set Qt path when running cmake") do |v|
qtPath = v
end
end.parse!(ARGV)
def cloneEverything()
puts "Initialising"
if File.exist?("#{Dir.pwd}/simgear") or File.exist?("#{Dir.pwd}/flightgear")
puts "Checkout already exists"
return
end
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/simgear simgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/flightgear flightgear`
`git clone git@github.com:zakalawe/osg.git osg`
end
def createDirs()
`mkdir -p sgbuild`
`mkdir -p fgbuild`
`mkdir -p osg_fg_build`
end
# path is needed for Cmake & running macdeployqt
if qtPath != ""
ENV['PATH'] = "#{ENV['PATH']}:#{qtPath}/bin"
end
if doClean
puts "Cleaning build dirs"
`rm -r sgbuild`
`rm -r fgbuild`
`rm -r osg_fg_build`
end
if doInit
puts "Doing init"
cloneEverything()
end
if doPull
puts "Pulling from Git"
dataPull = Thread.new do
puts "Syncing FGData"
Dir.chdir "#{baseDir}/fgdata"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/simgear"
`git pull #{gitArgs}`
Dir.chdir "#{baseDir}/flightgear"
`git pull #{gitArgs}`
end
createDirs()
Dir.chdir "#{baseDir}/osg_fg_build"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../osg #{cmakeCommonArgs}`
end
puts "Building OpenSceneGraph"
`make -j4`
`make install`
Dir.chdir "#{baseDir}/sgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/SimGear.xcodeproj")
`cmake ../simgear #{cmakePlatformArgs} #{cmakeCommonArgs} #{cmakeSGArgs}`
end
puts "Building SimGear Debug"
`xcodebuild -target install -configuration Debug`
puts "Building SimGear Release"
`xcodebuild -target install -configuration Release`
Dir.chdir "#{baseDir}/fgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/FlightGear.xcodeproj")
if qtPath != ""
cmakeFGArgs = '-DENABLE_QT=1'
end
`cmake ../flightgear #{cmakePlatformArgs} #{cmakeCommonArgs} #{cmakeFGArgs}`
end
puts "Building FlightGear Debug"
`xcodebuild -target fgfs -configuration Debug`
puts "Building FlightGear Release"
`xcodebuild -target fgfs -configuration Release`
puts "All done."

View File

@@ -1,52 +0,0 @@
SET PATH=%PATH%;%ProgramFiles%\CMake\bin
SET QT5SDK64=C:\Qt\5.6\msvc2015_64
SET CMAKE_TOOLCHAIN="Visual Studio 14 Win64"
SET ROOT_DIR=%CD%
md osgbuild
md sgbuild
md fgbuild
REM md fgrun-build
cd simgear
git pull --rebase
cd ..\flightgear
git pull --rebase
REM cd ..\fgrun
REM git pull --rebase
cd ..\osgbuild
cmake ..\osg -G %CMAKE_TOOLCHAIN% ^
-DACTUAL_3RDPARTY_DIR:PATH=%ROOT_DIR%\windows-3rd-party\msvc140\3rdparty.x64 ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist ^
-DOSG_USE_UTF8_FILENAME:BOOL=ON
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
cd ..\sgbuild
cmake ..\simgear -G %CMAKE_TOOLCHAIN% ^
-DMSVC_3RDPARTY_ROOT=%ROOT_DIR%\windows-3rd-party\msvc140 ^
-DOSG_FSTREAM_EXPORT_FIXED:BOOL=ON ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
cd ..\fgbuild
cmake ..\flightgear -G %CMAKE_TOOLCHAIN% ^
-DMSVC_3RDPARTY_ROOT=%ROOT_DIR%\windows-3rd-party\msvc140 ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist ^
-DCMAKE_PREFIX_PATH=%QT5SDK64% ^
-DOSG_FSTREAM_EXPORT_FIXED:BOOL=ON
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
REM cd ..\fgrun-build
REM cmake ..\fgrun -G %CMAKE_TOOLCHAIN% ^
REM -DMSVC_3RDPARTY_ROOT=C:\FGFS\windows-3rd-party\msvc140 ^
REM -DCMAKE_INSTALL_PREFIX:PATH=C:\FGFS\dist
REM cmake --build . --config Release --target INSTALL
REM cmake --build . --config Debug --target INSTALL

171
create_catalog.py Executable file
View File

@@ -0,0 +1,171 @@
#!/usr/bin/python
import os
import sys
import fnmatch
import tarfile
import hashlib
import shutil
import xml.etree.cElementTree as ET
rootPath = sys.argv[1]
outputDir = sys.argv[2]
existingCatalogPath = os.path.join(outputDir, 'catalog.xml')
existingCatalog = None
print 'existing ctalog path:' + existingCatalogPath
if os.path.exists(existingCatalogPath):
existingCatalog = ET.parse(existingCatalogPath)
for file in os.listdir(outputDir):
if fnmatch.fnmatch(file, '*.tar.gz'):
os.remove(os.path.join(outputDir, file));
thumbsDir = os.path.join(outputDir, 'thumbs')
shutil.rmtree(thumbsDir)
os.makedirs(thumbsDir)
def setProperty(node, id, value):
s = node.find(id) # check for existing
if s is None:
s = ET.SubElement(node, id)
s.text = value
def clearChildren(node, tag):
for c in node.findall(tag):
node.remove(c)
def parse_setXml(path):
tree = ET.parse(path)
desc = tree.find('sim/description')
ratings = tree.find('sim/rating')
if (ratings is not None):
for rating in list(ratings):
if rating.tag == 'status':
continue
rvalue = int(rating.text)
if rvalue < 2:
return None
else:
return None
d = {}
d['desc'] = desc
d['ratings'] = ratings;
d['status'] = tree.find('sim/status')
d['authors'] = tree.findall('sim/author')
return d
def process_aircraft(acft, path):
print '===' + acft + '==='
setFiles = []
thumbs = []
for file in os.listdir(path):
if fnmatch.fnmatch(file, '*-set.xml'):
setFiles.append(file);
if fnmatch.fnmatch(file, 'thumbnail*'):
thumbs.append(file)
aircraft = []
for s in setFiles:
d = parse_setXml(os.path.join(path, s))
if d is None:
continue
d['set'] = s[0:-8]
aircraft.append(d)
thumbnailNames = []
# copy thumbnails
for t in thumbs:
outThumb = os.path.join(thumbsDir, acft + "-" + t)
thumbnailNames.append(acft + "-" + t)
shutil.copyfile(os.path.join(path, t), outThumb)
if len(aircraft) == 0:
print "no aircraft profiles for " + acft
return
# tarball creation
outTar = os.path.join(outputDir, acft + ".tar.gz")
tar = tarfile.open(outTar, "w:gz")
tar.add(path, acft)
tar.close()
digest = hashlib.md5(open(outTar, 'r').read()).hexdigest()
revision = 1
# revision check
if acft in existingPackages:
previousMd5 = existingPackages[acft].find('md5').text
previousRevsion = int(existingPackages[acft].find('revision').text)
if digest != previousMd5:
print acft + ": MD5 has changed"
revision = previousRevsion + 1
else:
print acft + ": MD5 is unchanged"
else:
existingPackages[acft] = ET.Element('package')
setProperty(existingPackages[acft], 'id', acft)
setProperty(existingPackages[acft], 'revision', str(revision))
setProperty(existingPackages[acft], 'md5', digest)
setProperty(existingPackages[acft], 'description', aircraft[0]['desc'])
clearChildren(existingPackages[acft], 'thumbnail')
for t in thumbnailNames:
tn = ET.SubElement(existingPackages[acft], 'thumbnail')
tn.text = 'thumbs/' + t
clearChildren(existingPackages[acft], 'rating')
existingPackages[acft].append(aircraft[0]['ratings'])
print "wrote tarfile, digest is " + digest
root = ET.Element('PropertyList')
catalogTree = ET.ElementTree(root)
existingPackages = dict()
if (existingCatalog is not None):
print 'have existing catalog data'
root.append(existingCatalog.find('license'))
root.append(existingCatalog.find('url'))
root.append(existingCatalog.find('description'))
root.append(existingCatalog.find('id'))
# existing data (for revision incrementing)
for n in existingCatalog.findall('package'):
idNode = n.find('id')
if idNode is None:
print 'Missing <id> tag on package'
continue
existingPackages[idNode.text] = n;
#licenseElement = ET.SubElement(root, 'license')
#licenseElement.text = 'gpl'
#urlElement = ET.SubElement(root, 'url')
#urlElement.text = 'http://catalog.xml'
for acft in os.listdir(rootPath):
path = os.path.join(rootPath, acft);
if (os.path.isdir(path)):
process_aircraft(acft, path)
for ep in existingPackages:
root.append(existingPackages[ep])
catalogTree.write(os.path.join(outputDir, 'catalog.xml'), 'UTF-8')

View File

@@ -1,80 +0,0 @@
#!/usr/bin/env python3
#
# create_metar_dat.py
#
# Script to create metar.dat.gz by checking tgftp.nws.noaa.gov for stations
# that have reported recently.
#
# Usage: create_metar_dat.py [OUTPUT_FILENAME]
#
# If OUTPUT_FILENAME is omitted, creates metar.dat.gz in working directory.
#
# Copyright (c) 2016 Richard Senior
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import datetime
import dateutil.parser
import gzip
import os
import re
import sys
import urllib.request
filename = "metar.dat.gz" if len(sys.argv) <= 1 else sys.argv[1]
max_age_days = 7
url = "http://tgftp.nws.noaa.gov/data/observations/metar/stations/"
now = datetime.datetime.now()
script = os.path.basename(__file__)
class ParseException(Exception):
pass
def stations():
for line in urllib.request.urlopen(url).readlines():
if b".TXT" in line:
yield line
def active_stations():
cutoff = now - datetime.timedelta(max_age_days)
icao_pattern = re.compile("[A-Z][A-Z0-9]{3}")
for station in stations():
tokens = station.split()
last_modified = tokens[2][14:25]
if dateutil.parser.parse(last_modified) > cutoff:
icao = tokens[1][16:20:].decode()
# Sanity check on parsed ICAO code.
if not icao_pattern.match(icao):
raise ParseException("Dubious ICAO code: " + icao)
yield icao
# Run through the active stations before opening the file so that a file
# is not created (or overwritten) if an exception is thrown.
active = [icao + "\n" for icao in active_stations()]
# Sanity check on the number of stations.
if len(active) < 5000:
raise ParseException("Expected more than " + str(len(active)) + " stations")
with gzip.open(filename, "wt") as f:
print("# List of airports known to have metar data available", file=f)
print("# Generated by", script, "on", now.strftime("%Y-%m-%d"), file=f)
print("#", url, file=f)
f.writelines(active)
print(script + ": Wrote", len(active), "stations to", filename)

File diff suppressed because it is too large Load Diff

1
fgdata

Submodule fgdata deleted from c8b090fa4e

View File

@@ -1,646 +0,0 @@
#!/usr/bin/env python3
from __future__ import print_function#defaults to Python 3, but should also work in 2.7
"""Functions for checking fgdata for various problems (and one for creating smaller/split versions of it)
By Rebecca Palmer"""
import os
import os.path
import re
from collections import defaultdict
import subprocess
import multiprocessing
import math
import tarfile
import tempfile
import gzip
import shutil
import time
try:
devnull=subprocess.DEVNULL#hide annoying nvcompress messages
except (AttributeError,NameError):#pre-3.3 Python
devnull=None
def path_join(*args):
"""Unlike plain os.path.join, this always uses forward slashes, and doesn't add a trailing / if the last component is empty"""
return os.path.normpath(os.path.join(*args)).replace('\\','/')
def rfilelist(path,exclude_dirs=[]):
"""Dict of files/sizes in path, including those in any subdirectories (as relative paths)"""
files=defaultdict(int)
if not os.path.exists(path):
return files
dirs=[""]
while dirs:
cdir=dirs.pop()
cdirfiles=os.listdir(path_join(path,cdir))
for file in cdirfiles:
if os.path.isdir(path_join(path,cdir,file)):
if path_join(cdir,file) not in exclude_dirs:
dirs.append(path_join(cdir,file))
else:
files[path_join(cdir,file)]=os.path.getsize(path_join(path,cdir,file))
return files
def strip_comments(text,comment_types=None,filename=None):
"""Remove comments from text
Assumes comments don't nest (including different types of comments: will be wrong for e.g. /* aaa // bbb */ will-remove-this in C++ if // are removed first)
Doesn't check for being inside a string literal, and doesn't check for line-start * in C /* ... */"""
if comment_types is None:
if filename is None:
raise TypeError("must give either filename or comment_types")
if os.path.splitext(filename)[1] in (".xml",".eff"):
comment_types=(("<!--","-->",""),)
elif os.path.splitext(filename)[1] in (".c",".cpp",".cxx",".h",".hpp",".hxx",".frag",".vert"):
comment_types=(("//","\n","\n"),("/*","*/",""))
elif os.path.splitext(filename)[1] in (".nas",):
comment_types=(("#","\n","\n"),)
else:
comment_types=[]
if type(text) in (bytes,bytearray):
comment_types=[[bytes(c,encoding="ascii") for c in ct] for ct in comment_types]
for comment_type in comment_types:
text=text.split(comment_type[0],maxsplit=1)[0]+comment_type[2].join(s.split(comment_type[1],maxsplit=1)[1] for s in text.split(comment_type[0])[1:] if comment_type[1] in s)
return text
def files_used(pattern,path,exclude_dirs=[],filelist=None,filetypes=None,relative_path=False):
"""Files used by an element matching pattern, in a file in path or filelist"""
textures=[]
if filelist is None:
filelist=rfilelist(path,exclude_dirs).keys()
if filetypes is not None:
filelist=[f for f in filelist if os.path.splitext(f)[1] in filetypes]
texfind=re.compile(pattern)
for file in filelist:
try:
f=open(path_join(path,file),'r',errors='replace')
except FileNotFoundError:
continue
for line in f:
tex=texfind.search(line)
if tex:
if relative_path:
textures.append(os.path.normpath(path_join(os.path.dirname(file),tex.group(1).replace('\\','/'))).replace('\\','/'))
else:
textures.append(os.path.normpath(tex.group(1).replace('\\','/')).replace('\\','/'))
return textures
def find_unused_textures(basedir,output_lists=True,grep_check=False,output_rsync_rules=False,output_comparison_strips=False, output_removal_commands=False,return_used_noregions=False):
"""Checks if any textures are unused (wasting space), and if any textures are only available as .dds (not recommended in the source repository, as it is a lossy-compressed format)
Set basedir to your fg-root, and enable the kind(s) of output you want:
output_lists prints lists of unused textures, and of dds-only textures
grep_check checks for possible use outside the normal directories; requires Unix shell and assumes side-by-side fgdata,flightgear,simgear
output_rsync_rules prints rsync rules for excluding unused textures from the release flightgear-data. Warning: if you use this, re-run this script regularly, in case they start being used
output_comparison_strips creates thumbnail strips, unused_duplicate.png/unused_dds.png/high_low.png, for visually checking whether same-name textures are the same (remove the unused one entirely) or different (move it to Unused); requires imagemagick or graphicsmagick
output_removal_commands creates another script, delete_unused_textures.sh, which will remove unused textures when run in a Unix shell"""
false_positives=set(['buildings-lightmap.png','buildings.png','Credits','Globe/00README.txt', 'Globe/01READMEocean_depth_1png.txt', 'Globe/world.topo.bathy.200407.3x4096x2048.png','Trees/convert.pl','Splash1.png','Splash2.png','Splash3.png','Splash4.png','Splash5.png'])#these either aren't textures, or are used where we don't check; 'unknown.rgb','Terrain/unknown.rgb' are also referenced, but already don't exist
used_textures=set(files_used(path=path_join(basedir,'Materials'),pattern=r'<(?:texture|object-mask|tree-texture).*?>(\S+?)</(texture|object-mask|tree-texture)'))|false_positives
used_textures_noregions=set(files_used(path=path_join(basedir,'Materials'),exclude_dirs=['regions'],pattern=r'<(?:texture|object-mask|tree-texture).*?>(\S+?)</(texture|object-mask|tree-texture)'))|false_positives#this pattern matches a <texture> (possibly with number), <tree-texture> or <object-mask> element
used_effectslow=set(files_used(path=path_join(basedir,'Effects'),pattern=r'image.*?>[\\/]?Textures[\\/](\S+?)</.*?image'))|set(files_used(path=path_join(basedir,'Materials'),pattern=r'<building-(?:texture|lightmap).*?>Textures[\\/](\S+?)</building-(?:texture|lightmap)'))#Effects (<image>), and Materials <building-texture>/<building-lightmap>, explicitly includes the Textures/ or Textures.high/
used_effectshigh=set(files_used(path=path_join(basedir,'Effects'),pattern=r'image.*?>[\\/]?Textures.high[\\/](\S+?)</.*?image'))|set(files_used(path=path_join(basedir,'Materials'),pattern=r'<building-(?:texture|lightmap).*?>Textures.high[\\/](\S+?)</building-(?:texture|lightmap)'))
high_tsizes=rfilelist(path_join(basedir,'Textures.high'))
high_textures=set(high_tsizes.keys())
low_tsizes=rfilelist(path_join(basedir,'Textures'),exclude_dirs=['Sky','Unused'])#sky textures are used where we don't check
low_textures=set(low_tsizes.keys())
only_high=high_textures-low_textures
used_noreg_onlyhigh=(only_high&used_textures_noregions)|used_effectshigh
used_noreg_onlyhighsize=sum(high_tsizes[t] for t in used_noreg_onlyhigh)
used_noreg_low=(low_textures&used_textures_noregions)|used_effectslow
used_noregions=used_textures_noregions|used_effectshigh|used_effectslow
used_noreg_lowsize=sum(low_tsizes[t] for t in used_noreg_low)
used_noreg_defsize=sum(low_tsizes[t] for t in (used_textures_noregions-high_textures)|used_effectslow)+sum(high_tsizes[t] for t in used_textures_noregions|used_effectshigh)
used_defsize=sum(low_tsizes[t] for t in (used_textures-high_textures)|used_effectslow)+sum(high_tsizes[t] for t in used_textures|used_effectshigh)
unused=(high_textures|low_textures)-used_textures-used_effectslow-used_effectshigh
t_size=lambda tset: sum(high_tsizes[t] for t in tset)+sum(low_tsizes[t] for t in tset)
missing=(used_textures-(high_textures|low_textures))|(used_effectslow-low_textures)|(used_effectshigh-high_textures)
if missing:
raise ValueError("Some used textures not found: "+repr(missing))
sourceless=[f for f in (high_textures|low_textures) if (f[-4:]==".dds" and f[:-4]+".png" not in high_textures and (f in high_textures or f[:-4]+".png" not in low_textures) )]+['Terrain/airport.dds']#airport.dds isn't the same as airport.png; crop-colors.dds/cropgrass-colors.dds/rock-colors.dds/forest-colors.dds also differ but only in strip width, which doesn't matter as they are 1D color strips
sourceless_used=set(sourceless)-unused
needed_as_source=[f for f in unused if (f[-4:]!=".dds" and f[:-4]+".png" in (used_textures|used_effectslow|used_effectshigh) or f[:-4]+".dds" in (used_textures|used_effectslow|used_effectshigh))]+['Runway/designation_letters.svg']
known_non_duplicates=['deciduous.png','drycrop.png','irrcrop.png','marsh1.png','gravel.png','Town.png','grass.png','mixedcrop.png','resgrid.png']+['glacier.png','rock.png','cropgrass.png']#first group real winter textures, second group unrelated textures
unused_duplicate=[f for f in unused if (f[0:14]=="Terrain.winter" and "Terrain"+f[14:] in (high_textures|low_textures) and f[15:] not in known_non_duplicates)]
unused_dds=set(f for f in (unused-set(unused_duplicate)) if (f[-4:]==".dds" and f[:-4]+".png" in (high_textures|low_textures) and f!='Terrain/airport.dds'))#airport.dds isn't the same as airport.png; crop-colors.dds/cropgrass-colors.dds/rock-colors.dds/forest-colors.dds also differ but only in strip width, which doesn't matter as they are 1D color strips
unused_other=unused-set(unused_duplicate)-set(unused_dds)-set(needed_as_source)
known_highlow_mismatch=set(['Terrain.winter/mixedcrop4.png','Terrain.winter/cropgrass3.png','Terrain.winter/drycrop4.png','Terrain.winter/irrcrop2.png','Terrain.winter/drycrop1.png','Terrain.winter/drycrop3.png','Terrain.winter/mixedcrop1.png','Terrain.winter/ mixedforest2.png','Terrain.winter/cropgrass2.png','Terrain.winter/cropgrass1.png','Terrain.winter/tundra.png','Terrain.winter/mixedforest3.png','Terrain.winter/shrub2.png','Terrain.winter/drycrop2.png','Terrain.winter/deciduous1.png','Terrain.winter/ mixedcrop3.png','Terrain.winter/naturalcrop1.png']+['Terrain.winter/tundra3.png','Terrain.winter/forest1c.png','Terrain.winter/herbtundra.png']+['Terrain/grass_rwy.dds','Terrain/cropwood.dds','Terrain/herbtundra.dds','Terrain/irrcrop.dds','Terrain/shrub.dds','Terrain.winter/mixedforest.png','Runway/pa_taxiway.png','Runway/pc_taxiway.png'])#first group are different degrees of snow cover on the same base texture, last group unrelated textures, middle group hard to tell; p{a,c}_taxiway (only low-res has side lines) are also mismatched in .dds, but as each .dds matches its size .png, only the .png needs to be kept in Unused
lowres_maybe_source=['Terrain/lava1.png','Terrain/lava2.png','Terrain/lava3.png','Terrain/sand4.png','Terrain/sand5.png','Terrain/sand6.png']#these are clearly related, but the high-res version has unnatural-looking high-frequency noise, suggesting that the low-res version might be the original: keep it
unused_dds_matchhigh=set(f for f in (unused_dds&known_highlow_mismatch) if f[:-4]+".png" not in low_textures)
unused_dds_matchlow=set(f for f in (unused_dds&known_highlow_mismatch) if f[:-4]+".png" not in high_textures)
low_unneeded=(high_textures&low_textures)-used_effectslow-unused-set(lowres_maybe_source)
low_unneeded_duplicate=low_unneeded-set(known_highlow_mismatch)
low_unneeded_nondup=low_unneeded&set(known_highlow_mismatch)
def image_check_strip(basedir,index_fname,ilist1,ilist2=None,size=128):
"""Generate two rows of thumbnails, for easy visual comparison (between the two lists given, or if a single list is given, between low and high resolution)"""
if not ilist1:
print(index_fname," empty, skipping")
return
if ilist2 is None:
ipairs=[[path_join(basedir,'Textures',f),path_join(basedir,'Textures.high',f)] for f in ilist1]
else:
ipairs=[]
for f1,f2 in zip(ilist1,ilist2):
if f1 in low_textures:
ipairs.append([path_join(basedir,'Textures',f1),path_join(basedir,'Textures',f2) if f2 in low_textures else path_join(basedir,'Textures.high',f2)])
if f1 in high_textures:
ipairs.append([path_join(basedir,'Textures.high',f1),path_join(basedir,'Textures.high',f2) if f2 in high_textures else path_join(basedir,'Textures',f2)])
ilist_f=[f[0] for f in ipairs]+[f[1] for f in ipairs]
subprocess.call(['montage','-label',"'%f'"]+ilist_f+['-tile','x2','-geometry',str(size)+'x'+str(size)]+[index_fname])
def rsync_rules(basedir,flist,include=False,high=None):
"""Output rsync rules to exclude/include the specified textures from high/low/both (high=True/False/None) resolutions"""
for f in flist:
if high!=True and f in low_textures:
print("+" if include else "-",path_join('/fgdata/Textures',f))
if high!=False and f in high_textures:
print("+" if include else "-",path_join('/fgdata/Textures.high',f))
def removal_command(basedir,flist,high=None):
"""Return command to delete the specified textures from high/low/both (high=True/False/None) resolutions"""
if not flist:
return ""
a="rm"
for f in flist:
if high!=True and f in low_textures:
a=a+" "+path_join('Textures',f)
if high!=False and f in high_textures:
a=a+" "+path_join('Textures.high',f)
a=a+"\n"
return a
def move_command(basedir,flist,high=None,comment=False):
"""Return command to move the specified textures to Unused from high/low/both (high=True/False/None) resolutions"""
if not flist:
return ""
dirset_low=set() if high==True else set(os.path.dirname(f) for f in set(flist)&low_textures)
dirset_high=set() if high==False else set(os.path.dirname(f) for f in set(flist)&high_textures)
a=""
for d in dirset_low:
a=a+("#" if comment else "")+"mv --target-directory="+path_join("Textures/Unused",d)+" "+(" ".join(path_join("Textures",f) for f in flist if (os.path.dirname(f)==d and f in low_textures)))+"\n"
for d in dirset_high:
a=a+("#" if comment else "")+"mv --target-directory="+path_join("Textures/Unused",d+".high")+" "+(" ".join(path_join("Textures.high",f) for f in flist if (os.path.dirname(f)==d and f in high_textures)))+"\n"
return a
if output_comparison_strips:
image_check_strip(basedir,"unused_duplicate.png",unused_duplicate,["Terrain"+f[14:] for f in unused_duplicate])
image_check_strip(basedir,"unused_dds.png",unused_dds,[f[:-4]+".png" for f in unused_dds])
dds_skip=set(['Runway/rwy-normalmap.dds','Water/perlin-noise-nm.dds','Water/water_sine_nmap.dds','Water/waves-ver10-nm.dds'])
used_dds_withpng=set(f for f in (high_textures|low_textures) if (f[-4:]==".dds" and f[:-4]+".png" in (high_textures|low_textures)))-unused_dds-dds_skip
print(".dds omitted from comparison strip (normal maps etc): ",dds_skip)
#used_dds_withpng different: p{a,c}_taxiway.dds and possibly more runway markings (darker),sand{4,5,6}.dds(less high-freq noise),water.dds(more high-freq noise),grass_rwy.dds (has stripes),cropwood.dds,irrcrop.dds,shrub.dds,herbtundra.dds,cropgrass.dds(unrelated)
#water-reflection.{png,dds} really are plain white (so do match), not an alpha map
image_check_strip(basedir,"used_dds.png",used_dds_withpng,[f[:-4]+".png" for f in used_dds_withpng])
image_check_strip(basedir,"high_low.png",high_textures&low_textures)
#image_check_strip(basedir,"high_low2.png",[f for f in high_textures&low_textures if (f[0:14]=="Terrain.winter" or "_taxiway." in f or "lava" in f or "sand" in f)],size=512)#closer look at the doubtful cases
if output_lists:
print("\n\nunused-winter same as normal:",sorted(unused_duplicate),"\nsize=",t_size(unused_duplicate),"\n\nunused-dds with matching png:",sorted(unused_dds),"\nsize=",t_size(unused_dds),"\n\nunused-unique:",sorted(unused_other),"\nsize=",t_size(unused_other),"\n\nnot directly used but keep as source:",sorted(needed_as_source),"\nsize=",t_size(needed_as_source),"\n\nunused low, matches high:",sorted(low_unneeded_duplicate),"\nsize=",sum(low_tsizes[f] for f in low_unneeded_duplicate),"\n\nunused low, unique:",sorted(low_unneeded_nondup),"\nsize=",sum(low_tsizes[f] for f in low_unneeded_nondup),"\n\nall non-sky textures size=",sum(high_tsizes.values())+sum(low_tsizes.values()),"used size=",used_defsize,"used no-regions size=",used_noreg_defsize,"\n\nnot found:",sorted(missing),"\n\n.dds only/highest-res:",sorted(sourceless),"\n\n.dds only/highest-res, used:",sorted(sourceless_used))
#not really meaningful after removing low-res duplicates: ,"\n\nused high-only, not regions:",sorted(used_noreg_onlyhigh),"\nsize=",used_noreg_onlyhighsize,"these+used low (i.e. minimal flightgear-data) size=",used_noreg_onlyhighsize+used_noreg_lowsize
if grep_check:
unused_f=[os.path.basename(f) for f in unused]
all_f=[os.path.basename(f) for f in (high_textures|low_textures)]
print("\n\nPossible use outside main search:")#used to set false_positives
subprocess.call(["grep","-r","-E","--exclude-dir=Aircraft","--exclude-dir=.git","-e","("+")|(".join(unused)+")",basedir,path_join(basedir,"../flightgear"),path_join(basedir,"../simgear")])#everywhere using full names
subprocess.call(["grep","-r","-E","--exclude-dir=Aircraft","--exclude-dir=Textures.high","--exclude-dir=Models","--exclude-dir=Materials","--exclude-dir=Effects","--exclude-dir=.git","-e","("+")|(".join(all_f)+")",basedir,path_join(basedir,"../flightgear"),path_join(basedir,"../simgear")])#restricted (to avoid false positives from Terrain.winter vs Terrain) using filenames
subprocess.call(["grep","-r","-E","--exclude-dir=Aircraft","--exclude-dir=Textures.high","--exclude-dir=Models","--exclude-dir=Materials","--exclude-dir=Effects","--exclude-dir=.git","-e",'[."\']dds',basedir,path_join(basedir,"../flightgear"),path_join(basedir,"../simgear")])#check for programmatic .png -> .dds swap; none found
print("\n\nUse of sourceless textures:")
subprocess.call(["grep","-r","-E","--exclude-dir=Aircraft","--exclude-dir=.git","-e","("+")|(".join(sourceless)+")",basedir,path_join(basedir,"../flightgear"),path_join(basedir,"../simgear")])
if output_rsync_rules:
print("\n\nFull flightgear-data:\n")
rsync_rules(basedir,unused)
rsync_rules(basedir,low_unneeded,high=False)
print("\n\nMinimal flightgear-data:\n")
rsync_rules(basedir,low_textures-used_noreg_low,high=False)
rsync_rules(basedir,high_textures-used_noreg_onlyhigh,high=True)
if output_removal_commands:
r_script=open('delete_unused_textures.sh','w')
r_script.write("cd "+basedir+"\n")
r_script.write("#Unused duplicates\n")
r_script.write(removal_command(basedir,unused_duplicate))
r_script.write("#Unused .dds versions\n")
r_script.write(removal_command(basedir,unused_dds-unused_dds_matchhigh,high=False))
r_script.write(removal_command(basedir,unused_dds-unused_dds_matchlow,high=True))
r_script.write("#Unused reduced-resolution versions\n")
r_script.write(removal_command(basedir,low_unneeded_duplicate|(unused_other&high_textures&low_textures)-set(lowres_maybe_source),high=False))
r_script.write("#Unused unique .png (move to Unused)\n")
r_script.write("\n".join(["mkdir -p Textures/Unused/"+d for d in ['Terrain','Terrain.winter','Trees','Terrain.high','Terrain.winter.high','Trees.high','Runway','Water']])+"\n")
r_script.write(move_command(basedir,[f for f in unused_other&high_textures if (f[-4:]!=".dds" and f[:5]!="Signs" and f[:6]!="Runway")],high=True))
r_script.write(move_command(basedir,[f for f in (unused_other-high_textures)|low_unneeded_nondup if (f[-4:]!=".dds" and f[:5]!="Signs" and f[:6]!="Runway")],high=False))
r_script.write("#Unused unique .dds\n")
r_script.write("#It is my opinion that these should go, but if you'd prefer to move them to Unused I won't argue further\n")
r_script.write(removal_command(basedir,[f for f in (unused_other&high_textures)|unused_dds_matchlow if (f[-4:]==".dds" and f[:5]!="Signs" and f[:6]!="Runway")],high=True))
r_script.write(removal_command(basedir,[f for f in (unused_other-high_textures)|low_unneeded_nondup|unused_dds_matchhigh if f[-4:]==".dds"],high=False))
r_script.write(move_command(basedir,[f for f in (unused_other&high_textures)|unused_dds_matchlow if (f[-4:]==".dds" and f[:5]!="Signs" and f[:6]!="Runway")],high=True,comment=True))
r_script.write(move_command(basedir,[f for f in (unused_other-high_textures)|low_unneeded_nondup|unused_dds_matchhigh if (f[-4:]==".dds" and f[:5]!="Signs" and f[:6]!="Runway")],high=False,comment=True))
r_script.close()
if return_used_noregions:
return used_noregions|set([path_join('Sky',f) for f in rfilelist(path_join(basedir,'Textures/Sky'))])
def find_locally_unused_models(basedir):
"""Find models not used in the base scenery (these do need to be in Terrasync as they may well be used in other locations, but don't need to be in the base flightgear-data package)
Known bug: doesn't search everywhere: check /Nasal,.eff <image>,<inherits-from>,/(AI/)Aircraft not referenced in AI scenarios, unusual tags in Aircraft/Generic/Human/Models/walker.xml,HLA/av-aircraft.xml,/Environment,MP/aircraft_types.xml,preferences.xml"""
models_allfiles={path_join('Models',f):s for f,s in rfilelist(path_join(basedir,'Models')).items()}
t_size=lambda flist: sum(models_allfiles[f] for f in flist if f in models_allfiles)
used_models=set(files_used(path=path_join(basedir,'Scenery'),filetypes=".stg",pattern=r'OBJECT_SHARED (\S+?) '))|set(files_used(path=path_join(basedir,'AI'),exclude_dirs=["Aircraft","Traffic"],pattern=r'<model>[\\/]?(\S+?)</model>'))|set(f for f in files_used(path=path_join(basedir,'Materials'),filetypes=".xml",pattern=r'<path>[\\/]?(\S+?)</path>') if f[-4:]==".xml")
n=0
while n!=len(used_models):
n=len(used_models)
used_models=used_models|set(f for f in files_used(path=basedir,filelist=used_models,filetypes=".xml",pattern=r'<path>[\\/]?(\S+?)</path>') if f[-4:]==".xml")
used_textures=set(files_used(path=basedir,filelist=used_models,filetypes=".ac",pattern=r'texture "(\S+?)"',relative_path=True))|set(files_used(path=basedir,filelist=used_models,filetypes=".xml",pattern=r'<texture>[\\/]?(\S+?)</texture>',relative_path=True))
extra_used_models=set()
for f1 in used_models:
if f1[-4:]!=".xml":
continue
for f2 in files_used(path=basedir,filelist=[f1],pattern=r'<path>[\\/]?(\S+?)</path>',relative_path=True):
if f2[-3:]!=".ac":
continue
extra_used_models=extra_used_models|set([f2])
p2=[f for f in files_used(path=basedir,filelist=[f1],pattern=r'<texture-path>[\\/]?(\S+?)</texture-path>',relative_path=True)]
if len(p2)==0:
p2=[os.path.dirname(f1)]
if len(p2)!=1:
print("non-unique/not found:",f1,f2,p2)
continue
try:
used_textures=used_textures|set(os.path.normpath(path_join(p2[0],f)) for f in files_used(path=basedir,filelist=[f2],filetypes=".ac",pattern=r'texture "(\S+?)"'))
except (IOError,OSError):
print("not found",f1,f2,p2)
used_models=used_models|extra_used_models
unused=set(models_allfiles.keys())-(used_models|used_textures)
missing=set(f for f in (used_models|used_textures) if ((f.startswith('Models') and f not in models_allfiles.keys()) or not os.path.isfile(path_join(basedir,f))))
print("used\n",sorted(used_models),"\nsize=",t_size(used_models),"\n\n",sorted(used_textures),"\nsize=",t_size(used_textures),"\n\nunused\n",sorted(unused),"\nsize=",t_size(unused),"\n\nmissing\n",sorted(missing),"\nsize=",t_size(missing))
class FilesetSizes:
def __init__(self):
self.count=0
self.ncsize=0
self.csize=0
@property
def size(self):
if self.csize>0:
return self.csize
else:
return self.ncsize
def __str__(self):
if self.csize>0:
return "{0:10,} {1:15,} {2:15,}".format(self.count,self.ncsize,self.csize)
else:
return "{0:10,} {1:15,}".format(self.count,self.ncsize)
def __add__(self,other):
result=FilesetSizes()
result.count=self.count+other.count
result.ncsize=self.ncsize+other.ncsize
result.csize=self.csize+other.csize
return result
def size_by_category(path,exclude_dirs,keyfn,compressed_size=False):
"""Total size of files, in each category returned from keyfn"""
files=rfilelist(path,exclude_dirs)
result=defaultdict(FilesetSizes)
gzdir=tempfile.TemporaryDirectory()
gzpath=gzdir.name
gzcount=0
for file,size in files.items():
cat=keyfn(file,size)
if cat is None:
continue
result[cat].count=result[cat].count+1
result[cat].ncsize=result[cat].ncsize+size
if compressed_size:
try:
result[cat].targz.add(path_join(path,file))
except AttributeError:
result[cat].targzname=path_join(gzpath,str(gzcount)+".tar.gz")
result[cat].targz=tarfile.open(result[cat].targzname,mode="w:gz")
gzcount=gzcount+1
result[cat].targz.add(path_join(path,file))
if compressed_size:
for cat in result:
result[cat].targz.close()
result[cat].csize=os.path.getsize(result[cat].targzname)
return result
def fgdata_size(path,by_size=False,exclude_dirs=None,compressed_size=False,min_size=1e6,include_aircraft=['UIUC','777','777-200','b1900d','CitationX','ZLT-NT','dhc2','Cub','sopwithCamel','f-14b','ASK13','bo105','Dragonfly','SenecaII','A6M2'],sections={"Aircraft/c172p":"Aircraft-base","Aircraft/Generic":"Aircraft-base","Aircraft/Instruments":"Aircraft-base","Aircraft/Instruments-3d":"Aircraft-base","Aircraft/ufo":"Aircraft-base","Aircraft/777":"Aircraft-777","Aircraft/777-200":"Aircraft-777","Aircraft":"Aircraft-other","Textures":"Textures","Textures.high":"Textures","AI/Aircraft":"AI-aircraft","AI":"AI-other","Scenery":"scenery","Models":"models"}):
if any('\\' in s for s in sections):
raise ValueError("sections always uses forward slashes")
if "" not in sections:
sections[""]="Other"
if exclude_dirs is None:
if os.path.exists(path_join(path,".git")):
exclude_dirs=[".git","Textures/Unused"]+[path_join("Aircraft",d) for d in os.listdir(path_join(path,"Aircraft")) if d not in ["c172p","ufo","Generic","Instruments","Instruments-3d"]+include_aircraft]
else:
exclude_dirs=[]
if by_size:
keyfn=lambda file,size: ("texture",math.frexp(size)[1]) if os.path.splitext(file)[1] in [".png",".dds",".rgb",".jpg"] else ("nontexture",math.frexp(size)[1])
else:
def keyfn(file,size):
file_ext=os.path.splitext(file)[1]
if file_ext==".gz":
file_ext=os.path.splitext(os.path.splitext(file)[0])[1]+file_ext
file0=file.replace('\\','/')
section=sections[max((s for s in sections if file0.startswith(s)),key=len)]
return (section,file_ext)
result=size_by_category(path,exclude_dirs,keyfn,compressed_size)
#print(result)
totals1=defaultdict(FilesetSizes)
totals2=defaultdict(FilesetSizes)
other=defaultdict(FilesetSizes)
for cat in result:
totals1[cat[0]]=totals1[cat[0]]+result[cat]
totals2[cat[1]]=totals2[cat[1]]+result[cat]
if (not by_size) and (result[cat].size<min_size):
other[cat[0]]=other[cat[0]]+result[cat]
print("{0:>10} {1:>15} {2:>15}".format("Count","Size","Compr.size"))
for cat0,r0 in sorted(totals1.items(),key=lambda p:-p[1].size):
print(cat0)
for cat,r in sorted([(c[1],r) for (c,r) in result.items() if (c[0]==cat0 and (by_size or r.size>min_size))],key=(lambda p:p[0]) if by_size else (lambda p:-p[1].size)):
print(r,cat)
if not by_size:
print(other[cat0],"other")
print(totals1[cat0],"all")
print("All")
for cat,r in sorted([(c,r) for (c,r) in totals2.items() if (by_size or r.size>min_size)],key=(lambda p:p[0]) if by_size else (lambda p:-p[1].size)):
print(r,cat)
if not by_size:
print(sum((r for r in totals2.values() if r.size<min_size),FilesetSizes()),"other")
print(sum(totals1.values(),FilesetSizes()),"all")
def create_reduced_file(input_path,output_path,temp_path,cdir,file,downsample_this,compress_this,compress_names_find, compressed_format,texture_filetypes,binary_types,fclass):
"""Process a single file in create_reduced_fgdata. (Separate function to allow parallel processing)"""
retcode=0
if downsample_this or compress_this:
image_type=texture_filetypes[os.path.splitext(file)[1]]
output_image_type=compressed_format if compress_this else os.path.splitext(file)[1]
output_file=os.path.splitext(file)[0]+output_image_type
output_image_type=texture_filetypes[output_image_type]
if "{0}" in output_path and fclass=="base-textures":#downsampled in base-textures, full resolution in extra-textures
shutil.copy(path_join(input_path,cdir,file),path_join(output_path.format("extra-textures"),cdir,file))
if output_image_type=="DDS":# in Ubuntu, neither imagemagick nor graphicsmagick can write .dds
#doesn't work (for dds -> smaller dds): subprocess.call(["nvzoom","-s","0.5","-f","box",path_join(input_path,cdir,file),path_join(output_path.format(fclass),cdir,file)])
if subprocess.call(["convert",image_type+":"+path_join(input_path,cdir,file)]+(["-flip"] if ((image_type=="DDS")!=(output_image_type=="DDS")) else [])+(["-sample","50%"] if downsample_this else [])+[path_join(temp_path,cdir,os.path.splitext(file)[0]+".png")]):#fails on some DDS formats, so just copy them
shutil.copy(path_join(input_path,cdir,file),path_join(output_path.format(fclass),cdir,file))
print(path_join(cdir,file),"unsupported type, probably normal map")
if compress_this:
raise TypeError#copy will have the wrong name
else:
try:
image_properties=subprocess.check_output(["identify","-verbose",path_join(temp_path,cdir,os.path.splitext(file)[0]+".png")])
except subprocess.CalledProcessError as err:
print("identify error on",path_join(cdir,file),"after ",["convert",image_type+":"+path_join(input_path,cdir,file)]+(["-flip"] if ((image_type=="DDS")!=(output_image_type=="DDS")) else [])+(["-sample","50%"] if downsample_this else [])+[path_join(temp_path,cdir,os.path.splitext(file)[0]+".png")],["identify","-verbose",path_join(temp_path,cdir,os.path.splitext(file)[0]+".png")],err)
raise
has_alpha=b"Alpha" in image_properties
needs_alpha=has_alpha
if has_alpha and re.search(rb"Alpha:\s*min: 255 \(1\)",image_properties):
print(path_join(cdir,file),"has always-255 alpha")
needs_alpha=False
retcode=subprocess.call(["nvcompress","-bc3" if needs_alpha else "-bc1",path_join(temp_path,cdir,os.path.splitext(file)[0]+".png"),path_join(output_path.format(fclass),cdir,output_file)],stdout=devnull)
else:
retcode=subprocess.call(["convert",image_type+":"+path_join(input_path,cdir,file)]+(["-sample","50%"] if downsample_this else [])+[output_image_type+":"+path_join(output_path.format(fclass),cdir,output_file)])#we use sample rather than an averaging filter to not break mask/rotation/... maps
else:#not to be downsampled/compressed
if os.path.splitext(file)[1] in binary_types:#just copy
shutil.copy(path_join(input_path,cdir,file),path_join(output_path.format(fclass),cdir,file))
else:#texture name replacement
file_in=open(path_join(input_path,cdir,file),'rb')
file_out=open(path_join(output_path.format(fclass),cdir,file),'wb')
file_str=file_in.read(None)
file_in.close()
(file_strout,num_matches)=compress_names_find.subn(lambda mf: os.path.splitext(mf.group(0))[0]+(compressed_format.encode('utf-8')),file_str)
file_out.write(file_strout)
file_out.close()
#if ((os.path.splitext(file)[1] not in textureuser_types) and num_matches>0):
#print("Warning: ",num_matches," unexpected use(s) in ",path_join(cdir,file))
#if compress_names_find0.search(file_strout):
#print("Warning: unreplaced match(es) in ",path_join(cdir,file),compress_names_find0.search(file_strout).group(0))
"""Warning: unreplaced match(es) in... correct rejections of match within a filename:
Aircraft/Instruments-3d/AN-APS-13.ac b'panel.png'
Aircraft/Instruments-3d/magneto-switch/mag_switch.ac b'black.png'
Nasal/canvas/map/Images/chart_symbols.svg b'wash.png'
Models/Airport/blast-deflector49m.ac b'generic.png'
Models/Airport/blast-deflector63m.ac b'generic.png'
Models/Industrial/oilrig09.ac b'yellow.png'
Models/Industrial/oilrig10.ac b'yellow.png'
Models/Industrial/oilrig09.ac.before-color-change b'yellow.png'
Models/Industrial/oilrig10.ac.before-color-change b'yellow.png'
Models/Maritime/Civilian/Tanker.ac b'black.png'
Models/Transport/flatcar.xml b'evergreen.png'
Models/Commercial/tower-grey-black.ac b'black.png'
Materials/base/materials-base.xml b'yellow.png'
Warning: unexpected use(s) in...
Docs/README.local_weather.html (the only one that looke like an actual problem; hence, Docs is now skipped)
Nasal/canvas/map/Images/chart_symbols.svg (probably inkscape:export-filename, which are creator-specific absolute paths anyway, but now skipped)
oilrig09.ac.before-color-change,oilrig10.ac.before-color-change,stbd_coaming_panel.ac.bak (presumably backup files)
"""
if retcode:
print("Error ",retcode," in ",path_join(cdir,file))
def create_reduced_fgdata(input_path,output_path,reject_positional_args=None,split_textures=False,exclude_parts=[],include_aircraft=['UIUC','777','777-200','b1900d','CitationX','ZLT-NT','dhc2','Cub','sopwithCamel','f-14b','ASK13','bo105','Dragonfly','SenecaII','A6M2'],dirs_to_downsample=(),dirs_to_compress=(),compressed_format=".dds",downsample_min_filesize=1e5,compress_min_filesize=3e4,use_ready_compressed=True):
"""Create a smaller, reduced-quality flightgear-data package
Can downsample textures 50%, change texture format, and/or omit sections (region-specific textures, aircraft, AI traffic)
Downsampling and format change require imagemagick or graphicsmagick (for convert) and libnvtt-bin (for nvcompress)
Optional parts, use exclude_parts to omit:
ai: no background traffic, but tankers etc do still work
extra-textures (requires split_textures=True): no region-specific textures
The c172p and ufo are always included; other aircraft are added by include_aircraft
Texture downsampling: textures in dirs_to_downsample and larger than downsample_min_filesize downsampled 50%
Texture format conversion: textures in dirs_to_compress and larger than compress_min_filesize converted to compressed_format
use_ready_compressed determines what happens if a same-basename file in compressed_format already exists: True uses the already-compressed one, False uses the uncompressed one, None keeps both
Suggested dirs_to_downsample:
3.2: ('Textures.high/Terrain','Textures.high/Trees','Textures.high/Terrain.winter','AI/Aircraft','Models')
3.3: ('Textures/Terrain','Textures/Trees','Textures/Terrain.winter','AI/Aircraft','Models')
To do "everything" (a few are always skipped due to potential breakage), use dirs_to_compress=('',)
To put each section in its own directory (e.g. for building a Debian-style flightgear-data-* set of packages) use {0} in output_path, e.g.
python3 -c "import fgdata_checkers; fgdata_checkers.create_reduced_fgdata(input_path='/home/rnpalmer/fs_dev/git/fgdata',output_path='/home/rnpalmer/fs_dev/flightgear/data_split/debian/flightgear-data-{0}/usr/share/games/flightgear',include_aircraft=['UIUC','b1900d','CitationX','ZLT-NT','dhc2','Cub','sopwithCamel','f-14b','ASK13','bo105','Dragonfly','SenecaII','A6M2'])"
This creates separate preferences-regions.xml and preferences-noregions.xml files for with and without regional textures; you need to handle symlinking preferences.xml to the correct one
"""
start_time=time.time()
if reject_positional_args is not None:
raise TypeError("Keyword arguments only please: this is not a stable API")
if use_ready_compressed not in (True,False,None):
raise TypeError("invalid use_ready_compressed setting")
texture_filetypes={".png":"PNG",".dds":"DDS",".jpg":"JPEG"}#,".rgb":"SGI" loses cloud transparency
if compressed_format not in texture_filetypes:
raise ValueError("Invalid compressed_format (include the .)")
textureuser_types={".eff",".xml",".ac",".nas"}
binary_types={".png",".dds",".rgb",".RGB",".jpg",".wav",".WAV",".btg.gz",".zip",".tar.gz"}#don't search these for texture name replacement
"""Textures named directly in flightgear/simgear code:
gui/images/shadow.png,gui/cursor-spin-cw.png (probably safest to treat this as gui/*, they're all small)
Textures/Globe/world.topo.bathy.200407.3x4096x2048.png
Textures/buildings.png,Textures/buildings-lightmap.png
Textures/Sky/*
Textures/Splash*.png
unknown.rgb (probably Textures/ or Textures/Terrain/, neither exists)
Aircraft/Instruments/Textures/nd-symbols.png (doesn't actually exist),Aircraft/Instruments/Textures/compass-ribbon.rgb,Aircraft/Instruments/Textures/od_wxradar.rgb,Aircraft/Instruments/Textures/od_wxradar.rgb,Aircraft/Instruments/Textures/wxecho.rgb,Aircraft/Instruments/Textures/od_groundradar.rgb (doesn't actually exist)
also, Aircraft/{Instruments,Instruments-3d,Generic} may be used by downloaded aircraft, and Docs images are used in .html
Nasal (Canvas map) probably wouldn't break anything, but guessing it's a bad idea visually"""
no_compress_pattern=re.compile(r'mask|light|relief|nmap|nm\.|normal|dudv|^Splash[0-9].png$|^buildings.png$|^buildings-lightmap.png$|^world.topo.bathy.200407.3x4096x2048.png$|^ocean_depth_1.png$')#edge blurring from lossy compression may break masks (converting ocean_depth_1.png is known to give black water near shore at effects>=4), and this script doesn't know how to create DDS normal maps
no_compress_dirs=("gui","Docs","webgui","Nasal","Textures/Sky","Aircraft/Instruments","Aircraft/Instruments-3d","Aircraft/Generic")
exclude_dirs=[".git","Textures/Unused"]
exclude_unnamed_subdirs=["Aircraft"]#these are a separate mechanism from subtree_class/exclude_parts mostly to save time (subtree_class still fully scans excluded directories because the class may change again further down the tree, e.g. AI/Aircraft ai -> performancedb.xml base; these don't)
subtree_class={"Aircraft/c172p":"base","Aircraft/Generic":"base","Aircraft/Instruments":"base","Aircraft/Instruments-3d":"base","Aircraft/ufo":"base","Textures":"textures","Textures.high":"textures","AI/Aircraft":"ai","AI/Traffic":"ai","AI/Aircraft/performancedb.xml":"base","Scenery":"scenery","Models":"models"}
for aircraft in include_aircraft:
if "Aircraft/"+aircraft not in subtree_class:
subtree_class["Aircraft/"+aircraft]="aircraft"
include_files=[]
if split_textures:
base_texture_files=[]
for t in find_unused_textures(input_path,return_used_noregions=True):
base_texture_files.extend([path_join("Textures",t),path_join("Textures.high",t)])
#no longer a significant problem with exclude_dirs, and no longer exists for new fgdata: if os.path.exists(path_join(input_path,".git")):
#print(input_path,"""appears to be a git clone; this will work, but the result will be larger than starting from a standard flightgear-data package.\nTo create this use (adjusting paths as necessary) rsync -av --filter="merge /home/rnpalmer/FlightGear/source/fgmeta/base-package.rules" ~/FlightGear/source/fgdata ~/FlightGear/data_full""")
if os.path.exists(output_path.format("base")) and os.listdir(output_path.format("base")):
print("output path",output_path,"non-empty, aborting to avoid data loss\nIf you did want to lose its previous contents, run:\nrm -r",output_path,"\nthen re-run this script")
return
if compressed_format==".jpg":
print("Warning: selected compression format does not support transparency")
compress_names=set()
if dirs_to_compress:#need this preliminary pass to get names to change in .xml,etc
no_compress_names=set()
dirs={"":"base"}
while dirs:
cdir,cclass=dirs.popitem()
cdirfiles=os.listdir(path_join(input_path,cdir))
for file in cdirfiles:
fclass=subtree_class.get(path_join(cdir,file),cclass)
if os.path.isdir(path_join(input_path,cdir,file)):
if (path_join(cdir,file) not in exclude_dirs) and (cdir not in exclude_unnamed_subdirs or path_join(cdir,file) in subtree_class):
dirs[path_join(cdir,file)]=fclass
else:#file
compress_this=cdir.startswith(dirs_to_compress) and (os.path.splitext(file)[1] in texture_filetypes) and (os.path.splitext(file)[1]!=compressed_format) and (os.path.getsize(path_join(input_path,cdir,file))>compress_min_filesize) and not no_compress_pattern.search(file) and not cdir.startswith(no_compress_dirs) and (file not in no_compress_names) and ((use_ready_compressed is not None) or not os.path.exists(path_join(input_path,cdir,os.path.splitext(file)[0]+compressed_format)))
if compress_this:
compress_names.add(file)
else:
no_compress_names.add(file)
compress_names.discard(file)#if there are two with the same name in different directories, compress both or neither, to simplify name replacement
compress_names_find=re.compile(('(?<=["\'>/\\\\ \\n])('+'|'.join(re.escape(f) for f in compress_names)+')($|(?=["\'< \\n]))').encode('utf-8'))
compress_names_find0=re.compile(('|'.join(re.escape(f) for f in compress_names)).encode('utf-8'))
#print(compress_names,"\n\n",no_compress_names,"\n\n",'(?<=["\'>/\\\\ \\n])('+'|'.join(re.escape(f) for f in compress_names)+')($|(?=["\'< \\n]))',"\n\n",'|'.join(re.escape(f) for f in compress_names),"\n\n")
print("Starting conversion...",len(compress_names),"files to change format, runtime so far=",int(time.time()-start_time),"sec")
dirs={"":"base"}
subprocess_pool=multiprocessing.Pool(processes=8)
subprocess_list=[]
temp_dir=tempfile.TemporaryDirectory()
temp_path=temp_dir.name
while dirs:
cdir,cclass=dirs.popitem()
cdirfiles=os.listdir(path_join(input_path,cdir))
for file in cdirfiles:
fclass=subtree_class.get(path_join(cdir,file),cclass)
if os.path.isdir(path_join(input_path,cdir,file)):
if (path_join(cdir,file) not in exclude_dirs) and (cdir not in exclude_unnamed_subdirs or path_join(cdir,file) in subtree_class):
dirs[path_join(cdir,file)]=fclass
else:#file
if split_textures and fclass=="textures":
if path_join(cdir,file) in base_texture_files:
fclass="base-textures"
else:
fclass="extra-textures"
if fclass in exclude_parts:
continue
if not os.path.exists(path_join(output_path.format(fclass),cdir)):
os.makedirs(path_join(output_path.format(fclass),cdir))#errors out if the directory does exist, so calling it in the per-file subprocess would be a race condition
if "{0}" in output_path and fclass=="base-textures" and not os.path.exists(path_join(output_path.format("extra-textures"),cdir)):#downsampled in base-textures, full resolution in extra-textures
os.makedirs(path_join(output_path.format("extra-textures"),cdir))
if not os.path.exists(path_join(temp_path,cdir)):
os.makedirs(path_join(temp_path,cdir))
downsample_this=(cdir.startswith(dirs_to_downsample)) and (os.path.splitext(file)[1] in texture_filetypes) and (os.path.getsize(path_join(input_path,cdir,file))>downsample_min_filesize)
compress_this=(file in compress_names)
if compress_this and use_ready_compressed==True and os.path.exists(path_join(input_path,cdir,os.path.splitext(file)[0]+compressed_format)):
continue
if (not compress_this) and use_ready_compressed==False and os.path.splitext(file)[1]==compressed_format and any((os.path.exists(path_join(input_path,cdir,os.path.splitext(file)[0]+f)) and os.path.splitext(file)[0]+f in compress_names) for f in texture_filetypes if f!=os.path.splitext(file)[1]):
continue
subprocess_list.append(subprocess_pool.apply_async(create_reduced_file,args=(input_path,output_path,temp_path,cdir,file,downsample_this,compress_this,compress_names_find, compressed_format,texture_filetypes,binary_types,fclass)))
print(len(subprocess_list),"file tasks started...runtime so far=",int(time.time()-start_time),"sec\n(Not a linear progress indicator: they are different lengths.)")
last_report=time.time()-100#print first report immediately
for s0 in subprocess_list:
if time.time()>last_report+60:
print("Waiting for",len([s for s in subprocess_list if not s.ready()]),"file tasks...runtime so far=",int(time.time()-start_time),"sec")
last_report=time.time()
s0.get()
subprocess_pool.close()
subprocess_pool.join()
if "{0}" in output_path:
os.rename(path_join(output_path.format("base"),"preferences.xml"),path_join(output_path.format("base"),"preferences-regions.xml"))
if "extra-textures" in exclude_parts or "{0}" in output_path:
prefs_in=open(path_join(input_path,"preferences.xml"),'r')
prefs_out=open(path_join(output_path.format("base"),"preferences-noregions.xml" if "{0}" in output_path else "preferences.xml"),'w')
prefs_str=prefs_in.read(None)
prefs_in.close()
prefs_str=prefs_str.replace("Materials/regions/materials.xml","Materials/default/materials.xml")#turn off regional textures
prefs_out.write(prefs_str)
prefs_out.close()
print("Total runtime=",int(time.time()-start_time),"sec")
def check_text_encoding(path,filelist=None,binary_types=(".png",".dds",".rgb",".RGB",".jpg",".wav",".WAV",".btg.gz",".xcf.gz",".xcf",".XCF","Thumbs.db",".blend",".bmp",".gif", ".3ds",".3DS",".pdf",".ttf",".txf",".htsvoice",".odt",".ods",".xls",".mp3",".zip",".tar.gz"),exclude_dirs=[".git","Timezone"]):
"""filelist is intended for quick testing: see fgdata_nonascii_filelist.py"""
def err_context(err):
start=max(err.object.rfind(b'\n',0,err.start)+1,err.start-30,0)
end=min(err.object.find(b'\n',err.start),err.start+30,len(err.object))
if end<0:#not found
end=err.start+30
return err.object[start:end]
def dict_print(d):
return "".join(i[0]+"\n\t"+str(i[1])+"\n\t"+(str(i[1],encoding="utf-8",errors="replace")+"\n\t"+str(i[1],encoding="latin-1") if type(i[1])==bytes else "")+"\n" for i in sorted(d.items()))
if filelist is None:
filelist=[f for f in rfilelist(path,exclude_dirs) if not f.endswith(tuple(binary_types))]
utf8_files={}
withnulls_files=[]
othertext_files={}
mislabeled_xml={}
mislabeled_xml_nocomments={}
xml_encoding_pattern=re.compile(r'<\?xml.*?encoding="(\S+?)".*?\?>')
xml_noencoding_pattern=re.compile(r'<\?xml.*?\?>')
utf8_files_nocomments={}
othertext_files_nocomments={}
for fname in filelist:
if os.path.splitext(fname)[1]==".gz":
fobj=gzip.open(path_join(path,fname),mode='rb')
else:
fobj=open(path_join(path,fname),mode='rb')
fdata=fobj.read()
if b"\0" in fdata:
withnulls_files.append(fname)#two look like corrupted files: Aircraft/p51d/Resources/WIP/P-51D-25NA.ac (hangs gedit,large block of nulls in middle) Docs/Serial/nmeafaq.txt (block of nulls at end), rest are probably-binary types
continue
if os.path.splitext(fname)[1] in (".xml",".svg",".xhtml"):
encoding_mark=xml_encoding_pattern.search(str(fdata.split(b'\n',maxsplit=1)[0],encoding="utf-8"))
if encoding_mark:
encoding_mark=encoding_mark.group(1)
if encoding_mark not in ("utf-8","UTF-8","ISO-8859-1"):
mislabeled_xml_nocomments[fname]="unrecognised encoding "+encoding_mark
encoding_mark=None
else:
if xml_noencoding_pattern.search(str(fdata.split(b'\n',maxsplit=1)[0],encoding="utf-8")):
encoding_mark="utf-8"#XML standard allows either UTF-8 or UTF-16 (with BOM) in unlabeled files, but we only use -8
else:
encoding_mark=None
#mislabeled_xml_nocomments[fname]="no xml header"
else:
encoding_mark=None
try:
fdata.decode(encoding="ascii")
continue
except UnicodeError as err:
errline=err_context(err)
try:
fdata.decode(encoding="utf-8")
utf8_files[fname]=errline
if encoding_mark not in ("utf-8","UTF-8",None):
mislabeled_xml[fname]=bytes(encoding_mark,encoding="ascii")+errline
except UnicodeError as err:
errline=err_context(err)
othertext_files[fname]=errline
if encoding_mark not in ("ISO-8859-1",None):
mislabeled_xml[fname]=bytes(encoding_mark,encoding="ascii")+errline
if os.path.basename(fname) in ("Read-Me.txt","README.txt","Readme.txt","readme.txt","LIS-MOI_GNU-GPL"):
continue
fdata_nocomments=strip_comments(fdata,filename=fname)
if fdata_nocomments.startswith(bytes([0xef,0xbb,0xbf])) and fname not in mislabeled_xml:#UTF-8 BOM
fdata_nocomments=fdata_nocomments[3:]
try:
fdata_nocomments.decode(encoding="ascii")
continue
except UnicodeError as err:
errline=err_context(err)
try:
fdata_nocomments.decode(encoding="utf-8")
if encoding_mark is None:
utf8_files_nocomments[fname]=errline
if encoding_mark not in ("utf-8","UTF-8",None):
mislabeled_xml_nocomments[fname]=bytes(encoding_mark,encoding="ascii")+errline
except UnicodeError as err:
errline=err_context(err)
if encoding_mark is None:
othertext_files_nocomments[fname]=errline
if encoding_mark not in ("ISO-8859-1",None):
mislabeled_xml_nocomments[fname]=bytes(encoding_mark,encoding="ascii")+errline
print("non-ASCII valid UTF-8:",dict_print(utf8_files),"\n\nother:",dict_print(othertext_files),"\n\nmislabeled/unrecognised",dict_print(mislabeled_xml),"\n\nwith nulls (binary or UTF-16/32):",sorted(withnulls_files),"\n\nnon-ASCII valid UTF-8 (outside BOM/comments):",dict_print(utf8_files_nocomments),"\n\nother (outside comments):",dict_print(othertext_files_nocomments),"\n\nmislabeled/unrecognised (outside comments)",dict_print(mislabeled_xml_nocomments))

2
fgrun

Submodule fgrun updated: 3fb3be1935...e030882cdb

View File

@@ -9,17 +9,18 @@ VERSION=`cat flightgear/version`
#####################################################################################
# remove old and create fresh build directories
cd $WORKSPACE
rm -rf sgBuild
rm -rf fgBuild
mkdir -p sgBuild
mkdir -p fgBuild
mkdir -p output
rm -rf output/*
rm -rf dist/*
rm -rf $WORKSPACE/dist/include/simgear $WORKSPACE/dist/libSim* $WORKSPACE/dist/libsg*.a
#####################################################################################
echo "Starting on SimGear"
cd sgBuild
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DENABLE_DNS:BOOL="ON" -DSIMGEAR_SHARED:BOOL="ON" ../simgear
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" ../simgear
# compile
make
@@ -38,7 +39,7 @@ cp simgear-*.tar.bz2 ../output/.
#####################################################################################
echo "Starting on FlightGear"
cd ../fgBuild
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" -DFG_BUILD_TYPE=Release ../flightgear
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" ../flightgear
# compile
make
@@ -59,4 +60,9 @@ cp flightgear-*.tar.bz2 ../output/.
echo "Assembling base package"
cd $WORKSPACE
echo "Syncing base packages files from sphere.telascience.org"
rsync -avz --filter 'merge base-package.rules' \
-e ssh jturner@sphere.telascience.org:/home/jturner/fgdata .
tar cjf output/FlightGear-$VERSION-data.tar.bz2 fgdata/

View File

@@ -15,54 +15,59 @@ mkdir -p output
rm -rf output/*
rm -rf $WORKSPACE/dist/include/simgear $WORKSPACE/dist/libSim* $WORKSPACE/dist/libsg*.a
PATH=$PATH:$QTPATH
echo "Build path is: $PATH"
###############################################################################
echo "Starting on SimGear"
pushd sgBuild
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DCMAKE_BUILD_TYPE=RelWithDebInfo ../simgear
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -G Xcode ../simgear
# compile
make
xcodebuild -configuration Release -target install build
if [ $? -ne '0' ]; then
echo "make simgear failed"
exit 1
fi
make install
popd
################################################################################
echo "Starting on FlightGear"
pushd fgBuild
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -G Xcode ../flightgear
if [ $FG_IS_RELEASE == '1' ]; then
FGBUILDTYPE=Release
else
FGBUILDTYPE=Nightly
fi
cmake -DFG_BUILD_TYPE=$FGBUILDTYPE -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DCMAKE_BUILD_TYPE=RelWithDebInfo ../flightgear
make
xcodebuild -configuration Release -target install build
if [ $? -ne '0' ]; then
echo "make flightgear failed"
exit 1
fi
make install
popd
chmod +x $WORKSPACE/dist/bin/osgversion
################################################################################
echo "Building Macflightgear launcher"
#OSX_TARGET="10.6"
# JMT - disabling setting the sysroot since it's breaking things on
# current build slave. Sinc ethe slave runs 10.6 natively, we don't
# actually need to set these. Real solution would be to use a proper
# build system for the Mac-launcher of course.
# -mmacosx-version-min=$OSX_TARGET -isysroot $SDK_PATH
pushd maclauncher/FlightGearOSX
# compile the stub executable
gcc -o FlightGear main.m \
-framework Cocoa -framework RubyCocoa -framework Foundation -framework AppKit
popd
################################################################################
echo "Syncing base packages files from sphere.telascience.org"
rsync -avz --filter 'merge base-package.rules' \
-e ssh jturner@sphere.telascience.org:/home/jturner/fgdata .
# run the unlock script now - we need to do this right before code-signing,
# or the keychain may automatically re-lock after some period of time

View File

@@ -7,19 +7,6 @@ include FileUtils
$osgLibs = ['osgFX', 'osgParticle', 'osg', 'osgGA', 'osgText', 'osgUtil', 'osgSim', 'osgViewer', 'osgDB']
$osgPlugins = ['ac', 'osg', 'freetype', 'imageio', 'rgb', 'txf', 'mdl', '3ds']
# from http://drawingablank.me/blog/ruby-boolean-typecasting.html
class String
def to_bool
return true if self == true || self =~ (/^(true|t|yes|y|1)$/i)
return false if self == false || self.blank? || self =~ (/^(false|f|no|n|0)$/i)
raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
end
end
class NilClass
def to_bool; false; end
end
def runOsgVersion(option)
env = "export DYLD_LIBRARY_PATH=#{Dir.pwd}/dist/lib"
bin = Dir.pwd + "/dist/bin/osgversion"
@@ -32,35 +19,41 @@ $openThreadsSoVersion=runOsgVersion('openthreads-soversion-number')
$codeSignIdentity = ENV['FG_CODESIGN_IDENTITY']
puts "Code signing identity is #{$codeSignIdentity}"
puts "osgVersion=#{osgVersion}, so-number=#{$osgSoVersion}"
$isRelease = ENV['FG_IS_RELEASE'].to_bool
puts "Is-release? : ##{$isRelease}"
def fix_install_names(object)
#puts "fixing install names for #{object}"
$osgLibs.each do |l|
oldName = "lib#{l}.#{$osgSoVersion}.dylib"
newName = "@executable_path/../Frameworks/#{oldName}"
`install_name_tool -change #{oldName} #{newName} #{object}`
end
oldName = "libOpenThreads.#{$openThreadsSoVersion}.dylib"
newName= "@executable_path/../Frameworks/#{oldName}"
`install_name_tool -change #{oldName} #{newName} #{object}`
end
$prefixDir=Dir.pwd + "/dist"
dmgDir=Dir.pwd + "/image"
srcDir=Dir.pwd + "/flightgear"
def code_sign(path)
puts "Signing #{path}"
`codesign -s "#{$codeSignIdentity}" #{path}`
end
puts "Erasing previous image dir"
`rm -rf #{dmgDir}`
bundle=dmgDir + "/FlightGear.app"
# run macdeployt before we rename the bundle, otherwise it
# can't find the bundle executable
puts "Running macdeployqt on the bundle to copy Qt libraries"
`macdeployqt #{$prefixDir}/fgfs.app`
puts "Moving & renaming app bundle"
`mkdir -p #{dmgDir}`
`mv #{$prefixDir}/fgfs.app #{bundle}`
bundle=dmgDir + "/FlightGear.app"
contents=bundle + "/Contents"
macosDir=contents + "/MacOS"
$frameworksDir=contents +"/Frameworks"
resourcesDir=contents+"/Resources"
osgPluginsDir=contents+"/PlugIns/osgPlugins"
osgPluginsDir=contents+"/PlugIns/osgPlugins-#{osgVersion}"
# for writing copyright year to Info.plist
t = Time.new
@@ -69,13 +62,7 @@ fgCurrentYear = t.year
fgVersion = File.read("#{srcDir}/version").strip
volName="\"FlightGear #{fgVersion}\""
if $isRelease
dmgPath = "" # no 'lite' build for release candidates
dmgFullPath = Dir.pwd + "/output/FlightGear-#{fgVersion}.dmg"
else
dmgPath = Dir.pwd + "/output/FlightGear-#{fgVersion}-nightly.dmg"
dmgFullPath = Dir.pwd + "/output/FlightGear-#{fgVersion}-nightly-full.dmg"
end
dmgPath = Dir.pwd + "/output/FlightGear-#{fgVersion}.dmg"
puts "Creating directory structure"
`mkdir -p #{macosDir}`
@@ -83,22 +70,23 @@ puts "Creating directory structure"
`mkdir -p #{resourcesDir}`
`mkdir -p #{osgPluginsDir}`
puts "Copying auxilliary binaries"
bins = ['fgjs', 'fgcom']
puts "Copying binaries"
bins = ['fgfs', 'fgjs', 'fgcom', 'fgviewer']
bins.each do |b|
if !File.exist?("#{$prefixDir}/bin/#{b}")
next
end
outPath = "#{macosDir}/#{b}"
`cp #{$prefixDir}/bin/#{b} #{outPath}`
fix_install_names(outPath)
end
puts "copying libraries"
$osgLibs.each do |l|
libFile = "lib#{l}.#{$osgSoVersion}.dylib"
`cp #{$prefixDir}/lib/#{libFile} #{$frameworksDir}`
fix_install_names("#{$frameworksDir}/#{libFile}")
end
# and not forgetting OpenThreads
@@ -106,8 +94,17 @@ libFile = "libOpenThreads.#{$openThreadsSoVersion}.dylib"
`cp #{$prefixDir}/lib/#{libFile} #{$frameworksDir}`
$osgPlugins.each do |p|
pluginFile = "osgdb_#{p}.dylib"
`cp #{$prefixDir}/lib/osgPlugins/#{pluginFile} #{osgPluginsDir}`
pluginFile = "osgdb_#{p}.so"
`cp #{$prefixDir}/lib/osgPlugins-#{osgVersion}/#{pluginFile} #{osgPluginsDir}`
fix_install_names("#{osgPluginsDir}/#{pluginFile}")
end
# Macflightgear launcher
puts "Copying Macflightgear launcher files"
Dir.chdir "maclauncher/FlightGearOSX" do
`cp FlightGear #{macosDir}`
`rsync -a *.rb *.lproj *.sh *.tiff *.html #{resourcesDir}`
end
if File.exist?("#{$prefixDir}/bin/fgcom-data")
@@ -127,32 +124,24 @@ File.open("#{contents}/Info.plist", 'w') { |f|
`cp #{srcDir}/COPYING #{dmgDir}`
# move documentation to a public place
`cp fgdata/Docs/FGShortRef.pdf "#{dmgDir}/Quick Reference.pdf"`
`cp fgdata/Docs/getstart.pdf "#{dmgDir}/Getting Started.pdf"`
createArgs = "-format UDBZ -imagekey bzip2-level=9 -quiet -volname #{volName}"
if !$isRelease
# create the 'lite' DMG without the base files
# code sign the entire bundle once complete - v2 code-signing
puts "Signing #{bundle}"
`codesign --deep -s "#{$codeSignIdentity}" #{bundle}`
puts "Creating DMG"
`rm #{dmgPath}`
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgPath}`
end
puts "Creating full image with data"
`mv fgdata/Docs/FGShortRef.pdf "#{dmgDir}/Quick Reference.pdf"`
`mv fgdata/Docs/getstart.pdf "#{dmgDir}/Getting Started.pdf"`
puts "Copying base package files into the image"
`rsync -a fgdata/ #{resourcesDir}/data`
# re-sign the entire bundle
puts "Re-signing full #{bundle}"
`codesign --force --deep -s "#{$codeSignIdentity}" #{bundle}`
# code sign all executables in MacOS dir. Do this last since reource
# changes will invalidate the signature!
Dir.foreach(macosDir) do |b|
if b == '.' or b == '..' then
next
end
code_sign("#{macosDir}/#{b}")
end
`rm #{dmgFullPath}`
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgFullPath}`
puts "Creating DMG"
createArgs = "-format UDBZ -imagekey bzip2-level=9 -quiet -volname #{volName}"
`rm #{dmgPath}`
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgPath}`

23
hudson_win_build32.bat Normal file
View File

@@ -0,0 +1,23 @@
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
SET /P SIMGEAR_VERSION=<%WORKSPACE%\simgear\version
ECHO #define SIMGEAR_VERSION "%SIMGEAR_VERSION%" > %WORKSPACE%\simgear\simgear\version.h
rem set PATH=%PATH%;D:\Program Files (x86)\CMake 2.8\bin
rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
md build-sg
md build-fg
md build-fgrun
cd build-sg
cmake ..\simgear -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/SimGear -DBOOST_ROOT=%WORKSPACE%/Boost
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg
cmake ..\flightgear -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FlightGear -DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe -DBOOST_ROOT=%WORKSPACE%/Boost
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fgrun
cmake ..\fgrun -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FGRun -DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe -DBOOST_ROOT=%WORKSPACE%/Boost
cmake --build . --config Release --target INSTALL

24
hudson_win_build64.bat Normal file
View File

@@ -0,0 +1,24 @@
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
SET /P SIMGEAR_VERSION=<%WORKSPACE%\simgear\version
ECHO #define SIMGEAR_VERSION "%SIMGEAR_VERSION%" > %WORKSPACE%\simgear\simgear\version.h
rem ECHO #define SIMGEAR_VERSION "2.9.0" > %WORKSPACE%\simgear\simgear\version.h
rem set PATH=%PATH%;D:\Program Files (x86)\CMake 2.8\bin
rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64
md build-sg64
md build-fg64
md build-fgrun64
cd build-sg64
cmake ..\SimGear -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/SimGear -DBOOST_ROOT=%WORKSPACE%/Boost
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg64
cmake ..\flightgear -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FlightGear -DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe -DBOOST_ROOT=%WORKSPACE%/Boost -DWITH_FGPANEL=OFF -DENABLE_PROFILE=OFF
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fgrun64
cmake ..\fgrun -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FGRun -DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe -DBOOST_ROOT=%WORKSPACE%/Boost
cmake --build . --config Release --target INSTALL

View File

@@ -0,0 +1,40 @@
ECHO OFF
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
ECHO Packaging root is %WORKSPACE%
subst X: /D
subst X: %WORKSPACE%.
REM construct information file to be read by Inno-setup
set PATH=%WORKSPACE%\install\msvc100\OpenSceneGraph\bin;%PATH%
REM add 7-zip to the PATH
set PATH=%PATH%;C:\Program Files\7-zip
REM indirect way to get command output into an environment variable
osgversion --so-number > %TEMP%\osg-so-number.txt
osgversion --version-number > %TEMP%\osg-version.txt
osgversion --openthreads-soversion-number > %TEMP%\openthreads-so-number.txt
SET /P FLIGHTGEAR_VERSION=<flightgear\version
SET /P OSG_VERSION=<%TEMP%\osg-version.txt
SET /P OSG_SO_NUMBER=<%TEMP%\osg-so-number.txt
SET /P OT_SO_NUMBER=<%TEMP%\openthreads-so-number.txt
ECHO #define FGVersion "%FLIGHTGEAR_VERSION%" > InstallConfig.iss
ECHO #define OSGVersion "%OSG_VERSION%" >> InstallConfig.iss
ECHO #define OSGSoNumber "%OSG_SO_NUMBER%" >> InstallConfig.iss
ECHO #define OTSoNumber "%OT_SO_NUMBER%" >> InstallConfig.iss
set DATA_FILE=FlightGear-%FLIGHTGEAR_VERSION%-data
REM extract the data files
7z e -aoa %DATA_FILE%.tar.bz2 && 7z x -aoa %DATA_FILE%.tar
REM run Inno-setup!
REM use iscc instead of compil32 for better error reporting
iscc FlightGear.iss

View File

@@ -1,7 +1,6 @@
REM ExternalProject can't cleanly extract a zip into an existing directory
REM Instead we extract to a subdir, and then move the directories we want
REM using this bat file.
REM This script is used by the SuperBuild CMakeLists.txt
echo %CD%
IF EXIST winDeps/3rdParty (

1
maclauncher Submodule

Submodule maclauncher added at 45a598c7cc

View File

@@ -1,133 +0,0 @@
#!/usr/bin/python
# this file runs on the download server (download.flightgear.org)
# from the Jenkins upload-via-ssh jobs. It ensures that only complete
# uploads are visible (and mirrored to SF).
import os, sys, re, fnmatch
from subprocess import call
suffix = '.dmg'
release_version = "unknown"
if sys.argv[1] == 'windows':
suffix = '.exe'
if sys.argv[1] == 'linux':
suffix = '.tar.bz2'
isRelease = False
if len(sys.argv) > 2 and sys.argv[2] == 'release':
isRelease = True
if len(sys.argv) > 3:
release_version = sys.argv[3]
allSuffix = '*' + suffix
print "Wildcard pattern is:" + allSuffix
pattern = r'\w+-(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)([\w-]*)' + suffix
sourceForgeUserHost = "jmturner@frs.sourceforge.net"
sftpCommandFile = "sftp-commands"
symbolDir = "/home/jenkins/symbols"
if isRelease:
publicRoot = "/var/www/html/builds/rc"
incomingDir = "/home/jenkins/incoming"
sourceForgePath = "/home/frs/project/f/fl/flightgear/release-" + release_version + "/"
else:
publicRoot = "/var/www/html/builds/nightly"
incomingDir = "/home/jenkins/nightly-incoming"
sourceForgePath = "/home/frs/project/f/fl/flightgear/unstable/"
os.chdir(publicRoot)
def findFileVersion(dir):
for file in os.listdir(dir):
if fnmatch.fnmatch(file, allSuffix):
m = re.match(pattern, file)
if (m is not None):
return (m.group('major'), m.group('minor'), m.group('patch'))
return None
incomingVer = findFileVersion(incomingDir)
if incomingVer is None:
print "No incoming files found matching " + allSuffix
exit()
existingVer = findFileVersion('.')
# if files in dest location mis-match the version, archive them
# and re-create the symlinks
versionChange = (existingVer != incomingVer)
oldFiles = []
incomingFiles = []
newFiles = []
if versionChange:
print "Version number changing"
for file in os.listdir('.'):
if fnmatch.fnmatch(file, allSuffix):
if not os.path.islink(file):
oldFiles.append(file)
os.remove(file)
for file in os.listdir(incomingDir):
if fnmatch.fnmatch(file, allSuffix):
incomingFiles.append(file)
# copy and symlink
for file in incomingFiles:
# move it to the public location
srcFile = os.path.join(incomingDir, file)
outFile = file
# insert -rc before suffix
#if isRelease:
#m = re.match(r'(\w+-\d+\.\d+\.\d+[\w-]*)' + suffix, file)
#outFile = m.group(1) + '-rc' + suffix
#print "RC out name is " + outFile
os.rename(srcFile, outFile)
newFiles.append(outFile)
if not isRelease:
# symlink for stable web URL
m = re.match(r'(\w+)-\d+\.\d+\.\d+-([\w-]+)' + suffix, file)
latestName = m.group(1) + '-latest-' + m.group(2) + suffix
print "Creating symlink from " + file + " to " + latestName
if os.path.exists(latestName):
print "\tremoving existing target"
os.remove(latestName)
os.symlink(file, latestName)
# remove files from SF
#if len(oldFiles) > 0:
# f = open(sftpCommandFile, 'w')
# f.write("cd " + sourceForgePath + '\n')
# for file in oldFiles:
# print "Removing file " + file + " from SourceForge"
# f.write("rm " + file + '\n')
# f.write("bye\n")
# f.close()
#
# call(["sftp", "-b", sftpCommandFile, sourceForgeUserHost])
# os.remove(sftpCommandFile)
# upload to SourceForge
for file in newFiles:
print "Uploading " + file + " to SourceForge"
call(["scp", file, sourceForgeUserHost + ":" + sourceForgePath + file])
if sys.argv[1] == 'windows':
print "Archiving PDB files"
for file in os.listdir(incomingDir):
if fnmatch.fnmatch(file, "*.pdb"):
srcFile = os.path.join(incomingDir, file)
outFile = os.path.join(symbolDir, file)
os.rename(srcFile, outFile)

View File

@@ -1,73 +0,0 @@
#!/bin/bash
#This file is part of FlightGear
#
#FlightGear is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 2 of the License, or
#(at your option) any later version.
#
#FlightGear 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 General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with Foobar. If not, see <http://www.gnu.org/licenses/>.
if [ -z "$1" -o -z "$2" ]; then
echo "usage: thismajor.thisminor nextmajor.nextminor path"
exit
fi
IFS='.' read -r -a VERSION_A <<< "$1"
shift
if [ ${#VERSION_A[@]} != 2 ]; then
echo "Need version as 'number.number'"
exit
fi
THIS_MAJOR_VERSION=${VERSION_A[0]}
THIS_MINOR_VERSION=${VERSION_A[1]}
RELEASE_BRANCH="release/${THIS_MAJOR_VERSION}.${THIS_MINOR_VERSION}"
IFS='.' read -r -a VERSION_A <<< "$1"
shift
if [ ${#VERSION_A[@]} != 2 ]; then
echo "Need version as 'number.number'"
exit
fi
NEXT_MAJOR_VERSION=${VERSION_A[0]}
NEXT_MINOR_VERSION=${VERSION_A[1]}
setVersionTo() {
local V="$1"
echo "setting version to $V"
echo "$V" > version
git add version
echo "new version: $V" | git commit --file=-
git tag "version/$V"
}
createBranch() {
echo "Preparing release in `pwd`"
git checkout next
git pull --rebase
setVersionTo "${THIS_MAJOR_VERSION}.${THIS_MINOR_VERSION}.1"
echo "Creating branch $RELEASE_BRANCH for version $(cat version) in `pwd`"
git branch "$RELEASE_BRANCH"
setVersionTo "${NEXT_MAJOR_VERSION}.${NEXT_MINOR_VERSION}.0"
}
while [ $# -gt 0 ]; do
echo "Processing $1"
pushd $1 > /dev/null
git config user.name "Automatic Release Builder"
git config user.email "build@flightgear.org"
createBranch
popd > /dev/null
shift
done

View File

@@ -1,45 +0,0 @@
#!/bin/bash
THIS_RELEASE="2017.1"
NEXT_RELEASE="2017.2"
SUBMODULES="simgear flightgear fgdata"
#:<< 'COMMENT_END'
git checkout next
git pull --rebase
$(dirname $0)/create-release-branch-for.sh "$THIS_RELEASE" "$NEXT_RELEASE" $SUBMODULES .
# use release branch for submodules
git checkout release/${THIS_RELEASE}
for f in $SUBMODULES; do
git config -f .gitmodules submodule.${f}.branch release/${THIS_RELEASE}
done
git add .gitmodules && echo "set correct release-branch for submodules" | git commit --file=-
# track submodule changes
git checkout next
git add $SUBMODULES && echo "track submodule changes for release" | git commit --file=-
#COMMENT_END
echo "Check this and submodules $SUBMODULES - hit <enter> to push or <ctrl-c> to cancel"
read something
for f in $SUBMODULES .; do
pushd "$f"
echo "Pushing $f"
git checkout release/${THIS_RELEASE} && git push origin release/${THIS_RELEASE} && git push origin version/${THIS_RELEASE}.1 && git push origin version/${NEXT_RELEASE}.0 && git checkout next && git push
popd
done
#this needs ~/.ssh/config to contain this
#HOST sf svn.code.sf.net
# HOSTNAME svn.code.sf.net
# IdentityFile ~/.ssh/your_sf_keyfile
# IdentitiesOnly yes
# User user_sf_username
svn copy svn+ssh://svn.code.sf.net/p/flightgear/fgaddon/trunk \
svn+ssh://svn.code.sf.net/p/flightgear/fgaddon/branches/release-${THIS_RELEASE} \
-m "branching for release ${THIS_RELEASE}"

View File

@@ -1 +0,0 @@
2017.2.1

Submodule simgear updated: 9840302931...e218c099a2

View File

@@ -1 +0,0 @@
2017.2.0

View File

@@ -1,19 +0,0 @@
<?xml version="1.0"?>
<!--
The <regex> field is evaluated by preg_match
http://php.net/manual/en/function.preg-match.php
-->
<PropertyList>
<webhook>
<regex>/^Merge branch/</regex>
<description>Detect merge branch when rebase has been ommited</description>
</webhook>
<webhook>
<regex>/^test$/</regex>
<description>Detect for dummy message</description>
</webhook>
<webhook>
<regex>/blabla/</regex>
<description>Detect for bad commit description</description>
</webhook>
</PropertyList>