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
111
addons/simplelicense/GUI/LicenseGUI.tscn
Normal file
111
addons/simplelicense/GUI/LicenseGUI.tscn
Normal file
|
@ -0,0 +1,111 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bbhv8iqdbkqbt"]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/license_gui.gd" id="1_esldu"]
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/api/LicenseManager.gd" id="2_cpb2k"]
|
||||
|
||||
[node name="LicenseGUI" type="Control"]
|
||||
custom_minimum_size = Vector2(256, 256)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_esldu")
|
||||
load_locations = Array[String](["res://licenses", "res://addons/simplelicense/mod_example/licenses/"])
|
||||
export_locations = Array[String](["user://licenses/game/", "user://licenses/mods/mod_1/"])
|
||||
|
||||
[node name="LicenseManager" type="Node" parent="."]
|
||||
script = ExtResource("2_cpb2k")
|
||||
|
||||
[node name="background" type="Panel" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.381076
|
||||
anchor_right = 0.461806
|
||||
anchor_bottom = 0.0401235
|
||||
offset_left = 3.05176e-05
|
||||
grow_horizontal = 2
|
||||
text = "License Info"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Tree" type="Tree" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.00694444
|
||||
anchor_top = 0.0462963
|
||||
anchor_right = 0.404514
|
||||
anchor_bottom = 0.987654
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 2
|
||||
hide_root = true
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Text" type="TextEdit" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.434028
|
||||
anchor_top = 0.0462963
|
||||
anchor_right = 0.993056
|
||||
anchor_bottom = 0.987654
|
||||
offset_left = -8.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
editable = false
|
||||
scroll_smooth = true
|
||||
minimap_draw = true
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="btn_open_data_dir" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.585069
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.696181
|
||||
anchor_bottom = 0.0416667
|
||||
grow_horizontal = 2
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "Open Data Directory"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="btn_save_licenses" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.491319
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.56684
|
||||
anchor_bottom = 0.0416667
|
||||
grow_horizontal = 2
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "Save Licenses"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="op_locations" type="OptionButton" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.00694444
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.172743
|
||||
anchor_bottom = 0.0416667
|
||||
theme_override_font_sizes/font_size = 12
|
||||
item_count = 2
|
||||
popup/item_0/text = "a"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "b"
|
||||
popup/item_1/id = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[connection signal="item_activated" from="Tree" to="." method="_on_tree_item_activated"]
|
||||
[connection signal="item_selected" from="Tree" to="." method="_on_tree_item_selected"]
|
||||
[connection signal="pressed" from="btn_open_data_dir" to="." method="_on_btn_open_data_dir_pressed"]
|
||||
[connection signal="pressed" from="btn_save_licenses" to="." method="_on_button_pressed"]
|
||||
[connection signal="item_selected" from="op_locations" to="." method="_on_op_locations_item_selected"]
|
BIN
addons/simplelicense/Icon.png
Normal file
BIN
addons/simplelicense/Icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
34
addons/simplelicense/Icon.png.import
Normal file
34
addons/simplelicense/Icon.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://duvmbh55cyvev"
|
||||
path="res://.godot/imported/Icon.png-451064bd72ea26ed7eb00aedd926556f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simplelicense/Icon.png"
|
||||
dest_files=["res://.godot/imported/Icon.png-451064bd72ea26ed7eb00aedd926556f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
163
addons/simplelicense/Icon.svg
Normal file
163
addons/simplelicense/Icon.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 51 KiB |
37
addons/simplelicense/Icon.svg.import
Normal file
37
addons/simplelicense/Icon.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dnr20t153it5i"
|
||||
path="res://.godot/imported/Icon.svg-62b5bc5b7872f9c089f3b98f0084a03c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simplelicense/Icon.svg"
|
||||
dest_files=["res://.godot/imported/Icon.svg-62b5bc5b7872f9c089f3b98f0084a03c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
121
addons/simplelicense/LICENSE.txt
Normal file
121
addons/simplelicense/LICENSE.txt
Normal file
|
@ -0,0 +1,121 @@
|
|||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
37
addons/simplelicense/README.txt
Normal file
37
addons/simplelicense/README.txt
Normal file
|
@ -0,0 +1,37 @@
|
|||
A simple plugin, to make dealing with licensing simple.
|
||||
Files: ./addons/simplelicense/*
|
||||
License: CC0-1.0
|
||||
|
||||
Developed in Godot version: v4.0.beta.custom_build [166df0896]
|
||||
|
||||
Quick Example: (A License Viewer Scene, that you can also drop into one of your game scenes)
|
||||
Run the Scene at
|
||||
res://addons/simplelicense/GUI/LicenseGUI.tscn
|
||||
|
||||
look around, then
|
||||
click on the "open data directory" button
|
||||
then click on the "save licenses" button
|
||||
and watch the data directory populate with license files
|
||||
|
||||
|
||||
Quick Start:
|
||||
1. Create a "LicenseLink" Resource file inside the
|
||||
res://licenses/license_links/
|
||||
|
||||
2. Click on the the new Resource file, and try it out
|
||||
There are docs on how to use it, so just F1 + LicenseLink, to find out more
|
||||
|
||||
3. Load license information
|
||||
Create an instance of "LicenseManager" either in code or by adding the node to the scene
|
||||
then call "load_license_information" on the LicenseManager
|
||||
|
||||
4. Export License information
|
||||
call "export" function on the LicenseManager
|
||||
it will populate the "user://" directory with your license files
|
||||
one combined "COPYRIGHT.txt" file
|
||||
and individual copyright files into "user://licenses/<license_identifier>.txt".
|
||||
The license text will be formatted in the SPDX standard.
|
||||
It's the way the Godot Engine does it.
|
||||
in the Godot Editor: Help -> About Godot -> Third-party Licenses
|
||||
There is more you can do, just visit the docs!
|
||||
(Like support for loading mod's license information!)
|
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())
|
|
@ -0,0 +1,14 @@
|
|||
[gd_resource type="Resource" script_class="LicenseLink" load_steps=3 format=3 uid="uid://ch5muqo430mw"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/mod_example/mod_1.gd" id="1_3n7mw"]
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/api/LicenseLink.gd" id="1_gufc2"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_gufc2")
|
||||
link_files = Array[Resource]([])
|
||||
link_dirs = Array[Resource]([ExtResource("1_3n7mw")])
|
||||
link_paths = []
|
||||
componet_name = "Mod 1"
|
||||
extra = "extra info shown in the comment section of the link text"
|
||||
license_identifier = "mod_1_license_identifier"
|
||||
copyright = Array[String](["copyright year, (comma) name, (comma) company name"])
|
|
@ -0,0 +1,15 @@
|
|||
This is an example of the custom license terms for Mod_1
|
||||
|
||||
So like
|
||||
|
||||
MIT LICENSE TERMS
|
||||
...
|
||||
..
|
||||
.
|
||||
|
||||
or
|
||||
|
||||
CC0 1.0 LICENSE TERMS
|
||||
...
|
||||
..
|
||||
.
|
1
addons/simplelicense/mod_example/mod_1.gd
Normal file
1
addons/simplelicense/mod_example/mod_1.gd
Normal file
|
@ -0,0 +1 @@
|
|||
extends Node
|
9
addons/simplelicense/plugin.cfg
Normal file
9
addons/simplelicense/plugin.cfg
Normal file
|
@ -0,0 +1,9 @@
|
|||
[plugin]
|
||||
|
||||
name="SimpleLicense"
|
||||
description="A simple license managment plugin.
|
||||
|
||||
Licensed under: CC0-1.0"
|
||||
author="GradyTheDev"
|
||||
version="1.1.2"
|
||||
script="plugin.gd"
|
12
addons/simplelicense/plugin.gd
Normal file
12
addons/simplelicense/plugin.gd
Normal file
|
@ -0,0 +1,12 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
# Initialization of the plugin goes here
|
||||
pass
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
# Clean-up of the plugin goes here.
|
||||
pass
|
0
addons/simplelicense/screenshots/.gdignore
Normal file
0
addons/simplelicense/screenshots/.gdignore
Normal file
BIN
addons/simplelicense/screenshots/Example.png
Normal file
BIN
addons/simplelicense/screenshots/Example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 140 KiB |
Loading…
Add table
Add a link
Reference in a new issue