1 /* Copyright (C) 2007 The SpringLobby Team. All rights reserved. */
2
3 #include "c_api.h"
4
5 #include <stdexcept>
6 #include <cmath>
7 #include <boost/extension/shared_library.hpp>
8 #include <boost/foreach.hpp>
9 #include <boost/filesystem.hpp>
10 #include <boost/typeof/typeof.hpp>
11
12 #include <lslutils/logging.h>
13 #include <lslutils/misc.h>
14 #include <lslutils/globalsmanager.h>
15 #include <lslutils/debug.h>
16 #include <lslutils/conversion.h>
17
18 #include "image.h"
19 #include "loader.h"
20 #include "sharedlib.h"
21
22 #define UNITSYNC_EXCEPTION(cond,msg) do { if(!(cond))\
23 LSL_THROW(unitsync,msg); } while(0)
24
25 #define CHECK_FUNCTION( arg ) \
26 do { if ( !(arg) ) LSL_THROW( function_missing, "arg" ); } while (0)
27
28 #define LOCK_UNITSYNC boost::mutex::scoped_lock lock_criticalsection(m_lock)
29
30 //! Macro that checks if a function is present/loaded, unitsync is loaded, and locks it on call.
31 #define InitLib( arg ) \
32 LOCK_UNITSYNC; \
33 UNITSYNC_EXCEPTION( m_loaded, "Unitsync function not loaded:" #arg ); \
34 CHECK_FUNCTION( arg );
35
36
37 namespace LSL {
38
UnitsyncLib()39 UnitsyncLib::UnitsyncLib():
40 m_loaded(false),
41 m_libhandle(NULL),
42 m_path(std::string()),
43 m_init(NULL),
44 m_uninit(NULL)
45 {
46 }
47
48
~UnitsyncLib()49 UnitsyncLib::~UnitsyncLib()
50 {
51 Unload();
52 }
53
Load(const std::string & path)54 void UnitsyncLib::Load( const std::string& path)
55 {
56 LOCK_UNITSYNC;
57 _Load( path );
58 _Init();
59 }
60
61
_Load(const std::string & path)62 void UnitsyncLib::_Load( const std::string& path )
63 {
64 assert(!path.empty());
65 if ( _IsLoaded() && path == m_path ) return;
66
67 _Unload();
68
69 m_path = path;
70
71 // Load the library.
72 LslDebug( "Loading from: %s", path.c_str() );
73 m_libhandle = _LoadLibrary(path);
74
75 // Load all function from library.
76 try {
77 UnitsyncFunctionLoader::Basic( this );
78 UnitsyncFunctionLoader::Map( this );
79 UnitsyncFunctionLoader::Mod( this );
80 UnitsyncFunctionLoader::Config( this );
81 UnitsyncFunctionLoader::MMOptions( this );
82 UnitsyncFunctionLoader::LuaParser( this );
83 // only when we end up here unitsync was succesfully loaded.
84 m_loaded = true;
85 }
86 catch ( std::exception& e )
87 {
88 // don't uninit unitsync in _Unload -- it hasn't been init'ed yet
89 m_uninit = NULL;
90 _Unload();
91 LSL_THROW( unitsync, e.what() );
92 }
93 }
94
_Init()95 void UnitsyncLib::_Init()
96 {
97 if ( _IsLoaded() && m_init != NULL )
98 {
99 m_current_mod = std::string();
100 m_init( true, 1 );
101 BOOST_FOREACH( const std::string error, GetUnitsyncErrors() ) {
102 LslError( "%s", error.c_str() );
103 }
104 }
105 }
106
_RemoveAllArchives()107 void UnitsyncLib::_RemoveAllArchives()
108 {
109 if (m_remove_all_archives)
110 m_remove_all_archives();
111 else
112 _Init();
113 }
114
Unload()115 void UnitsyncLib::Unload()
116 {
117 if ( !_IsLoaded() ) return;// dont even lock anything if unloaded.
118 LOCK_UNITSYNC;
119 _Unload();
120 }
121
_Unload()122 void UnitsyncLib::_Unload()
123 {
124 // as soon as we enter m_uninit unitsync technically isn't loaded anymore.
125 m_loaded = false;
126
127 m_path = std::string();
128
129 // can't call UnSetCurrentMod() because it takes the unitsync lock
130 m_current_mod = std::string();
131
132 if (m_uninit)
133 m_uninit();
134 _FreeLibrary(m_libhandle);
135 m_libhandle = NULL;
136 m_init = NULL;
137 m_uninit = NULL;
138 }
139
IsLoaded() const140 bool UnitsyncLib::IsLoaded() const
141 {
142 return m_loaded;
143 }
144
_IsLoaded() const145 bool UnitsyncLib::_IsLoaded() const
146 {
147 return m_loaded;
148 }
149
AssertUnitsyncOk() const150 void UnitsyncLib::AssertUnitsyncOk() const
151 {
152 UNITSYNC_EXCEPTION( m_loaded, "Unitsync not loaded.");
153 UNITSYNC_EXCEPTION( m_get_next_error, "Function was not in unitsync library.");
154 UNITSYNC_EXCEPTION( false, m_get_next_error() );
155 }
156
GetUnitsyncErrors() const157 std::vector<std::string> UnitsyncLib::GetUnitsyncErrors() const
158 {
159 std::vector<std::string> ret;
160 try
161 {
162 UNITSYNC_EXCEPTION( m_loaded, "Unitsync not loaded.");
163 UNITSYNC_EXCEPTION( m_get_next_error, "Function was not in unitsync library.");
164
165 const char* msg = m_get_next_error();
166 while ( msg )
167 {
168 ret.push_back( msg );
169 msg = m_get_next_error();
170 }
171 return ret;
172 }
173 catch ( std::runtime_error &e )
174 {
175 ret.push_back( e.what() );
176 return ret;
177 }
178 }
179
VersionSupports(LSL::GameFeature feature) const180 bool UnitsyncLib::VersionSupports( LSL::GameFeature feature ) const
181 {
182 LOCK_UNITSYNC;
183 switch (feature)
184 {
185 case LSL::USYNC_Sett_Handler: return m_set_spring_config_string;
186 case LSL::USYNC_GetInfoMap: return m_get_infomap_size;
187 case LSL::USYNC_GetDataDir: return m_get_writeable_data_dir;
188 case LSL::USYNC_GetSkirmishAI: return m_get_skirmish_ai_count;
189 default: return false;
190 }
191 }
192
_ConvertSpringMapInfo(const SpringMapInfo & in,MapInfo & out)193 void UnitsyncLib::_ConvertSpringMapInfo( const SpringMapInfo& in, MapInfo& out )
194 {
195 out.author = in.author;
196 out.description = in.description;
197 out.extractorRadius = in.extractorRadius;
198 out.gravity = in.gravity;
199 out.tidalStrength = in.tidalStrength;
200 out.maxMetal = in.maxMetal;
201 out.minWind = in.minWind;
202 out.maxWind = in.maxWind;
203 out.width = in.width;
204 out.height = in.height;
205 out.positions = std::vector<StartPos>( in.positions, in.positions + in.posCount );
206 }
207
SetCurrentMod(const std::string & modname)208 void UnitsyncLib::SetCurrentMod( const std::string& modname )
209 {
210 InitLib( m_init ); // assumes the others are fine
211 // (m_add_all_archives, m_get_mod_archive, m_get_mod_index)
212
213 _SetCurrentMod( modname );
214 }
215
_SetCurrentMod(const std::string & modname)216 void UnitsyncLib::_SetCurrentMod( const std::string& modname )
217 {
218 if ( m_current_mod != modname )
219 {
220 if ( !m_current_mod.empty() ) _RemoveAllArchives();
221 m_add_all_archives( m_get_mod_archive( m_get_mod_index( modname.c_str() ) ) );
222 m_current_mod = modname;
223 }
224 }
225
UnSetCurrentMod()226 void UnitsyncLib::UnSetCurrentMod( )
227 {
228 LOCK_UNITSYNC;
229 if ( !m_current_mod.empty() ) _RemoveAllArchives();
230 m_current_mod = std::string();
231 }
232
GetModIndex(const std::string & name)233 int UnitsyncLib::GetModIndex( const std::string& name )
234 {
235 return GetPrimaryModIndex( name );
236 }
237
238 #ifdef __APPLE__
239 #define LIBEXT ".dylib"
240 #elif __WIN32__
241 #define LIBEXT ".dll"
242 #else
243 #define LIBEXT ".so"
244 #endif
245
246 #ifdef __WIN32__
247 #define EXEEXT ".exe"
248 #define SEP "\\"
249 #else
250 #define SEP "/"
251 #define EXEEXT ""
252 #endif
253
GetBundleVersion(bool force)254 bool SpringBundle::GetBundleVersion(bool force)
255 {
256 if (!force && !version.empty()) //get version only once
257 return true;
258 if (!Util::FileExists(unitsync)) {
259 return false;
260 }
261 void* temphandle = _LoadLibrary(unitsync);
262 std::string functionname = "GetSpringVersion";
263 GetSpringVersionPtr getspringversion =(GetSpringVersionPtr)GetLibFuncPtr( temphandle, functionname);
264 if( !getspringversion ) {
265 _FreeLibrary(temphandle);
266 LslError("getspringversion: function not found %s", unitsync.c_str());
267 return false;
268 }
269 functionname = "IsSpringReleaseVersion";
270 IsSpringReleaseVersionPtr isspringreleaseversion =(IsSpringReleaseVersionPtr)GetLibFuncPtr( temphandle, functionname);
271
272 functionname = "GetSpringVersionPatchset";
273 GetSpringVersionPatchsetPtr getspringversionpatcheset =(GetSpringVersionPatchsetPtr)GetLibFuncPtr( temphandle, functionname);
274
275 version = getspringversion();
276 if (isspringreleaseversion && getspringversionpatcheset && isspringreleaseversion()) {
277 version += ".";
278 version += getspringversionpatcheset();
279 }
280 return !version.empty();
281 }
282
IsValid()283 bool SpringBundle::IsValid()
284 {
285 if (valid) return true; //verify only once
286 if (!Util::FileExists(path)) {
287 return false;
288 }
289 if (!Util::FileExists(spring)) {
290 return false;
291 }
292 valid = GetBundleVersion();
293 return valid;
294 }
295
AutoFindUnitsync(const std::string & unitsyncpath)296 bool SpringBundle::AutoFindUnitsync(const std::string& unitsyncpath)
297 {
298 if (!unitsync.empty() && (Util::FileExists(unitsync)))
299 return true;
300 boost::filesystem::path tmp(unitsyncpath + SEP + "unitsync" + GetLibExtension());
301 if (Util::FileExists(tmp.string())) {
302 unitsync = tmp.string();
303 return true;
304 }
305
306 tmp = unitsyncpath + SEP + "libunitsync" + GetLibExtension();
307 if (Util::FileExists(tmp.string())) {
308 unitsync = tmp.string();
309 return true;
310 }
311 return false;
312 }
313
AutoComplete(std::string searchpath)314 bool SpringBundle::AutoComplete(std::string searchpath)
315 {
316 // try to find unitsync file name from path
317 if (unitsync.empty()) {
318 if (!searchpath.empty() && (AutoFindUnitsync(searchpath))) {}
319 else if (!path.empty())
320 AutoFindUnitsync(path);
321 }
322 //try to find path from unitsync
323 if (path.empty() && !unitsync.empty()) {
324 const boost::filesystem::path tmp(unitsync);
325 if (Util::FileExists(tmp.parent_path().string()))
326 path = tmp.parent_path().string();
327 }
328 //try to find path from spring
329 if (path.empty() && !spring.empty()) {
330 const boost::filesystem::path tmp(spring);
331 if (Util::FileExists(tmp.parent_path().string()))
332 path = tmp.parent_path().string();
333 }
334 if (spring.empty()) {
335 boost::filesystem::path tmp(path);
336 tmp /= "spring" EXEEXT;
337 if (Util::FileExists(tmp.string())) {
338 spring = tmp.string();
339 } else {
340 tmp = searchpath;
341 tmp /= "spring" EXEEXT;
342 if (Util::FileExists(tmp.string())) {
343 spring = tmp.string();
344 }
345 }
346 }
347 if (version.empty()) {
348 GetBundleVersion();
349 }
350 //printf("%s %s %s %s %s\n", __FUNCTION__, searchpath.c_str(), unitsync.c_str(), spring.c_str(), version.c_str());
351 return IsValid();
352 }
353
GetLibExtension()354 std::string SpringBundle::GetLibExtension()
355 {
356 #ifdef __APPLE__
357 return std::string(".dylib");
358 #elif __WIN32__
359 return std::string(".dll");
360 #else
361 return std::string(".so");
362 #endif
363 }
364
365
GetSpringVersionList(const std::list<SpringBundle> & unitsync_paths)366 std::map<std::string, SpringBundle> UnitsyncLib::GetSpringVersionList(const std::list<SpringBundle>& unitsync_paths)
367 {
368 LOCK_UNITSYNC;
369 std::map<std::string, SpringBundle> ret;
370
371 for (const auto bundle: unitsync_paths)
372 {
373 try
374 {
375 SpringBundle tmp(bundle);
376 tmp.AutoComplete();
377 if (tmp.IsValid()) {
378 LslDebug( "Found spring version: %s %s %s", tmp.version.c_str(), tmp.spring.c_str(), tmp.unitsync.c_str());
379 ret[tmp.version] = tmp;
380 }
381 }
382 catch(...){}
383 }
384 return ret;
385 }
386
387
388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
389 // -- The UnitSync functions --
390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
391
392
GetSpringVersion()393 std::string UnitsyncLib::GetSpringVersion()
394 {
395 InitLib( m_get_spring_version );
396 std::string version = m_get_spring_version();
397 if (m_is_spring_release_version && m_get_spring_version_patchset && m_is_spring_release_version()) {
398 version += ".";
399 version += m_get_spring_version_patchset();
400 }
401 return version;
402 }
403
GetSpringDataDir()404 std::string UnitsyncLib::GetSpringDataDir()
405 {
406 InitLib( m_get_writeable_data_dir );
407 return m_get_writeable_data_dir();
408 }
409
GetSpringDataDirCount()410 int UnitsyncLib::GetSpringDataDirCount()
411 {
412 InitLib( m_get_data_dir_count);
413 return m_get_data_dir_count();
414 }
415
GetSpringDataDirByIndex(const int index)416 std::string UnitsyncLib::GetSpringDataDirByIndex( const int index )
417 {
418 InitLib( m_get_data_dir_by_index );
419 return m_get_data_dir_by_index( index );
420 }
421
GetConfigFilePath()422 std::string UnitsyncLib::GetConfigFilePath()
423 {
424 InitLib( m_get_spring_config_file_path );
425 return m_get_spring_config_file_path();
426 }
427
GetMapCount()428 int UnitsyncLib::GetMapCount()
429 {
430 InitLib( m_get_map_count );
431 return m_get_map_count();
432 }
433
GetMapChecksum(int index)434 std::string UnitsyncLib::GetMapChecksum( int index )
435 {
436 InitLib( m_get_map_checksum );
437 return Util::ToString( (unsigned int)m_get_map_checksum( index ) );
438 }
439
GetMapName(int index)440 std::string UnitsyncLib::GetMapName( int index )
441 {
442 InitLib( m_get_map_name );
443 return m_get_map_name( index );
444 }
445
GetMapArchiveCount(int index)446 int UnitsyncLib::GetMapArchiveCount( int index )
447 {
448 InitLib( m_get_map_archive_count );
449 return m_get_map_archive_count( m_get_map_name( index ) );
450 }
451
GetMapArchiveName(int arnr)452 std::string UnitsyncLib::GetMapArchiveName( int arnr )
453 {
454 InitLib( m_get_map_archive_name );
455 return m_get_map_archive_name( arnr );
456 }
457
GetMapDeps(int index)458 UnitsyncLib::StringVector UnitsyncLib::GetMapDeps( int index )
459 {
460 int count = GetMapArchiveCount( index );
461 StringVector ret;
462 for ( int i = 0; i < count; i++ )
463 {
464 ret.push_back( GetMapArchiveName( i ) );
465 }
466 return ret;
467 }
468
GetMapInfoEx(int index,int version)469 MapInfo UnitsyncLib::GetMapInfoEx( int index, int version )
470 {
471 if (m_get_map_description == NULL) {
472 // old fetch method
473 InitLib( m_get_map_info_ex );
474
475 const std::string& mapName = m_get_map_name( index );
476
477 char tmpdesc[256];
478 char tmpauth[256];
479
480 MapInfo info;
481 SpringMapInfo tm;
482 tm.description = &tmpdesc[0];
483 tm.author = &tmpauth[0];
484
485 bool result = m_get_map_info_ex( mapName.c_str(), &tm, version );
486 if (!result)
487 LSL_THROW( unitsync, "Failed to get map infos");
488 _ConvertSpringMapInfo( tm, info );
489 return info;
490 } else {
491 // new fetch method
492 InitLib( m_get_map_description )
493
494 MapInfo info;
495 const char* desc = m_get_map_description( index);
496 if (desc == NULL)
497 info.description="";
498 else
499 info.description = desc;
500 info.tidalStrength = m_get_map_tidalStrength(index);
501 info.gravity = m_get_map_gravity(index);
502
503 const int resCount = m_get_map_resource_count(index);
504 if (resCount > 0) {
505 const int resourceIndex = 0;
506 info.maxMetal = m_get_map_resource_max(index, resourceIndex);
507 info.extractorRadius = m_get_map_resource_extractorRadius(index, resourceIndex);
508 } else {
509 info.maxMetal = 0.0f;
510 info.extractorRadius = 0.0f;
511 }
512
513 info.minWind = m_get_map_windMin(index);
514 info.maxWind = m_get_map_windMax(index);
515
516 info.width = m_get_map_width(index);
517 info.height = m_get_map_height(index);
518 const int posCount = m_get_map_pos_count(index);
519 for (int p = 0; p < posCount; ++p) {
520 StartPos sp;
521 sp.x = m_get_map_pos_x(index, p);
522 sp.y = m_get_map_pos_z(index, p);
523 info.positions.push_back(sp);
524 }
525 const char* author = m_get_map_author(index);
526 if (author == NULL)
527 info.author = "";
528 else
529 info.author = m_get_map_author(index);
530 return info;
531 }
532 }
533
GetMinimap(const std::string & mapFileName)534 UnitsyncImage UnitsyncLib::GetMinimap( const std::string& mapFileName )
535 {
536 InitLib( m_get_minimap );
537 const int miplevel = 1; // miplevel should not be 10 ffs
538 const int width = 1024 >> miplevel;
539 const int height = 1024 >> miplevel;
540 // this unitsync call returns a pointer to a static buffer
541 unsigned short* colors = (unsigned short*)m_get_minimap( mapFileName.c_str(), miplevel );
542 if (!colors)
543 LSL_THROW( unitsync, "Get minimap failed");
544 UnitsyncImage img = UnitsyncImage::FromMinimapData( colors, width, height );
545 img.RescaleIfBigger();
546 return img;
547 }
548
GetMetalmap(const std::string & mapFileName)549 UnitsyncImage UnitsyncLib::GetMetalmap( const std::string& mapFileName )
550 {
551 InitLib( m_get_infomap_size ); // assume GetInfoMap is available too
552 int width = 0, height = 0, retval;
553 retval = m_get_infomap_size(mapFileName.c_str(), "metal", &width, &height);
554 if ( !(retval != 0 && width * height != 0) )
555 LSL_THROW( unitsync, "Get metalmap size failed");
556 Util::uninitialized_array<unsigned char> grayscale(width * height);
557 retval = m_get_infomap(mapFileName.c_str(), "metal", grayscale, 1 /*byte per pixel*/);
558 if ( retval == 0 )
559 LSL_THROW( unitsync, "Get metalmap failed");
560 UnitsyncImage img = UnitsyncImage::FromMetalmapData(grayscale, width, height);
561 img.RescaleIfBigger();
562 return img;
563 }
564
GetHeightmap(const std::string & mapFileName)565 UnitsyncImage UnitsyncLib::GetHeightmap( const std::string& mapFileName )
566 {
567 InitLib( m_get_infomap_size ); // assume GetInfoMap is available too
568 int width = 0, height = 0, retval;
569 retval = m_get_infomap_size(mapFileName.c_str(), "height", &width, &height);
570 if ( !(retval != 0 && width * height != 0) )
571 LSL_THROW( unitsync, "Get heightmap size failed");
572 Util::uninitialized_array<unsigned short> grayscale(width * height);
573 retval = m_get_infomap(mapFileName.c_str(), "height", grayscale, 2 /*byte per pixel*/);
574 if ( retval == 0 )
575 LSL_THROW( unitsync, "Get heightmap failed");
576 UnitsyncImage img = UnitsyncImage::FromHeightmapData( grayscale, width, height );
577 img.RescaleIfBigger();
578 return img;
579 }
580
GetPrimaryModChecksum(int index)581 std::string UnitsyncLib::GetPrimaryModChecksum( int index )
582 {
583 InitLib( m_get_mod_checksum );
584 return Util::ToString( (unsigned int)m_get_mod_checksum( index ) );
585 }
586
GetPrimaryModIndex(const std::string & modName)587 int UnitsyncLib::GetPrimaryModIndex( const std::string& modName )
588 {
589 InitLib( m_get_mod_index );
590 return m_get_mod_index( modName.c_str() );
591 }
592
GetPrimaryModName(int index)593 std::string UnitsyncLib::GetPrimaryModName( int index )
594 {
595 InitLib( m_get_mod_name );
596 return m_get_mod_name( index );
597 }
598
GetPrimaryModCount()599 int UnitsyncLib::GetPrimaryModCount()
600 {
601 InitLib( m_get_mod_count );
602 return m_get_mod_count();
603 }
604
GetPrimaryModArchive(int index)605 std::string UnitsyncLib::GetPrimaryModArchive( int index )
606 {
607 InitLib( m_get_mod_archive );
608 if (!m_get_mod_count)
609 LSL_THROW( unitsync, "Function was not in unitsync library.");
610 int count = m_get_mod_count();
611 if (index >= count)
612 LSL_THROW( unitsync, "index out of bounds");
613 return m_get_mod_archive( index );
614 }
615
GetPrimaryModShortName(int index)616 std::string UnitsyncLib::GetPrimaryModShortName( int index )
617 {
618 InitLib( m_get_primary_mod_short_name );
619 return m_get_primary_mod_short_name( index );
620 }
621
GetPrimaryModVersion(int index)622 std::string UnitsyncLib::GetPrimaryModVersion( int index )
623 {
624 InitLib( m_get_primary_mod_version );
625 return m_get_primary_mod_version( index );
626 }
627
GetPrimaryModMutator(int index)628 std::string UnitsyncLib::GetPrimaryModMutator( int index )
629 {
630 InitLib( m_get_primary_mod_mutator );
631 return m_get_primary_mod_mutator( index );
632 }
633
GetPrimaryModGame(int index)634 std::string UnitsyncLib::GetPrimaryModGame( int index )
635 {
636 InitLib( m_get_primary_mod_game );
637 return m_get_primary_mod_game( index );
638 }
639
GetPrimaryModShortGame(int index)640 std::string UnitsyncLib::GetPrimaryModShortGame( int index )
641 {
642 InitLib( m_get_primary_mod_short_game );
643 return m_get_primary_mod_short_game( index );
644 }
645
GetPrimaryModDescription(int index)646 std::string UnitsyncLib::GetPrimaryModDescription( int index )
647 {
648 InitLib( m_get_primary_mod_description );
649 return m_get_primary_mod_description( index );
650 }
651
GetPrimaryModArchiveCount(int index)652 int UnitsyncLib::GetPrimaryModArchiveCount( int index )
653 {
654 InitLib( m_get_primary_mod_archive_count );
655 return m_get_primary_mod_archive_count( index );
656 }
657
GetPrimaryModArchiveList(int arnr)658 std::string UnitsyncLib::GetPrimaryModArchiveList( int arnr )
659 {
660 InitLib( m_get_primary_mod_archive_list );
661 return m_get_primary_mod_archive_list( arnr );
662 }
663
GetPrimaryModChecksumFromName(const std::string & name)664 std::string UnitsyncLib::GetPrimaryModChecksumFromName( const std::string& name )
665 {
666 InitLib( m_get_primary_mod_checksum_from_name );
667 return Util::ToString( (unsigned int)m_get_primary_mod_checksum_from_name( name.c_str() ) );
668 }
669
GetModDeps(int index)670 UnitsyncLib::StringVector UnitsyncLib::GetModDeps( int index )
671 {
672 int count = GetPrimaryModArchiveCount( index );
673 StringVector ret;
674 for ( int i = 0; i < count; i++ )
675 ret.push_back( GetPrimaryModArchiveList( i ) );
676 return ret;
677 }
678
GetSides(const std::string & modName)679 UnitsyncLib::StringVector UnitsyncLib::GetSides( const std::string& modName )
680 {
681 InitLib( m_get_side_count );
682 if (!m_get_side_name)
683 LSL_THROW( function_missing, "m_get_side_name");
684 _SetCurrentMod( modName );
685 int count = m_get_side_count();
686 StringVector ret;
687 for ( int i = 0; i < count; i ++ )
688 ret.push_back( m_get_side_name( i ) );
689 return ret;
690 }
691
AddAllArchives(const std::string & root)692 void UnitsyncLib::AddAllArchives( const std::string& root )
693 {
694 InitLib( m_add_all_archives );
695 m_add_all_archives( root.c_str() );
696 }
697
AddArchive(const std::string & name)698 void UnitsyncLib::AddArchive(const std::string &name)
699 {
700 InitLib( m_add_archive);
701 m_add_archive(name.c_str());
702 }
703
GetFullUnitName(int index)704 std::string UnitsyncLib::GetFullUnitName( int index )
705 {
706 InitLib( m_get_unit_full_name );
707 return m_get_unit_full_name( index );
708 }
709
GetUnitName(int index)710 std::string UnitsyncLib::GetUnitName( int index )
711 {
712 InitLib( m_get_unit_name );
713 return m_get_unit_name( index );
714 }
715
GetUnitCount()716 int UnitsyncLib::GetUnitCount()
717 {
718 InitLib( m_get_unit_count );
719 return m_get_unit_count();
720 }
721
ProcessUnitsNoChecksum()722 int UnitsyncLib::ProcessUnitsNoChecksum()
723 {
724 InitLib( m_proc_units_nocheck );
725 return m_proc_units_nocheck();
726 }
727
FindFilesVFS(const std::string & name)728 UnitsyncLib::StringVector UnitsyncLib::FindFilesVFS( const std::string& name )
729 {
730 InitLib( m_find_files_vfs );
731 CHECK_FUNCTION( m_init_find_vfs );
732 int handle = m_init_find_vfs( name.c_str() );
733 StringVector ret;
734 //thanks to assbars awesome edit we now get different invalid values from init and find
735 if ( handle != -1 ) {
736 do
737 {
738 char buffer[1025];
739 handle = m_find_files_vfs( handle, &buffer[0], 1024 );
740 buffer[1024] = 0;
741 ret.push_back( &buffer[0] );
742 }while ( handle );
743 }
744 return ret;
745 }
746
OpenFileVFS(const std::string & name)747 int UnitsyncLib::OpenFileVFS( const std::string& name )
748 {
749 InitLib( m_open_file_vfs );
750 return m_open_file_vfs( name.c_str() );
751 }
752
FileSizeVFS(int handle)753 int UnitsyncLib::FileSizeVFS( int handle )
754 {
755 InitLib( m_file_size_vfs );
756 return m_file_size_vfs( handle );
757 }
758
ReadFileVFS(int handle,void * buffer,int bufferLength)759 int UnitsyncLib::ReadFileVFS( int handle, void* buffer, int bufferLength )
760 {
761 InitLib( m_read_file_vfs );
762 return m_read_file_vfs( handle, buffer, bufferLength );
763 }
764
CloseFileVFS(int handle)765 void UnitsyncLib::CloseFileVFS( int handle )
766 {
767 InitLib( m_close_file_vfs );
768 m_close_file_vfs( handle );
769 }
770
GetValidMapCount(const std::string & modname)771 unsigned int UnitsyncLib::GetValidMapCount( const std::string& modname )
772 {
773 InitLib( m_get_mod_valid_map_count );
774 _SetCurrentMod( modname );
775 return m_get_mod_valid_map_count();
776 }
777
GetValidMapName(unsigned int MapIndex)778 std::string UnitsyncLib::GetValidMapName( unsigned int MapIndex )
779 {
780 InitLib( m_get_valid_map );
781 return m_get_valid_map( MapIndex );
782 }
783
GetMapOptionCount(const std::string & name)784 int UnitsyncLib::GetMapOptionCount( const std::string& name )
785 {
786 InitLib( m_get_map_option_count );
787 if (name.empty())
788 LSL_THROW( unitsync, "tried to pass empty mapname to unitsync");
789 return m_get_map_option_count( name.c_str() );
790 }
791
GetCustomOptionCount(const std::string & archive_name,const std::string & filename)792 int UnitsyncLib::GetCustomOptionCount( const std::string& archive_name, const std::string& filename )
793 {
794 InitLib( m_get_custom_option_count );
795 if (archive_name.empty())
796 LSL_THROW( unitsync, "tried to pass empty archive_name to unitsync");
797 _RemoveAllArchives();
798 m_add_all_archives( archive_name.c_str() );
799 return m_get_custom_option_count( filename.c_str() );
800 }
801
GetModOptionCount(const std::string & name)802 int UnitsyncLib::GetModOptionCount( const std::string& name )
803 {
804 InitLib( m_get_mod_option_count );
805 if (name.empty())
806 LSL_THROW( unitsync, "tried to pass empty modname to unitsync");
807 _SetCurrentMod( name );
808 return m_get_mod_option_count();
809 }
810
GetAIOptionCount(const std::string & modname,int aiIndex)811 int UnitsyncLib::GetAIOptionCount( const std::string& modname, int aiIndex )
812 {
813 InitLib( m_get_skirmish_ai_option_count );
814 _SetCurrentMod( modname );
815 CHECK_FUNCTION( m_get_skirmish_ai_count );
816 if ( !(( aiIndex >= 0 ) && ( aiIndex < m_get_skirmish_ai_count() )) )
817 LSL_THROW( unitsync, "aiIndex out of bounds");
818 return m_get_skirmish_ai_option_count( aiIndex );
819 }
820
GetOptionKey(int optIndex)821 std::string UnitsyncLib::GetOptionKey( int optIndex )
822 {
823 InitLib( m_get_option_key );
824 return m_get_option_key( optIndex );
825 }
826
GetOptionName(int optIndex)827 std::string UnitsyncLib::GetOptionName( int optIndex )
828 {
829 InitLib( m_get_option_name );
830 return m_get_option_name( optIndex );
831 }
832
GetOptionDesc(int optIndex)833 std::string UnitsyncLib::GetOptionDesc( int optIndex )
834 {
835 InitLib( m_get_option_desc );
836 return m_get_option_desc( optIndex );
837 }
838
GetOptionSection(int optIndex)839 std::string UnitsyncLib::GetOptionSection( int optIndex )
840 {
841 InitLib( m_get_option_section );
842 return m_get_option_section( optIndex );
843 }
844
GetOptionStyle(int optIndex)845 std::string UnitsyncLib::GetOptionStyle( int optIndex )
846 {
847 InitLib( m_get_option_style );
848 return m_get_option_style( optIndex );
849 }
850
GetOptionType(int optIndex)851 int UnitsyncLib::GetOptionType( int optIndex )
852 {
853 InitLib( m_get_option_type );
854 return m_get_option_type( optIndex );
855 }
856
GetOptionBoolDef(int optIndex)857 int UnitsyncLib::GetOptionBoolDef( int optIndex )
858 {
859 InitLib( m_get_option_bool_def );
860 return m_get_option_bool_def( optIndex );
861 }
862
GetOptionNumberDef(int optIndex)863 float UnitsyncLib::GetOptionNumberDef( int optIndex )
864 {
865 InitLib( m_get_option_number_def );
866 return m_get_option_number_def( optIndex );
867 }
868
GetOptionNumberMin(int optIndex)869 float UnitsyncLib::GetOptionNumberMin( int optIndex )
870 {
871 InitLib( m_get_option_number_min );
872 return m_get_option_number_min( optIndex );
873 }
874
GetOptionNumberMax(int optIndex)875 float UnitsyncLib::GetOptionNumberMax( int optIndex )
876 {
877 InitLib( m_get_option_number_max );
878 return m_get_option_number_max( optIndex );
879 }
880
GetOptionNumberStep(int optIndex)881 float UnitsyncLib::GetOptionNumberStep( int optIndex )
882 {
883 InitLib( m_get_option_number_step );
884 return m_get_option_number_step( optIndex );
885 }
886
GetOptionStringDef(int optIndex)887 std::string UnitsyncLib::GetOptionStringDef( int optIndex )
888 {
889 InitLib( m_get_option_string_def );
890 return m_get_option_string_def( optIndex );
891 }
892
GetOptionStringMaxLen(int optIndex)893 int UnitsyncLib::GetOptionStringMaxLen( int optIndex )
894 {
895 InitLib( m_get_option_string_max_len );
896 return m_get_option_string_max_len( optIndex );
897 }
898
GetOptionListCount(int optIndex)899 int UnitsyncLib::GetOptionListCount( int optIndex )
900 {
901 InitLib( m_get_option_list_count );
902 return m_get_option_list_count( optIndex );
903 }
904
GetOptionListDef(int optIndex)905 std::string UnitsyncLib::GetOptionListDef( int optIndex )
906 {
907 InitLib( m_get_option_list_def );
908 return m_get_option_list_def( optIndex );
909 }
910
GetOptionListItemKey(int optIndex,int itemIndex)911 std::string UnitsyncLib::GetOptionListItemKey( int optIndex, int itemIndex )
912 {
913 InitLib( m_get_option_list_item_key );
914 return m_get_option_list_item_key( optIndex, itemIndex );
915 }
916
GetOptionListItemName(int optIndex,int itemIndex)917 std::string UnitsyncLib::GetOptionListItemName( int optIndex, int itemIndex )
918 {
919 InitLib( m_get_option_list_item_name );
920 return m_get_option_list_item_name( optIndex, itemIndex );
921 }
922
GetOptionListItemDesc(int optIndex,int itemIndex)923 std::string UnitsyncLib::GetOptionListItemDesc( int optIndex, int itemIndex )
924 {
925 InitLib( m_get_option_list_item_desc );
926 return m_get_option_list_item_desc( optIndex, itemIndex );
927 }
928
OpenArchive(const std::string & name)929 int UnitsyncLib::OpenArchive( const std::string& name )
930 {
931 InitLib( m_open_archive );
932 return m_open_archive( name.c_str() );
933 }
934
CloseArchive(int archive)935 void UnitsyncLib::CloseArchive( int archive )
936 {
937 InitLib( m_close_archive );
938 m_close_archive( archive );
939 }
940
FindFilesArchive(int archive,int cur,std::string & nameBuf)941 int UnitsyncLib::FindFilesArchive( int archive, int cur, std::string& nameBuf )
942 {
943 InitLib( m_find_Files_archive );
944 char buffer[1025];
945 int size = 1024;
946 bool ret = m_find_Files_archive( archive, cur, &buffer[0], &size );
947 buffer[1024] = 0;
948 nameBuf = &buffer[0];
949 return ret;
950 }
951
OpenArchiveFile(int archive,const std::string & name)952 int UnitsyncLib::OpenArchiveFile( int archive, const std::string& name )
953 {
954 InitLib( m_open_archive_file );
955 return m_open_archive_file( archive, name.c_str() );
956 }
957
ReadArchiveFile(int archive,int handle,void * buffer,int numBytes)958 int UnitsyncLib::ReadArchiveFile( int archive, int handle, void* buffer, int numBytes)
959 {
960 InitLib( m_read_archive_file );
961 return m_read_archive_file( archive, handle, buffer, numBytes );
962 }
963
CloseArchiveFile(int archive,int handle)964 void UnitsyncLib::CloseArchiveFile( int archive, int handle )
965 {
966 InitLib( m_close_archive_file );
967 m_close_archive_file( archive, handle );
968 }
969
SizeArchiveFile(int archive,int handle)970 int UnitsyncLib::SizeArchiveFile( int archive, int handle )
971 {
972 InitLib( m_size_archive_file );
973 return m_size_archive_file( archive, handle );
974 }
975
GetArchivePath(const std::string & name)976 std::string UnitsyncLib::GetArchivePath( const std::string& name )
977 {
978 InitLib( m_get_archive_path );
979 return m_get_archive_path( name.c_str() );
980 }
981
GetSpringConfigInt(const std::string & key,int defValue)982 int UnitsyncLib::GetSpringConfigInt( const std::string& key, int defValue )
983 {
984 InitLib( m_get_spring_config_int );
985 return m_get_spring_config_int( key.c_str(), defValue );
986 }
987
GetSpringConfigString(const std::string & key,const std::string & defValue)988 std::string UnitsyncLib::GetSpringConfigString( const std::string& key, const std::string& defValue )
989 {
990 InitLib( m_get_spring_config_string );
991 return m_get_spring_config_string( key.c_str(), defValue.c_str() );
992 }
993
GetSpringConfigFloat(const std::string & key,const float defValue)994 float UnitsyncLib::GetSpringConfigFloat( const std::string& key, const float defValue )
995 {
996 InitLib( m_get_spring_config_float );
997 return m_get_spring_config_float( key.c_str(), defValue );
998 }
999
SetSpringConfigString(const std::string & key,const std::string & value)1000 void UnitsyncLib::SetSpringConfigString( const std::string& key, const std::string& value )
1001 {
1002 InitLib( m_set_spring_config_string );
1003 m_set_spring_config_string( key.c_str(), value.c_str() );
1004 }
1005
SetSpringConfigInt(const std::string & key,int value)1006 void UnitsyncLib::SetSpringConfigInt( const std::string& key, int value )
1007 {
1008 InitLib( m_set_spring_config_int );
1009 m_set_spring_config_int( key.c_str(), value );
1010 }
1011
1012
SetSpringConfigFloat(const std::string & key,const float value)1013 void UnitsyncLib::SetSpringConfigFloat( const std::string& key, const float value )
1014 {
1015 InitLib( m_set_spring_config_float );
1016
1017 m_set_spring_config_float( key.c_str(), value );
1018 }
1019
GetSkirmishAICount(const std::string & modname)1020 int UnitsyncLib::GetSkirmishAICount( const std::string& modname )
1021 {
1022 InitLib( m_get_skirmish_ai_count );
1023 _SetCurrentMod( modname );
1024 return m_get_skirmish_ai_count();
1025 }
1026
GetAIInfo(int aiIndex)1027 UnitsyncLib::StringVector UnitsyncLib::GetAIInfo( int aiIndex )
1028 {
1029 InitLib( m_get_skirmish_ai_count );
1030 CHECK_FUNCTION( m_get_skirmish_ai_info_count );
1031 CHECK_FUNCTION( m_get_skirmish_ai_info_description );
1032 CHECK_FUNCTION( m_get_skirmish_ai_info_key );
1033 CHECK_FUNCTION( m_get_skirmish_ai_info_value );
1034
1035 StringVector ret;
1036 if ( !(( aiIndex >= 0 ) && ( aiIndex < m_get_skirmish_ai_count() )) )
1037 LSL_THROW( unitsync, "aiIndex out of bounds");
1038
1039 int infoCount = m_get_skirmish_ai_info_count( aiIndex );
1040 for( int i = 0; i < infoCount; i++ )
1041 {
1042 ret.push_back( m_get_skirmish_ai_info_key( i ) );
1043 ret.push_back( m_get_skirmish_ai_info_value( i ) );
1044 ret.push_back( m_get_skirmish_ai_info_description( i ) );
1045 }
1046 return ret;
1047 }
1048
GetArchiveChecksum(const std::string & VFSPath)1049 std::string UnitsyncLib::GetArchiveChecksum( const std::string& VFSPath )
1050 {
1051 InitLib( m_get_archive_checksum );
1052 return Util::ToString( m_get_archive_checksum( VFSPath.c_str() ) );
1053 }
1054
1055 /// lua parser
1056
CloseParser()1057 void UnitsyncLib::CloseParser()
1058 {
1059 InitLib( m_parser_close );
1060 m_parser_close();
1061 }
1062
OpenParserFile(const std::string & filename,const std::string & filemodes,const std::string & accessModes)1063 bool UnitsyncLib::OpenParserFile( const std::string& filename, const std::string& filemodes, const std::string& accessModes )
1064 {
1065 InitLib( m_parser_open_file );
1066 return m_parser_open_file( filename.c_str(), filemodes.c_str(), accessModes.c_str() );
1067 }
1068
OpenParserSource(const std::string & source,const std::string & accessModes)1069 bool UnitsyncLib::OpenParserSource( const std::string& source, const std::string& accessModes )
1070 {
1071 InitLib( m_parser_open_source );
1072 return m_parser_open_source( source.c_str(), accessModes.c_str() );
1073 }
1074
ParserExecute()1075 bool UnitsyncLib::ParserExecute()
1076 {
1077 InitLib( m_parser_execute );
1078 return m_parser_execute();
1079 }
1080
ParserErrorLog()1081 std::string UnitsyncLib::ParserErrorLog()
1082 {
1083 InitLib( m_parser_error_log );
1084 return m_parser_error_log();
1085 }
1086
ParserAddTable(int key,bool override)1087 void UnitsyncLib::ParserAddTable( int key, bool override )
1088 {
1089 InitLib( m_parser_add_table_int );
1090 m_parser_add_table_int( key, override );
1091 }
1092
ParserAddTable(const std::string & key,bool override)1093 void UnitsyncLib::ParserAddTable( const std::string& key, bool override )
1094 {
1095 InitLib( m_parser_add_table_string );
1096 m_parser_add_table_string( key.c_str(), override );
1097 }
1098
ParserEndTable()1099 void UnitsyncLib::ParserEndTable()
1100 {
1101 InitLib( m_parser_end_table );
1102 m_parser_end_table();
1103 }
1104
ParserAddTableValue(int key,int val)1105 void UnitsyncLib::ParserAddTableValue( int key, int val )
1106 {
1107 InitLib( m_parser_add_int_key_int_value );
1108 m_parser_add_int_key_int_value( key, val );
1109 }
1110
ParserAddTableValue(const std::string & key,int val)1111 void UnitsyncLib::ParserAddTableValue( const std::string& key, int val )
1112 {
1113 InitLib( m_parser_add_string_key_int_value );
1114 m_parser_add_string_key_int_value( key.c_str(), val );
1115 }
1116
ParserAddTableValue(int key,bool val)1117 void UnitsyncLib::ParserAddTableValue( int key, bool val )
1118 {
1119 InitLib( m_parser_add_int_key_int_value );
1120 m_parser_add_int_key_int_value( key, val );
1121 }
1122
ParserAddTableValue(const std::string & key,bool val)1123 void UnitsyncLib::ParserAddTableValue( const std::string& key, bool val )
1124 {
1125 InitLib( m_parser_add_string_key_int_value );
1126 m_parser_add_string_key_int_value( key.c_str(), val );
1127 }
1128
ParserAddTableValue(int key,const std::string & val)1129 void UnitsyncLib::ParserAddTableValue( int key, const std::string& val )
1130 {
1131 InitLib( m_parser_add_int_key_string_value );
1132 m_parser_add_int_key_string_value( key, val.c_str() );
1133 }
1134
ParserAddTableValue(const std::string & key,const std::string & val)1135 void UnitsyncLib::ParserAddTableValue( const std::string& key, const std::string& val )
1136 {
1137 InitLib( m_parser_add_string_key_string_value );
1138 m_parser_add_string_key_string_value( key.c_str(), val.c_str() );
1139 }
1140
ParserAddTableValue(int key,float val)1141 void UnitsyncLib::ParserAddTableValue( int key, float val )
1142 {
1143 InitLib( m_parser_add_int_key_float_value );
1144 m_parser_add_int_key_float_value( key, val );
1145 }
1146
ParserAddTableValue(const std::string & key,float val)1147 void UnitsyncLib::ParserAddTableValue( const std::string& key, float val )
1148 {
1149 InitLib( m_parser_add_string_key_float_value );
1150 m_parser_add_string_key_float_value( key.c_str(), val );
1151 }
1152
ParserGetRootTable()1153 bool UnitsyncLib::ParserGetRootTable()
1154 {
1155 InitLib( m_parser_root_table );
1156 return m_parser_root_table();
1157 }
1158
ParserGetRootTableExpression(const std::string & exp)1159 bool UnitsyncLib::ParserGetRootTableExpression( const std::string& exp )
1160 {
1161 InitLib( m_parser_root_table_expression );
1162 return m_parser_root_table_expression( exp.c_str() );
1163 }
1164
ParserGetSubTableInt(int key)1165 bool UnitsyncLib::ParserGetSubTableInt( int key )
1166 {
1167 InitLib( m_parser_sub_table_int );
1168 return m_parser_sub_table_int( key );
1169 }
1170
ParserGetSubTableString(const std::string & key)1171 bool UnitsyncLib::ParserGetSubTableString( const std::string& key )
1172 {
1173 InitLib( m_parser_sub_table_string );
1174 return m_parser_sub_table_string( key.c_str() );
1175 }
1176
ParserGetSubTableInt(const std::string & exp)1177 bool UnitsyncLib::ParserGetSubTableInt( const std::string& exp )
1178 {
1179 InitLib( m_parser_sub_table_expression );
1180 return m_parser_sub_table_expression( exp.c_str() );
1181 }
1182
ParserPopTable()1183 void UnitsyncLib::ParserPopTable()
1184 {
1185 InitLib( m_parser_pop_table );
1186 m_parser_pop_table();
1187 }
1188
ParserKeyExists(int key)1189 bool UnitsyncLib::ParserKeyExists( int key )
1190 {
1191 InitLib( m_parser_key_int_exists );
1192 return m_parser_key_int_exists( key );
1193 }
1194
ParserKeyExists(const std::string & key)1195 bool UnitsyncLib::ParserKeyExists( const std::string& key )
1196 {
1197 InitLib( m_parser_key_string_exists );
1198 return m_parser_key_string_exists( key.c_str() );
1199 }
1200
ParserGetKeyType(int key)1201 int UnitsyncLib::ParserGetKeyType( int key )
1202 {
1203 InitLib( m_parser_int_key_get_type );
1204 return m_parser_int_key_get_type( key );
1205 }
1206
ParserGetKeyType(const std::string & key)1207 int UnitsyncLib::ParserGetKeyType( const std::string& key )
1208 {
1209 InitLib( m_parser_string_key_get_type );
1210 return m_parser_string_key_get_type( key.c_str() );
1211 }
1212
ParserGetIntKeyListCount()1213 int UnitsyncLib::ParserGetIntKeyListCount()
1214 {
1215 InitLib( m_parser_int_key_get_list_count );
1216 return m_parser_int_key_get_list_count();
1217 }
1218
ParserGetIntKeyListEntry(int index)1219 int UnitsyncLib::ParserGetIntKeyListEntry( int index )
1220 {
1221 InitLib( m_parser_int_key_get_list_entry );
1222 return m_parser_int_key_get_list_entry( index );
1223 }
1224
ParserGetStringKeyListCount()1225 int UnitsyncLib::ParserGetStringKeyListCount()
1226 {
1227 InitLib( m_parser_string_key_get_list_count );
1228 return m_parser_string_key_get_list_count();
1229 }
1230
ParserGetStringKeyListEntry(int index)1231 int UnitsyncLib::ParserGetStringKeyListEntry( int index )
1232 {
1233 InitLib( m_parser_int_key_get_list_entry );
1234 return m_parser_int_key_get_list_entry( index );
1235 }
1236
GetKeyValue(int key,int defval)1237 int UnitsyncLib::GetKeyValue( int key, int defval )
1238 {
1239 InitLib( m_parser_int_key_get_int_value );
1240 return m_parser_int_key_get_int_value( key, defval );
1241 }
1242
GetKeyValue(int key,bool defval)1243 bool UnitsyncLib::GetKeyValue( int key, bool defval )
1244 {
1245 InitLib( m_parser_int_key_get_bool_value );
1246 return m_parser_int_key_get_bool_value( key, defval );
1247 }
1248
GetKeyValue(int key,const std::string & defval)1249 std::string UnitsyncLib::GetKeyValue( int key, const std::string& defval )
1250 {
1251 InitLib( m_parser_int_key_get_string_value );
1252 return m_parser_int_key_get_string_value( key, defval.c_str() );
1253 }
1254
GetKeyValue(int key,float defval)1255 float UnitsyncLib::GetKeyValue( int key, float defval )
1256 {
1257 InitLib( m_parser_int_key_get_float_value );
1258 return m_parser_int_key_get_float_value( key, defval );
1259 }
1260
GetKeyValue(const std::string & key,int defval)1261 int UnitsyncLib::GetKeyValue( const std::string& key, int defval )
1262 {
1263 InitLib( m_parser_string_key_get_int_value );
1264 return m_parser_string_key_get_int_value( key.c_str(), defval );
1265 }
1266
GetKeyValue(const std::string & key,bool defval)1267 bool UnitsyncLib::GetKeyValue( const std::string& key, bool defval )
1268 {
1269 InitLib( m_parser_string_key_get_bool_value );
1270 return m_parser_string_key_get_bool_value( key.c_str(), defval );
1271 }
1272
GetKeyValue(const std::string & key,const std::string & defval)1273 std::string UnitsyncLib::GetKeyValue( const std::string& key, const std::string& defval )
1274 {
1275 InitLib( m_parser_string_key_get_string_value );
1276 return m_parser_string_key_get_string_value( key.c_str(), defval.c_str() );
1277 }
1278
GetKeyValue(const std::string & key,float defval)1279 float UnitsyncLib::GetKeyValue( const std::string& key, float defval )
1280 {
1281 InitLib( m_parser_string_key_get_float_value );
1282 return m_parser_string_key_get_float_value( key.c_str(), defval );
1283 }
1284
susynclib()1285 UnitsyncLib& susynclib()
1286 {
1287 static LSL::Util::LineInfo<UnitsyncLib> m( AT );
1288 static LSL::Util::GlobalObjectHolder<UnitsyncLib, LSL::Util::LineInfo<UnitsyncLib> > ss( m );
1289 return ss;
1290 }
1291
1292 } //namespace LSL
1293