From 49b4e6c79f645d9c37081580971c694e2c56142e Mon Sep 17 00:00:00 2001 From: Leonheart <33399712+bleonheart@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:17:51 +0000 Subject: [PATCH] Added Temporary Docs --- .gitattributes | 2 +- .github/workflows/ci.yml | 114 +++ .gitignore | 40 + .luacheckrc | 7 + config.ld | 73 ++ docs/css/highlight.css | 96 +++ docs/css/ldoc.css | 522 +++++++++++++ docs/hooks/class.lua | 49 ++ docs/hooks/faction.lua | 61 ++ docs/hooks/module.lua | 708 ++++++++++++++++++ docs/js/app.js | 168 +++++ docs/js/highlight.min.js | 2 + docs/manual/info_compatibility.md | 85 +++ docs/manual/info_converting-from-nutscript.md | 30 + docs/manual/info_features.md | 76 ++ docs/manual/info_installation.md | 88 +++ docs/manual/structure_class.md | 57 ++ docs/manual/structure_command.md | 46 ++ docs/manual/structure_faction.md | 58 ++ docs/manual/structure_items.md | 83 ++ docs/manual/structure_module.md | 98 +++ docs/templates/landing.ltp | 18 + docs/templates/ldoc.ltp | 90 +++ docs/templates/module.ltp | 117 +++ docs/templates/sidebar.ltp | 68 ++ 25 files changed, 2755 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .luacheckrc create mode 100644 config.ld create mode 100644 docs/css/highlight.css create mode 100644 docs/css/ldoc.css create mode 100644 docs/hooks/class.lua create mode 100644 docs/hooks/faction.lua create mode 100644 docs/hooks/module.lua create mode 100644 docs/js/app.js create mode 100644 docs/js/highlight.min.js create mode 100644 docs/manual/info_compatibility.md create mode 100644 docs/manual/info_converting-from-nutscript.md create mode 100644 docs/manual/info_features.md create mode 100644 docs/manual/info_installation.md create mode 100644 docs/manual/structure_class.md create mode 100644 docs/manual/structure_command.md create mode 100644 docs/manual/structure_faction.md create mode 100644 docs/manual/structure_items.md create mode 100644 docs/manual/structure_module.md create mode 100644 docs/templates/landing.ltp create mode 100644 docs/templates/ldoc.ltp create mode 100644 docs/templates/module.ltp create mode 100644 docs/templates/sidebar.ltp diff --git a/.gitattributes b/.gitattributes index dfe0770..eba1110 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ # Auto detect text files and perform LF normalization -* text=auto +* text=auto \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cdb2b25 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,114 @@ + +name: CI +on: [push, pull_request] + +permissions: + actions: write + checks: write + contents: write + deployments: write + id-token: write + issues: write + discussions: write + packages: write + pages: write + pull-requests: write + repository-projects: write + security-events: write + statuses: write + +jobs: + linter: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + path: lilia + + - uses: leafo/gh-actions-lua@v8.0.0 + with: + luaVersion: "5.2" + + - uses: leafo/gh-actions-luarocks@v4.0.0 + + - name: Pull gluacheck + uses: actions/checkout@v2 + with: + repository: impulsh/gluacheck + path: luacheck + + - name: Build gluacheck + working-directory: luacheck + run: luarocks make + + - name: Lint + working-directory: lilia + run: luacheck . --no-redefined + --no-global --no-self + --no-max-line-length --no-max-code-line-length + --no-max-string-line-length --no-max-comment-line-length + --no-max-cyclomatic-complexity + + docs: + runs-on: ubuntu-latest + needs: linter + steps: + - uses: actions/checkout@v2 + with: + path: lilia + + - uses: leafo/gh-actions-lua@v8.0.0 + with: + luaVersion: "5.2" + + - uses: leafo/gh-actions-luarocks@v4.0.0 + + - name: Pull LDoc + uses: actions/checkout@v2 + with: + repository: bleonheart/LDoc + path: ldoc + + - name: Build LDoc + working-directory: ldoc + run: luarocks make + + - name: Build docs + working-directory: lilia + run: ldoc . --fatalwarnings + + - name: Copy assets + working-directory: lilia + run: | + cp -v docs/css/* docs/html + cp -v docs/js/* docs/html + + - name: Deploy + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'LiliaFramework/Lilia' && success() + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: lilia/docs/html + + sync: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'LiliaFramework/Lilia' && success() + runs-on: ubuntu-latest + needs: docs + steps: + - name: Checkout source repository + uses: actions/checkout@v2 + - name: Push to destination repository + run: | + git config --global user.email "githubactions@github.com" + git config --global user.name "Github Actions" + git clone https://${{ env.ORG_NAME }}:${{ secrets.LiliaGitSecret }}@github.com/${{ env.ORG_NAME }}/LiliaFramework.github.io.git liliagit + cd liliagit + git remote add ${{ env.ORIGINAL_REPO_NAME }} https://${{ env.ORG_NAME }}:${{ secrets.LiliaGitSecret }}@github.com/${{ env.ORG_NAME }}/${{ env.ORIGINAL_REPO_NAME }}.git + git remote update + git merge ${{ env.ORIGINAL_REPO_NAME }}/gh-pages --allow-unrelated-histories gh-pages + git push origin gh-pages + env: + GITHUB_TOKEN: ${{ secrets.LiliaGitSecret }} + ORIGINAL_REPO_NAME: ${{ github.event.repository.name }} + ORG_NAME: LiliaFramework \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51b8439 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..2515f9b --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,7 @@ +exclude_files = { + "lilia/modules/utilities/logging/logs.lua", + "lilia/gamemode/libraries/thirdparty/**/*.lua", + "lilia/lilia.txt", + "docs/*.lua", + "docs/**/*.lua", +} \ No newline at end of file diff --git a/config.ld b/config.ld new file mode 100644 index 0000000..3b62ee2 --- /dev/null +++ b/config.ld @@ -0,0 +1,73 @@ +file = { + "docs/hooks", + "lilia", + exclude = {"lilia/gamemode/libraries/thirdparty"} +} + +module_file = { + Character = "lilia/gamemode/libraries/meta/character.lua", + Entity = "lilia/gamemode/libraries/meta/entity.lua", + Inventory = "lilia/gamemode/libraries/meta/inventory.lua", + Item = "lilia/gamemode/libraries/meta/item.lua", + Player = "lilia/gamemode/libraries/meta/player.lua" +} + +dir = "docs/html" +project = "Lilia" +title = "Lilia Documentation" +no_space_before_args = true +style = "docs/css" +template = "docs/templates" +format = "markdown" +ignore = true +topics = "docs/manual" +use_markdown_titles = true +kind_names = {module = "Libraries", topic = "Manual"} +merge = true +sort = true +sort_modules = true + +simple_args_string = true -- we show optionals/defaults outside of the display name +strip_metamethod_prefix = true -- remove the name of the table when displaying metamethod names +no_viewed_topic_at_top = true -- don't put the currently viewed topic at the top +use_new_templates = true -- new templating system +pretty_urls = true -- avoid showing .html in urls +pretty_topic_names = true -- strips extension from manual filenames, this does not check filename collisions + +custom_tags = { + {"realm", hidden = true}, + {"internal", hidden = true} +} + +custom_display_name_handler = function(item, default_handler) + if (item.type == "function" and item.module) then + if (item.module.type == "classmod" or item.module.type == "panel" or item.module.type == "configurations") then + return item.module.mod_name .. ":" .. default_handler(item) + elseif (item.module.type == "hooks") then + return item.module.mod_name:upper() .. ":" .. default_handler(item) + + end + end + + return default_handler(item) +end + +new_type("hooks", "Hooks", true) +new_type("configurations", "Configurations", true) +new_type("panel", "Panels", true) +tparam_alias("inventory", "Inventory") +tparam_alias("item", "Item") +tparam_alias("date", "date") +tparam_alias("panel", "panel") +tparam_alias("string", "string") +tparam_alias("bool", "boolean") +tparam_alias("func", "function") +tparam_alias("client", "Player") +tparam_alias("entity", "Entity") +tparam_alias("character", "Character") +tparam_alias("color", "color") +tparam_alias("tab", "table") +tparam_alias("material", "material") +tparam_alias("vector", "vector") +tparam_alias("angle", "angle") +tparam_alias("int", "integer") diff --git a/docs/css/highlight.css b/docs/css/highlight.css new file mode 100644 index 0000000..e3f984a --- /dev/null +++ b/docs/css/highlight.css @@ -0,0 +1,96 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + color: #333; +} + +.hljs-comment, +.hljs-quote { + color: #535346; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/docs/css/ldoc.css b/docs/css/ldoc.css new file mode 100644 index 0000000..3014c31 --- /dev/null +++ b/docs/css/ldoc.css @@ -0,0 +1,522 @@ + +:root { + --content-width: 1200px; + --sidebar-width: 330px; + + --padding-big: 48px; + --padding-normal: 24px; + --padding-small: 16px; + --padding-tiny: 10px; + + --font-massive: 32px; + --font-huge: 24px; + --font-big: 18px; + --font-normal: 16px; + --font-tiny: 12px; + + --font-style-normal: Segoe UI, Helvetica, Arial, sans-serif; + --font-style-code: Consolas, monospace; + + --color-accent: rgb(53, 133, 66); + --color-accent-dark: rgb(9, 69, 19); + --color-white: rgb(255, 255, 255); + --color-offwhite: rgb(200, 200, 200); + --color-white-accent: rgb(203, 190, 209); + --color-black: rgb(0, 0, 0); + --color-lightgrey: rgb(160, 160, 160); + --color-background-light: rgb(240, 240, 240); + --color-background-dark: rgb(33, 33, 33); +} + +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +body { + background-color: var(--color-background-light); + font-family: var(--font-style-normal); + + display: flex; + flex-direction: column; +} + +a { + color: inherit; + text-decoration: inherit; +} + +h1, h2, h3, h4 { + font-weight: 400; +} + +ul li { + margin-left: var(--padding-small); +} + +/* landing */ +.landing { + background-color: var(--color-accent); + color: var(--color-white); + + padding: 128px 0 128px 0; +} + +.landing h1 { + margin: 0; + padding: 0; + border: none; + + font-weight: 100; + font-size: var(--font-massive); + text-align: center; +} + +.wrapper { + padding: var(--padding-small); +} + +details { + user-select: none; +} + +details summary { + outline: none; +} + +code { + font-family: "Source Code Pro", monospace; + font-size: 85%; + white-space: pre; + tab-size: 4; + -moz-tab-size: 4; + padding: 2px 4px; + background-color: rgb(33, 33, 33, 0.1); +} + +pre { + background-color: rgb(33, 33, 33, 0.1); + margin-top: var(--padding-small); + padding: var(--padding-tiny); + overflow: auto; +} + +pre code { + background-color: transparent; +} + +span.realm { + width: 14px; + height: 14px; + border-radius: 3px; + display: inline-block; + margin-right: 6px; +} + +span.realm.shared { + background: linear-gradient(45deg, #f80 0%, #f80 50%, #08f 51%, #08f 100%); +} + +span.realm.client { + background-color: #f80; +} + +span.realm.server { + background-color: #08f; +} + +/* wrapper element for sidebar/content */ +main { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; + + width: var(--content-width); + margin: auto; +} + +/* sidebar */ +nav { + color: var(--color-offwhite); + background-color: var(--color-background-dark); + + position: fixed; + display: flex; + flex-direction: column; + + width: var(--sidebar-width); + height: 100%; +} + +/* sidebar header */ +nav header { + color: var(--color-white); + background-color: var(--color-accent); + + padding: var(--padding-small); +} + +nav header h1 { + font-size: var(--font-huge); + font-weight: 100; + text-align: center; + + margin-bottom: var(--padding-small); +} + +#search { + background-color: var(--color-accent-dark); + color: var(--color-white); + + border: none; + font-size: var(--font-normal); + outline: none; + + width: 100%; + padding: 6px; +} + +#search::placeholder { + color: var(--color-white-accent); +} + +#search::-webkit-search-cancel-button { + display: none; +} + +/* sidebar contents */ +nav section { + padding: var(--padding-small); + overflow: auto; +} + +nav section ul { + list-style-type: none; +} + +nav section::-webkit-scrollbar, +pre::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +nav section::-webkit-scrollbar-track, +pre::-webkit-scrollbar-track { + background: transparent; +} + +nav section::-webkit-scrollbar-thumb { + background-color: var(--color-lightgrey); +} + +pre::-webkit-scrollbar-thumb { + background-color: var(--color-lightgrey); +} + +/* sidebar contents category */ +nav section details.category { + padding-top: var(--padding-tiny); +} + +nav section details.category > ul > li { + margin: 0; + line-height: 1.5; +} + +nav section details.category > ul > li a { + display: inline-block; + width: 90%; +} + +nav section details.category:first-of-type { + padding-top: calc(var(--padding-tiny) * -1); +} + +nav section details.category summary::-webkit-details-marker { + opacity: 0.5; + cursor: pointer; +} + +nav section details.category summary h2 { + color: var(--color-accent); + + font-size: var(--font-big); + letter-spacing: 2px; + text-transform: uppercase; + cursor: pointer; + + padding-bottom: var(--padding-tiny); +} + +/* content */ +article { + background-color: rgb(255, 255, 255); + + width: calc(100% - var(--sidebar-width)); + min-height: 100vh; + margin-left: var(--sidebar-width); +} + +article .wrapper > *:first-child { + margin-top: 0; +} + +/* header */ +article header { + color: rgb(255, 255, 255); + background-color: rgb(9, 69, 19); + padding: var(--padding-tiny); +} + +article header h1 { + border-bottom: 1px solid rgba(255, 255, 255, 0.25); + padding-bottom: 8px; + font-family: var(--font-style-code); + margin: 0; +} + +article header h2 { + padding-top: var(--padding-tiny); + margin: 0; + font-size: var(--font-normal); + font-weight: normal; +} + +article header.module a { + color: white !important; + text-decoration: underline; +} + +details.category > summary { + list-style: none; +} + +details.category > summary::-webkit-details-marker { + display: none; +} + +article h1 { + font-size: 28px; + font-weight: 600; + border-bottom: 1px solid rgba(0, 0, 0, 0.25); + margin-top: 24px; + margin-bottom: 16px; + padding-bottom: 8px; +} + +article h2 { + font-size: 20px; + font-weight: 600; + margin-top: 12px; +} + +article h3 { + color: rgb(9, 69, 19); + margin-top: var(--padding-tiny); + text-transform: uppercase; +} + +article p { + margin-top: var(--padding-small); +} + +article p a, +article ul li a, +article h1 a, +article h2 a { + color: rgb(9, 69, 19); + font-weight: 600; +} + +article h1.title { + color: rgb(255, 255, 255); + background-color: rgb(9, 69, 19); + margin-top: var(--padding-small); + margin-bottom: 0; + padding: var(--padding-tiny); + + font-size: var(--font-big); + font-weight: 100; + letter-spacing: 2px; + text-transform: uppercase; +} + +a.reference { + color: rgb(9, 69, 19); + float: right; + margin-top: 8px; + padding-left: 8px; + font-size: 14px; + font-weight: 600; +} + +.notice { + --color-notice-background: var(--color-accent); + --color-notice-text: var(--color-notice-background); + + margin-top: var(--padding-tiny); + border: 2px solid var(--color-notice-background); +} + +.notice.error { + --color-notice-background: rgb(194, 52, 130); +} + +.notice.warning { + --color-notice-background: rgb(224, 169, 112); + --color-notice-text: rgb(167, 104, 37); +} + +.notice .title { + color: var(--color-white); + background-color: var(--color-notice-background); + + padding: var(--padding-tiny); + font-size: var(--font-normal); + + text-transform: uppercase; + letter-spacing: 2px; +} + +.notice p { + color: var(--color-notice-text); + + margin: 0 !important; + padding: var(--padding-tiny); +} + +/* function/table */ +.method { + display: flex; + flex-flow: column; + background-color: rgb(230, 230, 230); + padding: var(--padding-tiny); + margin-top: var(--padding-small); +} + +.method header { + color: rgb(0, 0, 0); + background-color: inherit; + padding: 0; + order: -1; +} + +.method header .anchor { + color: inherit; + text-decoration: inherit; +} + +.method header .anchor:target h1 { + background-color: rgba(53, 133, 66, 0.2); + background-clip: content-box; +} + +.method header h1 { + font-family: "Source Code Pro", monospace; + padding-bottom: var(--padding-tiny); + border-bottom: 1px solid rgba(0, 0, 0, 0.25); + font-size: 20px; +} + +.method header p:first-of-type { + margin-top: var(--padding-tiny); +} + +.method h3 { + color: rgb(9, 69, 19); + font-size: var(--font-normal); + letter-spacing: 2px; + text-transform: uppercase; +} + +.method pre { + margin-top: var(--padding-tiny); +} + +@media only screen and (max-width: 1100px) { + main nav { + position: inherit; + } + + main article { + margin-left: 0; + } +} + +.method ul { + margin-top: var(--padding-tiny); + background-color: inherit; +} + +.method ul li { + list-style: none; + margin: 4px 0 0 var(--padding-normal); +} + +.method ul li:first-of-type { + margin-top: 0; +} + +.method ul li p { + margin: 4px 0 0 var(--padding-normal); +} + +.method ul li pre { + margin: 4px 0 0 var(--padding-normal); +} + +.method ul li a { + color: rgb(9, 69, 19); + font-weight: 600; +} + +/* we have to manually specify these instead of making a shared class since you cannot customize the parameter class in ldoc */ +.parameter, .type, .default { + display: inline-block; + color: rgb(255, 255, 255) !important; + + padding: 4px; + font-size: 14px; + font-family: "Source Code Pro", monospace; +} + +.parameter { + background-color: rgb(9, 69, 19); +} + +.type { + background-color: rgb(31, 141, 155); +} + +a.type { + font-weight: 300 !important; + text-decoration: underline; +} + +.default { + background-color: rgb(193, 114, 11); +} + +.type a { + padding: 0; +} + +.or { + color: rgba(53, 133, 66, 0.5); + background-color: inherit; + + width: calc(100% - 32px); + height: 8px; + margin: 0 0 8px 32px; + + text-align: center; + font-weight: 600; + border-bottom: 1px solid rgba(53, 133, 66, 0.5); +} + +.or span { + background-color: inherit; + padding: 0 8px 0 8px; +} diff --git a/docs/hooks/class.lua b/docs/hooks/class.lua new file mode 100644 index 0000000..e5878da --- /dev/null +++ b/docs/hooks/class.lua @@ -0,0 +1,49 @@ +--[[-- +Class setup hooks. + +As with `Faction`s, `Class`es get their own hooks for when players leave/join a class, etc. These hooks are only +valid in class tables that are created in `schema/classes/classname.lua`, and cannot be used like regular gamemode hooks. +]] +-- @hooks Class + +--- Whether or not a player can switch to this class. +-- @realm shared +-- @client client Player who wants to switch to this class +-- @treturn bool True if the player is allowed to switch to this class +-- @usage function CLASS:onCanBe(client) +-- return client:IsAdmin() or client:getChar():hasFlags("Z") -- Only admins or people with the Z flag are allowed in this class! +-- end +function onCanBe(client) +end + +--- Called when a character has left this class and has joined a different one. +-- @realm server +-- @client client Player who left this class +-- @usage +-- function CLASS:onLeave(client) +-- local character = client:getChar() +-- character:setModel("models/player/alyx.mdl") +-- end +function onLeave(client) +end + +--- Called when a character has joined this class. +-- @realm server +-- @client client Player who has joined this class +-- @usage +-- function CLASS:onSet(client) +-- client:setModel("models/police.mdl") +-- end +function onSet(client) +end + +--- Called when a character in this class has spawned in the world. +-- @realm server +-- @client client Player that has just spawned +-- @usage +-- function CLASS:onSpawn(client) +-- client:SetMaxHealth(500) -- Sets your Max Health to 500. +-- client:SetHealth(500) -- Subsequently sets your Health to 500. +-- end +function onSpawn(client) +end diff --git a/docs/hooks/faction.lua b/docs/hooks/faction.lua new file mode 100644 index 0000000..83efa6f --- /dev/null +++ b/docs/hooks/faction.lua @@ -0,0 +1,61 @@ +--[[-- +Faction setup hooks. + +Factions have their own hooks that are called for various reasons, with the most common being to set up a character +once it's created and assigned to a certain faction. For example, giving a police faction character a weapon upon creation. +These hooks are used in faction tables that are created in `schema/factions/sfactionname.lua` and cannot be used like +regular gamemode hooks. +]] +-- @hooks Faction + +--- Called when the default name for a character needs to be retrieved (i.e., upon initial creation). +-- @realm shared +-- @client client The client for whom the default name is being retrieved +-- @treturn string The default name for the newly created character +-- @usage function FACTION:getDefaultName(client) +-- return "CT-" .. math.random(111111, 999999) +-- end +function getDefaultName(client) +end + +--- Called when the default description for a character needs to be retrieved. +-- This function allows factions to define custom default descriptions for characters. +-- @realm shared +-- @client client The client for whom the default description is being retrieved +-- @character faction The faction ID for which the default description is being retrieved +-- @treturn string The default description for the newly created character +-- @usage function FACTION:getDefaultDesc(client, faction) +-- return "A police officer" +-- end +function getDefaultDesc(client, faction) +end + +--- Called when a character has been initially created and assigned to this faction. +-- @realm server +-- @client client The client that owns the character +-- @character character The character that has been created +-- @usage function FACTION:onCharCreated(client, character) +-- local inventory = character:getInv() +-- inventory:add("fancy_suit") +-- end +function onCharCreated(client, character) +end + +--- Called when a character in this faction has spawned in the world. +-- @realm server +-- @client client The player that has just spawned +-- @usage function FACTION:onSpawn(client) +-- client:ChatPrint("You have spawned!") +-- end +function onSpawn(client) +end + +--- Called when a player's character has been transferred to this faction. +-- @realm server +-- @character character The character that was transferred +-- @usage function FACTION:onTransferred(character) +-- local randomModelIndex = math.random(1, #self.models) +-- character:setModel(self.models[randomModelIndex]) +-- end +function onTransferred(character) +end \ No newline at end of file diff --git a/docs/hooks/module.lua b/docs/hooks/module.lua new file mode 100644 index 0000000..058deea --- /dev/null +++ b/docs/hooks/module.lua @@ -0,0 +1,708 @@ +--[[-- +General Hooks. + +These hooks are regular hooks that can be used in your schema with `SCHEMA:HookName(args)`, in your module with +`MODULE:HookName(args)`, or in your addon with `hook.Add("HookName", function(args) end)`. +They can be used for an assorted of reasons, depending on what you are trying to achieve. +]] +-- @hooks Module + +--- Called after a player sends a chat message. +-- @realm server +-- @client client The player entity who sent the message. +-- @string message The message sent by the player. +-- @string chatType The type of chat message (e.g., "ic" for in-character, "ooc" for out-of-character). +-- @bool anonymous Whether the message was sent anonymously (true) or not (false). +function PostPlayerSay(client, message, chatType, anonymous) +end + +--- Whether or not a player can trade with a vendor. +-- @realm server +-- @client client Player attempting to trade +-- @entity entity Vendor entity +-- @string uniqueID The uniqueID of the item being traded. +-- @bool isSellingToVendor If the client is selling to the vendor +-- @treturn bool Whether or not to allow the client to trade with the vendor +-- @usage function MODULE:CanPlayerTradeWithVendor(client, entity, uniqueID, isSellingToVendor) +-- return false -- Disallow trading with vendors outright. +-- end +function CanPlayerTradeWithVendor(client, entity, uniqueID, isSellingToVendor) +end + +--- Whether or not a player can unequip an item. +-- @realm server +-- @client client Player attempting to unequip an item +-- @tab item Item being unequipped +-- @treturn bool Whether or not to allow the player to unequip the item +-- @see CanPlayerEquipItem +-- @usage function MODULE:CanPlayerUnequipItem(client, item) +-- return false -- Disallow unequipping items. +-- end +function CanPlayerUnequipItem(client, item) +end + +--- Whether or not a player is allowed to drop the given `item`. +-- @realm server +-- @client client Player attempting to drop an item +-- @number item instance ID of the item being dropped +-- @treturn bool Whether or not to allow the player to drop the item +-- @usage function MODULE:CanPlayerDropItem(client, item) +-- return false -- Never allow dropping items. +-- end +function CanPlayerDropItem(client, item) +end + +--- Whether or not a player is allowed to take an item and put it in their inventory. +-- @realm server +-- @client client Player attempting to take the item +-- @entity item Entity corresponding to the item +-- @treturn bool Whether or not to allow the player to take the item +-- @usage function MODULE:CanPlayerTakeItem(client, item) +-- return !(client:GetMoveType() == MOVETYPE_NOCLIP and !client:InVehicle()) -- Disallow players in observer taking items. +-- end +function CanPlayerTakeItem(client, item) +end + +--- Whether or not a player can equip the given `item`. This is called for items with `outfit`, `pacoutfit`, or `weapons` as +-- their base. Schemas/modules can utilize this hook for their items. +-- @realm server +-- @client client Player attempting to equip the item +-- @tab item Item being equipped +-- @treturn bool Whether or not to allow the player to equip the item +-- @see CanPlayerUnequipItem +-- @usage function MODULE:CanPlayerEquipItem(client, item) +-- return client:IsAdmin() -- Restrict equipping items to admins only. +-- end +function CanPlayerEquipItem(client, item) +end + +--- Whether or not a player is allowed to interact with an item via an inventory action (e.g picking up, dropping, transferring +-- inventories, etc). Note that this is for an item *table*, not an item *entity*. This is called after `CanPlayerDropItem` +-- and `CanPlayerTakeItem`. +-- @realm server +-- @client client Player attempting interaction +-- @string action The action being performed +-- @param item Item's instance ID or item table +-- @treturn bool Whether or not to allow the player to interact with the item +-- @usage function MODULE:CanPlayerInteractItem(client, action, item, data) +-- return false -- Disallow interacting with any item. +-- end +function CanPlayerInteractItem(client, action, item) +end + +--- Displays the context menu for interacting with an item entity. +--- @realm client +--- @entity entity The item entity for which the context menu is displayed. +function ItemShowEntityMenu(entity) +end + +--- Called when the third person mode is toggled. +--- @realm client +--- @bool state Indicates whether the third person mode is enabled (`true`) or disabled (`false`). +function thirdPersonToggled(state) +end + +--- Called when a character trades with a vendor entity. +-- This function can be used to perform additional actions when a character trades +-- with a vendor entity. +-- @realm shared +-- @client client The player character trading with the vendor +-- @entity entity The vendor entity being traded with +-- @string uniqueID The unique identifier of the traded item +-- @bool isSellingToVendor Whether the trade involves selling to the vendor +-- @see VendorSellEvent +-- @see VendorBuyEvent +-- @usage function CharacterVendorTraded(client, entity, uniqueID, isSellingToVendor) +-- -- Perform additional actions when a character trades with the vendor +-- end +function CharacterVendorTraded(client, entity, uniqueID, isSellingToVendor) +end + +--- Called when a player interacts with a vendor entity. +-- This function adds the player to the vendor's receivers list and notifies the player +-- about accessing the vendor. +-- @client client The player accessing the vendor +-- @entity entity The vendor +-- @usage function PlayerAccessVendor(client, entity) +-- -- Add the player to the vendor's receivers list +-- entity.receivers[#entity.receivers + 1] = client +-- +-- -- Notify the player about accessing the vendor +-- if entity.messages[VENDOR_WELCOME] then +-- client:notify(entity:getNetVar("name") .. ": " .. entity.messages[VENDOR_WELCOME]) +-- end +-- end +--- @realm shared +--- @treturn bool True if the player can access the vendor. +function PlayerAccessVendor(client, entity) +end + +--- Called when a player sells an item to a vendor. +-- @realm shared +-- This function handles the event where a player sells an item to a vendor. +-- @client client The player selling the item +-- @entity vendor The vendor entity +-- @string itemType The uniqueID of item being sold +-- @bool isSellingToVendor Indicates whether the player is selling to the vendor (always false in this context) +-- @character character The character of the player selling the item +-- @int price The price at which the item is sold +-- @see VendorBuyEvent +function VendorSellEvent(client, vendor, itemType, isSellingToVendor, character, price) +end + +--- Called when a player successfully buys an item from a vendor. +-- This function is called when a player successfully completes a purchase from a vendor. +-- @client client The player who made the purchase +-- @entity vendor The vendor entity from which the item was bought +-- @string itemType The uniqueID of item being sold +-- @bool isSellingToVendor Indicates whether the player is selling to the vendor (always false in this context) +-- @character character The character of the player involved in the trade +-- @int price The price of the item being bought +-- @realm shared +-- @see VendorSellEvent +function VendorBuyEvent(client, vendor, itemType, isSellingToVendor, character, price) +end + +--- Called to determine whether data should be saved before shutting down the server. +-- This function is called to determine whether data should be saved before the server shuts down. +-- @treturn boolean True if data should be saved, false otherwise +-- @realm server +function ShouldDataBeSaved() +end + +--- Called when a player picks up money. +-- This function is called when a player picks up money from the ground. +-- @client client The player who picked up the money +-- @entity moneyEntity The entity representing the money being picked up +-- @realm server +function OnPickupMoney(client, moneyEntity) +end +--- Determines whether an item can be transferred between inventories. +-- @realm shared +-- This hook allows custom logic to be implemented to determine if an item can be transferred +-- from one inventory to another. It can be used to impose restrictions on item transfers. +-- @param item The item being transferred +-- @param currentInv The current inventory from which the item is being transferred +-- @param oldInv The old inventory to which the item belonged +-- @treturn boolean|string Whether the item can be transferred, or false and a reason if not +function CanItemBeTransfered(item, currentInv, oldInv) +end + + +--- Whether or not a player is allowed to create a new character. +-- @realm server +-- @client client Player attempting to create a new character +-- @treturn bool Whether or not the player is allowed to create the character. This function defaults to `true`, so you +-- should only ever return `false` if you're disallowing creation. Otherwise, don't return anything as you'll prevent any other +-- calls to this hook from running. +-- @treturn string Language phrase to use for the error message +-- @treturn ... Arguments to use for the language phrase +-- @usage function MODULE:CanPlayerCreateCharacter(client) +-- if (!client:IsAdmin()) then +-- return false, "notNow" -- only allow admins to create a character +-- end +-- end +-- -- non-admins will see the message "You are not allowed to do this right now!" +function CanPlayerCreateCharacter(client) +end + +--- Called after a character is deleted. +-- @realm server +-- @client client The player entity. +-- @character character The character being deleted. +function PostCharDelete(client, character) +end + +--- Called after a player's loadout is applied. +-- @realm server +-- @client client The player entity. +function PostPlayerLoadout(client) +end + +--- Retrieves the maximum number of characters a player can have. +--- @client client The player for whom to retrieve the maximum number of characters. +--- @treturn int The maximum number of characters the player can have. +--- @realm shared +function GetMaxPlayerCharacter(client) +end + +--- Called after all of the player's loadout hooks are executed (PlayerLoadout, FactionOnLoadout, ClassOnLoadout). +-- This hook is called after a player's loadout has been fully applied, including faction and class loadouts. +-- @client client The player entity for whom the loadout was applied. +-- @realm server +function PostPlayerLoadout(client) +end + +--- Called after PlayerLoadout is executed. +-- This hook is called after a player's faction loadout has been applied. +-- @client client The player entity for whom the faction loadout was applied. +-- @realm server +function FactionOnLoadout(client) +end + +--- Called after FactionOnLoadout is executed. +-- This hook is called after a player's class loadout has been applied. +-- @client client The player entity for whom the class loadout was applied. +-- @realm server +function ClassOnLoadout(client) +end + +--- Called after PostPlayerLoadout is executed. +-- This hook is called after additional actions related to a player's faction loadout have been performed. +-- @client client The player entity for whom the faction loadout was applied. +-- @realm server +function FactionPostLoadout(client) +end + +--- Called after FactionPostLoadout is executed. +-- This hook is called after additional actions related to a player's class loadout have been performed. +-- @client client The player entity for whom the class loadout was applied. +-- @realm server +function ClassPostLoadout(client) +end + +--- Called after a character is deleted. +-- @realm server +-- @client client The player entity. +-- @character character The character being deleted. +function CharDeleted(client, character) +end + +--- Called before a player's character is loaded. +-- @realm server +-- @client client The player entity. +-- @character character The character being loaded. +-- @character currentChar The current character of the player. +function PrePlayerLoadedChar(client, character, currentChar) +end + +--- Called when a player's character is loaded. +-- @realm server +-- @client client The player entity. +-- @character character The character being loaded. +-- @character currentChar The current character of the player. +function PlayerLoadedChar(client, character, currentChar) +end + +--- Called after a player's character is loaded. +-- @realm server +-- @client client The player entity. +-- @character character The character being loaded. +-- @character currentChar The current character of the player. +function PostPlayerLoadedChar(client, character, currentChar) +end + +--- Determines whether a client should drown. +-- @realm server +-- @client client The player entity. +-- @treturn boolean True if the client should drown, false otherwise. +function ShouldClientDrown(client) +end + +--- Called when a player tries to use abilities on the door, such as locking. +-- @realm shared +-- @client client The client trying something on the door. +-- @entity door The door entity itself. +-- @number access The access level used when called. +-- @treturn bool Whether or not to allow the client access. +-- @usage function MODULE:CanPlayerAccessDoor(client, door, access) +-- return true -- Always allow access. +-- end +function CanPlayerAccessDoor(client, door, access) +end + +--- Whether or not a player is allowed to join a class. +-- @realm shared +-- @client client Player attempting to join +-- @number class ID of the class +-- @tab info The class table +-- @treturn bool Whether or not to allow the player to join the class +-- @usage function MODULE:CanPlayerJoinClass(client, class, info) +-- return client:IsAdmin() -- Restrict joining classes to admins only. +-- end +function CanPlayerJoinClass(client, class, info) +end + +--- Whether or not a player can earn money at regular intervals. This hook runs only if the player's character faction has +-- a salary set i.e `FACTION.pay` is set to something other than `0` for their faction. +-- @realm server +-- @client client Player to give money to +-- @tab faction Faction of the player's character +-- @tab class Class of the player's character +-- @treturn bool Whether or not to allow the player to earn salary +-- @usage function MODULE:CanPlayerEarnSalary(client, faction) +-- return client:IsAdmin() -- Restricts earning salary to admins only. +-- end +function CanPlayerEarnSalary(client, faction, class) +end + +--- Whether or not the player is allowed to punch with the hands SWEP. +-- @realm shared +-- @client client Player attempting throw a punch +-- @treturn bool Whether or not to allow the player to punch +-- @usage function MODULE:CanPlayerThrowPunch(client) +-- return client:GetCharacter():GetAttribute("str", 0) > 0 -- Only allow players with strength to punch. +-- end +function CanPlayerThrowPunch(client) +end + +--- Determines whether a player is allowed to use a specific character. +-- This hook can be used to implement custom checks to determine if a player is +-- allowed to use a particular character. +-- @realm shared +-- @client client The player attempting to use the character +-- @character character The character being considered for use +-- @treturn boolean Whether the player is allowed to use the character +-- @treturn string|nil If disallowed, a reason for the disallowance; otherwise, nil +function CanPlayerUseChar(client, character) +end + +--- Determines whether a player is allowed to use a door entity. +-- This hook can be used to implement custom checks to determine if a player is +-- allowed to use a specific door entity. +-- @realm server +-- @client client The player attempting to use the door +-- @entity entity The door entity being considered for use +-- @treturn boolean Whether the player is allowed to use the door +function CanPlayerUseDoor(client, entity) +end + +--- Determines whether a player is allowed to access a vendor entity. +-- This hook can be used to implement custom checks to determine if a player is +-- allowed to access a specific vendor entity. +-- @realm server +-- @client client The player attempting to access the vendor +function CanPlayerAccessVendor(client) +end + +--- Called when a character is loaded. +-- This function is called after a character has been successfully loaded. +-- @character character The character that has been loaded +-- @realm shared +function CharLoaded(character) +end + +--- Called after a character has been saved. +-- This function is called after a character has been successfully saved. +-- @character character The character that has been saved +-- @realm server +function CharPostSave(character) +end + +--- Called before a character is saved. +-- This function is called before a character is about to be saved. +-- @character character The character about to be saved +-- @realm shared +function CharPreSave(character) +end + +--- Called whenever an item entity has spawned in the world. You can access the entity's item table with +-- `entity:getItemTable()`. +-- @realm server +-- @entity entity Spawned item entity +-- @usage function MODULE:OnItemSpawned(entity) +-- local item = entity:getItemTable() +-- -- do something with the item here +-- end +function OnItemSpawned(entity) +end + +--- Whether or not the ammo HUD should be drawn. +-- @realm client +-- @entity weapon Weapon the player currently is holding +-- @treturn bool Whether or not to draw the ammo hud +-- @usage function MODULE:ShouldDrawAmmoHUD(weapon) +-- if (weapon:GetClass() == "weapon_frag") then +-- return false +-- end +-- end +function ShouldDrawAmmoHUD(weapon) +end + +--- Determines whether a bar should be drawn. +-- @realm client +-- @tab bar The bar object. +-- @treturn boolean True if the bar should be drawn, false otherwise. +function ShouldBarDraw(bar) +end + +--- Determines whether the crosshair should be drawn for a specific client and weapon. +--- @realm client +--- @client client The player entity. +--- @string weapon The weapon entity. +--- @treturn boolean True if the crosshair should be drawn, false otherwise. +function ShouldDrawCrosshair(client, weapon) +end + +--- Determines whether bars should be hidden. +--- @realm client +--- @treturn boolean True if bars should be hidden, false otherwise. +function ShouldHideBars() +end + +--- Called when the screen resolution changes. +-- @realm client +-- @int width number The new width of the screen. +-- @int height number The new height of the screen. +function ScreenResolutionChanged(width, height) +end + +--- Determines whether a player should be shown on the scoreboard. +--- @realm client +--- @client client The player entity to be evaluated. +--- @treturn bool True if the player should be shown on the scoreboard, false otherwise. +function ShouldShowPlayerOnScoreboard(client) +end + +--- Called after the player's inventory is drawn. +-- @realm client +-- @panel panel The panel containing the inventory. +function PostDrawInventory(panel) +end + +-- This function determines whether certain information can be displayed in the character info panel in the F1 menu. +-- @realm client +-- @table Information to **NOT** display in the UI. This is a table of the names of some panels to avoid displaying. Valid names include: +-- `name` name of the character +-- `desc` description of the character +-- `faction` faction name of the character +-- `money` current money the character has +-- `class` name of the character's class if they're in one +-- Note that schemas/modules can add additional character info panels. +-- @usage function MODULE:CanDisplayCharacterInfo(suppress) +-- suppress.faction = true +-- end +function CanDisplayCharacterInfo(suppress) +end + +--- Determines whether a player is allowed to view their inventory. +-- @realm client +-- This hook can be used to implement custom checks to determine if a player is +-- allowed to view their inventory. +-- @treturn boolean Whether the player is allowed to view their inventory +function CanPlayerViewInventory() +end + + +--- Checks if a character is recognized. +--- @character character The character to check. +--- @int id Identifier for the character. +-- @realm shared +function isCharRecognized(character, id) + +end + +--- Checks if a character is fake recognized. +--- @character character The character to check. +--- @int id Identifier for the character. +-- @realm shared +function isCharFakeRecognized(character, id) +end + +--- Checks if a fake name exists in the given character name list. +-- @realm shared +--- @string name The name to check. +--- @tab nameList A list of character names. +--- @treturn True if the name exists in the list, false otherwise. +function isFakeNameExistant(name, nameList) +end + +--- Called when a character is recognized. +--- @client client The client whose character is recognized. +--- @int id Identifier for the recognized character. +--- @realm client +function OnCharRecognized(client, id) +end + +--- Initiates character recognition process. +--- @int level The recognition level. +--- @realm client +--- @string name The name of the character to be recognized. +function CharRecognize(level, name) +end + +--- Creates menu buttons for the F1 menu. +--- @tab tabs A table to store the created buttons. +--- @realm client +function CreateMenuButtons(tabs) +end + +--- Called when lia.config has been initialized. +--- @realm shared +function InitializedConfig() +end + +--- Called when all the modules have been initialized. +--- @realm shared +function InitializedModules() +end + +--- Called when the schema has been initialized. +--- @realm shared +function InitializedSchema() +end + +--- Loads custom fonts for the client. +--- @string font The path to the font file. +--- @string genericFont The path to the generic font file. +--- @realm client +function LoadFonts(font, genericFont) +end + +--- Loads Core Lilia fonts for the client. +--- @string font The path to the font file. +--- @string genericFont The path to the generic font file. +--- @realm client +-- @internal +function LoadLiliaFonts(font, genericFont) +end + +--- Creates a timer to manage player salary. +--- @client client The player for whom the salary timer is created. +--- @realm shared +function CreateSalaryTimer(client) +end + +--- Determines if a player is allowed to earn salary. +--- @client client The player whose eligibility for salary is being checked. +--- @tab faction The faction the player belongs to. +--- @tab class The class of the player's character. +--- @treturn True if the player is allowed to earn salary, false otherwise. +--- @realm shared +function CanPlayerEarnSalary(client, faction, class) +end + +--- Called when a module has finished loading. +--- @realm shared +function ModuleLoaded() +end + +--- Retrieves the salary limit for a player. +--- @client client The player for whom to retrieve the salary limit. +--- @tab faction The faction the player belongs to. +--- @tab class The class of the player's character. +--- @treturn The salary limit for the player. +--- @realm shared +function GetSalaryLimit(client, faction, class) +end + +--- Retrieves the amount of salary a player should receive. +--- @client client The player receiving the salary. +--- @tab faction The faction the player belongs to. +--- @tab class The class of the player's character. +--- @treturn The amount of salary the player should receive. +--- @realm shared +function GetSalaryAmount(client, faction, class) +end + +--- Called to draw additional content within the model view panel. +--- @panel panel The panel containing the model view. +--- @entity entity The entity being drawn. +--- @realm client +function DrawLiliaModelView(panel, entity) +end + +--- Whether or not a player is allowed to spawn a container entity. +-- @client client The player attempting to spawn a container. +-- @entity entity The container entity being spawned. +-- @tab data Additional data related to the container being spawned. +-- @treturn bool Whether or not to allow the player to spawn the container. +-- @realm server +-- @usage function MODULE:CanPlayerSpawnStorage(client, entity, data) +-- return client:IsAdmin() -- Restrict spawning containers to admins. +-- end +function CanPlayerSpawnStorage(client, entity, data) +end +--- Determines if a player can throw a punch with a weapon. +--- @client client The player attempting to throw a punch. +--- @tab trace The trace result. +--- @treturn True if the player can throw a punch, false otherwise. +--- @realm shared +function CanPlayerThrowPunch(client, trace) +end + +--- Called when a player purchases a door. +--- @client client The player who purchased the door. +--- @entity entity The door entity that was purchased. +--- @bool buying True if the player is buying the door, false if selling. +--- @func CallOnDoorChild A function to call on door children. +--- @realm server +function OnPlayerPurchaseDoor(client, entity, buying, CallOnDoorChild) +end +--- Called when a character's attribute is updated. +--- @client client The client associated with the character. +--- @character character The character whose attribute is updated. +--- @string attribID The ID of the attribute being updated. +--- @string boostID The ID of the boost being applied to the attribute. +--- @int boostAmount The amount of boost being applied to the attribute. +--- @realm shared +function OnCharAttribUpdated(client, character, attribID, boostID, boostAmount) +end + +--- Called when a character's attribute is updated. +--- @client client The client associated with the character. +--- @character character The character whose attribute is updated. +--- @string key The key of the attribute being updated. +--- @int value The new value of the attribute. +--- @realm shared +function OnCharAttribUpdated(client, character, key, value) +end +--- Called when a player's model is changed. +--- @client client The client whose model is changed. +--- @string model The new model path. +--- @realm shared +function PlayerModelChanged(client, model) +end +--- Determines if a character has the given flag(s). +--- @character character The character to check for flags. +--- @string flags The flag(s) to check access for. +--- @treturn bool Whether or not this character has access to the given flag(s). +--- @realm shared +function CharHasFlags(character, flags) +end + +--- Called when a player gains stamina. +--- @client client The player who gained stamina. +--- @realm server +function PlayerStaminaGained(client) +end + +--- Called when a player loses stamina. +--- @client client The player who lost stamina. +--- @realm server +function PlayerStaminaLost(client) +end + +--- Saves the server data. +-- @realm server +function SaveData() +end + +--- Loads the server data. +-- @realm server +function LoadData() +end + +--- Called after data has been loaded. +-- @realm server +function PostLoadData() +end + +--- Called when the database has been successfully connected. +--- @realm server +-- @internal +function DatabaseConnected() +end + +--- Called after wiping tables. +--- @realm server +-- @internal +function OnWipeTables() +end + +--- Sets up the database. +--- @realm server +-- @internal +function SetupDatabase() +end + diff --git a/docs/js/app.js b/docs/js/app.js new file mode 100644 index 0000000..ce0cee1 --- /dev/null +++ b/docs/js/app.js @@ -0,0 +1,168 @@ + +const skippedCategories = ["manual"]; + +class Node +{ + constructor(name, element, expandable, noAutoCollapse, children = []) + { + this.name = name; + this.element = element; + this.expandable = expandable; + this.noAutoCollapse = noAutoCollapse; + this.children = children; + } + + AddChild(name, element, expandable, noAutoCollapse, children) + { + let newNode = new Node(name, element, expandable, noAutoCollapse, children); + this.children.push(newNode); + + return newNode; + } +} + +class SearchManager +{ + constructor(input, contents) + { + this.input = input; + this.input.addEventListener("input", event => + { + this.OnInputUpdated(this.input.value.toLowerCase().replace(/:/g, ".")); + }); + + // setup search tree + this.tree = new Node("", document.createElement("null"), true, true); + this.entries = {}; + + const categoryElements = contents.querySelectorAll(".category"); + + // iterate each kind (hooks/libraries/classes/etc) + for (const category of categoryElements) + { + const nameElement = category.querySelector(":scope > summary > h2"); + + if (!nameElement) + { + continue; + } + + const categoryName = nameElement.textContent.trim().toLowerCase(); + + if (skippedCategories.includes(categoryName)) + { + continue; + } + + let categoryNode = this.tree.AddChild(categoryName, category, true, true); + const sectionElements = category.querySelectorAll(":scope > ul > li"); + + for (const section of sectionElements) + { + const entryElements = section.querySelectorAll(":scope > details > ul > li > a"); + const sectionName = section.querySelector(":scope > details > summary > a") + .textContent + .trim() + .toLowerCase(); + + let sectionNode = categoryNode.AddChild(sectionName, section.querySelector(":scope > details"), true); + + for (let i = 0; i < entryElements.length; i++) + { + const entryElement = entryElements[i]; + const entryName = entryElement.textContent.trim().toLowerCase(); + + sectionNode.AddChild(sectionName + "." + entryName, entryElement.parentElement); + } + } + } + } + + ResetVisibility(current) + { + current.element.style.display = ""; + + if (current.noAutoCollapse) + { + current.element.open = true; + } + else if (current.expandable) + { + current.element.open = false; + } + + for (let node of current.children) + { + this.ResetVisibility(node); + } + } + + Search(input, current) + { + let matched = false; + + if (current.name.indexOf(input) != -1) + { + matched = true; + } + + for (let node of current.children) + { + let childMatched = this.Search(input, node); + matched = matched || childMatched; + } + + if (matched) + { + current.element.style.display = ""; + + if (current.expandable) + { + current.element.open = true; + } + } + else + { + current.element.style.display = "none"; + + if (current.expandable) + { + current.element.open = false; + } + } + + return matched; + } + + OnInputUpdated(input) + { + if (input.length <= 1) + { + this.ResetVisibility(this.tree); + return; + } + + this.Search(input, this.tree); + } +} + +window.onload = function() +{ + const openDetails = document.querySelector(".category > ul > li > details[open]"); + + if (openDetails) + { + openDetails.scrollIntoView(); + } +} + +document.addEventListener("DOMContentLoaded", function() +{ + const searchInput = document.getElementById("search"); + const contents = document.querySelector("body > main > nav > section"); + + if (searchInput && contents) + { + new SearchManager(searchInput, contents); + } +}); diff --git a/docs/js/highlight.min.js b/docs/js/highlight.min.js new file mode 100644 index 0000000..dd8dd8d --- /dev/null +++ b/docs/js/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[e.C("--(?!"+t+")","$"),e.C("--"+t,a,{c:[r],r:10})];return{l:e.UIR,k:{literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}}); \ No newline at end of file diff --git a/docs/manual/info_compatibility.md b/docs/manual/info_compatibility.md new file mode 100644 index 0000000..f2c2f91 --- /dev/null +++ b/docs/manual/info_compatibility.md @@ -0,0 +1,85 @@ +# Addons with Improved Compatibility + +## Prone Mod + +- Addon URL: [Prone Mod](https://github.com/gspetrou/Prone-Mod) + +- Compatibility Added: Made animations reset at proper times. + +## ULX + +- Addon URL: [ULX](https://steamcommunity.com/sharedfiles/filedetails/?id=557962280) + +- Compatibility Added: Removed obsolete hooks. + +## SAM + +- Addon URL: [SAM](https://www.gmodstore.com/market/view/sam) + +- Compatibility Added: Implemented an auto administrator setter and fixed prop limits to work with SAM. + +## Serverguard + +- Addon URL: [Serverguard](https://www.gmodstore.com/market/view/serverguard) + +- Compatibility Added: Allowed CAMI (permissions system) to work with Lilia and Serverguard. + +## Advanced Dupe 2 + +- Addon URL: [Advanced Dupe 2](https://steamcommunity.com/sharedfiles/filedetails/?id=773402917) + +- Compatibility Added: Fixed several crashing exploits. + +## Advanced Dupe 1 + +- Addon URL: [Advanced Dupe 1](https://steamcommunity.com/sharedfiles/filedetails/?id=163806212) + +- Compatibility Added: Fixed several crashing exploits. + +## PermaProps + +- Addon URL: [PermaProps](https://steamcommunity.com/sharedfiles/filedetails/?id=220336312) + +- Compatibility Added: Removed the ability to PermaProp certain restricted entities. + +## PAC3 + +- Addon URL: [PAC3](https://steamcommunity.com/workshop/filedetails/?id=104691717) + +- Compatibility Added: Restricted PAC to a flag and permission, and made it reset when needed. + +## Simfphys Vehicles + +- Addon URL: [Simfphys Vehicles](https://steamcommunity.com/sharedfiles/filedetails/?id=771487490) + +- Compatibility Added: Added car crash damage and implemented some console commands for performance. + +## Sit Anywhere + +- Addon URL: [Sit Anywhere](https://steamcommunity.com/sharedfiles/filedetails/?id=108176967) + +- Compatibility Added: Removed the ability to sit on certain mingy locations and added damage on seats by default. + +## Stormfox 2 + +- Addon URL: [Stormfox 2](https://steamcommunity.com/workshop/filedetails/?id=2447774443) + +- Compatibility Added: Improved SF2 lighting reload. + +## 3D Stream Radio + +- Addon URL: [3D Stream Radio](https://steamcommunity.com/sharedfiles/filedetails/?id=246756300) + +- Compatibility Added: Added ability for radios to save on the map. + +## VCMod + +- Addon URL: [VCMod Main](https://www.gmodstore.com/market/view/vcmod-main) + +- Compatibility Added: Added monetary compatibility. + +## VJBase + +- Addon URL: [VJBase](https://steamcommunity.com/workshop/filedetails/?id=131759821) + +- Compatibility Added: Made the server enable certain settings by default, improving performance, and removed some harmful hooks. \ No newline at end of file diff --git a/docs/manual/info_converting-from-nutscript.md b/docs/manual/info_converting-from-nutscript.md new file mode 100644 index 0000000..e844e43 --- /dev/null +++ b/docs/manual/info_converting-from-nutscript.md @@ -0,0 +1,30 @@ +# Information - Porting From NS + +If you're considering porting Nutscript Plugins to Lilia Modules, here are some helpful pointers on replaceable variables. It's worth noting that while porting from Nutscript to Lilia is feasible and supported, going the other way around can be complex and may lead to long-term issues, as certain key hooks used in Lilia are not present in Nutscript. + +``` + +| **Nutscript** | **Lilia** | +|:---------------: |:---------------: | +| nut | lia | +| PLUGIN | MODULE | +| sh_plugin | module | +| sh_schema | schema | +| nut.plugin.list | lia.module.list | +| sh_itemid | itemid | +| sh_factionid | factionid | +| sh_attributeid | attribid | + +``` + +Make sure to check the following available content to get assistance with your porting: + +- [Class Structure](https://LiliaFramework.github.io/Lilia/manual/structure_class/) + +- [Command Structure](https://LiliaFramework.github.io/Lilia/manual/structure_command/) + +- [Faction Structure](https://LiliaFramework.github.io/Lilia/manual/structure_faction/) + +- [Item Structure](https://LiliaFramework.github.io/Lilia/manual/structure_items) + +- [Module Structure](https://LiliaFramework.github.io/Lilia/manual/structure_module) \ No newline at end of file diff --git a/docs/manual/info_features.md b/docs/manual/info_features.md new file mode 100644 index 0000000..1836331 --- /dev/null +++ b/docs/manual/info_features.md @@ -0,0 +1,76 @@ +# Improvements & Fixes +- Fixed Vendor Crash Exploit that used Item Spawning Spam. + +- Limited Commands to Permissions, rather than just [IsAdmin](https://wiki.facepunch.com/gmod/Player:IsAdmin) or [IsSuperAdmin](https://wiki.facepunch.com/gmod/Player:IsSuperAdmin). + +- Added Several New Commands, both for utility as well as administration. + +- Added New Chat Types. + +- Made Config Hardcoded, avoiding any potential lack of sync on configuration. + +- Improved Logging System, adding a log viewing menu. + +- Moved all permissions to [CAMI](https://github.com/glua/CAMI), tying them with UserGroups by doing so. + +- Made PlayerModel animations default, instead of Citizen animations, effectively making all models with player animations work by default. + +- Improved F1 Menu and Main Menu, allowing for extreme customization by simply modifying your config files. + +- Rewrote Notification Derma. + +- Expanded on Faction and Classes System, by adding several new parameters for customization. Check [Faction Structure](https://liliaframework.github.io/manual/structure_faction/) and [Class Structure](https://liliaframework.github.io/manual/structure_class/) for more information. + +- Fixed Several Exploits within the Inventory, like equipping weapons within inventories that aren't directly connected to the player. + +- Added Multiple Player, Character, and Entity Meta to allow for simpler coding. + +- Improved Recognition, adding the ability to use Fake Names. + +- Adding Voice Tones, allowing for you to Yell, Whisper, and Talk normally over Voice Chat. + +- Added an Interaction Menu, allowing players to run customizable tasks by simply walking up to a player and holding tab. + +- Improved Scoreboard, adding Players Online, Staff on Duty Online, and Staff Online. + +- Added a Crash Screen. + +- Added Multi-Faction Support to Doors. + +- Added a Third-Person Bind. + +- Added a Weapon Item Generator. + +- Bettered Protection towards several exploits, both originally on the forked framework as well as on GMOD. + +- Categorized Permissions, allowing for stuff like limiting PhysGun Pickups to certain entities or using certain tools. + +- Added an Anti-Alting System. + +- Added an Anti-Cheat. + +- Improved Clientside Performance by Tweaking Rendering. + +- Improved Serverside Performance by Optimizing several functions, as well as loops. + +- Limited Vendor Editing to Permissions. + +- Added Blacklisting and Whitelisting. + +- Added Workshop Downloader. + +- Added NetMessage Logging. + +- Added Console Command Logging. + +- Added Downtime Notifier. + +- Added Modules Configuration explanations to wiki. + +- Added Command List to wiki. + +- Added new item bases. Check [Item Structure](https://liliaframework.github.io/manual/structure_items/) for more information. + +- Created an extremely detailed wiki so that even the average joe can understand the framework easily. + +- Extensive [Compatibility List](https://liliaframework.github.io/manual/info_compatibility) \ No newline at end of file diff --git a/docs/manual/info_installation.md b/docs/manual/info_installation.md new file mode 100644 index 0000000..5edc795 --- /dev/null +++ b/docs/manual/info_installation.md @@ -0,0 +1,88 @@ +# Information - Installation Tutorial + +Lilia is a versatile roleplaying framework for the Garry's Mod game. This tutorial will guide you through the process of installing Lilia for your Garry's Mod server. + +## Prerequisites + +Before you begin, make sure you have the following: + +- A working Garry's Mod server. + +- Basic knowledge of Garry's Mod server administration. + +- An understanding of how to use the command line. + +- An Admin Menu (we recommend [SAM](https://www.gmodstore.com/market/view/sam)). + +## Step 1: Setting Up Your Garry's Mod Server + +If you haven't already, set up your Garry's Mod server and ensure it's running without any issues. + +## Step 2: Downloading Lilia + +- After downloading the ZIP file, visit the Lilia GitHub repository: [Lilia GitHub Repo](https://github.com/LiliaFramework/Lilia). + +- Click on the green "Code" button and select "Download ZIP." + +- Save the ZIP file to a location on your computer. + +## Step 3: Extracting Lilia + +- After downloading, locate the ZIP file and extract its contents to a temporary folder on your computer. + +- You should now have a folder named something like "Lilia-main.zip." + +- Extract the contents inside to a folder within your desktop. + +- You will be faced with several files alongside with 2 folders: `docs` and `lilia`. Move `lilia` into a separate folder. + +## Step 4: Uploading Lilia to Your Server + +- Connect to your server using a tool like FTP or SFTP. + +- Navigate to the `garrysmod/gamemodes` directory within your server. + +- Upload the previously mentioned "lilia" folder into the `gamemodes` directory. + +## Step 5: Configuring Lilia + +- Before making any changes, consider making a backup of the default configuration. + +- Edit this [configuration](https://github.com/LiliaFramework/Lilia-Skeleton/blob/main/skeleton/schema/config/shared.lua) to override any default values you wish. + +## Step 6: Starting Lilia on Your Server + +- Restart your Garry's Mod server for the changes to take effect. + +- If you encounter any issues, refer to the troubleshooting tips in the documentation. + +## Step 7: Installing Roleplay Schemas + +To install a roleplay schema for your Lilia framework, follow these steps: + +- Download one of the available schemas from the repositories listed below, based on your server's theme: + - [Framework](https://github.com/LiliaFramework/Lilia) + + - [Skeleton Schema](https://github.com/LiliaFramework/Lilia-Skeleton) + + - [MafiaRP Schema](https://github.com/LiliaFramework/Lilia-MafiaRP) + + - [HL2RP Schema](https://github.com/LiliaFramework/Lilia-HL2RP) + + - [MetroRP Schema](https://github.com/LiliaFramework/Lilia-MetroRP) + + - [1942RP Schema](https://github.com/LiliaFramework/Lilia-1942RP) + + - [Public Modules](https://github.com/LiliaFramework/Lilia-Modules) + + - [Bozy's Modules](https://github.com/B0zy/Boz-Lilia-Modules) + +- Set up factions, items, and modules as required. + +- Set the startup gamemode to the schema folder ID within your server's startup configuration. + +That's it! You've successfully installed a roleplay schema using Lilia. Enjoy your customized roleplaying experience! + +## Conclusion + +Congratulations! You've successfully installed Lilia and set up your own roleplaying schema on your Garry's Mod server. Remember that Lilia offers a wide range of features and customization options, so be sure to explore its documentation and community resources to make the most out of your roleplaying experience. \ No newline at end of file diff --git a/docs/manual/structure_class.md b/docs/manual/structure_class.md new file mode 100644 index 0000000..40c0c60 --- /dev/null +++ b/docs/manual/structure_class.md @@ -0,0 +1,57 @@ +# Structure - Class + +```lua +CLASS.name = "Steve" +CLASS.desc = "The Steves of the Minecrafter Faction." +CLASS.isDefault = true +CLASS.faction = FACTION_MINECRAFTER +CLASS.color = Color(0, 255, 0) +CLASS.weapons = {"gold_pickaxe", "netherite_spade"} +CLASS.pay = 50 +CLASS.payTimer = 3600 +CLASS_STEVE = CLASS.index +``` + +## CLASS Variables + +- **CLASS.name**: The name of your class. + +- **CLASS.desc**: A description of your class. + +- **CLASS.isDefault**: Indicates whether this is the default class. Set to true if it's the default class, allowing anyone to join. + +- **CLASS.color**: The color associated with your class. This can be used for class-specific coloring. + +- **CLASS.weapons**: Weapons that players in this class can use. This can include weapon IDs or references to the weapons available to class members. **Optional** + +- **CLASS.pay**: The payment amount associated with the class. This represents any in-game currency or rewards tied to being a member of this class. **Optional** + +- **CLASS.payTimer**: The timer or schedule for payments. Specify the interval in seconds for payments to occur. For example, if payments are made every 30 minutes, set this value to 1800 (30 minutes \* 60 seconds). **Optional** + +- **CLASS.limit**: The limit of players in this class at a given time. This restricts how many players can be members of this class simultaneously. **Optional** + +- **CLASS.health**: This variable represents the default health of players in the class. You can set a numerical value, such as 100, to specify the default health. Players in this class will start with this amount of health unless modified by other in-game factors. **Optional** + +- **CLASS.armor**: Similar to health, this variable represents the default armor value of players in the class. Armor can provide additional protection against damage. Set a numerical value, such as 50, to determine the default armor value for class members. **Optional** + +- **CLASS.scale**: Scale affects the size of the player model. You can set a value like 1.2 to make class members slightly larger or 0.8 to make them smaller. This can be used for visual customization. **Optional** + +- **CLASS.runSpeed**: This variable determines the default running speed of players in the class. You can set a numerical value like 300 to specify the speed in units per second. **Optional** + +- **CLASS.runSpeedMultiplier**: When set to true, this indicates that the runSpeed value should be multiplied by the default speed set in the game configuration. When set to false, it means that the runSpeed value should directly set the running speed, overriding the game's default. **Optional** + +- **CLASS.walkSpeed**: Similar to runSpeed, this variable sets the default walking speed of players in the class. You can set a numerical value like 150 to specify the walking speed in units per second.**Optional** + +- **CLASS.walkSpeedMultiplier**: Like runSpeedMultiplier, when set to true, it multiplies the walkSpeed value by the default walk speed set in the game configuration. When set to false, it directly sets the walking speed. **Optional** + +- **CLASS.jumpPower**: This variable determines the default jump power of players in the class. Jump power controls how high a player can jump. You can set a numerical value like 200 to specify the jump power. **Optional** + +- **CLASS.jumpPowerMultiplier**: When set to true, jumpPower is multiplied by the default jump power configured in the game. When set to false, it directly sets the jump power for class members. **Optional** + +- **CLASS.bloodcolor**: This variable allows you to specify the blood color of players in the class when they take damage. You can use the blood enums provided by Garry's Mod, which are listed in [Blood Color ENUMS](https://wiki.facepunch.com/gmod/Enums/BLOOD_COLOR). For example, you can set it to BLOOD_COLOR_YELLOW to make the class's blood appear yellow when they are injured. **Optional** + +- **CLASS.bodyGroups**: This variable allows you to define class-specific bodygroups for player models upon spawn. Bodygroups control the appearance and configuration of specific parts of the player model. You can specify the bodygroups using a table format. Each entry in the table represents a bodygroup and its corresponding value.b**Optional** + +- **CLASS.model**: This variable allows you to define class-specific models that get set on spawn. **Optional** + +- **CLASS.index**: The Unique ID (UniqueID) of the class. This is a unique identifier used to distinguish this class from others. diff --git a/docs/manual/structure_command.md b/docs/manual/structure_command.md new file mode 100644 index 0000000..15e3993 --- /dev/null +++ b/docs/manual/structure_command.md @@ -0,0 +1,46 @@ +# Structure - Command + +```lua +lia.command.add("charsetskin", { + -- This command is restricted to administrators only by default. CAMI can change this + adminOnly = true, + + -- Specifies the required privilege for using this command + privilege = "Change Skin", -- This would end up being the permission "Commands - Change Skin" + + -- Command syntax with name and an optional skin number + syntax = " [number skin]", + + -- Execute this function when the command is used + onRun = function(client, arguments) + -- Parse the second argument as a number (skin) + local skin = tonumber(arguments[2]) + + -- Find the player specified by name in the first argument + local target = lia.command.findPlayer(client, arguments[1]) + + -- Check if the target player is valid and has a character + if IsValid(target) and target:getChar() then + -- Set the "skin" data attribute of the target's character + target:getChar():setData("skin", skin) + + -- Change the skin of the target player, defaulting to 0 if skin is not provided + target:SetSkin(skin or 0) + + -- Notify the client about the skin change + client:notifyLocalized("cChangeSkin", client:Name(), target:Name(), skin or 0) + end + } +}) + +``` + +## Command Variables + +- **privilege**: This variable specifies the permission associated with the command. It determines who is allowed to use the command and what actions they can perform. + +- **adminOnly** or **superAdminOnly**: These variables are used to categorize the privilege into different levels. You can choose either one of them, and if set to false, it means that the command can be used by regular users as well. + +- **syntax**: This variable provides information about the command's syntax. It helps users understand how to correctly structure their input when using the command. + +- **onRun**: This is a function that defines what actions should be executed when the command is used. It specifies the actual behavior of the command, including any processing or tasks it should perform. diff --git a/docs/manual/structure_faction.md b/docs/manual/structure_faction.md new file mode 100644 index 0000000..be394e7 --- /dev/null +++ b/docs/manual/structure_faction.md @@ -0,0 +1,58 @@ +# Structure - Faction + +```lua +FACTION.name = "Minecrafters" +FACTION.desc = "Surviving and crafting in the blocky world." +FACTION.isDefault = false +FACTION.color = Color(0, 255, 0) +FACTION.models = {"minecraft_model_1.mdl", "minecraft_model_2.mdl", "minecraft_model_3.mdl",} +FACTION.weapons = {"stone_sword", "iron_pickaxe"} +FACTION.pay = 50 +FACTION.payTimer = 3600 +FACTION_MINECRAFTER = FACTION.index +``` + +#Faction Variables + +- **FACTION.name**: The name of your faction. + +- **FACTION.desc**: A description or lore for your faction. + +- **FACTION.isDefault**: Indicates whether this is the default faction. Set to true if it's the default faction; otherwise, set to false. Using isDefault removes the need for a whitelist. + +- **FACTION.color**: The color associated with your faction. This can be used for faction-specific coloring or theming. + +- **FACTION.models**: Models that players in this faction can use. These are the character models available to faction members. + +- **FACTION.weapons**: Weapons that players in this faction can use. This can include weapon IDs or references to the weapons available to faction members. **Optional** + +- **FACTION.pay**: The payment amount associated with the faction. This represents any in-game currency or rewards tied to being a member of this faction. **Optional** + +- **FACTION.payTimer**: The timer or schedule for payments. Specify the interval in seconds for payments to occur. For example, if payments are made every 30 minutes, set this value to 1800 (30 minutes \* 60 seconds). **Optional** + +- **FACTION.limit**: The limit of players in this faction at a given time. This restricts how many players can be members of this faction simultaneously. **Optional** + +- **FACTION.oneCharOnly**: Adds a limit that prevents a player from having more than one character in a faction when being transferred. **Optional** + +- **FACTION.health**: This variable represents the default health of players in the faction. You can set a numerical value, such as 100, to specify the default health. Players in this faction will start with this amount of health unless modified by other in-game factors. **Optional** + +- **FACTION.armor**: Similar to health, this variable represents the default armor value of players in the faction. Armor can provide additional protection against damage. Set a numerical value, such as 50, to determine the default armor value for faction members. **Optional** + +- **FACTION.scale**: Scale affects the size of the player model. You can set a value like 1.2 to make faction members slightly larger or 0.8 to make them smaller. This can be used for visual customization. **Optional** +- **FACTION.runSpeed**: This variable determines the default running speed of players in the faction. You can set a numerical value like 300 to specify the speed in units per second. **Optional** + +- **FACTION.runSpeedMultiplier**: When set to true, this indicates that the runSpeed value should be multiplied by the default speed set in the game configuration. When set to false, it means that the runSpeed value should directly set the running speed, overriding the game's default. **Optional** + +- **FACTION.walkSpeed**: Similar to runSpeed, this variable sets the default walking speed of players in the faction. You can set a numerical value like 150 to specify the walking speed in units per second. **Optional** + +- **FACTION.walkSpeedMultiplier**: Like runSpeedMultiplier, when set to true, it multiplies the walkSpeed value by the default walk speed set in the game configuration. When set to false, it directly sets the walking speed. **Optional** + +- **FACTION.jumpPower**: This variable determines the default jump power of players in the faction. Jump power controls how high a player can jump. You can set a numerical value like 200 to specify the jump power.**Optional** + +- **FACTION.jumpPowerMultiplier**: When set to true, jumpPower is multiplied by the default jump power configured in the game. When set to false, it directly sets the jump power for faction members. **Optional** + +- **FACTION.bloodcolor**: This variable allows you to specify the blood color of players in the faction when they take damage. You can use the blood enums provided by Garry's Mod, which are listed in [Blood Color ENUMS](https://wiki.facepunch.com/gmod/Enums/BLOOD_COLOR). For example, you can set it to BLOOD_COLOR_YELLOW to make the faction's blood appear yellow when they are injured. **Optional** + +- **FACTION.bodyGroups**: This variable allows you to define faction-specific bodygroups for player models upon spawn. Bodygroups control the appearance and configuration of specific parts of the player model. You can specify the bodygroups using a table format. Each entry in the table represents a bodygroup and its corresponding value. **Optional** + +- **FACTION.index**: The Unique ID (UniqueID) of the faction. This is a unique identifier used to distinguish this faction from others. It corresponds to a Garry's Mod team index or identifier. diff --git a/docs/manual/structure_items.md b/docs/manual/structure_items.md new file mode 100644 index 0000000..256bb81 --- /dev/null +++ b/docs/manual/structure_items.md @@ -0,0 +1,83 @@ +# Structure - Items + +Items with a specific base must be organized within a folder named after that base. For example, if you have a weapon that uses the 'weapons' base, you should save it under 'items/weapons/ItemID.lua'. If an item is not found within a corresponding base folder or if its base is missing, it will default to the basic item base, which only allows for dropping + +### Default Item Example: + +```lua +ITEM.name = "Test Item" -- The name of the item +ITEM.desc = "A test item!" -- A brief description of the item +ITEM.model = "models/props_c17/oildrum001.mdl" -- The 3D model for the item +``` + +### Vehicles Item Example: + +```lua +ITEM.name = "A Vehicle" -- The name of the vehicle +ITEM.desc = "A Vehicle" -- A brief description of the vehicle +ITEM.model = "models/props_c17/BriefCase001a.mdl" -- The 3D model for the vehicle +ITEM.category = "Vehicles" -- The category of the vehicle +ITEM.vehicleid = "VehicleID" -- The identifier for the vehicle +``` + +### Outfit Item Example: + +```lua +ITEM.name = "Combine Armor" -- The name of the outfit +ITEM.desc = "Protects your insides from the outsides" -- A brief description of the outfit +ITEM.model = "models/props_c17/BriefCase001a.mdl" -- The 3D model for the outfit +ITEM.width = 2 -- The width of the outfit in inventory +ITEM.height = 2 -- The height of the outfit in inventory +ITEM.replacements = "models/player/combine_soldier.mdl" -- Model replacement for the player wearing the outfit +``` + +### Entities Item Example: + +```lua +ITEM.name = "Item Suit" -- The name of the entities item +ITEM.desc = "An HL2 Item Suit" -- A brief description of the entities item +ITEM.model = "models/props_c17/BriefCase001a.mdl" -- The 3D model for the entities item +ITEM.category = "Entities" -- The category of the entities item +ITEM.entityid = "item_suit" -- The identifier for the entities item +``` + +### Books Item Example: + +```lua +ITEM.name = "Example" -- The name of the book +ITEM.desc = "An Example" -- A brief description of the book +ITEM.contents = [[ +

An Example

+

By Example

+

+EXAMPLE PARA. +EXAMPLE PARA. +EXAMPLE PARAGRAPH. +EXAMPLE PARAGRAH! +

+]] -- The contents of the book, in HTML format +``` + +### Ammo Item Example: + +```lua +ITEM.name = ".357 Ammo" -- The name of the ammo +ITEM.model = "models/items/357ammo.mdl" -- The 3D model for the ammo +ITEM.ammo = "357" -- The type of ammo +ITEM.ammoAmount = 12 -- The amount of ammo in the box +ITEM.ammoDesc = "A Box that contains %s of .357 Ammo" -- Description of the ammo box +``` + +### Weapons Item Example: + +```lua +ITEM.name = "AR2" -- The name of the weapon +ITEM.desc = "A Weapon." -- A brief description of the weapon +ITEM.model = "models/weapons/w_IRifle.mdl" -- The 3D model for the weapon +ITEM.class = "weapon_ar2" -- The class used to spawn this weapon +ITEM.weaponCategory = "primary" -- The category of the weapon +ITEM.width = 4 -- The width of the weapon in inventory +ITEM.height = 2 -- The height of the weapon in inventory +``` + +If you don't wish to manually code weapons, you can enable [this](https://github.com/LiliaFramework/Lilia/blob/main/lilia/modules/utilities/wepgenerator/config/shared.lua#L1) \ No newline at end of file diff --git a/docs/manual/structure_module.md b/docs/manual/structure_module.md new file mode 100644 index 0000000..eba8d03 --- /dev/null +++ b/docs/manual/structure_module.md @@ -0,0 +1,98 @@ +# Structure - Module + +```lua +MODULE.name = "A Module" + +MODULE.author = "76561198312513285" + +MODULE.discord = "@liliaplayer" + +MODULE.desc = "This is a Example Module." + +MODULE.WorkshopContent = {"2959728255"} + +MODULE.enabled = true + +MODULE.CAMIPrivileges = { + { + Name = "Staff Permissions - Kekw", + MinAccess = "superadmin", + Description = "Allows access to kewking.", + }, +} + +MODULE.Dependencies = { + { + File = MODULE.path .. "/nicebogusfile.lua", + Realm = "server", + }, + { + File = MODULE.path .. "/badbogusfile.lua", + Realm = "client", + }, +} +``` + +--- + +## Module Configuration + +- **`MODULE.name`:** Specifies the name of the module, which is "Core - Permissions" in this case. This variable identifies the module. + +- **`MODULE.author`:** Indicates the author of the module. It can be a STEAMID64 or Name. Replace "76561198312513285" with the actual author information. + +- **`MODULE.discord`:** Indicates the discord of the module creator, in this case, as shown, is liliaplayer. + +- **`MODULE.desc`:** Provides a brief description of the module's purpose. In this case, it states that the module adds skills functionality to the framework. + +- **`MODULE.identifier`:** This global variable uniquely identifies the module and allows it to be accessed from outside its scope. **Optional** + +- **`MODULE.CAMIPrivileges`:** An example CAMI permission that is loaded alongside the module. **Optional** + +- **`MODULE.WorkshopContent`:** Workshop Content to be added. **Optional** + +- **`MODULE.enabled`:** Indicates if the module is active or not. If False, then it won't be. **Optional** + +- **`MODULE.Dependencies`:** Files and corresponding realms to be included. **Optional** + +### Automatically Included Files and Folders in the Module: + +**Files:** + +- client.lua + +- cl_module.lua + +- sv_module.lua + +- server.lua + +- config.lua + +- sconfig.lua + +**Folders:** + +- dependencies + +- config +- permissions + +- libs + +- hooks + +- libraries + +- commands + +- netcalls + +- meta + +- derma + +- pim + +- concommands + diff --git a/docs/templates/landing.ltp b/docs/templates/landing.ltp new file mode 100644 index 0000000..cdbba92 --- /dev/null +++ b/docs/templates/landing.ltp @@ -0,0 +1,18 @@ +
+

Lilia Documentation

+
+ +
+

Welcome to the documentation for Lilia.

+

Developers

+

The sidebar shows the entire contents of the documentation. Libraries, hooks, etc are all searchable with the search box at the top of the sidebar. Migrating from Nutscript? Check out the porting guide in the manual.

+

Server owners

+

If you're looking to get your Lilia server up and running as soon as possible, check out the Installation Tutorial guide in the manual. If you are looking for the feature list, you can find it here .

+

Community

+

Questions? Want to show off your work? Maybe drop a new module release? Come join our community Discord server.

+

Contributing

+

Lilia is still early on its lifespan and there are still a few things missing here and there. Contributions to the documentation - from function references, to simple typo fixes - are welcomed!> +

If you'd like to contribute code, you can visit the GitHub repository and make a pull request.

+

Learning

+

Getting started on developing with the Lilia framework requires an intermediate level of Garry's Mod Lua knowledge. You'll want to learn the basics before you get starting making a schema. The Garry's Mod Wiki is a good place to start.

+
diff --git a/docs/templates/ldoc.ltp b/docs/templates/ldoc.ltp new file mode 100644 index 0000000..e347fec --- /dev/null +++ b/docs/templates/ldoc.ltp @@ -0,0 +1,90 @@ + +{% +local baseUrl = ldoc.css:gsub("ldoc.css", "") +local repo = "https://github.com/LiliaFramework/Lilia" +local pageTitle = mod and (ldoc.display_name(mod) .. " - " .. ldoc.title) or ldoc.title + +local oldmarkup = ldoc.markup +function ldoc.markup(text, item) + return oldmarkup(text, item, ldoc.plain) +end + +function ldoc.url(path) + return baseUrl .. path +end + +function ldoc.realm_icon(realm) + return ""; +end + +function ldoc.is_kind_classmethod(kind) + return kind ~= "libraries" +end + +function ldoc.repo_reference(item) + return repo .. "tree/main" .. item.file.filename:gsub(item.file.base, "/gamemode") .. "#L" .. item.lineno +end + +local function moduleDescription(mod) + if (mod.type == "topic") then + return mod.body:gsub(mod.display_name, ""):gsub("#", ""):sub(1, 256) .. "..." + end + + return mod.summary +end +%} + + + + {{pageTitle}} + + + + + + {% if (mod) then %} + + {% else %} + + {% end %} + + + + + + + +
+ {(docs/templates/sidebar.ltp)} + +
+ {% if (ldoc.root) then -- we're rendering the landing page (index.html) %} + {(docs/templates/landing.ltp)} + {% elseif (ldoc.body) then -- we're rendering non-code elements %} +
+ {* ldoc.body *} +
+ {% elseif (module) then -- we're rendering libary contents %} +
+ {(docs/templates/module.ltp)} +
+ {% end %} +
+
+ + + + + + diff --git a/docs/templates/module.ltp b/docs/templates/module.ltp new file mode 100644 index 0000000..e39bb3c --- /dev/null +++ b/docs/templates/module.ltp @@ -0,0 +1,117 @@ +
+

{{mod.name}}

+

{* ldoc.markup(mod.summary) *}

+
+ +

{* ldoc.markup(mod.description) *}

+ +{% for kind, items in mod.kinds() do %} +

{{kind}}

+ + {% for item in items() do %} +
+
+ +

{* ldoc.realm_icon(item.tags.realm[1]) *}{{ldoc.display_name(item)}}

+
+ + {% if (item.tags.internal) then %} +
+
Internal
+

This is an internal function! You are able to use it, but you risk unintended side effects if used incorrectly.

+
+ {% end %} + {% if (ldoc.descript(item):len() == 0) then %} +
+
Incomplete
+

Documentation for this section is incomplete and needs expanding.

+
+ {% else %} +

{* ldoc.markup(ldoc.descript(item)) *}

+ {% end %} +
+ + {# function arguments #} + {% if (item.params and #item.params > 0) then %} + {% local subnames = mod.kinds:type_of(item).subnames %} + + {% if (subnames) then %} +

{{subnames}}

+ {% end %} + + {% for argument in ldoc.modules.iter(item.params) do %} + {% local argument, sublist = item:subparam(argument) %} + +
    + {% for argumentName in ldoc.modules.iter(argument) do %} + {% local displayName = item:display_name_of(argumentName) %} + {% local type = ldoc.typename(item:type_of_param(argumentName)) %} + {% local default = item:default_of_param(argumentName) %} + +
  • + {{displayName}} + + {% if (type ~= "") then %} + {* type *} + {% end %} + + {% if (default and default ~= true) then %} + default: {{default}} + {% elseif (default) then %} + optional + {% end %} + +

    {* ldoc.markup(item.params.map[argumentName]) *}

    +
  • + {% end %} +
+ {% end %} + {% end %} + + {# function returns #} + {% if ((not ldoc.no_return_or_parms) and item.retgroups) then %} + {% local groups = item.retgroups %} + +

Returns

+
    + {% for i, group in ldoc.ipairs(groups) do %} + {% for returnValue in group:iter() do %} + {% local type, ctypes = item:return_type(returnValue) %} + {% type = ldoc.typename(type) %} + +
  • + {% if (type ~= "") then %} + {* type *} + {% else -- we'll assume that it will return a variable type if none is set %} + any + {% end %} + +

    {* ldoc.markup(returnValue.text) *}

    +
  • + {% end %} + + {% if (i ~= #groups) then %} +
    OR
    + {% end %} + {% end %} +
+ {% end %} + + {% if (item.usage) then -- function usage %} +

Example Usage

+ {% for usage in ldoc.modules.iter(item.usage) do %} +
{* usage *}
+ {% end %} + {% end %} + + {% if (item.see) then %} +

See Also

+
    + {% for see in ldoc.modules.iter(item.see) do %} +
  • {{see.label}}
  • + {% end %} +
+ {% end %} +
+ {% end %} +{% end %} \ No newline at end of file diff --git a/docs/templates/sidebar.ltp b/docs/templates/sidebar.ltp new file mode 100644 index 0000000..0aec919 --- /dev/null +++ b/docs/templates/sidebar.ltp @@ -0,0 +1,68 @@ +{% +local function isKindExpandable(kind) + return kind ~= "Manual" +end +%} + + \ No newline at end of file