Rev 1 | Rev 7 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "SpkFile.h"
CSpkFile::CSpkFile() : CBaseFile ()
{
SetDefaults ();
m_iType = TYPE_SPK;
}
CSpkFile::~CSpkFile()
{
Delete ();
}
/*
Func: SetDefaults
Desc: Sets the default values when class is created
*/
void CSpkFile::SetDefaults ()
{
m_pLastWare = NULL;
m_iPackageType = PACKAGETYPE_NORMAL;
m_bForceProfile = false;
m_iScriptType = SCRIPTTYPE_CUSTOM;
CBaseFile::SetDefaults ();
}
void CSpkFile::Delete ()
{
m_lWares.clear(true);
m_lSettings.clear(true);
CBaseFile::Delete ();
}
bool CSpkFile::CheckHeader ( CyString header )
{
if ( header.Compare("SPKCycrow") )
return true;
return false;
}
/*
Func: ParseValueLine
Input: String - single line from a file to set
Return: Boolean - returns true if value exists
Desc: Reads the line and assigns the parameters for the file
*/
bool CSpkFile::ParseValueLine ( CyString line )
{
CyString first = line.GetToken ( 1, ' ' );
CyString rest = line.GetToken ( 2, -1, ' ' );
if ( first == "AnotherMod:" )
{
m_sOtherAuthor = rest.GetToken ( 1, '|' );
m_sOtherName = rest.GetToken ( 2, -1, '|' );
}
else if ( line == "CustomStart" )
m_iPackageType = PACKAGETYPE_CUSTOMSTART;
else if ( line == "PackageUpdate" )
m_iPackageType = PACKAGETYPE_UPDATE;
else if ( line == "Patch" )
m_iPackageType = PACKAGETYPE_PATCH;
else if ( line == "ForceProfile" )
m_bForceProfile = true;
else if ( line == "Signed" )
m_bSigned = true;
else if ( first == "ScriptType:" )
m_sScriptType = rest;
else if ( first == "ScriptTypeNew:" )
m_iScriptType = rest.ToInt();
else if ( first == "PackageType:" )
m_iPackageType = rest.ToInt();
else if ( first == "Ware:" )
AddWare ( rest );
else if ( (first == "WareText:") && (m_pLastWare) )
AddWareText ( rest );
else if ( first == "Setting:" )
{
SSettingType *t = AddSetting ( rest.GetToken ( 2, '|' ), rest.GetToken ( 1, '|' ).ToInt() );
ConvertSetting ( t, rest.GetToken ( 3, -1, '|' ) );
}
else
return CBaseFile::ParseValueLine ( line );
return true;
}
/*
Func: CreateValuesLine
Return: String - returns the full string for values
Desc: Creates a single string for all values, this is used when compressing to write to the spk file
*/
CyString CSpkFile::CreateValuesLine ()
{
CyString values = CBaseFile::CreateValuesLine ();
// combine all values together
if ( (!m_sOtherAuthor.Empty()) && (!m_sOtherName.Empty()) )
values += (CyString("AnotherMod: ") + m_sOtherAuthor + "|" + m_sOtherName + "\n");
if ( m_bForceProfile )
values += "ForceProfile\n";
if ( !m_sScriptType.Empty() )
values += (CyString("ScriptType: ") + m_sScriptType + "\n");
values += (CyString("PackageType: ") + (long)m_iPackageType + "\n");
values += (CyString("ScriptTypeNew: ") + (long)m_iScriptType + "\n");
for ( SSettingType *st = m_lSettings.First(); st; st = m_lSettings.Next() )
values += (CyString("Setting: ") + CyString::Number(st->iType) + "|" + st->sKey + "|" + GetSetting(st) + "\n");
for ( SWares *ware = m_lWares.First(); ware; ware = m_lWares.Next() )
{
if ( ware->iTextID > 0 )
values += CyString("Ware: ") + ware->cType + ":" + ware->iPrice + ":" + (long)ware->iSize + ":" + (long)ware->iVolumn + ":" + ware->sID + ":" + (long)ware->iNotority + ":" + (long)ware->iTextID + "," + (long)ware->iTextPage + "\n";
else
values += CyString("Ware: ") + ware->cType + ":" + ware->iPrice + ":" + (long)ware->iSize + ":" + (long)ware->iVolumn + ":" + ware->sID + ":" + (long)ware->iNotority + "\n";
for ( SWaresText *wt = ware->lText.First(); wt; wt = ware->lText.Next() )
values += CyString("WareText: ") + (long)wt->iLang + " " + wt->sName + "|" + wt->sDesc + "\n";
}
return values;
}
CyString CSpkFile::GetCustomScriptType (int lang)
{
if ( !m_sScriptType.Empty() )
{
int max;
CyString *split = m_sScriptType.SplitToken("<br>", &max);
if ( max && split )
{
for ( int i = 1; i < max; i++ )
{
CyString str = split[i];
int num = str.GetToken(":", 1, 1).ToInt();
CyString name = str.GetToken(":", 2);
if ( num == lang )
{
CLEANSPLIT(split, max)
return name;
}
}
CyString ret = split[0];
CLEANSPLIT(split, max)
return ret;
}
CLEANSPLIT(split, max)
}
return m_sScriptType;
}
bool CSpkFile::WriteHeader(FILE *id, int valueheader, int valueComprLen)
{
fprintf ( id, "SPKCycrow;%.2f;%d;%d\n", FILEVERSION, valueheader, valueComprLen );
if ( ferror(id) )
return false;
return true;
}
void CSpkFile::AddWareText ( CyString rest )
{
if ( !m_pLastWare )
return;
SWaresText *wt = new SWaresText;
wt->iLang = rest.GetToken ( 1, ' ' ).ToInt();
wt->sName = rest.GetToken ( 2, -1, ' ' ).GetToken ( 1, '|' );
wt->sDesc = rest.GetToken ( 2, -1, ' ' ).GetToken ( 2, -1, '|' );
m_pLastWare->lText.push_back ( wt );
m_bChanged = true;
}
void CSpkFile::AddWare ( CyString rest )
{
SWares *ware = new SWares;
ware->iTextID = -1;
ware->iTextPage = 0;
ware->cType = rest.GetToken ( 1, ':' )[0];
ware->iPrice = rest.GetToken ( 2, ':' ).ToLong();
ware->iSize = rest.GetToken ( 3, ':' ).ToInt();
ware->iVolumn = rest.GetToken ( 4, ':' ).ToInt();
ware->sID = rest.GetToken ( 5, ':' );
ware->iNotority = rest.GetToken ( 6, ':' ).ToInt();
if ( !rest.GetToken( 7, ':' ).Empty() )
{
CyString r = rest.GetToken ( 7, ':' );
ware->iTextID = r.GetToken(",", 1, 1).ToInt();
ware->iTextPage = r.GetToken(",", 2, 2).ToInt();
}
m_lWares.push_back ( ware );
m_pLastWare = ware;
m_bChanged = true;
}
bool CSpkFile::ReadFileToMemory ( C_File *file )
{
if ( !file )
return false;
// check if data is already extracted
if ( (file->GetDataSize ()) && (file->GetData()) )
return true;
// no file to read from
if ( m_sFilename.Empty() )
return false;
// now open the file
FILE *id = fopen ( m_sFilename.c_str(), "rb" );
if ( !id )
return false;
// read the header
GetEndOfLine ( id, NULL, false );
// skip past values
fseek ( id, m_SHeader.lValueCompressSize, SEEK_CUR );
// read the next header
GetEndOfLine ( id, NULL, false );
// skip past files
fseek ( id, 4, SEEK_CUR );
fseek ( id, m_SHeader2.lSize, SEEK_CUR );
// skip the icon file
if ( m_pIconFile )
{
fseek ( id, 4, SEEK_CUR );
fseek ( id, m_pIconFile->GetDataSize (), SEEK_CUR );
}
// now were in the file section
// skip past each one
for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
{
C_File *fit = node->Data();
if ( fit == file )
break;
fseek ( id, 4, SEEK_CUR );
fseek ( id, fit->GetDataSize(), SEEK_CUR );
}
// now we should be at the start of the file
// read the data into memory
if ( !file->ReadFromFile ( id, file->GetDataSize() ) )
{
fclose ( id );
return false;
}
fclose ( id );
return true;
}
bool CSpkFile::CheckValidReadmes ()
{
for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
{
C_File *file = node->Data();
if ( file->GetFileType() != FILETYPE_README )
continue;
if ( !file->CheckValidFilePointer() )
continue;
return true;
}
return false;
}
void CSpkFile::ClearWares()
{
for ( CListNode<SWares> *node = m_lWares.Front(); node; node = node->next() )
{
node->Data()->lText.clear(true);
node->DeleteData();
}
m_bChanged = true;
m_lWares.clear(true);
}
SWares *CSpkFile::FindWare ( CyString id )
{
for ( SWares *w = m_lWares.First(); w; w = m_lWares.Next() )
{
if ( w->sID.ToUpper() == id.ToUpper() )
return w;
}
return NULL;
}
void CSpkFile::RemoveWare ( CyString id )
{
for ( SWares *w = m_lWares.First(); w; w = m_lWares.Next() )
{
if ( w->sID.ToUpper() == id.ToUpper() )
{
m_lWares.RemoveCurrent ();
delete w;
m_bChanged = true;
return;
}
}
}
void CSpkFile::AddWare ( SWares *ware )
{
ware->sID.RemoveChar ( ' ' );
ware->sID = ware->sID.ToUpper();
SWares *newware = FindWare ( ware->sID );
if ( newware )
m_lWares.remove ( newware );
m_lWares.push_back ( ware );
m_bChanged = true;
}
void CSpkFile::AddWareText ( SWares *w, int lang, CyString name, CyString desc )
{
SWaresText *wt;
for ( wt = w->lText.First(); wt; wt = w->lText.Next() )
{
if ( wt->iLang == lang )
{
wt->sDesc = desc;
wt->sName = name;
return;
}
}
wt = new SWaresText;
wt->iLang = lang;
wt->sName = name;
wt->sDesc = desc;
w->lText.push_back ( wt );
m_bChanged = true;
}
void CSpkFile::ClearWareText ( CyString id )
{
SWares *w = FindWare ( id );
ClearWareText ( w );
}
void CSpkFile::ClearWareText ( SWares *w )
{
if ( !w ) return;
w->lText.clear(true);
m_bChanged = true;
}
void CSpkFile::RemoveWareText ( CyString wid, int lang )
{
SWares *w = FindWare ( wid );
if ( w )
{
for ( SWaresText *wt = w->lText.First(); wt; wt = w->lText.Next() )
{
if ( wt->iLang == lang )
{
w->lText.RemoveCurrent();
m_bChanged = true;
delete wt;
break;
}
}
}
}
int CSpkFile::CheckValidCustomStart ()
{
for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
{
C_File *file = node->Data();
if ( file->GetFileType() != FILETYPE_SCRIPT )
continue;
CyString basename = file->GetName().GetToken ( 1, file->GetName().NumToken('.') - 1, '.' );
if ( basename.ToLower().Right(15) == ".initplayership" )
return 0;
}
if ( !IsAnotherMod() )
return 1;
else
return 2;
}
bool CSpkFile::UpdateSigned (bool updateFiles)
{
// check for any custom wares
// patch mods and custom starts are also not signed
if ( (!m_lWares.empty()) || (this->IsPatch()) || (this->IsCustomStart()) )
{
m_bSigned = false;
return false;
}
return CBaseFile::UpdateSigned(updateFiles);
}
SSettingType *CSpkFile::AddSetting ( CyString key, int type )
{
key.RemoveChar ( '|' );
SSettingType *t;
for ( t = m_lSettings.First(); t; t = m_lSettings.Next() )
{
if ( t->sKey.upper() == key.lower() )
return NULL;
}
switch ( type )
{
case SETTING_STRING:
t = new SSettingString;
break;
case SETTING_INTEGER:
t = new SSettingInteger;
break;
case SETTING_CHECK:
t = new SSettingCheck;
break;
}
if ( !t )
return NULL;
t->sKey = key;
t->iType = type;
m_lSettings.push_back ( t );
m_bChanged = true;
return t;
}
void CSpkFile::ConvertSetting ( SSettingType *t, CyString set )
{
if ( !t )
return;
switch ( t->iType )
{
case SETTING_STRING:
((SSettingString *)t)->sValue = set;
break;
case SETTING_INTEGER:
((SSettingInteger *)t)->iValue = set.ToInt();
break;
case SETTING_CHECK:
((SSettingCheck *)t)->bValue = set.ToBool();
break;
}
}
CyString CSpkFile::GetSetting ( SSettingType *t )
{
if ( !t )
return "";
switch ( t->iType )
{
case SETTING_STRING:
return ((SSettingString *)t)->sValue;
case SETTING_INTEGER:
return CyString::Number(((SSettingInteger *)t)->iValue);
case SETTING_CHECK:
return (((SSettingInteger *)t)->iValue) ? "1" : "0";
}
return "";
}
void CSpkFile::ClearSettings ()
{
m_lSettings.clear(true);
m_bChanged = true;
}
bool CSpkFile::IsMatchingMod ( CyString mod )
{
for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
{
C_File *file = node->Data();
if ( file->GetFileType() != FILETYPE_MOD )
continue;
if ( file->IsFakePatch() )
continue;
CyString filename = file->GetBaseName();
if ( filename.lower() == mod.lower() )
return true;
}
return false;
}
CyString CSpkFile::GetScriptTypeString(int lang)
{
int iType = m_iScriptType;
if ( this->IsLibrary() )
return "Library";
else if ( this->IsPackageUpdate() )
return "Package Update";
else if ( this->IsCustomStart() )
return "Custom Start";
else if ( this->IsPatch() )
return "Patch";
else if ( m_iScriptType == SCRIPTTYPE_CUSTOM )
{
CyString type = this->GetCustomScriptType(lang);
if ( !type.Empty() )
return type;
iType = -1;
}
if (iType == -1) // no script type
{
if ( this->IsFakePatch() )
return "Fake Patch";
}
CyString sType = CSpkFile::GetScriptTypeStringStatic(m_iScriptType);
if ( sType.Empty() )
return "Other";
return sType;
}
int CSpkFile::ConvertScriptType(CyString sType)
{
for ( int i = 0; i < SCRIPTTYPE_MAX; i++ )
{
if ( sType.Compare(CSpkFile::GetScriptTypeStringStatic(i)) )
return i;
}
return -1;
}
CyString CSpkFile::GetScriptTypeStringStatic(int type)
{
switch ( type )
{
case SCRIPTTYPE_CUSTOM:
return "Custom";
case SCRIPTTYPE_NAVIGATION:
return "Navigation";
case SCRIPTTYPE_COMBAT:
return "Combat";
case SCRIPTTYPE_MISSION:
return "Mission";
case SCRIPTTYPE_ALPLUGIN:
return "AL Plugin";
case SCRIPTTYPE_HOTKEY:
return "Hotkey";
case SCRIPTTYPE_SHIPUPGRADE:
return "Ship Upgrade";
case SCRIPTTYPE_SHIPCOMMAND:
return "Ship Command";
case SCRIPTTYPE_STATIONCOMMAND:
return "Station Command";
case SCRIPTTYPE_FLEET:
return "Fleet Management";
case SCRIPTTYPE_TRADE:
return "Trade";
case SCRIPTTYPE_PIRACY:
return "Piracy";
case SCRIPTTYPE_CHEAT:
return "Cheat";
case SCRIPTTYPE_EXTENSION:
return "Extension Mods";
case SCRIPTTYPE_REBALANCE:
return "Rebalance";
case SCRIPTTYPE_FIX:
return "Vanilla Fix";
case SCRIPTTYPE_GENERALMOD:
return "General Mod";
case SCRIPTTYPE_TOTAL:
return "Totel Conversion";
case SCRIPTTYPE_WINGCOMMAND:
return "Wing Command";
}
return "Other";
}
bool CSpkFile::LoadPackageData(CyString first, CyString rest)
{
if ( first.Compare("ScriptType") )
{
if ( rest.Compare("Library") || rest.Compare("Library Script") )
this->SetLibrary();
else if ( rest.Compare("Update") || rest.Compare("Package Update") || rest.Compare("Mod Update") )
this->SetPackageUpdate();
else if ( rest.Compare("Start") || rest.Compare("Custom Start") )
this->SetCustomStart();
else if ( rest.Compare("Patch") || rest.Compare("Patch Mod") )
this->SetPatch();
else
{
int check = rest.ToInt();
if ( check || rest == "0" )
m_iScriptType = check;
else
{
m_iScriptType = CSpkFile::ConvertScriptType(rest);
if ( m_iScriptType == -1 )
m_sScriptType = rest;
}
}
}
else if ( first.Compare("AnotherMod") )
{
m_sOtherName = rest.GetToken("|", 1, 1);
m_sOtherAuthor = rest.GetToken("|", 2);
}
else if ( first.Compare("WareName") || first.Compare("WareDesc") )
{
// find the ware to use
SWares *useWare = m_pLastWare;
CyString id = rest.GetToken(" ", 1, 1);
for ( CListNode<SWares> *wNode = m_lWares.Front(); wNode; wNode = wNode->next() )
{
if ( wNode->Data()->sID.Compare(id) )
{
useWare = wNode->Data();
break;
}
}
// check if we have the id already
if ( useWare )
{
int lang = rest.GetToken(" ", 2, 2).ToInt();
SWaresText *wt = NULL;
for ( CListNode<SWaresText> *tNode = useWare->lText.Front(); tNode; tNode = tNode->next() )
{
if ( tNode->Data()->iLang == lang )
{
wt = tNode->Data();
break;
}
}
if ( !wt )
{
wt = new SWaresText;
wt->iLang = lang;
useWare->lText.push_back(wt);
}
if ( first.Compare("WareName") )
wt->sName = rest.GetToken(" ", 3);
else
wt->sDesc = rest.GetToken(" ", 3);
}
}
else if ( first.Left(4).Compare("Ware") )
{
SWares *ware = new SWares;
ware->iTextID = -1;
ware->iTextPage = 0;
ware->cType = first[4];
ware->iPrice = rest.GetToken ( " ", 2, 2 ).ToLong();
ware->iSize = rest.GetToken ( " ", 3, 3 ).ToInt();
ware->iVolumn = rest.GetToken ( " ", 4, 4 ).ToInt();
ware->sID = rest.GetToken ( " ", 1, 1 );
ware->iNotority = rest.GetToken ( " ", 5, 5 ).ToInt();
if ( !rest.GetToken(" ", 6, 6).Empty() )
{
ware->iTextID = rest.GetToken ( " ", 6, 6 ).GetToken(",", 2, 2).ToInt();
ware->iTextPage = rest.GetToken ( " ", 6, 6 ).GetToken(",", 1, 1).ToInt();
}
m_lWares.push_back ( ware );
m_pLastWare = ware;
}
else if ( CBaseFile::LoadPackageData(first, rest) )
return true;
else
return false;
return true;
}
bool CSpkFile::GeneratePackagerScript(bool wildcard, CyStringList *list, bool datafile)
{
if ( !CBaseFile::GeneratePackagerScript(wildcard, list, datafile) )
return false;
list->PushBack("# Script Type, the type of package file, some are special types, others are just for show");
if ( this->IsLibrary() )
list->PushBack("ScriptType: Library");
else if ( this->IsPackageUpdate() )
list->PushBack("ScriptType: Package Update");
else if ( this->IsCustomStart() )
list->PushBack("ScriptType: Custom Start");
else if ( this->IsPatch() )
list->PushBack("ScriptType: Patch");
else
list->PushBack(CyString("ScriptType: ") + this->GetScriptTypeString(44));
list->PushBack("");
if ( this->IsAnotherMod() )
{
list->PushBack("# For another mod/package, this is a child package");
list->PushBack(CyString("AnotherMod: ") + m_sOtherName + "|" + m_sOtherAuthor);
list->PushBack("");
}
if ( !m_lWares.empty() )
{
list->PushBack("# Custom Wares, Ware<type>: <id> <price> <size> <volumn> <notority>");
for ( CListNode<SWares> *node = m_lWares.Front(); node; node = node->next() )
{
SWares *w = node->Data();
if ( w->iTextID > 0 )
list->PushBack(CyString("Ware") + (char)w->cType + ": " + w->sID + " " + (long)w->iPrice + " " + (long)w->iSize + " " + (long)w->iVolumn + " " + (long)w->iNotority + " " + (long)w->iTextPage + "," + (long)w->iTextID);
else
list->PushBack(CyString("Ware") + (char)w->cType + ": " + w->sID + " " + (long)w->iPrice + " " + (long)w->iSize + " " + (long)w->iVolumn + " " + (long)w->iNotority);
for ( CListNode<SWaresText> *wNode = w->lText.Front(); wNode; wNode = wNode->next() )
{
SWaresText *wt = wNode->Data();
if ( !wt->sName.Empty() )
list->PushBack(CyString("WareName: ") + w->sID + " " + (long)wt->iLang + " " + wt->sName);
if ( !wt->sDesc.Empty() )
list->PushBack(CyString("WareDesc: ") + w->sID + " " + (long)wt->iLang + " " + wt->sDesc);
}
list->PushBack("");
}
}
if ( !datafile )
{
if ( !CBaseFile::GeneratePackagerScriptFile(wildcard, list) )
return false;
}
return true;
}
CyString CSpkFile::GetWareText(SWares *w, int lang)
{
// return the text page if being used
if ( w->iTextID > 0 && w->iTextPage > 0 )
return CyString("{") + (long)w->iTextPage + "," + (long)w->iTextID + "}";
CyString name;
for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
{
if ( wt->Data()->sName.Empty() )
continue;
if ( wt->Data()->iLang == lang )
name = wt->Data()->sName;
else if ( name.Empty() && wt->Data()->iLang == 44 )
name = wt->Data()->sName;
else if ( name.Empty() )
name = wt->Data()->sName;
}
return name;
}
CyString CSpkFile::GetWareDesc(SWares *w, int lang)
{
// return the text page if being used
if ( w->iTextID > 0 && w->iTextPage > 0 )
return CyString("{") + (long)w->iTextPage + "," + ((long)w->iTextID + 1) + "}";
CyString name;
for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
{
if ( wt->Data()->sDesc.Empty() )
continue;
if ( wt->Data()->iLang == lang )
name = wt->Data()->sDesc;
else if ( name.Empty() && wt->Data()->iLang == 44 )
name = wt->Data()->sDesc;
else if ( name.Empty() )
name = wt->Data()->sDesc;
}
return name;
}
CyString CSpkFile::GetCustomStartName()
{
if ( !this->IsCustomStart() )
return NullString;
// else find the custom start script
C_File *file = NULL;
for ( file = this->GetFirstFile(FILETYPE_SCRIPT); file; file = this->GetNextFile(file) )
{
if ( file->GetFilename().IsIn("initplayership") && file->GetFilename().GetToken(".", 1, 1).Compare("galaxy") )
break;
}
if ( !file )
return NullString;
return file->GetFilename().GetToken(".", 2, 2);
}
void CSpkFile::MergePackage(CBaseFile *base)
{
// update version information
m_sVersion = base->GetVersion();
m_sCreationDate = base->GetCreationDate();
m_iPluginType = base->GetPluginType();
// update possible changes
if ( base->GetType() == TYPE_SPK )
{
CSpkFile *spk = (CSpkFile *)base;
m_bForceProfile = spk->IsForceProfile();
// add any new wares
if ( spk->AnyWares() )
{
for ( CListNode<SWares> *node = spk->GetWaresList()->Front(); node; node = node->next() )
this->AddWare(node->Data());
spk->GetWaresList()->clear(); // remove wares so they aren't deleted
}
// add any settings
if ( spk->AnySettings() )
{
for ( CListNode<SSettingType> *node = spk->GetSettingsList()->Front(); node; node = node->next() )
this->AddSetting(node->Data()->sKey, node->Data()->iType);
}
if ( !spk->GetOtherName().Empty() )
{
m_sOtherName = spk->GetOtherName();
m_sOtherAuthor = spk->GetOtherAuthor();
}
}
// copy settings from base class
m_iGameChanging = base->GetGameChanging();
m_iRecommended = base->GetRecommended();
m_iEaseOfUse = base->GetEaseOfUse();
for ( CListNode<SGameCompat> *gNode = base->GetGameCompatabilityList()->Front(); gNode; gNode = gNode->next() ) {
if ( !gNode->Data()->sVersion.Empty() )
this->AddGameCompatability(gNode->Data()->iGame, gNode->Data()->sVersion);
else
this->AddGameCompatability(gNode->Data()->iGame, CyString::Number(gNode->Data()->iVersion));
}
if ( !base->GetWebAddress().Empty() )
m_sWebAddress = base->GetWebAddress();
if ( !base->GetWebSite().Empty() )
m_sWebSite = base->GetWebSite();
if ( !base->GetEmail().Empty() )
m_sEmail = base->GetEmail();
if ( !base->GetForumLink().Empty() )
m_sForumLink = base->GetForumLink();
m_sDescription = base->GetDescription();
// copy over needed librarys
for ( CListNode<SNeededLibrary> *lNode = base->GetNeededLibraries()->Front(); lNode; lNode = lNode->next() )
this->AddNeededLibrary(lNode->Data()->sName, lNode->Data()->sAuthor, lNode->Data()->sMinVersion);
// web mirror address, add any new ones
for ( SStringList *str = base->GetWebMirrors()->Head(); str; str = str->next )
this->AddWebMirror(str->str);
// copy over any install text
for ( CListNode<SInstallText> *iNode = base->GetInstallTextList()->Front(); iNode; iNode = iNode->next() )
{
if ( !iNode->Data()->sAfter.Empty() )
this->AddInstallAfterText(iNode->Data()->iLanguage, iNode->Data()->sAfter);
if ( !iNode->Data()->sBefore.Empty() )
this->AddInstallBeforeText(iNode->Data()->iLanguage, iNode->Data()->sBefore);
}
for ( CListNode<SInstallText> *iNode = base->GetUninstallTextList()->Front(); iNode; iNode = iNode->next() )
{
if ( !iNode->Data()->sAfter.Empty() )
this->AddUninstallAfterText(iNode->Data()->iLanguage, iNode->Data()->sAfter);
if ( !iNode->Data()->sBefore.Empty() )
this->AddUninstallBeforeText(iNode->Data()->iLanguage, iNode->Data()->sBefore);
}
// copy over package names
for ( CListNode<SNames> *nNode = base->GetNamesList()->Front(); nNode; nNode = nNode->next() )
this->AddLanguageName(nNode->Data()->iLanguage, nNode->Data()->sName);
// finally do all the files
for ( CListNode<C_File> *node = base->GetFileList()->Front(); node; node = node->next() )
{
C_File *f = node->Data();
// if it exists, remove the old
for ( CListNode<C_File> *thisNode = m_lFiles.Front(); thisNode; thisNode = thisNode->next() )
{
if ( thisNode->Data()->GetFileType() == f->GetFileType() && thisNode->Data()->GetFilename().Compare(f->GetFilename()) && thisNode->Data()->GetDir().Compare(f->GetDir()) )
{
m_lFiles.remove(thisNode);
break;
}
}
m_lFiles.push_back(f);
}
// clear the files so we dont delete them later
base->GetFileList()->clear();
}