Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
cheese3660 authored Feb 26, 2023
2 parents 49cb46f + 0304e51 commit d1ad3a6
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 40 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ bld/

# Visual Studio 2015/2017 cache/options directory
.vs/
.idea/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

Expand Down
118 changes: 88 additions & 30 deletions ModTemplateGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,95 @@
# !.gitignore

import os
from os.path import expanduser


def find_ksp2_install_path():
# Look for the game in Steam library folders
steam_path = os.path.join(os.getenv("ProgramFiles(x86)"), "Steam")
steam_library_folders_file = os.path.join(steam_path, "steamapps", "libraryfolders.vdf")
steam_install_folder = os.path.join(steam_path, "steamapps", "common", "Kerbal Space Program 2")

if os.path.exists(steam_library_folders_file):
with open(steam_library_folders_file) as f:
for line in f:
if "BaseInstallFolder" in line:
steam_library_path = line.strip().split("\"")[3]
if os.path.exists(os.path.join(steam_library_path, "steamapps", "appmanifest_1406800.acf")):
steam_install_folder = os.path.join(steam_library_path, "steamapps", "common", "Kerbal Space Program 2")
break

# Look for the game in default installation path
if not os.path.exists(steam_install_folder):
default_install_folder = os.path.join(os.getenv("ProgramFiles"), "Private Division", "Kerbal Space Program 2")
if os.path.exists(default_install_folder):
steam_install_folder = default_install_folder

return steam_install_folder

print("Space Warp Mod Setup Wizard")
project_name = input("What would you like to name the project: ")
mod_id = input("What is the ID of the mod: ")
mod_author = input("Who is the author of the mod: ")
mod_name = input("What is the name of the mod: ")

# while True:
# project_name = input("What would you like to name the project: ")
# if not project_name:
# print("Project name cannot be empty, please try again.")
# else:
# break

while True:
mod_id = input("What is the ID of the mod (This should be in snake_case): ")
if not mod_id:
print("Mod ID cannot be empty, please try again.")
else:
break

while True:
mod_author = input("Who is the author of the mod: ")
if not mod_author:
print("Mod author cannot be empty, please try again.")
else:
break

while True:
mod_name = input("What is the name of the mod: ")
if not mod_name:
print("Mod name cannot be empty, please try again.")
else:
break

mod_description = input("What is a short description of the mod: ")
mod_source = input("What is the source link of the mod: ")
mod_version = input("What is the starting version of the mod: ")
mod_ksp_min_version = input("What is the minimum version of KSP2 this mod will accept: ")
mod_ksp_max_version = input("What is the maximum version of KSP2 this mod will accept: ")

# Now we copy all the game directories
space_warp_path = input("What is the path to spacewarp.dll: ")
managed_path = input("What is the path to the KSP managed dlls: ")

os.mkdir(project_name)
os.mkdir(f"{project_name}/{mod_id}")
os.mkdir(f"{project_name}/{mod_id}/assets")
os.mkdir(f"{project_name}/{mod_id}/assets/parts")
os.mkdir(f"{project_name}/{mod_id}/assets/models")
os.mkdir(f"{project_name}/{mod_id}/assets/resources")
os.mkdir(f"{project_name}/{mod_id}/bin")
os.mkdir(f"{project_name}/{mod_id}/config")
namespace = mod_id.replace("_", " ").title().replace(" ", "")
os.mkdir(f"{project_name}/{mod_id}project_name")
os.mkdir(f"{project_name}/{mod_id}/namespace")
os.mkdir(f"{project_name}/external_dlls")

external_dlls = f"{project_name}/external_dlls"
release_folder = f"{project_name}/{mod_id}"
steam_install_folder = find_ksp2_install_path()

if os.path.exists(steam_install_folder):
print(f"Kerbal Space Program 2 is installed at {steam_install_folder}")
else:
managed_path = input("Could not find the installation path for Kerbal Space Program 2.\n Please enter the path to the KSP2 installation folder manually: ")

managed_path = os.path.join(steam_install_folder, "KSP2_x64_Data", "Managed")


mod_id_title = mod_id.replace("_", " ").title().replace(" ", "")
os.mkdir(mod_id)
os.mkdir(f"{mod_id}/{mod_id}")
os.mkdir(f"{mod_id}/{mod_id}/assets")
os.mkdir(f"{mod_id}/{mod_id}/assets/parts")
os.mkdir(f"{mod_id}/{mod_id}/assets/models")
os.mkdir(f"{mod_id}/{mod_id}/assets/resources")
os.mkdir(f"{mod_id}/{mod_id}/bin")
os.mkdir(f"{mod_id}/{mod_id}/config")
os.mkdir(f"{mod_id}/{mod_id_title}")
os.mkdir(f"{mod_id}/{mod_id_title}/{mod_id_title}")
os.mkdir(f"{mod_id}/external_dlls")

external_dlls = f"{mod_id}/external_dlls"
release_folder = f"{mod_id}/{mod_id}"

space_warp_path = os.path.join(managed_path, "SpaceWarp.dll")

shutil.copy2(space_warp_path,external_dlls)

Expand All @@ -91,7 +149,7 @@
with open(f"{external_dlls}/.gitignore","w") as external_gitignore:
external_gitignore.write("*\n!.gitignore")

with open(f"{project_name}/.gitignore","w") as main_gitignore:
with open(f"{mod_id}/.gitignore","w") as main_gitignore:
main_gitignore.writelines(
[
"*.rsuser",
Expand Down Expand Up @@ -140,13 +198,13 @@
with open(f"{release_folder}/README.json","w") as readme:
readme.write("# Default Readme")

code_folder = f"{project_name}/{project_name}/{namespace}"
code_folder = f"{mod_id}/{mod_id_title}/{mod_id_title}"

with open(f"{code_folder}/{namespace}Mod.cs","w") as default_code:
default_code.write("using SpaceWarp.API.Mods;\n\nnamespace " + namespace + "\n{\n [MainMod]\n public class " + namespace + "Mod : Mod\n {\n public override void OnInitialized()\n {\n Logger.Info(\"Mod is initialized\");\n }\n }\n}")
with open(f"{code_folder}/{mod_id_title}Mod.cs","w") as default_code:
default_code.write("using SpaceWarp.API.Mods;\n\nnamespace " + mod_id_title + "\n{\n [MainMod]\n public class " + mod_id_title + "Mod : Mod\n {\n public override void OnInitialized()\n {\n Logger.Info(\"Mod is initialized\");\n }\n }\n}")

with open(f"{code_folder}/{namespace}Config.cs","w") as default_config:
default_config.write("using SpaceWarp.API.Configuration;\nusing Newtonsoft.Json;\n\nnamespace " + namespace + "\n{\n [JsonObject(MemberSerialization.OptOut)]\n [ModConfig]\n public class " + namespace + "Config\n {\n [ConfigField(\"pi\")] [ConfigDefaultValue(3.14159)] public double pi;\n }\n}")
with open(f"{code_folder}/{mod_id_title}Config.cs","w") as default_config:
default_config.write("using SpaceWarp.API.Configuration;\nusing Newtonsoft.Json;\n\nnamespace " + mod_id_title + "\n{\n [JsonObject(MemberSerialization.OptOut)]\n [ModConfig]\n public class " + mod_id_title + "Config\n {\n [ConfigField(\"pi\")] [ConfigDefaultValue(3.14159)] public double pi;\n }\n}")


def quickCreateProperty(root,name,text):
Expand All @@ -156,7 +214,7 @@ def quickCreateProperty(root,name,text):
return a


with open(f"{project_name}/{project_name}/{project_name}.csproj","w") as csproj:
with open(f"{mod_id}/{mod_id_title}/{mod_id_title}.csproj","w") as csproj:
root = minidom.Document()
xml = root.createElement('Project')
xml.setAttribute('Sdk','Microsoft.NET.Sdk')
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Note: Use at your own risk, this is an early version which is expected to have a
# Compiling
In order to compile this project you need the code from kerbal space program 2, so before you can build anything, copy everything in ``Kerbal Space Program 2\KSP2_x64_Data\Managed`` into ``external_dlls/``

Then run one of the build scripts and copy the contents from build to KSP2 root directory.

Then run one of the build scripts and copy the contents from build to KSP2 root directory

Then run KSP2, and wait until the title screen, there should then be a mods folder under the `KSP2_X64_data` folder

Expand Down
14 changes: 14 additions & 0 deletions SpaceWarp/API/Configuration/ConfigSectionAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace SpaceWarp.API.Configuration
{
public class ConfigSectionAttribute : Attribute
{
public string Path;

public ConfigSectionAttribute(string path)
{
Path = path;
}
}
}
1 change: 1 addition & 0 deletions SpaceWarp/SpaceWarp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
<ItemGroup>
<Compile Include="API\Configuration\ConfigDefaultValueAttribute.cs" />
<Compile Include="API\Configuration\ConfigFieldAttribute.cs" />
<Compile Include="API\Configuration\ConfigSectionAttribute.cs" />
<Compile Include="API\Configuration\ConfigurationManager.cs" />
<Compile Include="API\Configuration\DependencyInfo.cs" />
<Compile Include="API\Configuration\ModConfigAttribute.cs" />
Expand Down
106 changes: 97 additions & 9 deletions SpaceWarp/UI/ModConfigurationUI.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using KSP.Game;
using SpaceWarp.API.Configuration;
using SpaceWarp.API.Managers;
Expand All @@ -21,11 +23,15 @@ public class ModConfigurationUI : KerbalMonoBehaviour
private int windowWidth = 350;
private int windowHeight = 700;
private Rect windowRect;

//Have the file structure

// private List<(string name, FieldInfo info, object confAttribute)> fieldsToConfigure =
// new List<(string name, FieldInfo info, object confAttribute)>();


private List<(string name, FieldInfo info, object confAttribute)> fieldsToConfigure =
new List<(string name, FieldInfo info, object confAttribute)>();

private ModConfigurationSection _rootSection = new ModConfigurationSection();


void Awake()
{
windowWidth = (int)(Screen.width * 0.5f);
Expand All @@ -38,13 +44,19 @@ public void Start()
{
object attribute = null;
string attributeName = "";
string section = "";
var sectionAttribute = field.GetCustomAttribute<ConfigSectionAttribute>();
if (sectionAttribute != null)
{
section = sectionAttribute.Path;
}

var fieldAttribute = field.GetCustomAttribute<ConfigFieldAttribute>();
if (fieldAttribute != null)
{
attribute = fieldAttribute;
attributeName = fieldAttribute.Name;
fieldsToConfigure.Add((attributeName, field, attribute));

_rootSection.Insert(section.Split(new []{'/'},StringSplitOptions.RemoveEmptyEntries), (attributeName, field, attribute));
}
}
windowRect = new Rect((Screen.width * 0.15f), (Screen.height * 0.15f),
Expand All @@ -63,7 +75,7 @@ public void OnGUI()
}


public void EditorInputField(string fieldName, FieldInfo info, ConfigFieldAttribute fieldAttribute)
private void EditorInputField(string fieldName, FieldInfo info, ConfigFieldAttribute fieldAttribute)
{
GUILayout.BeginHorizontal();
if (info.FieldType != typeof(bool))
Expand All @@ -81,24 +93,53 @@ public void EditorInputField(string fieldName, FieldInfo info, ConfigFieldAttrib
GUILayout.EndHorizontal();
}

public void EditorForField((string name, FieldInfo info, object confAttribute) field)
private void EditorForField((string name, FieldInfo info, object confAttribute) field)
{
if (field.confAttribute is ConfigFieldAttribute fieldAttribute)
{
EditorInputField(field.name,field.info,fieldAttribute);
}
}

private void SectionPropertyViewer(string sectionName, ModConfigurationSection section, string parent)
{
if (GUILayout.Button(parent == "" ? sectionName : parent + "/" + sectionName))
{
section.Open = !section.Open;
}

if (!section.Open) return;
// Debug.Log($"[ModConfigurationSection] {sectionName} - {section}: {section.Properties.Count}");
foreach (var property in section.Properties)
{
// Debug.Log($"[ModConfigurationUI] {property.name}, {property.info}, {property.confAttribute}");
EditorForField(property);
}

foreach (var sub in section.SubSections)
{
SectionPropertyViewer(sub.path, sub.section, parent == "" ? sectionName : parent + "/" + sectionName);
}
}

private static GUIStyle boxStyle;

private void FillWindow(int windowID)
{
boxStyle = GUI.skin.GetStyle("Box");
GUILayout.BeginVertical();
foreach (var field in fieldsToConfigure)
// These are the root properties
foreach (var field in _rootSection.Properties)
{
// Debug.Log($"[ModConfigurationUI] {field.name}, {field.info}, {field.confAttribute}");
EditorForField(field);
}

foreach (var section in _rootSection.SubSections)
{
SectionPropertyViewer(section.path, section.section, "");
}

if (GUILayout.Button("Save and close"))
{
//Run saving code from the configuration manager
Expand All @@ -112,4 +153,51 @@ private void FillWindow(int windowID)
GUI.DragWindow(new Rect(0, 0, 10000, 500));
}
}

class ModConfigurationSection
{
public bool Open = false;

public List<(string name, FieldInfo info, object confAttribute)> Properties =
new List<(string name, FieldInfo info, object confAttribute)>();
public List<(string path, ModConfigurationSection section)> SubSections =
new List<(string path, ModConfigurationSection section)>();

private ModConfigurationSection TouchSubSection(string subsection)
{
var sub1 = SubSections.FirstOrDefault(sub => sub.path == subsection);
if (sub1 != default) return sub1.section;
var sub2 = new ModConfigurationSection();
// Debug.Log($"[ModConfigurationSection] creating {subsection} - {sub2.GetHashCode()}");
SubSections.Add((subsection,sub2));
return sub2;
}
public void Insert(string[] path, (string name, FieldInfo info, object confAttribute) property)
{
var sb = new StringBuilder();
foreach (var t in path)
{
sb.Append(t + "/");
}
// Debug.Log($"[ModConfigurationSection] {path.Length}: {sb}");
if (path.Length > 0)
{
var subPath = new List<string>();
for (var i = 1; i < path.Length; i++)
{
subPath.Add(path[i]);
}

var recieved_sub = TouchSubSection(path[0]);

// Debug.Log($"[ModConfigurationSection] received {path[0]} - {recieved_sub.GetHashCode()}");
recieved_sub.Insert(subPath.ToArray(),property);
}
else
{
// Debug.Log($"[ModConfigurationSection] {property.name}, {property.info}, {property.confAttribute}");
Properties.Add(property);
}
}
}
}

0 comments on commit d1ad3a6

Please sign in to comment.