worksjop fix

This commit is contained in:
Frank Harris 2026-06-09 14:59:06 -05:00
parent 3b186a61c0
commit efeeeae691
16 changed files with 1541 additions and 0 deletions

View file

@ -0,0 +1,219 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
function create_drop_box_from_array_onchange($input_array,$listname,$current_value = "")
{
$only_one = count($input_array) == 1;
$disabled = $only_one? "disabled=disabled":"";
$retval = "<select id=\"$listname\" name=\"$listname\" style=\"max-width:330px;\" onchange=\"this.form.submit()\" $disabled>\n";
foreach($input_array as $key => $value)
{
// Make sure we don't allow HTML or script
$key = trim(strip_tags($key));
$value = trim(strip_tags($value));
// We want to print lines with zeros, but not empty lines.
if ( empty($value) and $value !="0" )
{
continue;
}
$sel = "";
if ( $key == $current_value )
{
$sel .= "selected='selected'";
}
$retval .= "<option value='$key' $sel>$value</option>\n";
}
$retval .= "</select>\n";
return $retval;
}
function get_mod_names_list($mods_list, $xml_mods)
{
$mod_names = "";
foreach(explode(',', $mods_list) as $workshop_mod_id)
{
foreach($xml_mods as $mod)
{
if($mod['id'] == $workshop_mod_id)
{
if($mod_names != "")
$mod_names .= ",";
$mod_names .= $mod->name;
}
}
}
return $mod_names;
}
function get_mod_info($workshop_mod_id)
{
$request = http_build_query(array('itemcount' => '1', 'publishedfileids[0]' => "$workshop_mod_id"));
$context = stream_context_create
(array('http' => array
(
'method' => "POST",
'header' => "Content-type: application/x-www-form-urlencoded",
'content' => $request,
'timeout' => 5
)));
$json = @file_get_contents('http://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/', false, $context);
$response_array = json_decode($json, true);
$app_info = $response_array['response']['publishedfiledetails'][0];
return array($app_info['title'], $app_info['description'], $app_info['preview_url'], $app_info['file_url'], basename($app_info['filename']), $app_info['file_size']);
}
function belongs_to_workshop($workshop_mod_id, $workshop_id)
{
$request = http_build_query(array('itemcount' => '1', 'publishedfileids[0]' => "$workshop_mod_id"));
$context = stream_context_create
(array('http' => array
(
'method' => "POST",
'header' => "Content-type: application/x-www-form-urlencoded",
'content' => $request,
'timeout' => 5
)));
$json = @file_get_contents('http://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/', false, $context);
$response_array = json_decode($json, true);
$app_info = $response_array['response']['publishedfiledetails'][0];
if($app_info['creator_app_id'] == $workshop_id)
return true;
else
return false;
}
function get_installed_mods($home_cfg, $remote, $xml)
{
$workshop_id = $xml->workshop_id;
$config = $xml->config;
$regex = $config->regex;
$mods_backreference_index = (int)$config->mods_backreference_index;
$string_separator = stripcslashes($config->string_separator);
$filepath = $config->filepath;
$mods = $xml->mods->mod;
$full_filepath = clean_path($home_cfg['home_path']."/$filepath");
if($remote->rfile_exists($full_filepath) === 0)
return False;
if($remote->remote_readfile($full_filepath, $file_content) !== 1)
return False;
if(preg_match("/$regex/m", $file_content, $matches))
{
$full_regex_string = trim($matches[0]);
$current_mods_string = trim($matches[$mods_backreference_index]);
if($current_mods_string != '')
{
$retval = $remote->get_workshop_mods_info($mod_info_array);
$current = explode($string_separator, $current_mods_string);
$installed_mods = array();
foreach($current as $c)
{
if($c != "")
{
$mod_string = trim($c);
if($retval == "1")
$installed_mods["$mod_string"] = isset($mod_info_array["$mod_string"])?$mod_info_array["$mod_string"]:$mod_string;
else
$installed_mods["$mod_string"] = $mod_string;
}
}
return $installed_mods;
}
else
return False;
}
else
return False;
}
function remove_mod($home_cfg, $remote, $xml, $mod_string)
{
$config = $xml->config;
$regex = $config->regex;
$mods_backreference_index = (int)$config->mods_backreference_index;
$variable = $config->variable;
$string_separator = stripcslashes($config->string_separator);
$filepath = $config->filepath;
$full_filepath = $home_cfg['home_path']."/$filepath";
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
if($remote->rfile_exists($full_filepath) === 0)
return False;
$remote->remote_readfile($full_filepath, $file_content);
if(preg_match("/$regex/m", $file_content, $matches))
{
$full_regex_string = trim($matches[0]);
$current_mods_string = trim($matches[$mods_backreference_index]);
if($current_mods_string != '')
{
$current = explode($string_separator, $current_mods_string);
foreach($current as $index => $c)
{
if(trim($c) == $mod_string)
unset($current[$index]);
}
$current = array_filter($current);
$new_mods_string = implode($string_separator, $current);
$replacement = $variable.$new_mods_string;
$file_content = str_replace($full_regex_string, $replacement, $file_content);
}
else
return False;
}
else
return False;
$remote->remote_writefile($full_filepath, $file_content);
$uninstall_filepath = clean_path($mods_full_path.'/postuninstall.sh');
$uninstallcmd = str_replace('%mods_full_path%', $mods_full_path, $xml->uninstall);
$uninstallcmd = str_replace('%mod_string%', $mod_string, $uninstallcmd);
$uninstallcmd .= "\nrm -f $uninstall_filepath";
$output = "";
if($remote->remote_writefile($uninstall_filepath, $uninstallcmd) === 1)
$output .= $remote->exec("bash $uninstall_filepath");
return $output;
}
function get_blacklist()
{
return array( "232330","90","294420","251570","17515","34120","302550","42750","489650","748090","232290",
"17585","739590","17555","232370","55280","17705","261140","222840","320850","317670","824360","381690",
"41005","208050","105600","556450","402370");
}
?>

View file

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>228380</workshop_id>
<download_method>steamcmd</download_method>
<anonymous_login>0</anonymous_login>
<mods_path>mods</mods_path>
<mods/>
<config>
<regex>mods=(([0-z]+,?)*)</regex>
<mods_backreference_index>1</mods_backreference_index>
<variable>mods=</variable>
<place_after/>
<mod_string>%workshop_mod_id%</mod_string>
<string_separator>,</string_separator>
<filepath>server_config.cfg</filepath>
</config>
<post_install>printf "\nMoving item %workshop_mod_id% ..."&#xD;
cp -Rf "%mods_full_path%/steamapps/workshop/content/228380/%workshop_mod_id%" "%mods_full_path%/."&#xD;
rm -Rf "%mods_full_path%/steamapps/workshop/content/228380/%workshop_mod_id%"&#xD;
printf "\nSuccess."</post_install>
<uninstall>printf "\nUninstalling item %mod_string% ...\n"&#xD;
rm -Rf "%mods_full_path%/%mod_string%"&#xD;
printf "\nSuccess."</uninstall>
</workshop_settings>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,104 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>4000</workshop_id>
<download_method>steamapi</download_method>
<anonymous_login>1</anonymous_login>
<mods_path>mods</mods_path>
<mods>
<mod id="1403476308">
<name>gm_news_studio</name>
<description>TmV3cyBTdHVkaW8gb2YgR2FycnkncyBNb2QhIFlvdSBjYW4gZmluYWxseSBtYWtlIHlvdXIgb3duIG5ld3Mgb24gdGhpcyBtYXAhDQpNYXAgZG9lcyBub3QgcmVxdWlyZSBhbnkgYWRkaXRpb25hbCBjb250ZW50Lg0KU29tZSBwYXJ0cyBvZiBtYXAgYXJlIGNvbG91cmFibGUuDQoNCklmIHlvdSBsaWtlIHRoaXMgYWRkb24gc28gbXVjaCwgdGhhdCB5b3UgY2FuIGdpZnQgbWUgc29tZXRoaW5nIC0gaGVyZSdzIG15IHRyYWRlLW9mZmVyOg0KDQpodHRwczovL3N0ZWFtY29tbXVuaXR5LmNvbS90cmFkZW9mZmVyL25ldy8/cGFydG5lcj0xMTEzOTA4NDAmdG9rZW49c3c4ekZmWEQNCg0KVGFnczoNCk5ld3MNClRGTg0KQnJvYWRjYXN0DQpTYW5kYm94DQpNb3ZpZQ0KQW5pbWF0aW9uDQpDYW1lcmENClZpZGlv</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/910171257329171075/337E32C3BEE684EFF58A0837FAADE9CC69AE04AC/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/909045760924451577/085F0A63EC79B0509E2C8643DFAFE0D9E4785FCE/</download_url>
<filename>1528544715_223866981.gma</filename>
<file_size>6461914</file_size>
</mod>
<mod id="1437899079">
<name>Smitty Werbenjagermanjensen - Spongebob Squarepants</name>
<description>Ikl0IHdhcyBoaXMgaGF0IE1yLiBLcmFicyEgSGUgd2FzIG51bWJlciBvbmUhIg0KDQpTbWl0dHkgV2VyYmVuamFnZXJtYW5qZW5zZW4sIGZhaXRoZnVsbHkgcmVjcmVhdGVkIGZyb20gdGhlIGVwaXNvZGUgIk9uZSBLcmFiJ3MgVHJhc2giDQoNCltoMV1JbmNsdWRlcyBbL2gxXQ0KDQpQbGF5ZXIgbW9kZWwgDQpSYWdkb2xsIA0KRmluZ2VyIFBvc2luZyAoT25seSBvbmUgZmluZ2VyKQ0KRlBTIEFybXMNCkZyaWVuZGx5IGFuZCBIb3N0aWxlIE5QQ3MNCg0KW2gxXUNyZWRpdHMgYW5kIEh1Z2UgVGhhbmtzIFRvWy9oMV0NCltiXUdyaWZmYm9bL2JdIFRoZSBib2R5IGZvciBoaW0sIEkgZG91YnQgSSB3b3VsZCd2ZSBiZWVuIGFibGUgdG8gZG8gdGhpcy4NCltiXVdpbm5pbmdSb29rWy9iXSBGb3IgdGhlIHBpY3R1cmUuDQpbYl1TcGlrZVsvYl0gRm9yIHRoZSBoYXRzLCBoZWFkIGFuZCB0ZXh0dXJlcy4=</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/955210546397733977/A0293C4D6AD86A37CFCB8EC18071FCB3E773D76B/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/955210546397733770/C0A22FDAC654A2067C761E5C322986CFBCC3A158/</download_url>
<filename>1531283572_229351499.gma</filename>
<file_size>2577446</file_size>
</mod>
<mod id="1443096823">
<name>gm_goldencity_day</name>
<description>SGVyZSdzIGEgbWFwIHRoYXQncyBoZWF2aWx5IGluc3BpcmVkIGJ5IGdtX2JpZ2NpdHkuIEkndmUgYmVlbiB3YW50aW5nIHRvIG1ha2UgYSBjaXR5IG1hcCBsaWtlIHRoaXMgZm9yIGEgZGVjYWRlLCBhbmQgSSd2ZSBmaW5hbGx5IGdvdHRlbiBhcm91bmQgaW50byBkb2luZyBqdXN0IHRoYXQuIEkgcHJvYmFibHkgY291bGQgaGF2ZSBnb3R0ZW4gdGhpcyBvdXQgb2YgdGhlIHdheSBhIHdoaWxlIGFnbywgYnV0IGJldHRlciBsYXRlIHRoYW4gbmV2ZXIsIEkgc3VwcG9zZS4NCg0KRmVhdHVyZXM6DQoNCi0gQSBkb3dudG93biBhcmVhIHBsdXMgYSBoaWdocmlzZSBhcmVhDQotIEEgc3Vua2VuIGhpZ2h3YXkgd2l0aCBhIGNvdXBsZSBvZiB0dW5uZWxzIGNvbm5lY3RpbmcgdG8gdGhlIG90aGVyIHJvYWRzDQotIDE0IGJ1aWxkaW5ncyB3aXRoIGludGVyaW9ycy4gVGhlcmUgYXJlIHNvbWUgZXh0ZXJpb3Igb3BlbiBkb29ycyB0aGF0IHlvdSBjYW4gd2FsayBpbnRvIHRoYXQgdGVsZXBvcnQgeW91IGludG8gdGhlIGludGVyaW9yLiBUbyBnbyBiYWNrIG91dHNpZGUsIHByZXNzIEUgb24gb25lIG9mIHRoZSBlbGV2YXRvciBkb29ycyBvciB3aGF0ZXZlciBraW5kIG9mIGRvb3IgeW91IHRlbGVwb3J0ZWQgaW4gZnJvbnQgb2YuDQotIEFuIEFJIE5vZGVncmFwaA0KLSBIRFINCi0gQSBzaW5nbGUgc291bmRzY2FwZSB0aHJvdWdob3V0IHRoZSBtYXAuIFRoZSByZWFzb24gaXQncyBqdXN0IG9uZSBpcyBiZWNhdXNlIEknbSBub3QgZ3JlYXQgYXQgc291bmRzY2FwZXMuIEknbGwgcHJvYmFibHkgd29yayBvbiB0aGF0IGxhdGVyIGFzIHdlbGwuDQotIEEgc2luZ2xlIGN1YmVtYXAgdGhhdCBhY3R1YWxseSB3b3JrcyAoYXQgbGVhc3Qgb24gbXkgZW5kLCB0aG91Z2ggSSBtYWRlIHN1cmUgaXQgd2Fzbid0IGp1c3QgdGhlIGxlZnRvdmVyIGJzcCB0aGF0IGhhZCB0aGF0KSB1bmxpa2UgdGhlIG9uZXMgaW4gdGhlIHByZXZpb3VzIG1hcCBJIHVwbG9hZGVkDQotIFR3byBjdXN0b20gbW9kZWxzIChBIHRyZWUgYW5kIGEgYmFza2V0YmFsbCBob29wKSB1c2VkIGluIHRoZSBtYXAgdGhhdCB5b3UgY2FuIHVzZSB5b3Vyc2VsZg0KLSBBIGNvdXBsZSBvZiBzZWNyZXRzDQoNCkNyZWRpdHM6DQoNCkRvY3RvciBGbG91bmRlciBCb3gsIGZvciB0aGUgYmFza2V0YmFsbCBob29wIG1vZGVsDQpCbHVlYmVycnlfUGllLCBmb3IgY29taW5nIHVwIHdpdGggdGhlIGlsbHVtaW5hdGVkIHdpbmRvdyB0ZWNobmlxdWUgKG5pZ2h0IHZlcnNpb24pDQpLaW5nUG9tbWUsIGZvciBleHBhbmRpbmcgb24gdGhhdCB0ZWNobmlxdWUgKG5pZ2h0IHZlcnNpb24pDQpic2hhZG93LCBmb3IgdGhlIGludmlzaWJsZSByYWQgbGlnaHQgdGVjaG5pcXVlIHVzZWQgZm9yIHRoZSBzdHJlZXRsaWdodHMgKG5pZ2h0IHZlcnNpb24pDQpKYWtvYmkgTydCcmllbiwgZm9yIGhlbHBpbmcgbWUgb3V0IHdpdGggYSBiaXQgb2Ygb3B0aW1pemF0aW9uIChUaG91Z2ggSSBkaWRuJ3QgZG8gYSBncmVhdCBqb2Igd2l0aCBpdCBvbiB0aGlzIHVwZGF0ZS4gSSdsbCBwcm9iYWJseSB3b3JrIG9uIGl0IHNvbWUgbW9yZSBvbiB0aGUgbmV4dCB1cGRhdGUpDQpWYWx2ZSBhbmQgQ0dUZXh0dXJlcywgZm9yIHRoZSBzb3VyY2UgbWF0ZXJpYWwgdXNlZCBmb3IgdGhlIGN1c3RvbSB0ZXh0dXJlcw0KRXZlcnlvbmUgd2hvIGdhdmUgZmVlZGJhY2sgb24gdGhlIG1hcCBpbiB0aGUgd29yay1pbi1wcm9ncmVzcyB0aHJlYWQNCg0KWW91IHdvbid0IG5lZWQgQ291bnRlciBTdHJpa2U6IFNvdXJjZSBvciBMZWZ0IDQgRGVhZCBmb3IgdGhlIHRleHR1cmVzIG9uIHRoaXMgbWFwIHRvIHdvcmssIGZvciB0aG9zZSBvZiB5b3Ugd2hvIGRvbid0IGhhdmUgZWl0aGVyIGdhbWUuIFRoZXJlIGlzIGFsc28gYSBuaWdodCB2ZXJzaW9uIG9mIHRoaXMgbWFwIHdoaWNoIGlzIHRoZSBvcmlnaW5hbCwgaWYgeW91IHdhbnQgdG8gY2hlY2sgdGhhdCBvdXQuDQoNCkFsc28sIEkganVzdCBub3RpY2VkIHRoYXQgdGhlcmUncyBhIGJ1ZyBvbiB0aGlzIG1hcCB3aGVyZSBzbWFsbCBmbGlja2VyaW5nIGJsYWNrIHRyaWFuZ2xlcyB3aWxsIGFwcGVhciBpbiB0aGUgY29ybmVycyBvZiB0aGUgc2t5Ym94IGlmIHlvdSBsb29rIGF0IGFueSBvZiB0aG9zZSBjb3JuZXJzLiBJIGhhdmUgbm8gaWRlYSBob3cgdG8gZml4IHRoaXMsIHRob3VnaCBpdCdzIG5vdCB0b28gbm90aWNhYmxlLiBJJ20gdGhpbmtpbmcgaXQgaGFzIHNvbWV0aGluZyB0byBkbyB3aXRoIHRoZSByZW5kZXIgZGlzdGFuY2UsIHdoaWNoIHdvdWxkbid0IHJlYWxseSBtYWtlIGFueSBzZW5zZSBzaW5jZSB0aGUgc2t5Ym94IGlzbid0IHN1cHBvc2VkIHRvIGhhdmUgdGhhdCBpc3N1ZS4=</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/943951991654869773/338A0338BA966AF835CEB2B3B5A800487A1BACE1/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/943951991654867861/F167313D927ECA5D4AFAEFD76644F598B9A55AC1/</download_url>
<filename>1531788260_1094686331.gma</filename>
<file_size>25824223</file_size>
</mod>
</mods>
<config>
<regex>(.*\n?)*</regex>
<mods_backreference_index>0</mods_backreference_index>
<variable/>
<place_after/>
<mod_string>%first_file%</mod_string>
<string_separator>\n</string_separator>
<filepath>mods/mods.txt</filepath>
</config>
<post_install>cd "%mods_full_path%/steamapps/workshop/content/4000/%workshop_mod_id%"&#xD;
cp -f %first_file% myfile.gma&#xD;
7z x myfile.gma -aoa &gt; /dev/null 2&gt;&amp;1&#xD;
cp -f myfile content.gma&#xD;
rm -f myfile.gma myfile&#xD;
"%mods_full_path%/../bin/gmad_linux" content.gma &gt; /dev/null 2&gt;&amp;1&#xD;
rm -f "content.gma"&#xD;
cd content&#xD;
zip -r "%mods_full_path%/steamapps/workshop/content/4000/%first_file%.zip" * &gt; /dev/null 2&gt;&amp;1&#xD;
cd ../..&#xD;
rm -Rf "%mods_full_path%/steamapps/workshop/content/4000/%workshop_mod_id%"&#xD;
unzip -Z1 "%first_file%.zip" &gt; "%first_file%.list"&#xD;
tac "%first_file%.list" &gt; "%first_file%.listinv"&#xD;
cp -f "%first_file%.listinv" "%first_file%.list"&#xD;
rm "%first_file%.listinv"&#xD;
unzip -o "%first_file%.zip" -d "%mods_full_path%/../garrysmod" &gt; /dev/null 2&gt;&amp;1&#xD;
rm -f "%first_file%.zip"&#xD;
&#xD;
if [ -f "%mods_full_path%/steamapps/workshop/content/4000/%first_file%.list" ];then&#xD;
cd "%mods_full_path%/../garrysmod"&#xD;
luaFile="%mods_full_path%/../garrysmod/lua/autorun/server/resources.lua"&#xD;
while read p; do&#xD;
if [ -f "$p" ] &amp;&amp; [ ! -d "$p" ]; then&#xD;
filename=$(basename -- "$p")&#xD;
extension="${filename##*.}"&#xD;
if [ "$extension" != "bsp" ] &amp;&amp; [ "$extension" != "png" ]; then&#xD;
newstring="resource.AddSingleFile(\"$p\")"&#xD;
if ! grep -Fxq "$newstring" "$luaFile"; then&#xD;
echo "$newstring" &gt;&gt; "$luaFile"&#xD;
fi &#xD;
fi&#xD;
fi&#xD;
done &lt;"%mods_full_path%/steamapps/workshop/content/4000/%first_file%.list"&#xD;
printf "\nContents of %first_file% successfully installed!"&#xD;
else&#xD;
printf "\nFile listing not found, try it again after reinstalling the mod."&#xD;
fi&#xD;
&#xD;
</post_install>
<uninstall>if [ -f "%mods_full_path%/steamapps/workshop/content/4000/%mod_string%.list" ];then&#xD;
cd "%mods_full_path%/../garrysmod"&#xD;
luaFile="%mods_full_path%/../garrysmod/lua/autorun/server/resources.lua"&#xD;
while read p; do&#xD;
if [ -d "$p" ]; then&#xD;
if [ -z "$(ls -A "$p")" ]; then&#xD;
rm -vRf "$p"&#xD;
fi&#xD;
else&#xD;
if [ -f "$p" ]; then&#xD;
rm -vf "$p"&#xD;
filestring="resource.AddSingleFile(\"$p\")"&#xD;
if grep -Fxq "$filestring" "$luaFile"; then&#xD;
escaped_filestring=$(sed -e 's/[]\/$*.^[]/\\&amp;/g' &lt;&lt;&lt; $filestring)&#xD;
sed -i "/$escaped_filestring/d" "$luaFile"&#xD;
fi &#xD;
fi&#xD;
fi&#xD;
done &lt;"%mods_full_path%/steamapps/workshop/content/4000/%mod_string%.list"&#xD;
printf "\nContents of %mod_string% successfully uninstalled!"&#xD;
else&#xD;
printf "\nFile listing not found, try it again after reinstalling the mod."&#xD;
fi</uninstall>
</workshop_settings>

View file

@ -0,0 +1,101 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>440900</workshop_id>
<download_method>steamcmd</download_method>
<anonymous_login>1</anonymous_login>
<mods_path>ConanSandbox/Mods</mods_path>
<mods>
<mod id="864199675">
<name>Pickup+</name>
<description>V2l0aCB0aGlzIG1vZCB5b3UgYXJlIGFibGUgdG8gcGljayB1cCBhbGwgdGhlIHRoaW5ncyB5b3UndmUgcGxhY2VkIC0gc2ltcGxlIGFzIHRoYXQhIDotKQoKKioqIEFkZGVkIHBpY2t1cCBzdXBwb3J0IGZvciB0aHJhbGxzISAqKioKCi0gV29ya3Mgb24gc2luZ2xlcGxheWVyIGFuZCBkZWRpY2F0ZWQgc2VydmVycyEKLSBBZG1pbnMgaGF2ZSB0aGUgb3B0aW9uIHRvIHJlbW92ZSB0aGUgcGlja3VwIG9wdGlvbiBmcm9tIGl0ZW1zIChPbmx5IGluIE1QKQotIEFkbWlucyBoYXZlIHRoZSBvcHRpb24gdG8gZW5hYmxlL2Rpc2FibGUgdGhlIHBpY2t1cCBvcHRpb24gZnJvbSBhbGwgdGhyYWxscyBvdmVyIHRoZSBvcHRpb25zd2hlZWwgKE9ubHkgaW4gTVApCgoqKiogWW91IGNhbiBvbmx5IHBpY2t1cCB0aHJhbGxzIHRoYXQgYXJlIG5vdCB3ZWFyaW5nIGFueSBhcm1vciEgKioqCgoKWW91IHdhbnQgdG8gcmVwb3J0IGEgYnVnPyBQbGVhc2UgdXNlIHRoaXMgdGVtcGxhdGUgYW5kIGp1c3QgcG9zdCBpdCBpbiB0aGUgY29tbWVudHMhCmh0dHBzOi8vc3RlYW1jb21tdW5pdHkuY29tL3dvcmtzaG9wL2ZpbGVkZXRhaWxzL2Rpc2N1c3Npb24vODY0MTk5Njc1LzE3Mjg3MDE4Nzc0ODE5NTQ0NTkvIAoKCkhhdmUgRnVuIQoKCk1PRCBJRDogODY0MTk5Njc1CgpJZiB5b3UgaGF2ZSBhbnkgcHJvYmxlbXMgb3Igc3VnZ2VzdGlvbnMgZmVlbCBmcmVlIHRvIHdyaXRlIGl0IGluIHRoZSBjb21tZW50cyBvciBzdGFydCBhIGRpc2N1c3Npb24hCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhpcyBtb2QvY29kZS93b3JrIGlzIHByb3RlY3RlZCBieSB0aGUgW1VSTD1odHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy1uZC80LjAvbGVnYWxjb2RlXUF0dHJpYnV0aW9uLU5vbkNvbW1lcmNpYWwtTm9EZXJpdmF0aXZlcyA0LjAgSW50ZXJuYXRpb25hbCBDcmVhdGl2ZSBDb21tb25zIExpY2Vuc2UuCltJTUddaHR0cHM6Ly9pLmNyZWF0aXZlY29tbW9ucy5vcmcvbC9ieS1uYy1uZC80LjAvODh4MzEucG5nWy9JTUddWy9VUkxd</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/96102470863175828/E2FD19AEC364F48C7B0D0FB7231D937A097A0EEB/</image_url>
<download_url/>
<filename/>
<file_size>691137</file_size>
</mod>
<mod id="1367404881">
<name>Savage Steel</name>
<description>VGhpcyBtb2QgaGFzIGEgd2lkZSB2YXJpZXR5IG9mIHJlYWxpc3RpYyBwbGFjZWFibGUgb3IgUlAgaXRlbXMuIFNvbWUgb2YgdGhlIGZlYXR1cmVzIHRoYXQgd2UgaGF2ZSBhcmUgaW52ZW50b3JpZXMgaW4gc2Fja3MsIGNyYXRlcywgYmFycmVscyBhbmQgbWFueSBvdGhlciBpdGVtcy4gV2UgYWxzbyBoYXZlIGV4dHJhIHN0b3JhZ2Ugc3BhY2UgaW4gb3VyIFN0cm9uZ2JveCBjaGVzdC4gV2Ugbm93IGhhdmUgIlBpY2sgVXAiIG9uIHRoZSBTYXZhZ2UgU3RlZWwgcGxhY2VhYmxlcy4gV2UgaGF2ZSBkZXNpZ25lZCBvdXIgcGxhY2VhYmxlcyB0byBiZSBwbGFjZWQgY2xvc2VseSB0b2dldGhlciBvciBzdGFja2VkLCBpZiBkZXNpcmVkLiBXZSB3aWxsIGNvbnRpbnVlIHRvIGFkZCB0byB0aGlzIG1vZCBvbiBhbiBvbmdvaW5nIGJhc2lzLiBUaGlzIG1vZCBpcyBkZXNpZ25lZCBmb3IgdGhlIFNhdmFnZSBTdGVlbCBzZXJ2ZXIsIGJ1dCBhbnlvbmUgaXMgd2VsY29tZSB0byB1c2UgaXQuIElmIHlvdSBsaWtlIG91ciBtb2QgcGxlYXNlIGJlIHN1cmUgdG8gZ2l2ZSB1cyBhICJUaHVtYnMgVXAiISEgDQoNCltoMV1MaXN0IG9mIFBsYWNlYWJsZXNbL2gxXSANCg0KW2gxXVN0b3JhZ2UgSXRlbXNbL2gxXSANCg0KQnVja2V0ICANClRhbGwgQnVja2V0IA0KMyBkaWZmZXJlbnQgQ2xvdGggQmFsZXMgDQozIGRpZmZlcmVudCBCYWdzIA0KV29vZGVuIFR1YiANCkJhc2tldCANClRhbGwgQmFza2V0IA0KMyBCYXJyZWxzIA0KNCBkaWZmZXJlbnQgQ3JhdGVzIA0KMiBkaWZmZXJlbnQgU3Ryb25nYm94IENoZXN0cyANCg0KW2gxXUZ1cm5pc2hpbmdzWy9oMV0gDQoNCkxhcmdlIENhc2sgDQozIGJhciBwaWVjZXMgDQpGdWxseSBhc3NlbWJsZWQgYmFyIA0KQ2xvdGggQmFyIGNvdmVyIA0KMiBkaWZmZXJlbnQgZW1wdHkgYm93bHMgDQoyIGRpZmZlcmVudCBmdWxsIGJvd2xzIA0KQ2FiaW5ldCANCjIgZGlmZmVyZW50IFNoZWx2ZXMgDQpDYWJpbmV0IHdpdGggc2hlbGYgDQo1IGRpZmZlcmVudCBoZXJiIGJpbnMgDQpEcmVzc2VyIA0KV2FsbCBTaGVsZiANCkJhdGggDQpTdHlnaWFuIEJhdGggDQpSdXN0aWMgQmF0aCAod29vZGVuKSANCkN1cnRhaW5zIA0KQ2hhbWJlciBQb3QNClNhdWNlcGFuDQpTb3VwIExhZGxlDQo0IENhbmlzdGVycyAoU2FsdCwgUGVwcGVyLCBDaW5uYW1vbiAmIFBhcHJpa2EpIHdpdGggNSBzdG9yYWdlIHNsb3RzIGVhY2gNCkNhbmlzdGVyIFNldCBvbiBhIHNoZWxmIHdpdGggMjAgc3RvcmFnZSBzbG90cw0KMiBXZWFwb24gRHJvcHMgLSBOb3J0aGVybiBhbmQgU291dGhlcm4NCkxhdW5kcnkgQnVja2V0DQpTY3JvbGwgU3RhbXANClNlYWxlZCBTY3JvbGwNClNjcm9sbCB3YXgNCjMgZGlmZmVyZW50IHJ1Z3MNCiANCltoMV1Gb29kWy9oMV0gDQogDQpDaGlja2VuIExlZ3Mgb24gYSBQbGF0ZSANCldoaXRlIEJyZWFkIG9uIGEgcGxhdGUgDQpDYWtlcyBvbiBhIHBsYXRlIA0KQ2hlZXNlIHdoZWVsIG9uIGEgcGxhdGUgDQpCb3dsIG9mIEVnZ3MgDQpGcmllZCBlZ2dzIG9uIGEgcGxhdGUgDQpIYW0gb24gYSBwbGF0ZSANCkJyZWFkIG9uIGEgcGxhdGUgDQogDQpbaDFdQWxjaGVteS9BcG90aGVjYXJ5Wy9oMV0gDQoNCkFsY2hlbXkgRGVzayANCkFsY2hlbXkgRGVzayBDaGFpciANCkluayBXZWxsIG9wZW4gDQpJbmsgV2VsbCBDbG9zZWQgDQpJbmsgd2VsbCBjYXAgDQo0IGRpZmZlcmVudCBQb3Rpb25zIA0KMyBkaWZmZXJlbnQgQXBvdGhlY2FyeSBOb3RlcyANCjYgZGlmZmVyZW50IEZlYXRoZXJzIA0KTW9ydGFyICYgUGVzdGxlIA0KMiBkaWZmZXJlbnQgSGFuZ2luZyBIZXJiIHJhY2tzIChvbmUgd29vZCBhbmQgb25lIG1ldGFsKSANCjMgZGlmZmVyZW50IEFsY2hlbXkgc2V0cyANCjUgZGlmZmVyZW50IGhlcmJzIHRvIHBsYWNlIG9uIGEgdGFibGUgb3IgY291bnRlcg0KDQpbaDFdT3V0ZG9vciBEZWNvclsvaDFdIA0KDQpXYXRlciBDYW4gDQpXYWdvbiANCldhZ29uIFdoZWVsIA0KQnJ1c2h3b29kIA0KOCBkaWZmZXJlbnQgcGllY2VzIG9mIGZpcmV3b29kICg0IHN0YW5kaW5nIHVwLCA0IGxheWluZyBkb3duKSANCjIgTG9ncyANCjUgZGlmZmVyZW50IFBsYW5rcyANCkdhbGxvd3MNCkV4ZWN1dGlvbmVyJ3MgQmxvY2ssIEF4ZSBhbmQgY29tYmluYXRpb24NCkd1aWxsb3RpbmUNClBpbGxhcnkNCkhhbmdpbmcgQ2FnZQ0KDQogW2gxXX5+ICBNb2QgSUQgMTM2NzQwNDg4MVsvaDFdDQoNCltoMV1XZSBub3cgaGF2ZSBhIERpc2NvcmQgc2VydmVyOlsvaDFdDQpodHRwczovL2Rpc2NvcmQuZ2cvcUVoTTNXdA0KDQpUbyBnZXQgdGhlIEdVSSBib3ggb24gYm90aCBiYXRocywgaG92ZXIgb3ZlciB0aGUgbGFkZGVyIGFyZWEuIFRoaXMgc2hvdWxkIGdpdmUgeW91IHRoZSBvcHRpb24gdG8gcGlja3VwIG9yIGRlc3Ryb3kuIA0KDQoNClRoYW5rcyB0byBTaGFkb3dDTUQgZm9yIGFsbCB5b3VyIGhlbHAgYW5kIHBhdGllbmNlIGFuZCB0byBSZWQgTWFyY2ggZm9yIGhlbHBpbmcgd2l0aCB0aGUgaWNvbnMgYW5kICB0aGUgYXJ0d29yayBmb3IgdGhlIG1vZCBjb3ZlciEh</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/929311364899517529/96C8FED0D19E78C69A2D571BE083FC7FC26A3F32/</image_url>
<download_url/>
<filename/>
<file_size>2644257234</file_size>
</mod>
<mod id="1384471264">
<name>Drag thralls in water (May 2018)</name>
<description>RHJhZyB0aHJhbGxzIHRocm91Z2ggd2F0ZXIgd2l0aCByb3BlLgoKU3VnZ2VzdGVkIGJ5IERyZWFndWgu</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/912420738527948826/40A5E9CD53E58008EBDC0EC4519DF55144DD03C5/</image_url>
<download_url/>
<filename/>
<file_size>777732</file_size>
</mod>
<mod id="1378596051">
<name>Banners to the Gods</name>
<description>VGhpcyBNb2QgaXMgYSBtb2QgdGhhdCBnaXZlcyAzIG5ldyBmbGF2b3JzIG9mIGJhbm5lcnMgdG8geW91ciBnYW1lLiBEZXJrZXRvLCBNaXRyYSBhbmQgWW1pciBiYW5uZXJzLiBTaW5jZSB0aGVyZSB3ZXJlIG9ubHkgU2V0LCBhbmQgRGFyZmFyaSBiYW5uZXJzLCBwbHVzIG9mIGNvdXJzZSB0aGUgb3RoZXIgY2xhbnMgaW4gdGhlIEV4aWxlZCBsYW5kcy4uLiBZZXQsIG5vdyB0aGUgTm9yZGhlaW1lcnMsIHRoZSBNaXRyYWVucywgRGVya2V0aWFucywgaGF2ZSBhIGJhbm5lciBhcyB3ZWxsIQ==</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/930434406223072719/09C64DD22443CA300AB5C9C148D542385C458BDF/</image_url>
<download_url/>
<filename/>
<file_size>155457134</file_size>
</mod>
<mod id="1426203926">
<name>Compass Icon</name>
<description>QSB2ZXJ5IGJhc2ljIGNvbXBhc3MgaWNvbiB0aGF0IG1vdmVzIHRvIGluZGljYXRlIE5vcnRoIGFuZCBibGVuZHMgd2l0aCB0aGUgZXhpc3RpbmcgVUkuCgpJIHdhcyB0cnlpbmcgdG8gZmlndXJlIG91dCBob3cgdG8gZG8gbW9kcyBzbyBJIG1hZGUgYSBzdXBlciBiYXNpYyBjb21wYXNzLCBJIGZpZ3VyZWQgSSBtaWdodCBhcyB3ZWxsIHNoYXJlIGl0LiBJJ20gc3RpbGwgbGVhcm5pbmcgc28gYW55IGZlZWRiYWNrIGlzIHdlbGNvbWUu</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/952957720418478101/595F301CFA480B162796FE56793C1A650722DEDF/</image_url>
<download_url/>
<filename/>
<file_size>1942869</file_size>
</mod>
<mod id="1113901982">
<name>The Age of Calamitous</name>
<description>W2gxXVdlbGNvbWUgdG8gVGhlIEFnZSBvZiBDYWxhbWl0b3VzIVsvaDFdCgpUaGlzIG1vZCBzZXJ2ZXMgYXMgYSB0b3RhbCBjb252ZXJzaW9uIG1vZCwgaW50cm9kdWNpbmcgbmV3IHN5c3RlbXMsIGNvbnRlbnQsIGZlYXRzLCBhbmQgbXVjaCBtb3JlISAKCkhlcmUgaXMgYSBsaXN0IG9mIHNvbWUgYWRkaXRpb25zIHRvIHRoZSBnYW1lOgpbbGlzdF0KWypdIEFkZGl0aW9uYWwgQ2hhcmFjdGVyIENyZWF0aW9uIE9wdGlvbnMKWypdIE5ldyBTdGFja3MgJiBXZWlnaHQKWypdIFVJIC8gSFVEIG1vZGlmaWNhdGlvbnMKWypdIEh1bmRyZWRzIG9mIE5ldyBEZWNvcmF0aW9ucywgUHJvcHMsIEl0ZW1zLCBXZWFwb25zLCBldGMuClsqXSBNYW55IE5ldyBDcmFmdGluZyBTdGF0aW9ucywgRmVhdHMgJiBSZWNpcGVzClsqXSBOZXcgTGV2ZWwgQ2FwIDEwMCAoQXNjZW5zaW9uIDEwMS0xMjApClsqXSBTcGVjaWFsIGNvbnRlbnQgZnJvbSBUaGUgQWdlIG9mIENhbGFtaXRvdXMKWy9saXN0XQpBbmQgbXVjaCBtb3JlIQoKW2gxXVdBUk5JTkdbL2gxXQoKVGhpcyBtb2QgaXMgaW4gYWN0aXZlIGRldmVsb3BtZW50LCBhbmQgdGhlcmVmb3JlIHRoZXJlIHdpbGwgYmUgZnJlcXVlbnQgcGF0Y2hlcyBjb21pbmcgb3V0LiBTbWFsbCAmIGxhcmdlIG9uZXMgY29udGFpbmluZyBhZGp1c3RtZW50cywgYmFsYW5jaW5nLCBjb250ZW50ICYgZml4ZXMuCklmIHlvdSBkbyBub3Qgd2FudCB0byBrZWVwIHVwIHdpdGggZnJlcXVlbnQgdXBkYXRlcywgYXZvaWQgdXNpbmcgdGhlIG1vZCB1bnRpbCBpdCdzIGluIGEgY29tcGxldGVkIHN0YXRlLgpUaGlzIG1vZCBpcyBpbnRlbmRlZCB0byBiZSBzdGFuZGFsb25lIGFuZCBpcyBub3QgbWFkZSB0byB3b3JrIHdpdGggYWRkaXRpb25hbCBtb2RzLgpSZWFkIG1vcmUgYXQgdGhlIEltcG9ydGFudCBJbmZvcm1hdGlvbiB0b3BpYyBpbiB0aGUgZGlzY3Vzc2lvbnMuCgpbaDFdSW5mb3JtYXRpb25bL2gxXQoKVGhlIGludGVudGlvbiBvZiB0aGlzIG1vZCBpcyB0byBleHBhbmQgdXBvbiBDb25hbiBFeGlsZXMgd2l0aCBuZXcgY29udGVudCBmcm9tIFRoZSBBZ2Ugb2YgQ2FsYW1pdG91cyB1bml2ZXJzZSwgaW50cm9kdWNpbmcgYSBmZXcgYXNwZWN0cyBvZiB0aGUgZmFudGFzeSBtZWRpZXZhbCBnZW5yZS4KSm9pbiB1cyBvbiBEaXNjb3JkIGZvciBtb2QgdXBkYXRlcyBhbmQgc2VydmVycyBydW5uaW5nIHRoZSBtb2Q6Ci0gW3VybD1odHRwczovL2Rpc2NvcmQuZ2cvODJoZ3ZHaF0gRGlzY29yZFsvdXJsXQoKRmVlbCBmcmVlIHRvIHJlZ2lzdGVyIG9uIHRoZSB3ZWJzaXRlIHRvIGtlZXAgeW91cnNlbGYgdXAgdG8gZGF0ZSB3aXRoIHRoZSBsYXRlc3QgbmV3cyEKLSBbdXJsPWh0dHA6Ly93d3cudGhlLWFnZS1vZi1jYWxhbWl0b3VzLmNvbS9dIFRoZSBBZ2Ugb2YgQ2FsYW1pdG91cyBXZWJzaXRlWy91cmxdCgpNT0QgSUQ6IDExMTM5MDE5ODIKCltoMV1UaGUgT2ZmaWNpYWwgQWdlIG9mIENhbGFtaXRvdXMgUHJvamVjdFsvaDFdCgpJZiB5b3UgYXJlIGludGVyZXN0ZWQgaW4gbGVhcm5pbmcgbW9yZSBhYm91dCB3aGF0IFRoZSBBZ2Ugb2YgQ2FsYW1pdG91cyBwcm9qZWN0IGlzLCB5b3UgY2FuIGRyb3AgYnkgb3VyIG9mZmljaWFsIEZhY2Vib29rIHBhZ2UhIEJlIGF3YXJlIHRoYXQgdGhpcyBpcyB0aGUgb2ZmaWNpYWwgcHJvamVjdCBhbmQgbm90IHRoZSBtb2QuIFRoZSBtb2QgaXMgYSBwZXJzb25hbCBzaWRlIHByb2plY3QgYW5kIGlzIG5vdCB0aGUgb2ZmaWNpYWwgcHJvamVjdC4KLSBbdXJsPWh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9BbmFyaW91c1Byb2R1Y3Rpb25zXSBUaGUgQWdlIG9mIENhbGFtaXRvdXMgRmFjZWJvb2tbL3VybF0KCkFkZGl0aW9uYWxseSwgeW91IGNhbiBmb2xsb3cgbWUgb24gVHdpdHRlciBmb3IgYW55IG5ld3MgdXBkYXRlcyByZWdhcmRpbmcgdGhlIG1vZCBhbmQgdGhlIG92ZXJhbGwgcHJvamVjdC4gCi0gW3VybD1odHRwczovL3R3aXR0ZXIuY29tL0VzcGVuR0pvaGFuc2VuXSBUd2l0dGVyWy91cmxdCgpbaDFdV2FudCB0byBzdXBwb3J0IHRoZSBwcm9qZWN0P1svaDFdCgpBbnkgZm9ybSBvZiBzdXBwb3J0IGlzIGdyZWF0bHkgYXBwcmVjaWF0ZWQhCkFsbCB0cmlidXRlcyBtYWRlIHRocm91Z2ggRG9uYXRpb24gYW5kL29yIFBhdHJlb24gd2lsbCBnbyB0b3dhcmRzIGV4cGFuZGluZyBUaGUgQWdlIG9mIENhbGFtaXRvdXMgcHJvamVjdC4KLSBbdXJsPWh0dHA6Ly93d3cudGhlLWFnZS1vZi1jYWxhbWl0b3VzLmNvbS9dIERvbmF0aW9uWy91cmxdCi0gW3VybD1odHRwczovL3d3dy5wYXRyZW9uLmNvbS9lc3Blbmdqb2hhbnNlbl0gUGF0cmVvblsvdXJsXQoKCkFsbCBjb250ZW50IG93bmVkIGFuZC9vciBwcm92aWRlZCBmb3IgVGhlIEFnZSBvZiBDYWxhbWl0b3VzIGlzIGNvcHlyaWdodGVkLgooYylDb3B5cmlnaHQgMjAxMS0yMDE4IEFuYXJpb3VzIFByb2R1Y3Rpb25zLCBBbGwgUmlnaHRzIFJlc2VydmVkCihjKUNvcHlyaWdodCAyMDExLTIwMTggRXNwZW4gR3JhdmRhaGwgSm9oYW5zZW4sIEFsbCBSaWdodHMgUmVzZXJ2ZWQKCkNvbmFuIEV4aWxlcyBjb250ZW50IGFuZCBtYXRlcmlhbHMgYXJlIHRyYWRlbWFya3MgYW5kIGNvcHlyaWdodHMgb2YgRnVuY29tLiA=</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/861731135277865883/BCA986F592ABA8A6B95A687E0E1A3BE8749CDD3F/</image_url>
<download_url/>
<filename/>
<file_size>1291252425</file_size>
</mod>
<mod id="1403991684">
<name>Exile Architect</name>
<description>QnVpbGRpbmcgYmxvY2sgc2V0IGZvciBzY2FmZm9sZGluZyBvciBicmlkZ2VzLCBhbmQgbWFzb24gbGluZXMgdG8gaGVscCBsYXlvdXQgZm91bmRhdGlvbnMuIE1hc29uIGxpbmVzIGJlaGF2ZXMgbGlrZSBmZW5jZSBmb3VuZGF0aW9ucywgYnV0IGNhbiBhbHNvIHNuYXAgYXQgYW5nbGVzLgoKVGhlcmUncyBhIDEgcG9pbnQgZmVhdCBpbiB0aGUgYnVpbGRpbmcgY2F0ZWdvcnkuCgpLbm93biBpc3N1ZXM6CgoqU2hvcnQgbWFzb24gbGluZXMgY2FuIG5vdyBzbmFwIGF0IDYwPyBhbmdsZXMgZm9yIGRyYXdpbmcgdHJpYW5nbGVzLiBCdXQgZHVlIHRvIGhvdyBzb2NrZXRzIHdvcmssIHRoZXknbGwgYWxzbyBzbmFwIGF0IDMwPyBhbmdsZXMsIHNvIGJlIGF3YXJlLgoKKkZlbmNlcyBhbmQgd2FsbHMgY2FuIHN0YWNrIG9uIG1hc29uIGxpbmVzLiBUaGV5IGhhdmUgcmF0aGVyIGxvdyBoZWFsdGggdGhvdWdoLCBzbyBpdCdzIHByb2JhYmx5IG5vdCBhIGdvb2QgaWRlYSB0byB1c2UgdGhlbSBhcyBmb3VuZGF0aW9ucyBvbiBhbnl0aGluZyBkZWZlbnNpdmUuCgoqSWYgdXBncmFkaW5nIGZyb20gcHJldmlvdXMgdmVyc2lvbiwgeW91IG1heSBuZWVkIHRvIGRyaW5rIGEgbG90dXMgcG90IChvciBhZG1pbiBzZWxmIGlmIFNQKSB0byByZWxlYXJuIGZlYXQgdG8gZ2V0IG5ldyByZWNpcGVzLgoKTW9kIGNvbXBhdGliaWxpdHkgbm90ZXM6CgpJdGVtIElEcyAxNzc1MDAxIC0gMTc3NTAwOQpSZWNpcGUgSURzIDE3NzUxMDEgLSAxNzc1MTA5CkZlYXQgSUQgMTc3NTEwMA==</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/915800878318924163/704FD0BCBB9780EBCD0AB50B81DCEA210EC752C6/</image_url>
<download_url/>
<filename/>
<file_size>21626043</file_size>
</mod>
<mod id="1382120864">
<name>LowerMonsterHPSolo</name>
<description>Q2hhbmdlczoNCk1vbnN0ZXJIZWFsdGgNCjgJTlBDX0thcHBhSGF0Y2hsaW5nDQo4CU5QQ19SYWJiaXQNCjExCU5QQ19WdWx0dXJlDQoxMwlOUENfR2F6ZWxsZUZhd24NCjEzCU5QQ19IeWVuYVNwb3R0ZWRDdWINCjEzCU5QQ19IeWVuYVN0cmlwZWRDdWINCjE5CU5QQ19QaXJhbmhhDQoyMAlOUENfVGlnZXJDdWINCjIwCU5QQ19Xb2xmUHVwcHkNCjIyCU5QQ19Pc3RyaWNoQ2hpY2sNCjIyCU5QQ19Xb2xmRGlyZVB1cHB5DQoyMwlOUENfQ3JvY29kaWxlQmFieQ0KMjMJTlBDX1NhYnJldG9vdGhDdWINCjI1CU5QQ19KYWd1YXJDdWINCjI1CU5QQ19QYW50aGVyQ3ViDQoyNQlOUENfUGlnbGV0DQoyNQlOUENfV2lsZEJvYXJQaWdsZXQNCjMwCU5QQ19CZWFyQmxhY2tDdWINCjMwCU5QQ19CZWFyQnJvd25DdWINCjQ2CU5QQ19SaGlub0JhYnkNCjU3CU5QQ19QaWtlZmlzaA0KNTgJTlBDX0ltcA0KNTgJTlBDX0ltcEV4cGxvc2l2ZQ0KNjUJTlBDX0dhemVsbGUNCjY2CU5QQ19Db2JyYQ0KNjgJTlBDX0VsZXBoYW50QmFieQ0KODcJTlBDX1NwaWRlckJyb3duDQo4OQlOUENfT3N0cmljaA0KOTIJTlBDX0FudGVsb3BlU3BpcmFsSG9ybg0KOTYJTlBDX0h5ZW5hU3BvdHRlZA0KMTAwCU5QQ19IdW1hbm9pZA0KMTAzCU5QQ19IeWVuYVN0cmlwZWQNCjEwOQlOUENfU3BpZGVyV2lkb3dZZWxsb3cNCjE0MAkjTi9BDQoxNDIJTlBDX0FudGVsb3BlS2luZw0KMTQ3CU5QQ19TcGlkZXJHcmV5DQoxNDcJTlBDX1NlcnBlbnRwZW9wbGVIb3JkZWxpbmcNCjE0NwlOUENfU2VycGVudHBlb3BsZUlsbHVzaW9uDQoxNTIJTlBDX01vdW50YWluR29hdA0KMTU5CU5QQ19HZW5lcmljDQoxNjQJTlBDX0h5ZW5hVW5kZWFkDQoxNzEJTlBDX1NwaWRlclJlZG1vdXRoDQoxOTUJTlBDX1NwaWRlcldpZG93DQoyMDAJTlBDX1Njb3JwaW9uTWVkaXVtDQoyMDAJTlBDX1NwaWRlckdyZWVuDQoyMTcJTlBDX09vemUNCjIzNQlOUENfS2FwcGENCjIzNQlOUENfU2tlbGV0b25EYXJmYXJpDQoyMzYJTlBDX0RlZXINCjIzNwlOUENfUm9ja25vc2UNCjI2MQlOUENfQ3JvY29kaWxlDQoyNjUJTlBDX0NhbWVsDQoyNzgJTlBDX0Vsaw0KMjkxCU5QQ19Sb2Nrbm9zZU1vbHRlbg0KMjkxCU5QQ19Sb2Nrbm9zZVdoaXRlDQozMDgJTlBDX1NwaWRlcldpZG93Qmx1ZQ0KMzEwCU5QQ19Ta2VsZXRvbkRyZWdzDQozMTEJTlBDX0xvY3VzdEdyZWVuDQozMTEJTlBDX1RpZ2VyDQozMTgJTlBDX1NwaWRlcldpZG93R3JlZW4NCjMyMQlOUENfU2NvcnBpb25MYXJnZQ0KMzU5CU5QQ19TcGlkZXJXaWRvd1JlZA0KMzU5CU5QQ19Xb2xmDQozODUJTlBDX1BhbnRoZXINCjQwMAlOUENfSnVuZ2xlQmlyZA0KNDMwCU5QQ19KYWd1YXINCjQ0MwlOUENfS29tb2RvDQo0NDkJTlBDX0xvY3VzdFllbGxvdw0KNTA0CU5QQ19TYWxhbWFuZGVyDQo1MDcJTlBDX0xvY3VzdFdoaXRlDQo1MzEJTlBDX1NlcnBlbnRwZW9wbGVCb3cNCjUzMQlOUENfU2VycGVudHBlb3BsZVN3b3Jkcw0KNTM1CU5QQ19BcnRpbGxlcnkNCjUzNQlOUENfQmVhc3RtYXN0ZXINCjUzNQlOUENfQnJhd2xlcg0KNTM1CU5QQ19DcnVzaGVyDQo1MzUJTlBDX01vdW50ZWQNCjUzNQlOUENfUmFuZ2VyDQo1MzUJTlBDX1Njb3V0DQo1MzUJTlBDX1VuZGVhZA0KNTM1CU5QQ19XYXJyaW9yDQo1MzUJTlBDX1dlcmVoeWVuYQ0KNTM1CU5QQ19XaWxkQm9hcg0KNjEwCU5QQ19Hb3JpbGxhDQo2MzcJTlBDX1NhYnJldG9vdGgNCjY3MwlOUENfUmVwdGlsZUJlYXN0DQo2ODUJTlBDX0NoaWxkcmVuT2ZKaGlsDQo2ODUJTlBDX0dyZXlBcGUNCjY4NQlOUENfU2tlbGV0b25TZXJwZW50TWFuDQo3NTAJTlBDX1JvY2tub3NlS2luZ01vbHRlbg0KNzUwCU5QQ19CYXREZW1vbg0KODE4CU5QQ19Hb3JpbGxhU2lsdmVyYmFjaw0KODE4CU5QQ19LYXBwYVVuZGVhZA0KODM1CU5QQ19Ta2VsZXRvbkFybW9yDQo4NTUJTlBDX0JlYXJCcm93bg0KODgwCU5QQ19EZWF0aEtuaWdodE1pbmlvbg0KOTA5CU5QQ19Xb2xmRGlyZQ0KOTEwCU5QQ19ZZXRpDQoxMTUyCU5QQ19CZWFyDQoxMjc0CU5QQ19XaWdodA0KMTI5OAlOUENfUmhpbm9HcmV5DQoxMjk4CU5QQ19SaGlub1doaXRlDQoxMzY1CU5QQ19JbXBLaW5nDQoxNDY3CU5QQ19FbGtLaW5nDQoxNDY3CU5QQ19FbGVwaGFudA0KMTU5MAlOUENfQ3JvY29kaWxlR2lhbnRUb21iDQoxNjI2CU5QQ19Gcm9zdEdpYW50DQoxNjI2CU5QQ19Gcm9zdEdpYW50VHV0b3JpYWwNCjE3MzEJTlBDX1JvY2tub3NlS2luZw0KMTk3MwlOUENfTWFtbW90aA0KMjA3OAlOUENfUm9ja25vc2VLaW5nSWNlDQoyMTA4CU5QQ19TZXJwZW50cGVvcGxlQnJ1dGUNCjIxNDIJTlBDX1N0b3J5Ym9zcw0KMjE3NQlOUENfU2VycGVudHBlb3BsZUJvd0tpbmcNCjIxNzUJTlBDX1NlcnBlbnRwZW9wbGVTd29yZHNLaW5nDQoyMjQwCU5QQ19HaWFudEtpbmdHaG9zdA0KMjQ5MglOUENfV2l0Y2hRdWVlbkd1YXJkaWFuDQoyNTQwCU5QQ19TYW5kc3Rvcm1CZWFzdA0KMjcyMAlOUENfV2lsZEJvYXJCb3NzDQozMjAwCU5QQ19LYXBwYUtpbmcNCjM2NTAJTlBDX0JhdERlbW9uV2hpdGUNCjM4MzIJTlBDX0xhdmFXb3JtDQo0MDU0CU5QQ19TZXdlckFib21pbmF0aW9uDQo0MjEzCU5QQ19HaWFudEtpbmdCb3NzDQo0ODkwCU5QQ19SaGlub0JsYWNrDQo1NTY1CU5QQ19EcmFnb25IYXRjaGxpbmcNCjU4MjcJTlBDX0Zyb3N0R2lhbnRCb3NzDQo1ODI3CU5QQ19Gcm9zdEdpYW50U21pdGgNCjYxODMJTlBDX0RlYXRoS25pZ2h0Qm9zcw0KNjE4MwlOUENfTG9jdXN0UXVlZW5Td2FtcFRvbWINCjkwOTUJTlBDX1JvY2tub3NlS2luZ0Jvc3NNb3NzDQo5MTAwCU5QQ19EcmFnb24NCjkxMDAJTlBDX0RyYWdvbkdyZWVuDQo5MTAwCU5QQ19VbmRlYWREcmFnb24NCjkxMDAJTlBDX0RyYWdvbldoaXRlDQoxMDA1MwlOUENfQWxwaGFlbGVwaGFudA0KMTAwNTMJTlBDX0FscGhhc25ha2UNCjEwMDUzCU5QQ19TbmFrZUdpYW50DQoxMDI2NAlOUENfTG9jdXN0UXVlZW5EZXNlcnQNCjEwMjY0CU5QQ19Mb2N1c3RRdWVlblN3YW1wDQoxMDI2NAlOUENfVGlnZXJXaGl0ZQ0KMTA3NDQJTlBDX0RlbW9uU3BpZGVyDQoxMDc0NAlOUENfU3BpZGVyR2lhbnQNCjExMDQ0CU5QQ19Dcm9jb2RpbGVHaWFudA0KMTE0NzkJTlBDX1Njb3JwaW9uS2luZw0KMTE2NTEJTlBDX1JlcHRpbGVCZWFzdEJvc3MNCjEyOTAwCU5QQ19SaGlub0tpbmcNCjEzMjAwCU5QQ19Td2FtcEtpbmcNCg==</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/929309228564296120/59CC87CB7CC2019162FFD950A15765B0420D4431/</image_url>
<download_url/>
<filename/>
<file_size>724791</file_size>
</mod>
<mod id="1369802940">
<name>Emberlight</name>
<description>TW9kIElEOiAxMzY5ODAyOTQwDQoNCldlbGNvbWUgdG8gRW1iZXJsaWdodCEgVGhpcyBtb2QgaXMgaW50ZW5kZWQgZm9yIHJvbGVwbGF5ZXJzIGFuZCBvdGhlciBDb25hbiBFeGlsZXMgcGxheWVycyB3aG8gd2FudCBhIHJpY2hlciBhbmQgbW9yZSBpbW1lcnNpdmUgZXhwZXJpZW5jZS4gSXQgZm9jdXNlcyBlbnRpcmVseSBvbiBjb250ZW50IGZvciBwbGF5ZXJzOyB5b3Ugd29uJ3QgbmVlZCB0aGUgYWRtaW4gcGFuZWwgdG8gYWNjZXNzIGFueSBvZiB0aGUgbW9kJ3MgY3VycmVudCBvciBmdXR1cmUgY29udGVudC4gUmVhZCBvbiB0byBzZWUgd2hhdCB0aGUgbW9kIGluY2x1ZGVzIGN1cnJlbnRseSBhbmQgd2hhdCB3ZSBoYXZlIHBsYW5uZWQgZm9yIGZvciB0aGUgd2Vla3MgYW5kIG1vbnRocyBhaGVhZC4NCg0KSm9pbiB0aGUgRW1iZXJsZWdpb24gb24gRGlzY29yZDoNCmh0dHBzOi8vZGlzY29yZC5nZy81TXY3ZWR5DQoNCllvdSBjYW4gYWxzbyBiZWNvbWUgYW4gRW1iZXJsaWdodCBQYXRyb24gaGVyZToNCmh0dHBzOi8vd3d3LnBhdHJlb24uY29tL3N0dWRpb2VtYmVybGlnaHQNCg0KDQoNCltoMV1GRUFUVVJFUyBTVU1NQVJZWy9oMV0NCg0KKFZpc2l0IG91ciBEaXNjdXNzaW9ucyB0YWIgZm9yIGEgbW9yZSBkZXRhaWxlZCBicmVha2Rvd24gb2YgRW1iZXJsaWdodCdzIGZlYXR1cmVzKQ0KDQpbYl1Ib3J0aWN1bHR1cmVbL2JdDQpbbGlzdF1bKl1DcmFmdCwgZmFybSBhbmQgZGVjb3JhdGUgd2l0aCBhIHdpZGUgdmFyaWV0eSBvZiBpdGVtczoNCltsaXN0XVsqXURlY29yYXRpdmUgZmxvd2VyIHBvdHMgYW5kIHRyZWVzDQpbKl1QbGFjZWFibGUgcG90dGVkIHBsYW50ZXJzIGFuZCBtdXNocm9vbSBib3hlcw0KWypdR2FyZGVuIGJveGVzIGFuZCB3ZWRnZXMgd2hpY2ggY2FuIHNuYXAgdG8gYnVpbGRpbmcgcGllY2VzWy9saXN0XVsvbGlzdF0NCg0KW2JdQW5pbWFsIEh1c2JhbmRyeVsvYl0NCltsaXN0XVsqXUJ1aWxkIHBlbnMgYW5kIGtlZXAgZ2FtZSBmb3IgaGlkZXMsIG1lYXQgYW5kIG90aGVyIHJlc291cmNlcy4gVGhlIGZvbGxvd2luZyBhbmltYWxzIGNhbiBiZSBkb21lc3RpY2F0ZWQ6DQpbbGlzdF1bKl1SYWJiaXRzDQpbKl1BbnRlbG9wZXMNClsqXUdhemVsbGUNClsqXU9zdHJpY2hlcw0KWypdR29hdHMNClsqXUJvYXINClsqXURlZXINClsqXUp1bmdsZSBCaXJkc1svbGlzdF1bL2xpc3RdDQoNCltiXUN1aXNpbmUhWy9iXQ0KW2xpc3RdWypdRm9vZCwgc291cHMgYW5kIGRyaW5rcyBhcmUgbm93IHZpc2libGUgd2hlbiBwbGFjZWQgaW4gdGhlIGludmVudG9yeSBvZiBzcGVjaWFsIFNlcnZpbmcgZGlzaGVzIGFuZCBtdWdzLCB0YW5rYXJkcyBhbmQgZmxhZ29ucy4gWW91IGNhbiBvYnRhaW4gdGhlc2UgaXRlbXMgZnJvbSB0aGUgSG9zcGl0YWxpdHkgZmVhdHMgaW4gdGhlIERlY29yYXRpb24gdGFiIG9mIHlvdXIgRmVhdHMgc2NyZWVuLlsvbGlzdF0NCg0KW2JdU3RyYWlnaHQgUmF6b3JbL2JdDQpbbGlzdF1bKl1Vc2UgdGhlIFZhbml0eSBwbGFjZWFibGUgaXRlbSB0byBjdXN0b21pemUgeW91ciBjaGFyYWN0ZXIncyBoZWFkIGFuZCBib2R5IGhhaXIuWy9saXN0XQ0KDQpbYl1BZGRpdGlvbmFsIFdlYXBvbnMgYW5kIEFybW9yWy9iXQ0KW2xpc3RdWypdQ3VsdHVyYWwgV2VhcG9ucyB3aXRoIGZ1bGwgdGllciBwcm9ncmVzc2lvbnMNClsqXUFybW9yIGFuZCBjbG90aGluZyB2YXJpYW50cw0KWypdRW5kZ2FtZSB2YXJpYW50cyBvZiBwb3B1bGFyIGxvd2VyLXRpZXIgd2VhcG9ucw0KWypdRmlzdCBXZWFwb25zIGZvciB0aWVycyAyIHRocm91Z2ggNQ0KWypdV29vZGVuIHdlYXBvbnMgZm9yIHNwYXJyaW5nDQpbKl1SdWdnZWQgV3JhcHMsIHJlaW50cm9kdWNpbmcgdGhlIGxvaW5jbG90aCBhbmQgY2hlc3R3cmFwIG9mIG9sZA0KWypdQ29sZCB3ZWF0aGVyIGNsaW1iaW5nIGJvb3RzIGFuZCBnbG92ZXMsIGxlYXJuZWQgdmlhIHRoZSBNb3VudGFpbmVlciBmZWF0Wy9saXN0XQ0KDQpbYl1BZGRpdGlvbmFsIEl0ZW1zWy9iXQ0KW2xpc3RdWypdQmluZGFibGUgQmVkIFBpbGxvd3MNClsqXUJvb2sgc2hlbHZlcyBhbmQgcGxhY2VhYmxlIHJvd3Mgb2Ygam91cm5hbHMgYW5kIHN0YWNrcyBvZiBzY3JvbGxzDQpbKl1TdG9uZSBidXRjaGVyIHRvb2xzIChsZWFybmVkIHdpdGggdGhlIEFwcHJlbnRpY2UgQnV0Y2hlciBmZWF0KQ0KWypdSXJvbiBTaWNrbGUgKGxlYXJuZWQgd2l0aCB0aGUgSXJvbiBUb29scyBmZWF0KVsvbGlzdF0NCg0KW2JdUXVhbGl0eSBvZiBsaWZlIGltcHJvdmVtZW50c1svYl0NCltsaXN0XVsqXXN0YWNrIHNpemVzIGluY3JlYXNlZCB0byAxMDAgZm9yIG1vc3QgY29uc3VtYWJsZXMgYW5kIG1hdGVyaWFscw0KWypdQmFzaWMgY3JhZnRpbmcgc3RhdGlvbiBpbnZlbnRvcnkgc2l6ZSBpbmNyZWFzZWQgdG8gMzAgc2xvdHMuDQpbKl1QcmVzZXJ2YXRpb24gYm94IGFuZCBJbXByb3ZlZCBQcmVzZXJ2YXRpb24gYm94IGludmVudG9yaWVzIGRvdWJsZWQuDQpbKl1CYXJyZWxzIGFuZCBTbWFsbCBCYXJyZWxzIGNhbiBub3cgYmUgdXNlZCB0byBzdG9yZSBpdGVtcw0KWypdQ29tYmluZSBMZWF0aGVyIHRvIG1ha2UgVGhpY2sgTGVhdGhlciBhdCB0aGUgQXJtb3JlcidzIEJlbmNoDQpbKl1DcmFmdGluZyBzaGFwZWQgd29vZCBwcm9kdWNlcyAxIGJhcmsNClsqXVZhbml0eSBDYW1lcmEgYWRqdXN0ZWQgdG8gYWxsb3cgeW91IHRvIGdldCB5b3VyIEdVSSBiYWNrIGJ5IGNyb3VjaGluZyBvciBlbW90aW5nLlsvbGlzdF0NCg0KDQoNCltoMV1GRUFUVVJFUyAoQ29taW5nIFNvb24hKVsvaDFdDQoNClsqXU1vcmUgY3VsdHVyYWwgd2VhcG9ucyBhbmQgbW9yZSBhcm1vciB2YXJpYW50cw0KWypdQ29uc2NyaXB0cyEgU2VuZCB5b3VyIHRocmFsbHMgb3V0IHRvIGNvbGxlY3QgcmVzb3VyY2VzIGFuZCBjb21wbGV0ZSBvdGhlciB0YXNrcw0KWypdTmV3IGJ1aWxkaW5nIGJsb2NrcyBhbmQgZGVjbyBpdGVtc1svbGlzdF0NCg0KDQoNCltoMV1GRUFUVVJFUyAoQ29taW5nIG5vdCBhcyBzb29uISlbL2gxXQ0KDQpbbGlzdF1bKl1BZHZhbmNlZCBjb21iYXQNClsqXUFkdmFuY2VkIHJlbGlnaW9uLCBteXN0aWNpc20gYW5kIGFsY2hlbXlbL2xpc3RdDQoNCg0KDQpbaDFdS05PV04gSVNTVUVTWy9oMV0NCg0KWypdU29tZSBob3J0aWN1bHR1cmUgaXRlbXMgZG9uJ3QgcGxheSB0aGVpciBwbGFjZW1lbnQgc291bmRzLg0KWypdR2FyZGVuIFdlZGdlcyBjYW4gYmUgcGxhY2VkIGluc2lkZSBvZiBHYXJkZW4gQm94ZXMuIElmIHlvdSBkbyB0aGlzLCB5b3UncmUgYmFkLiBEb24ndCBiZSBiYWQuDQpbKl1Mb290IHByZXZpZXcgZG9lcyBub3Qgc2hvdyB0aGUgb3V0cHV0IG9mIEhvcnRpY3VsdHVyZSBtYWNoaW5lcyAoZ2FyZGVuIGJveGVzIGFuZCB3ZWRnZXMsIHBsYW50ZXJzIGFuZCBtdXNocm9vbSBib3hlcykuIFRoZSBvdXRwdXQgb2YgdGhlc2Ugc3RhdGlvbnMgaXMgY2FsY3VsYXRlZCBvbiBwbGF5ZXIgaW50ZXJhY3Rpb24gdG8gcmVkdWNlIHNlcnZlciBsb2FkLiBXZSdyZSB3b3JraW5nIG9uIGEgc29sdXRpb24gZm9yIHRoaXMuWy9saXN0XQ0KDQoNCg0KU3BlY2lhbCB0aGFua3MgdG8gSm9zaHRlY2ggYW5kIHRoZSBQSVBQSSB0ZWFtIGZvciB0aGVpciBzdXBwb3J0IGFuZCBicmFpbiBwb3dlci4gd2UgPDMgdSBndXl6Lg==</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/929308506301543680/CE3C865085C0C5FF2879FB8E9D875098C17F01B5/</image_url>
<download_url/>
<filename/>
<file_size>1667910631</file_size>
</mod>
</mods>
<config>
<regex>(.*\n?)*</regex>
<mods_backreference_index>0</mods_backreference_index>
<variable/>
<place_after/>
<mod_string>%first_file%</mod_string>
<string_separator>\n</string_separator>
<filepath>ConanSandbox/Mods/modlist.txt</filepath>
</config>
<post_install>printf "\nRunning post installation for mod %workshop_mod_id%"&#xD;
printf "\nMovin Folders"&#xD;
mv %mods_full_path%/steamapps/workshop/content/440900/%workshop_mod_id%/%first_file% %mods_full_path%/%first_file%&#xD;
printf "\nCleaning up"&#xD;
rm -Rf %mods_full_path%/steamapps/workshop/content/440900/%workshop_mod_id%&#xD;
printf "\nInstallation for mod %workshop_mod_id% completed!"&#xD;
</post_install>
<uninstall>printf "\nUninstalling...\n"&#xD;
rm -vf %mods_full_path%/%mod_string%&#xD;
printf "\nDone!"&#xD;
</uninstall>
</workshop_settings>

View file

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>211820</workshop_id>
<download_method>steamcmd</download_method>
<anonymous_login>0</anonymous_login>
<mods_path>mods</mods_path>
<mods/>
<config>
<regex>mods=(([0-9]+,?)*)</regex>
<mods_backreference_index>1</mods_backreference_index>
<variable>mods=</variable>
<place_after/>
<mod_string>%workshop_mod_id%</mod_string>
<string_separator>,</string_separator>
<filepath>steam_workshop.cfg</filepath>
</config>
<post_install>printf "\nMoving item %workshop_mod_id% ..."&#xD;
mv -f "%mods_full_path%/steamapps/workshop/content/211820/%workshop_mod_id%/contents.pak" "%mods_full_path%/%workshop_mod_id%.pak"&#xD;
rm -Rf "%mods_full_path%/steamapps/workshop/content/211820/%workshop_mod_id%"&#xD;
printf "\nSuccess."</post_install>
<uninstall>printf "\nUninstalling item %mod_string% ...\n"&#xD;
rm -Rf "%mods_full_path%/%mod_string%.pak"&#xD;
printf "\nSuccess."</uninstall>
</workshop_settings>

View file

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>211820</workshop_id>
<download_method>steamcmd</download_method>
<anonymous_login>0</anonymous_login>
<mods_path>mods</mods_path>
<mods/>
<config>
<regex>mods=(([0-9]+,?)*)</regex>
<mods_backreference_index>1</mods_backreference_index>
<variable>mods=</variable>
<place_after/>
<mod_string>%workshop_mod_id%</mod_string>
<string_separator>,</string_separator>
<filepath>steam_workshop.cfg</filepath>
</config>
<post_install>printf "\nMoving item %workshop_mod_id% ..."&#xD;
mv -f "%mods_full_path%/steamapps/workshop/content/211820/%workshop_mod_id%/contents.pak" "%mods_full_path%/%workshop_mod_id%.pak"&#xD;
rm -Rf "%mods_full_path%/steamapps/workshop/content/211820/%workshop_mod_id%"&#xD;
printf "\nSuccess."</post_install>
<uninstall>printf "\nUninstalling item %mod_string% ...\n"&#xD;
rm -Rf "%mods_full_path%/%mod_string%.pak"&#xD;
printf "\nSuccess."</uninstall>
</workshop_settings>

View file

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<workshop_settings>
<workshop_id>730</workshop_id>
<download_method>steamapi</download_method>
<anonymous_login>1</anonymous_login>
<mods_path>mods</mods_path>
<mods>
<mod id="1433404064">
<name>Mirage [Compatibility Version 1.36.3.8]</name>
<description>QW4gb2xkZXIgdmVyc2lvbiBvZiBvZmZpY2lhbCBtYXAgYnkgVmFsdmUgZm9yIGRlbW8gcGxheWJhY2sgY29tcGF0aWJpbGl0eS4gVGhpcyBtYXAgd2FzIHByZXZpb3VzbHkgdXNlZCBpbiBPZmZpY2lhbCBNYXRjaG1ha2luZyBpbiBDUzpHTy4gSXQgY291bGQgYmUgcGxheWVkIGluIERlYXRobWF0Y2gsIENsYXNzaWMgQ2FzdWFsLCBhbmQgQ2xhc3NpYyBDb21wZXRpdGl2ZS4=</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/387665671598503104/9BC8E9D876916173C915233460D559231FF4E4E3/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/945077059916661709/A20ADA8668F0BB0EE12F61314137BE71EFDFF6C3/</download_url>
<filename>de_mirage.bsp</filename>
<file_size>17429043</file_size>
</mod>
<mod id="1440818854">
<name>cs_noffice [office in nuke-style]</name>
<description>YSBzbWFsbCBmdW5tYXANCg0KZW5qb3kgYW5kIGhhdmUgZnVuIDotKQ==</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/964217986228487212/CF7FB6AFE894AF59908CDA64AD5E8F852D39AE1E/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/964217986228482922/A3EB0675317A2395DC96870AFE3EDB9608616787/</download_url>
<filename>cs_noffice.bsp</filename>
<file_size>72639068</file_size>
</mod>
<mod id="1414531578">
<name>de_cornerwork</name>
<description>RGVfY29ybmVyd29yayBmcm9tIENTTzIsIG1hZGUgYnkgTmV4b24=</description>
<image_url>https://steamuserimages-a.akamaihd.net/ugc/938320142839248719/DE42CB9345A53EC8B4BBE5381D8AD55407FD88D1/</image_url>
<download_url>https://steamusercontent-a.akamaihd.net/ugc/938321006101014631/2F2EF3472A0FC4B10D1AD559FC516B742AF43C15/</download_url>
<filename>de_cornerwork.bsp</filename>
<file_size>87872150</file_size>
</mod>
</mods>
<config>
<regex>(.*\n?)*</regex>
<mods_backreference_index>0</mods_backreference_index>
<variable/>
<place_after/>
<mod_string>%first_file%</mod_string>
<string_separator>\n</string_separator>
<filepath>mods/modlist.txt</filepath>
</config>
<post_install>printf "\nRunning post installation for mod %workshop_mod_id%"&#xD;
printf "\nInstalling Map %first_file%\n"&#xD;
unzip -o "%mods_full_path%/steamapps/workshop/content/730/%workshop_mod_id%/%first_file%" -d "%mods_full_path%/../csgo/maps"&#xD;
printf "\nCleaning up"&#xD;
rm -Rf "%mods_full_path%/steamapps/workshop/content/730/%workshop_mod_id%"&#xD;
map=%first_file%&#xD;
map=${map%.bsp}&#xD;
maplist_file="%mods_full_path%/../csgo/maplist.txt"&#xD;
maplist_content=$(cat "$maplist_file")&#xD;
if [ ! -z "${maplist_content##*$map*}" ];then&#xD;
printf "\nAdding Map to maplist.txt"&#xD;
echo $map &gt;&gt; "$maplist_file"&#xD;
else&#xD;
printf "\nMap already in maplist.txt"&#xD;
fi&#xD;
printf "\nInstallation for map %first_file% completed!"&#xD;
</post_install>
<uninstall>map=%mod_string%&#xD;
if [ -f "%mods_full_path%/../csgo/maps/$map" ];then&#xD;
rm -f $map&#xD;
fi&#xD;
map=${map%.bsp}&#xD;
maplist_file="%mods_full_path%/../csgo/maplist.txt"&#xD;
sed -i "/^$map$/d" $maplist_file&#xD;
</uninstall>
</workshop_settings>

View file

@ -0,0 +1,332 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
require_once("includes/lib_remote.php");
require_once("modules/config_games/server_config_parser.php");
require_once("modules/steam_workshop/functions.php");
require_once('includes/form_table_class.php');
echo '<link rel="stylesheet" type="text/css" href="css/xbbcode/xbbcode.css">'."\n".
'<script type="text/javascript" src="js/xbbcode/xbbcode.js"></script>'."\n".
'<script type="text/javascript" src="js/modules/steam_workshop.js"></script>';
function exec_ogp_module()
{
Global $db,$view,$settings;
echo '<h2>Steam Workshop</h2>';
define('CONFIGS', "modules/steam_workshop/game_configs/");
if(isset($_GET['home_id-mod_id-ip-port']) && $_GET['home_id-mod_id-ip-port'] != "")
list($home_id, $mod_id, $ip, $port) = explode("-", $_GET['home_id-mod_id-ip-port']);
else
{
print_failure(get_lang('no_game_servers_assigned'));
return;
}
if(!isset($_POST['workshop_mod_id']) and !isset($_GET['show_log']) and !isset($_POST['manual_workshop_mod_id']))
{
echo "<ul>".
"<li><a href='?m=steam_workshop&p=uninstall&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('uninstall_mods')."</a></li>".
"<li><a href='?m=gamemanager&p=game_monitor&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('back')."</a></li>".
"</ul>";
}
$isAdmin = $db->isAdmin( $_SESSION['user_id'] );
if($isAdmin)
$home_cfg = $db->getGameHome($home_id);
else
$home_cfg = $db->getUserGameHome($_SESSION['user_id'],$home_id);
if($home_cfg)
{
$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_cfg['home_cfg_file']);
if($server_xml === FALSE)
{
print_failure(get_lang_f('failed_reading_xml_file', SERVER_CONFIG_LOCATION."/".$home_cfg['home_cfg_file']));
return;
}
if(!isset($home_cfg['mods'][$mod_id]['mod_key']))
{
print_failure(get_lang_f('mod_id_does_not_exists_in_home', $mod_id, $home_id));
return;
}
$modkey = $home_cfg['mods'][$mod_id]['mod_key'];
$mod_xml = xml_get_mod($server_xml, $modkey);
if (!$mod_xml)
{
print_failure(get_lang_f('mod_key_not_found_from_xml', $modkey));
return;
}
if(preg_match('/(linux|win)(32|64)?/i', $home_cfg['game_key'], $matches))
{
$os = "";
if(strtolower($matches[1]) == 'linux')
$os = "Linux";
elseif(strtolower($matches[1]) == 'win')
$os = "Windows";
}
else
{
print_failure(get_lang_f('unable_to_get_os_from_game_key', $home_cfg['game_key']));
return;
}
$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
if(!file_exists($xml_file))
{
print_failure(get_lang('workshop_configuration_not_found'));
return;
}
$dom = new DOMDocument();
if ( @$dom->load($xml_file) === FALSE )
{
print_failure(get_lang('workshop_configuration_file_has_bad_format'));
return;
}
$xml = simplexml_load_file($xml_file);
if($xml !== false)
{
$remote = new OGPRemoteLibrary($home_cfg['agent_ip'],$home_cfg['agent_port'],$home_cfg['encryption_key'], $home_cfg['timeout']);
if($remote->status_chk() !== 1)
{
print_failure(get_lang('remote_server_offline'));
}
if(isset($_GET['show_log']))
{
$update_active = $remote->get_log(OGP_SCREEN_TYPE_UPDATE,$home_id,clean_path($home_cfg['home_path']),$log_txt);
if ( $update_active == 1 )
{
if(isset($_POST['sgc']))
{
$remote->send_steam_guard_code($home_id, $_POST['sgc']);
return;
}
echo "<p class='note'>". get_lang("update_in_progress") ."</p>\n";
echo "<pre>".$log_txt."</pre>\n</script>\n<div id='dialog' ></div>\n";
if(preg_match('/Two-factor code:$/m', $log_txt) and !isset($_GET['get_sgc']))
{
$view->refresh("?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."&get_sgc=show&show_log",0);
return;
}
if(isset($_GET['get_sgc']) && $_GET['get_sgc'] == 'show')
return;
echo "<p><a href=\"?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."&show_log\">";
echo get_lang("refresh_steam_workshop_status") ."</a></p>";
$view->refresh("?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."&show_log",5);
}
else
{
print_success( get_lang("update_completed") );
echo "<pre>".$log_txt."</pre>\n";
echo "<table class='center'><tr><td><a href='?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'><< ". get_lang("back") ."</a></td></tr></table>";
}
}
else
{
if(isset($_POST['workshop_mod_id']) OR isset($_POST['manual_workshop_mod_id']))
{
$failure = false;
if(isset($_POST['manual_workshop_mod_id']) and $_POST['manual_workshop_mod_id'] != "" and preg_match('/^([0-9]+,?)+$/', $_POST['manual_workshop_mod_id']))
{
$mods_list = $_POST['manual_workshop_mod_id'];
$mod_id_array = explode(',', $mods_list);
foreach($mod_id_array as $workshop_mod_id)
{
$exist = false;
foreach($xml->mods->mod as $mod)
{
if($mod['id'] == $workshop_mod_id)
{
$exist = true;
break;
}
}
if(belongs_to_workshop($workshop_mod_id, $xml->workshop_id))
{
if(!$exist)
{
list($mod_title, $mod_description, $mod_image_url, $download_url, $filename, $file_size) = get_mod_info($workshop_mod_id);
//add mods to the xml
$mod = new SimpleXMLElement('<mod/>');
$mod->addAttribute('id', $workshop_mod_id);
$mod->addChild('name', $mod_title);
$mod->addChild('description', base64_encode($mod_description));
$mod->addChild('image_url', $mod_image_url);
$mod->addChild('download_url', $download_url);
$mod->addChild('filename', $filename);
$mod->addChild('file_size', $file_size);
$moddom = dom_import_simplexml($mod)->ownerDocument;
$moddom->formatOutput = true;
$mod_string = $moddom->saveXML($moddom->documentElement);
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
$mods = $dom->getElementsByTagName('mods')->item(0);
$f = $dom->createDocumentFragment();
$f->appendXML($mod_string."\n");
$mods->appendChild($f);
file_put_contents($xml_file, $dom->saveXML());
$xml = simplexml_load_file($xml_file);
}
}
else
{
print_failure(get_lang_f('mod_does_not_belong_to_workshop', $workshop_mod_id));
$failure = true;
}
}
}
elseif(isset($_POST['workshop_mod_id']))
{
$mods_list = implode(',',$_POST['workshop_mod_id']);
}
if(isset($_POST['install']) and !$failure and isset($mods_list) and preg_match('/^([0-9]+,?)+$/', $mods_list))
{
$config = $xml->config;
$anonymous_login = $xml->anonymous_login;
$download_method = $xml->download_method;
$user = $settings['steam_user'];
$pass = $settings['steam_pass'];
$regex = $config->regex;
$mods_backreference_index = (int)$config->mods_backreference_index;
$variable = $config->variable;
$place_after = $config->place_after;
$mod_string = $config->mod_string;
$string_separator = $config->string_separator;
$config_file_path = clean_path($home_cfg['home_path']."/".$config->filepath);
$post_install = $xml->post_install;
$mod_names_list = get_mod_names_list($mods_list, $xml->mods->mod);
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
$workshop_id = $xml->workshop_id;
$url_list = "";
$filename_list = "";
if($download_method == "steamapi")
{
foreach(explode(',', $mods_list) as $workshop_mod_id)
{
foreach($xml->mods->mod as $mod)
{
if($mod['id'] == $workshop_mod_id)
{
$separator = $url_list == ""?"":",";
$url_list .= $separator.$mod->download_url;
$filename_list .= $separator.$mod->filename;
}
}
}
}
$steam_out = $remote->steam_workshop($home_id, $mods_full_path,
$workshop_id, $mods_list,
$regex, $mods_backreference_index,
$variable, $place_after, $mod_string,
$string_separator, $config_file_path,
$post_install, $mod_names_list,
$anonymous_login, $user, $pass,
$download_method, $url_list, $filename_list);
if ( $steam_out === 1 )
{
print_success( get_lang("mod_installation_started") );
$view->refresh("?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."&show_log", 2);
}
elseif( $steam_out === 0 )
{
print_failure( get_lang("failed_to_start_steam_workshop") );
return;
}
elseif ( $steam_out === -1 )
{
print_failure( get_lang("connection_error") );
}
}
if(isset($_POST['show_info']) and !$failure and isset($mods_list) and preg_match('/^([0-9]+,?)+$/', $mods_list))
{
$mod_id_array = explode(',', $mods_list);
echo "<table>";
foreach($xml->mods->mod as $mod)
{
if(in_array($mod['id'],$mod_id_array))
{
echo "<tr><td><h4>".$mod->name."</h4>".
"<div><img width='240px' style='float:left;' src='".$mod->image_url."'>".
"<div class='bbcode_container' style='padding-left:245px;'>".htmlentities(base64_decode($mod->description))."</div></div><td><tr>";
}
}
echo "</table><a href='?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('back')."</a>";
}
}
else
{
$ft = new FormTable();
$ft->start_form("?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port'], "post", "onsubmit='return isValidForm(this)' data-form-error='".get_lang('select_at_least_one_mod_or_enter_mod_id')."'");
$ft->start_table();
if(count($xml->mods->mod) > 0)
{
echo '<tr><td colspan=2><div id="uninstall_scrolling_checkbox">';
foreach($xml->mods->mod as $mod)
echo "<input type='checkbox' id='select_mod_$mod[id]' name='workshop_mod_id[]' value='$mod[id]'><label for='select_mod_$mod[id]'>".$mod->name."</label><br>";
echo '</div></td></tr>';
}
$ft->add_field('string', 'manual_workshop_mod_id','');
$ft->end_table();
$ft->add_button("submit", "install", get_lang('install_mod'));
$ft->add_button("submit", "show_info", get_lang('show_mod_info'));
$ft->end_form();
}
}
}
else
{
print_failure(get_lang('workshop_configuration_file_has_bad_format'));
return;
}
}
else
{
print_failure(get_lang('game_home_not_found'));
return;
}
}
?>

View file

@ -0,0 +1,30 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
// Module general information
$module_title = "Steam Workshop";
$module_version = "1.1";
$db_version = 0;
$module_required = TRUE;
$module_menus = array(array( 'subpage' => 'workshop_admin', 'name'=>'Steam Workshop', 'group'=>'admin' ));
?>

View file

@ -0,0 +1,43 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
if(isset($server_xml->installer) and $server_xml->installer == "steamcmd")
{
$mod_xml = xml_get_mod($server_xml, $server_home['mod_key']);
require_once("modules/steam_workshop/functions.php");
if(isset($mod_xml->installer_name) and !in_array((string)$mod_xml->installer_name, get_blacklist()))
{
$module_buttons = array(
"<a class='monitorbutton' href='?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$server_home['home_id']."-".$server_home['mod_id']."-".$server_home['ip']."-".$server_home['port']."'>
<img src='" . check_theme_image("images/steam_workshop.png") . "' title='Steam Workshop'>
<span>Steam Workshop</span>
</a>"
);
}
else
$module_buttons = array();
}
else
$module_buttons = array();
?>

View file

@ -0,0 +1,5 @@
<navigation>
<page key="main" file="main.php" access="user,admin" />
<page key="uninstall" file="uninstall.php" access="user,admin" />
<page key="workshop_admin" file="workshop_admin.php" access="admin" />
</navigation>

View file

@ -0,0 +1,17 @@
#scrolling_checkbox{
border:2px solid #ccc;
width:500px;
display: inline-block;
height: 80px;
overflow-y: scroll;
text-align:left;
}
#uninstall_scrolling_checkbox{
border:2px solid #ccc;
width:500px;
display: inline-block;
height: 80px;
overflow-y: scroll;
text-align:left;
}

View file

@ -0,0 +1,178 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
require_once("includes/lib_remote.php");
require_once("modules/config_games/server_config_parser.php");
require_once("modules/steam_workshop/functions.php");
require_once('includes/form_table_class.php');
function exec_ogp_module()
{
Global $db,$view;
echo '<h2>Steam Workshop</h2>';
define('CONFIGS', "modules/steam_workshop/game_configs/");
if(isset($_GET['home_id-mod_id-ip-port']) && $_GET['home_id-mod_id-ip-port'] != "")
list($home_id, $mod_id, $ip, $port) = explode("-", $_GET['home_id-mod_id-ip-port']);
else
{
print_failure(get_lang('no_game_servers_assigned'));
return;
}
if(!isset($_POST['uninstall']))
{
echo "<ul>".
"<li><a href='?m=steam_workshop&p=main&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('install_mods')."</a></li>".
"<li><a href='?m=gamemanager&p=game_monitor&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('back')."</a></li>".
"</ul>";
}
$isAdmin = $db->isAdmin( $_SESSION['user_id'] );
if($isAdmin)
$home_cfg = $db->getGameHome($home_id);
else
$home_cfg = $db->getUserGameHome($_SESSION['user_id'],$home_id);
if($home_cfg)
{
$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_cfg['home_cfg_file']);
if($server_xml === FALSE)
{
print_failure(get_lang_f('failed_reading_xml_file', SERVER_CONFIG_LOCATION."/".$home_cfg['home_cfg_file']));
return;
}
if(!isset($home_cfg['mods'][$mod_id]['mod_key']))
{
print_failure(get_lang_f('mod_id_does_not_exists_in_home', $mod_id, $home_id));
return;
}
$modkey = $home_cfg['mods'][$mod_id]['mod_key'];
$mod_xml = xml_get_mod($server_xml, $modkey);
if (!$mod_xml)
{
print_failure(get_lang_f('mod_key_not_found_from_xml', $modkey));
return;
}
preg_match('/(linux|win)(32|64)?/i', $home_cfg['game_key'], $matches);
if(!isset($matches[1]))
{
print_failure(get_lang_f('unable_to_get_os_from_game_key', $home_cfg['game_key']));
return;
}
if(strtolower($matches[1]) == 'linux')
$os = "Linux";
elseif(strtolower($matches[1]) == 'win')
$os = "Windows";
if(!isset($os))
{
print_failure(get_lang_f('unable_to_get_os_from_game_key', $home_cfg['game_key']));
return;
}
$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
if(!file_exists($xml_file))
{
print_failure(get_lang('no_workshop_configuration_available_for_this_game'));
return;
}
$dom = new DOMDocument();
if ( @$dom->load($xml_file) === FALSE )
{
print_failure(get_lang('workshop_configuration_file_has_bad_format'));
return;
}
$xml = simplexml_load_file($xml_file);
if($xml !== false)
{
$remote = new OGPRemoteLibrary($home_cfg['agent_ip'],$home_cfg['agent_port'],$home_cfg['encryption_key'], $home_cfg['timeout']);
if($remote->status_chk() !== 1)
{
print_failure(get_lang('remote_server_offline'));
}
if(isset($_POST['uninstall']) and isset($_POST['mod_string']))
{
$output = "";
foreach($_POST['mod_string'] as $mod_string)
{
$result = remove_mod($home_cfg, $remote, $xml, $mod_string);
if($result !== FALSE)
$output .= $result."\n";
else
$output .= get_lang_f('failed_uninstalling_mod', $mod_string)."\n";
}
echo "<pre>$output</pre>";
echo "<a href='?m=steam_workshop&p=uninstall&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port']."'>".get_lang('back')."</a>";
}
else
{
$mods = get_installed_mods($home_cfg, $remote, $xml);
if($mods and count($mods) > 0)
{
$ft = new FormTable();
$ft->start_form("?m=steam_workshop&p=uninstall&home_id-mod_id-ip-port=".$_GET['home_id-mod_id-ip-port'], "post", "autocomplete=\"off\"");
$ft->start_table();
echo '<tr><td><div id="uninstall_scrolling_checkbox">';
foreach($mods as $mod_id => $mod_name)
echo "<input type='checkbox' id='select_mod_$mod_id' name='mod_string[]' value='$mod_id'><label for='select_mod_$mod_id'>$mod_name</label><br>";
echo '</div></td></tr>';
$ft->end_table();
$ft->add_button("submit", "uninstall", get_lang('uninstall_mods'));
$ft->end_form();
}
else
{
print_failure(get_lang('there_are_no_mods_installed_on_this_game_server'));
return;
}
}
}
else
{
print_failure(get_lang('workshop_configuration_file_has_bad_format'));
return;
}
}
else
{
print_failure(get_lang('game_home_not_found'));
return;
}
}
?>

View file

@ -0,0 +1,255 @@
<?php
/*
*
* OGP - Open Game Panel
* Copyright (C) 2008 - 2018 The OGP Development Team
*
* http://www.opengamepanel.org/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
require_once('includes/form_table_class.php');
require_once("modules/steam_workshop/functions.php");
function exec_ogp_module()
{
Global $db,$view;
echo '<h2>Steam Workshop</h2>';
define('CONFIGS', "modules/steam_workshop/game_configs/");
if(isset($_REQUEST['home_cfg_id-mod_cfg_id-os']))
list($home_cfg_id, $mod_cfg_id, $os) = explode('-', $_REQUEST['home_cfg_id-mod_cfg_id-os']);
if(isset($home_cfg_id) and isset($mod_cfg_id))
{
$gameCfg = $db->getGameCfg($home_cfg_id);
$cfgMods = $db->getCfgMods($home_cfg_id);
foreach($cfgMods as $cfgMod)
{
if($cfgMod['mod_cfg_id'] == $mod_cfg_id)
$modkey = $cfgMod['mod_key'];
}
$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$gameCfg['home_cfg_file']);
$mod_xml = xml_get_mod($server_xml, $modkey);
if (!$mod_xml)
{
print_failure(get_lang_f('mod_key_not_found_from_xml',$modkey));
return;
}
$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
if(isset($_POST['save_config']))
{
$xml = new SimpleXMLElement('<workshop_settings/>');
$xml->addChild('workshop_id', $_POST['workshop_id']);
$xml->addChild('download_method', $_POST['download_method']);
$xml->addChild('anonymous_login', $_POST['anonymous_login']);
$xml->addChild('mods_path', $_POST['mods_path']);
$mods = $xml->addChild('mods');
if(file_exists($xml_file))
{
$file_xml = simplexml_load_file($xml_file);
foreach($file_xml->mods->mod as $xml_mod)
{
$mod = $mods->addChild('mod');
$mod->addAttribute('id', $xml_mod['id']);
$mod->addChild('name', $xml_mod->name);
$mod->addChild('description', $xml_mod->description);
$mod->addChild('image_url', $xml_mod->image_url);
$mod->addChild('download_url', $xml_mod->download_url);
$mod->addChild('filename', $xml_mod->filename);
$mod->addChild('file_size', $xml_mod->file_size);
}
}
$config = $xml->addChild('config');
$config->addChild('regex', $_POST['regex']);
$config->addChild('mods_backreference_index', $_POST['mods_backreference_index']);
$config->addChild('variable', $_POST['variable']);
$config->addChild('place_after', $_POST['place_after']);
$config->addChild('mod_string', $_POST['mod_string']);
$config->addChild('string_separator', $_POST['string_separator']);
$config->addChild('filepath', $_POST['filepath']);
$xml->addChild('post_install', str_replace('&','&amp;',$_POST['post_install']));
$xml->addChild('uninstall', str_replace('&','&amp;',$_POST['uninstall']));
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
file_put_contents($xml_file, $dom->saveXML());
}
if(isset($_POST['remove_mods']))
{
$xml = new SimpleXMLElement('<workshop_settings/>');
$xml->addChild('workshop_id', $_POST['workshop_id']);
$xml->addChild('download_method', $_POST['download_method']);
$xml->addChild('anonymous_login', $_POST['anonymous_login']);
$xml->addChild('mods_path', $_POST['mods_path']);
$mods = $xml->addChild('mods');
if(file_exists($xml_file))
{
$file_xml = simplexml_load_file($xml_file);
foreach($file_xml->mods->mod as $xml_mod)
{
if(in_array($xml_mod['id'],$_POST['workshop_mod_id']))
continue;
$mod = $mods->addChild('mod');
$mod->addAttribute('id', $xml_mod['id']);
$mod->addChild('name', $xml_mod->name);
$mod->addChild('description', $xml_mod->description);
$mod->addChild('image_url', $xml_mod->image_url);
$mod->addChild('download_url', $xml_mod->download_url);
$mod->addChild('filename', $xml_mod->filename);
$mod->addChild('file_size', $xml_mod->file_size);
}
}
$config = $xml->addChild('config');
$config->addChild('regex', $_POST['regex']);
$config->addChild('mods_backreference_index', $_POST['mods_backreference_index']);
$config->addChild('variable', $_POST['variable']);
$config->addChild('place_after', $_POST['place_after']);
$config->addChild('mod_string', $_POST['mod_string']);
$config->addChild('string_separator', $_POST['string_separator']);
$config->addChild('filepath', $_POST['filepath']);
$xml->addChild('post_install', $_POST['post_install']);
$xml->addChild('uninstall', $_POST['uninstall']);
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
file_put_contents($xml_file, $dom->saveXML());
}
if(file_exists($xml_file))
{
$xml = simplexml_load_file($xml_file);
$workshop_id = $xml->workshop_id;
$download_method = $xml->download_method;
$anonymous_login = $xml->anonymous_login;
$mods_path = $xml->mods_path;
$regex = $xml->config->regex;
$mods_backreference_index = $xml->config->mods_backreference_index;
$variable = $xml->config->variable;
$place_after = $xml->config->place_after;
$mod_string = $xml->config->mod_string;
$string_separator = $xml->config->string_separator;
$filepath = $xml->config->filepath;
$post_install = $xml->post_install;
$uninstall = $xml->uninstall;
}
}
$game_cfgs = $db->getGameCfgs();
$games[0] = get_lang('select_game');
foreach($game_cfgs as $game_cfg)
{
$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$game_cfg['home_cfg_file']);
if(isset($server_xml->installer) and $server_xml->installer == "steamcmd")
{
$cfgMods = $db->getCfgMods($game_cfg['home_cfg_id']);
foreach($cfgMods as $cfgMod)
{
$mod_xml = xml_get_mod($server_xml, $cfgMod['mod_key']);
if(isset($mod_xml->installer_name) and !in_array((string)$mod_xml->installer_name, get_blacklist()))
{
preg_match('/(linux|win)(32|64)?/i', $game_cfg['game_key'], $matches);
if(strtolower($matches[1]) == 'linux')
$os = "Linux";
elseif(strtolower($matches[1]) == 'win')
$os = "Windows";
if(isset($matches[2]) and strtolower($matches[2]) == '64')
$arch = "64";
else
$arch = "32";
$modname = strtolower($cfgMod['mod_name']) == "none"? "":" [MOD:" . $cfgMod['mod_name']."]";
$games[$game_cfg['home_cfg_id'].'-'.$cfgMod['mod_cfg_id'].'-'.$os] = $game_cfg['game_name'] . " (" . $os . " " . $arch . "bits)$modname";
}
}
}
}
$download_methods = array("steamcmd", "steamapi");
$ft = new FormTable();
$ft->start_form("?m=steam_workshop&p=workshop_admin", "post", "autocomplete=\"off\"");
$ft->start_table();
$ft->add_custom_field('game', create_drop_box_from_array_onchange($games, "home_cfg_id-mod_cfg_id-os", @$_REQUEST['home_cfg_id-mod_cfg_id-os']));
if(isset($home_cfg_id) and isset($mod_cfg_id))
{
$ft->add_field('string','workshop_id',@$workshop_id);
$ft->add_custom_field('download_method',create_drop_box_from_array($download_methods, "download_method", @$download_method));
$ft->add_field('on_off','anonymous_login',@$anonymous_login);
$ft->add_field('string','mods_path',@$mods_path);
$ft->add_field('string','regex',@$regex);
$ft->add_field('string','mods_backreference_index',@$mods_backreference_index);
$ft->add_field('string','variable',@$variable);
$ft->add_field('string','place_after',@$place_after);
$ft->add_field('string','mod_string',@$mod_string);
$ft->add_field('string','string_separator',@$string_separator);
$ft->add_field('string','filepath',@$filepath);
$ft->add_field('text','post_install',@$post_install);
$ft->add_field('text','uninstall',@$uninstall);
$ft->end_table();
$ft->add_button("submit","save_config",get_lang('save_config'));
$ft->end_form();
}
else
{
$ft->end_table();
$ft->end_form();
}
if(isset($xml) and count($xml->mods->mod) > 0)
{
$ft = new FormTable();
$ft->start_form("?m=steam_workshop&p=workshop_admin&home_cfg_id-mod_cfg_id-os=".$_REQUEST['home_cfg_id-mod_cfg_id-os'], "post", "autocomplete=\"off\"");
$ft->start_table();
echo "<tr><td>";
$ft->add_field_hidden('workshop_id',$workshop_id);
$ft->add_field_hidden('download_method',$download_method);
$ft->add_field_hidden('anonymous_login',$anonymous_login);
$ft->add_field_hidden('mods_path',$mods_path);
$ft->add_field_hidden('regex',$regex);
$ft->add_field_hidden('mods_backreference_index',$mods_backreference_index);
$ft->add_field_hidden('variable',$variable);
$ft->add_field_hidden('place_after',$place_after);
$ft->add_field_hidden('mod_string',$mod_string);
$ft->add_field_hidden('string_separator',$string_separator);
$ft->add_field_hidden('filepath',$filepath);
$ft->add_field_hidden('post_install',$post_install);
$ft->add_field_hidden('uninstall',$uninstall);
echo "</td></tr>".
'<tr><td colspan=2><div id="scrolling_checkbox">';
foreach($xml->mods->mod as $mod)
echo "<input type='checkbox' id='select_mod_$mod[id]' name='workshop_mod_id[]' value='$mod[id]'><label for='select_mod_$mod[id]'>".$mod->name."</label><br>";
echo '</div></td></tr>';
$ft->end_table();
$ft->add_button("submit","remove_mods",get_lang('remove_mods'));
$ft->end_form();
}
}
?>