Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ModConfig.cpp
Go to the documentation of this file.
1 /* Project Starshatter 5.0
2  Destroyer Studios LLC
3  Copyright © 1997-2007. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: ModConfig.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Mod file deployment configuration and manager
13 */
14 
15 
16 #include "MemDebug.h"
17 #include "ModConfig.h"
18 #include "ModInfo.h"
19 #include "Campaign.h"
20 #include "ShipDesign.h"
21 #include "WeaponDesign.h"
22 #include "Starshatter.h"
23 #include "ParseUtil.h"
24 #include "DataLoader.h"
25 
26 // +-------------------------------------------------------------------+
27 
28 static ModConfig* mod_config = 0;
29 
30 // +-------------------------------------------------------------------+
31 
33 {
34  mod_config = this;
35 
36  Load();
37  FindMods();
38  Deploy();
39 }
40 
42 {
43  if (mod_config == this)
44  mod_config = 0;
45 
46  Undeploy();
47 
48  enabled.destroy();
49  disabled.destroy();
50  mods.destroy();
51 }
52 
53 // +-------------------------------------------------------------------+
54 
55 void
57 {
58  mod_config = new(__FILE__,__LINE__) ModConfig;
59 }
60 
61 void
63 {
64  delete mod_config;
65  mod_config = 0;
66 }
67 
68 // +-------------------------------------------------------------------+
69 
70 ModConfig*
72 {
73  return mod_config;
74 }
75 
76 // +-------------------------------------------------------------------+
77 
78 void
80 {
81  // read the config file:
82  BYTE* block = 0;
83  int blocklen = 0;
84 
85  char filename[64];
86  strcpy_s(filename, "mod.cfg");
87 
88  FILE* f;
89  ::fopen_s(&f, filename, "rb");
90 
91  if (f) {
92  ::fseek(f, 0, SEEK_END);
93  blocklen = ftell(f);
94  ::fseek(f, 0, SEEK_SET);
95 
96  block = new(__FILE__,__LINE__) BYTE[blocklen+1];
97  block[blocklen] = 0;
98 
99  ::fread(block, blocklen, 1, f);
100  ::fclose(f);
101  }
102 
103  if (blocklen == 0)
104  return;
105 
106  Parser parser(new(__FILE__,__LINE__) BlockReader((const char*) block, blocklen));
107  Term* term = parser.ParseTerm();
108 
109  if (!term) {
110  Print("ERROR: could not parse '%s'.\n", filename);
111  return;
112  }
113  else {
114  TermText* file_type = term->isText();
115  if (!file_type || file_type->value() != "MOD_CONFIG") {
116  Print("WARNING: invalid '%s' file. No mods deployed\n", filename);
117  return;
118  }
119  }
120 
121  enabled.destroy();
122 
123  do {
124  delete term;
125 
126  term = parser.ParseTerm();
127 
128  if (term) {
129  TermDef* def = term->isDef();
130  if (def) {
131  Text name;
132  GetDefText(name, def, filename);
133  enabled.append(new(__FILE__,__LINE__) Text(name));
134  }
135  }
136  }
137  while (term);
138 
139  delete [] block;
140 }
141 
142 void
144 {
145  FILE* f;
146  fopen_s(&f, "mod.cfg", "w");
147  if (f) {
148  fprintf(f, "MOD_CONFIG\n\n");
149 
150  ListIter<Text> iter = enabled;
151  while (++iter) {
152  Text* name = iter.value();
153  fprintf(f, "mod: \"%s\"\n", name->data());
154  }
155 
156  fclose(f);
157  }
158 }
159 
160 void
162 {
163  disabled.destroy();
164 
165  DataLoader* loader = DataLoader::GetLoader();
166 
167  if (loader) {
168  loader->UseFileSystem(true);
169  loader->ListFiles("*.dat", disabled, true);
171 
172  ListIter<Text> iter = disabled;
173  while (++iter) {
174  Text* name = iter.value();
175  name->setSensitive(false);
176 
177  if (*name == "shatter.dat" ||
178  *name == "beta.dat" ||
179  *name == "start.dat" ||
180  *name == "irunin.dat" ||
181  *name == "vox.dat" ||
182  name->contains("uninstall") ||
183  enabled.contains(name))
184  delete iter.removeItem();
185  }
186  }
187 }
188 
189 // +-------------------------------------------------------------------+
190 
191 ModInfo*
193 {
194  for (int i = 0; i < mods.size(); i++) {
195  ModInfo* mod_info = mods[i];
196 
197  if (mod_info->Filename() == filename && mod_info->IsEnabled())
198  return mod_info;
199  }
200 
201  return false;
202 }
203 
204 // +-------------------------------------------------------------------+
205 
206 bool
208 {
209  for (int i = 0; i < mods.size(); i++) {
210  ModInfo* mod_info = mods[i];
211 
212  if (mod_info->Name() == name && mod_info->IsEnabled())
213  return true;
214  }
215 
216  return false;
217 }
218 
219 // +-------------------------------------------------------------------+
220 
221 void
223 {
224  Save();
225 
226  if (enabled.size() < 1)
227  return;
228 
229 #ifdef STARSHATTER_DEMO_RELEASE
230  Print("\nPACKAGED MODS ARE NOT SUPPORTED IN THIS DEMO\n");
231 #else
232  Print("\nDEPLOYING MODS\n--------------\n");
233 
234  int i = 1;
235  ListIter<Text> iter = enabled;
236  while (++iter) {
237  Text* name = iter.value();
238 
239  if (IsDeployed(name->data())) {
240  Print(" %d. %s is already deployed (skipping)\n", i++, name->data());
241  continue;
242  }
243 
244  Print(" %d. %s\n", i++, name->data());
245 
246  ModInfo* mod_info = new(__FILE__,__LINE__) ModInfo;
247 
248  if (mod_info->Load(name->data()) && mod_info->Enable()) {
249  mods.append(mod_info);
250  }
251  else {
252  Print(" Could not deploy '%s' - disabling\n", name->data());
253 
254  delete mod_info;
255  iter.removeItem();
256  disabled.append(name);
257  }
258  }
259 
260  Print("\n");
261  Game::UseLocale(0);
262 #endif
263 }
264 
265 void
267 {
268  Print("UNDEPLOYING MODS\n");
269  mods.destroy();
270 
273 }
274 
275 void
277 {
278  Undeploy();
279  Deploy();
280 
281  Campaign::Close();
283  Campaign::SelectCampaign("Single Missions");
284 }
285 
286 // +-------------------------------------------------------------------+
287 
288 void
290 {
291 #ifdef STARSHATTER_DEMO_RELEASE
292  DisableMod(name);
293 #else
294 
295  if (!name || !*name)
296  return;
297 
298  Text* mod_name;
299 
300  ListIter<Text> iter = disabled;
301  while (++iter) {
302  Text* t = iter.value();
303 
304  if (*t == name) {
305  mod_name = t;
306  iter.removeItem();
307  break;
308  }
309  }
310 
311  if (mod_name) {
312  enabled.append(mod_name);
313 
314  if (!IsDeployed(*mod_name)) {
315  ModInfo* mod_info = new(__FILE__,__LINE__) ModInfo;
316 
317  if (mod_info->Load(*mod_name) && mod_info->Enable()) {
318  mods.append(mod_info);
319  }
320  }
321  }
322 #endif
323 }
324 
325 void
327 {
328  if (!name || !*name)
329  return;
330 
331  Text* mod_name;
332 
333  ListIter<Text> iter = enabled;
334  while (++iter) {
335  Text* t = iter.value();
336 
337  if (*t == name) {
338  mod_name = t;
339  iter.removeItem();
340  break;
341  }
342  }
343 
344  if (mod_name) {
345  disabled.append(mod_name);
346 
347  ListIter<ModInfo> iter = mods;
348  while (++iter) {
349  ModInfo* mod_info = iter.value();
350  if (mod_info->Name() == *mod_name) {
351  delete iter.removeItem();
352  break;
353  }
354  }
355  }
356 }
357 
358 // +-------------------------------------------------------------------+
359 
360 void
362 {
363  if (mod_index > 0 && mod_index < enabled.size()) {
364  Text* mod1 = enabled.at(mod_index-1);
365  Text* mod2 = enabled.at(mod_index);
366 
367  enabled.at(mod_index-1) = mod2;
368  enabled.at(mod_index) = mod1;
369  }
370 }
371 
372 void
374 {
375  if (mod_index >= 0 && mod_index < enabled.size()-1) {
376  Text* mod1 = enabled.at(mod_index);
377  Text* mod2 = enabled.at(mod_index+1);
378 
379  enabled.at(mod_index) = mod2;
380  enabled.at(mod_index+1) = mod1;
381  }
382 }
383