mirror of
https://github.com/tonytins/citylimits
synced 2025-06-25 17:34:43 -04:00
Major clean up and reorganization
- Upgraded to Godot 4 - Just remembered the basic principles are based on a tile editor, and dramatically simplified from there. Derp. - New state machine and license display add-ons. - Re-licensed under the GPL because Micropolis' assets aren't under a separate one.
This commit is contained in:
parent
55ed76c914
commit
c980445340
337 changed files with 5129 additions and 7661 deletions
78
addons/simplelicense/api/License.gd
Normal file
78
addons/simplelicense/api/License.gd
Normal file
|
@ -0,0 +1,78 @@
|
|||
class_name License
|
||||
extends Resource
|
||||
## Holds AUTO GENERATED License information
|
||||
|
||||
## SPDX-License-Identifier or similar to it. CASE SENSITIVE[br]
|
||||
## Like "CC0-1.0"[br]
|
||||
## See [url=https://spdx.org/licenses/]SPDX Identifier List[/url]
|
||||
var identifier: String = ""
|
||||
|
||||
## The License's Name. [br]
|
||||
## Like "CC0 1.0 Universal"
|
||||
var name: String = ""
|
||||
|
||||
## License Terms; The text of a license file
|
||||
var terms: String = ""
|
||||
|
||||
## Returns a string containing this license's information, formatted to [url=https://spdx.dev/resources/use/]SPDX Standards[/url]
|
||||
func to_formatted_string() -> String:
|
||||
return "License: {identifier}\n{terms}".format({
|
||||
'identifier': identifier,
|
||||
'terms': _add_line_padding(terms)
|
||||
})
|
||||
|
||||
|
||||
# wouldn't recomend using this, unless you know what your doing
|
||||
# but if you do, this loads and parses all licenses (.txt files) in a directory,
|
||||
# plus Godot's built-in Licenses
|
||||
static func _load_licenses_in(dir: String):
|
||||
var dict = {}
|
||||
|
||||
# get game licenses
|
||||
var names = DirAccess.get_files_at(dir)
|
||||
if names.size() == 0:
|
||||
print_verbose("\nSimple License: No License files found in dir\n", dir, "\nif you have no license files there, then this can be ignored\n")
|
||||
for _name in names:
|
||||
var ext = _name.rsplit('.', false, 1)
|
||||
if ext.size() == 0 or ext[-1] != 'txt':
|
||||
continue
|
||||
|
||||
var l = new()
|
||||
l.identifier = _name.split('.', false, 1)[0]
|
||||
l.name = l.identifier
|
||||
l.terms = FileAccess.open(dir.path_join(_name), FileAccess.READ).get_as_text()
|
||||
dict[l.identifier] = l
|
||||
|
||||
# get licenses built into the Godot Engine
|
||||
var tmp = Engine.get_license_info()
|
||||
for id in tmp:
|
||||
if dict.has(id):
|
||||
continue
|
||||
|
||||
var l = new()
|
||||
l.identifier = id
|
||||
l.terms = tmp[id]
|
||||
dict[id] = l
|
||||
|
||||
return dict
|
||||
|
||||
|
||||
# this is for formatting individual lines accoring to SPDX standards
|
||||
static func _add_line_padding(combined_lines: String, padding: String = " ") -> String:
|
||||
if combined_lines.is_empty():
|
||||
return combined_lines
|
||||
|
||||
var lines = combined_lines.split("\n")
|
||||
|
||||
var s = ""
|
||||
for i in len(lines):
|
||||
if lines[i].is_empty() or lines[i] == "\n":
|
||||
if i+1 < len(lines):
|
||||
s += padding + "." + "\n"
|
||||
else:
|
||||
s += '\n'
|
||||
else:
|
||||
s += padding + lines[i] + "\n"
|
||||
s = s.strip_edges(false)
|
||||
s += '\n'
|
||||
return s
|
178
addons/simplelicense/api/LicenseLink.gd
Normal file
178
addons/simplelicense/api/LicenseLink.gd
Normal file
|
@ -0,0 +1,178 @@
|
|||
class_name LicenseLink
|
||||
extends Resource
|
||||
|
||||
## Files that are under this license [br]
|
||||
## [color=red]WARNING[/color] DO NOT put in any file that Godot Cannot load, via Resource.load() [br]
|
||||
## or it will prevent the game from launching. files like .txt .csg etc
|
||||
@export var link_files: Array[Resource]
|
||||
|
||||
## Directories that are under this license [br]
|
||||
## The given file's Parent Directory will be tracked [br]
|
||||
## [color=red]WARNING[/color] DO NOT put in any file that Godot Cannot load, via Resource.load() [br]
|
||||
## or it will prevent the game from launching. files like .txt .csg etc
|
||||
@export var link_dirs: Array[Resource]
|
||||
|
||||
## Files that are under this license [br]
|
||||
## Note: These paths are [b]NOT[/b] automatically tracked, [br]
|
||||
## you will have to, manually keep these paths up to date
|
||||
@export var link_paths: Array
|
||||
|
||||
## Example: Godot_Icon, Custom Font Name, Your Games Name, etc
|
||||
@export var componet_name: String = ""
|
||||
|
||||
## Gets included in [method to_formatted_string] right after [member componet_name] [br]
|
||||
## as part of the "Comment:" Section of the SPDX format
|
||||
@export var extra: String = ""
|
||||
|
||||
## SPDX-License-Identifier or similar to it. CASE SENSITIVE[br]
|
||||
## Like "CC0-1.0" or more complex entries like [br]
|
||||
## "CC0-1.0 or MIT" [br]
|
||||
## "CC0-1.0 and MIT" [br]
|
||||
## See [url=https://spdx.org/licenses/]SPDX Identifier List[/url]
|
||||
@export var license_identifier: String = "" : set = _set_identifier
|
||||
|
||||
## who and when was the copyright was created [br]
|
||||
## example [br]
|
||||
## 2022, John Doe [br]
|
||||
## (next entry) [br]
|
||||
## 2022-2023, Jim Stirling, Corp xyz [br]
|
||||
@export var copyright: Array[String]
|
||||
|
||||
var license: License
|
||||
|
||||
## Unlike [member license_identifier] this contains [b]ONLY[/b] the identifiers [br]
|
||||
var license_identifiers: Array[String]
|
||||
|
||||
## Either "Godot Engine" or "Game" [br]
|
||||
## This value is AUTO GENERATED [br]
|
||||
## [b]DON'T SET THIS VALUE MANUALLY[/b], IT CAN BREAK THINGS
|
||||
var component_of: String = ""
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_set_identifier(license_identifier)
|
||||
|
||||
|
||||
func _set_identifier(v: String):
|
||||
license_identifier = v
|
||||
|
||||
var tmp = v.replace(' and ', '!break!').replace(' or ', '!break!').split('!break!', false)
|
||||
for x in tmp:
|
||||
license_identifiers.append(x)
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return self.to_formatted_string()
|
||||
|
||||
## Returns a string containing this link's information, formatted to [url=https://spdx.dev/resources/use/]SPDX Standards[/url]
|
||||
func to_formatted_string(hide_files: bool = false):
|
||||
var _files = ""
|
||||
if not hide_files:
|
||||
for x in link_files:
|
||||
_files += x.resource_path.replace("res://", " ./").strip_edges() + "\n"
|
||||
for x in link_dirs:
|
||||
_files += (
|
||||
x.resource_path.replace("res://", " ./").rsplit("/", false, 1)[0].strip_edges()
|
||||
+ "/*\n"
|
||||
)
|
||||
for x in link_paths:
|
||||
_files += x.replace("res://", " ./").strip_edges() + "\n"
|
||||
_files = _files.strip_edges()
|
||||
|
||||
var _comment = ""
|
||||
if not componet_name.is_empty():
|
||||
_comment += componet_name
|
||||
if not extra.is_empty():
|
||||
_comment += "\n"
|
||||
if not extra.is_empty():
|
||||
_comment += extra
|
||||
|
||||
return "Files:{files}\nComment:{comment}\nCopyright:{copyright}\nLicense:{identifier}\n".format(
|
||||
{
|
||||
"files": _add_line_padding(_files, " "),
|
||||
"comment": _add_line_padding(_comment, " "),
|
||||
"copyright": _add_line_padding("\n".join(copyright), " "),
|
||||
"identifier": _add_line_padding(license_identifier, " "),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# wouldn't recomend using this, unless you know what your doing
|
||||
# but if you do, this loads and parses all links (LicenseLink Resource files) in a directory,
|
||||
# plus Godot's built-in Licenses
|
||||
#
|
||||
# exclude engine: excludes loading Godot's built-in license information
|
||||
# this is for mods, in which the main game will have already shown the Godot Engine's Licensing
|
||||
static func _load_links_in(dir: String, exclude_engine: bool = false):
|
||||
var dict = {
|
||||
'array': [],
|
||||
'by_identifier': {},
|
||||
'by_parent': {},
|
||||
}
|
||||
|
||||
if not DirAccess.dir_exists_absolute(dir):
|
||||
printerr('Simple License: LicenseLinks directory is missing! ', dir)
|
||||
return dict
|
||||
|
||||
|
||||
# get Game license links
|
||||
var names = DirAccess.get_files_at(dir)
|
||||
if len(names) == 0:
|
||||
print_verbose("\nSimple License: No LicenseLinks found in dir\n", dir, "\nif you have no LicenseLinks there, then this can be ignored\n")
|
||||
for name in names:
|
||||
name = name.replace('.remap', '')
|
||||
var path = dir.path_join(name)
|
||||
var res = ResourceLoader.load(path)
|
||||
if res is Resource and res.get("copyright") != null:
|
||||
if res.component_of.is_empty():
|
||||
res.component_of = "Game"
|
||||
|
||||
dict.array.append(res)
|
||||
|
||||
dict.by_identifier[res.license_identifier] = res
|
||||
|
||||
if not dict.by_parent.has(res.component_of):
|
||||
dict.by_parent[res.component_of] = {}
|
||||
dict.by_parent[res.component_of][res.license_identifier] = res
|
||||
|
||||
# Get Engine license links
|
||||
if not exclude_engine:
|
||||
for a in Engine.get_copyright_info():
|
||||
var l = new()
|
||||
l.componet_name = a.name
|
||||
l.component_of = "Godot Engine"
|
||||
l.link_paths = a.parts[0].files
|
||||
|
||||
l.license_identifier = a.parts[0].license
|
||||
l.copyright.append_array(a.parts[0].copyright)
|
||||
|
||||
dict.array.append(l)
|
||||
|
||||
dict.by_identifier[l.license_identifier] = l
|
||||
|
||||
if not dict.by_parent.has(l.component_of):
|
||||
dict.by_parent[l.component_of] = {}
|
||||
|
||||
if not dict.by_parent[l.component_of].has(l.license_identifier):
|
||||
dict.by_parent[l.component_of][l.license_identifier] = l
|
||||
|
||||
return dict
|
||||
|
||||
# this is for formatting individual lines accoring to SPDX standards
|
||||
static func _add_line_padding(combined_lines: String, padding: String) -> String:
|
||||
if combined_lines.is_empty():
|
||||
return combined_lines
|
||||
|
||||
var lines = combined_lines.split("\n")
|
||||
|
||||
var s = ""
|
||||
for i in len(lines):
|
||||
if lines[i].is_empty() or lines[i] == "\n":
|
||||
if i+1 < len(lines):
|
||||
s += padding + "." + "\n"
|
||||
else:
|
||||
s += '\n'
|
||||
else:
|
||||
s += padding + lines[i] + "\n"
|
||||
s = s.strip_edges(false)
|
||||
return s
|
121
addons/simplelicense/api/LicenseManager.gd
Normal file
121
addons/simplelicense/api/LicenseManager.gd
Normal file
|
@ -0,0 +1,121 @@
|
|||
class_name LicenseManager
|
||||
extends Node
|
||||
|
||||
## loads license information from this directory and the sub-directory "license_links"
|
||||
@export var load_dir: String = "res://licenses"
|
||||
|
||||
## export license information to this directory and the sub-directory "licenses"
|
||||
@export var export_dir: String = "user://"
|
||||
|
||||
## This disables loading Godot's built-in license information [br]
|
||||
## this is for mods, in which the main game will have already shown the Godot's built-in Licensing
|
||||
@export var exclude_engine: bool = false
|
||||
|
||||
## contains all loaded [License]s [br]
|
||||
## key = identifier [br]
|
||||
## value = [License]
|
||||
var licenses := {}
|
||||
|
||||
## contains all loaded [LicenseLink]s [br]
|
||||
## with searching in mind [br]
|
||||
## "array" [] [br]
|
||||
## "by_identifier" {} license identifier [br]
|
||||
## "by_parent" {} parent component name [br]
|
||||
var license_links := {
|
||||
'array': [],
|
||||
'by_identifier': {},
|
||||
'by_parent': {},
|
||||
}
|
||||
|
||||
|
||||
## Loads license information from [member load_dir] [br]
|
||||
func load_license_information():
|
||||
licenses.clear()
|
||||
license_links.array.clear()
|
||||
license_links.by_identifier.clear()
|
||||
license_links.by_parent.clear()
|
||||
|
||||
if not DirAccess.dir_exists_absolute(load_dir):
|
||||
printerr("Failed to find license directory ", load_dir)
|
||||
return
|
||||
|
||||
licenses = License._load_licenses_in(load_dir)
|
||||
if licenses.has('Expat') and not licenses.has('MIT'):
|
||||
var l = licenses['Expat'].duplicate() as License
|
||||
l.identifier = 'MIT'
|
||||
licenses['MIT'] = l
|
||||
|
||||
license_links = LicenseLink._load_links_in(load_dir.path_join('license_links'), exclude_engine)
|
||||
|
||||
|
||||
## Returns a single string "file", that is formatted in the SPDX Standard [br]
|
||||
## that contains all licensing information, contained in this instance, [br]
|
||||
## if only_links, then the returned data will omit the licensing term files
|
||||
func get_combined_copyright(only_links: bool = false) -> String:
|
||||
var lines = ""
|
||||
|
||||
var used_licenses = {}
|
||||
|
||||
# Links
|
||||
for link in license_links.array:
|
||||
if link is LicenseLink:
|
||||
lines += link.to_formatted_string(link.component_of == 'Godot Engine')
|
||||
lines += '\n'
|
||||
used_licenses.merge(get_all_valid_licenses(link))
|
||||
|
||||
lines += '\n\n'
|
||||
|
||||
if only_links:
|
||||
return lines
|
||||
|
||||
# License Terms
|
||||
var values = used_licenses.values()
|
||||
for i in len(values):
|
||||
if i+1 < len(values):
|
||||
lines += values[i].to_formatted_string() + '\n'
|
||||
else:
|
||||
lines += values[i].to_formatted_string()
|
||||
|
||||
return lines
|
||||
|
||||
## Returns all licenses that are "valid"/exist [br]
|
||||
## Sometimes license files are missing, or Identifiers are incorrectly spelled, this helps with that.
|
||||
func get_all_valid_licenses(link: LicenseLink) -> Dictionary:
|
||||
var d = {}
|
||||
for x in link.license_identifiers:
|
||||
if licenses.has(x):
|
||||
d[x] = licenses[x]
|
||||
return d
|
||||
|
||||
## export all license information to [member export_dir] and the sub-directory "licenses"
|
||||
func export(directory: String = ""):
|
||||
if directory.is_empty():
|
||||
directory = export_dir
|
||||
|
||||
var licenses_path = directory.path_join('licenses')
|
||||
if not DirAccess.dir_exists_absolute(licenses_path):
|
||||
DirAccess.make_dir_recursive_absolute(licenses_path)
|
||||
|
||||
# Export the combined license file
|
||||
var f = FileAccess.open(directory.path_join('COPYRIGHT.txt'), FileAccess.WRITE)
|
||||
if f is FileAccess:
|
||||
f.store_string(self.get_combined_copyright())
|
||||
|
||||
# Export the slim license file
|
||||
f = FileAccess.open(directory.path_join('COPYRIGHT_SLIM.txt'), FileAccess.WRITE)
|
||||
if f is FileAccess:
|
||||
f.store_string(self.get_combined_copyright(true))
|
||||
|
||||
|
||||
# Export the individual license files
|
||||
|
||||
var used = {}
|
||||
for i in license_links.array.size():
|
||||
var license = license_links.array[i] as LicenseLink
|
||||
var ids = self.get_all_valid_licenses(license)
|
||||
used.merge(ids)
|
||||
|
||||
for id in ids:
|
||||
var license_path = licenses_path.path_join(id)+'.txt'
|
||||
f = FileAccess.open(license_path, FileAccess.WRITE)
|
||||
f.store_string(licenses[id].to_formatted_string())
|
Loading…
Add table
Add a link
Reference in a new issue