Showing preview only (1,807K chars total). Download the full file or copy to clipboard to get everything.
Repository: 3ddelano/epic-online-services-godot
Branch: main
Commit: 6f5368bf027b
Files: 276
Total size: 1.7 MB
Directory structure:
gitextract_ngm7nid4/
├── .clang-format
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ ├── build.yml
│ └── deploy-docs.yml
├── .gitignore
├── .gitmodules
├── .pre-commit-config.yaml
├── .vscode/
│ ├── c_cpp_properties.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── LICENSE.md
├── README.md
├── SConstruct
├── build-ios.sh
├── debug-entitlements.plist
├── debug.cmd
├── debug.sh
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── bun.lockb
│ ├── docs/
│ │ ├── installation.md
│ │ ├── introduction.md
│ │ ├── sample-project.md
│ │ ├── topics/
│ │ │ ├── authentication.md
│ │ │ └── initialization.md
│ │ └── update-guide.md
│ ├── docusaurus.config.ts
│ ├── package.json
│ ├── postcss.config.js
│ ├── sidebars.ts
│ ├── src/
│ │ ├── components/
│ │ │ ├── ExampleSection.tsx
│ │ │ ├── FeaturesSection.tsx
│ │ │ ├── HeroSection.tsx
│ │ │ ├── Icons.tsx
│ │ │ ├── InfoSections.tsx
│ │ │ ├── Layout.tsx
│ │ │ ├── MainSystemsSection.tsx
│ │ │ ├── MediaSections.tsx
│ │ │ └── SupportSection.tsx
│ │ ├── css/
│ │ │ └── custom.css
│ │ ├── pages/
│ │ │ ├── index.tsx
│ │ │ └── showcase.md
│ │ └── plugins/
│ │ └── tailwind-config.ts
│ ├── static/
│ │ └── .nojekyll
│ └── tsconfig.json
├── function_analyzer.py
├── sample/
│ ├── .gitignore
│ ├── AntiCheatServerMain.gd
│ ├── AntiCheatServerMain.gd.uid
│ ├── Main.gd
│ ├── Main.gd.uid
│ ├── Main.tscn
│ ├── addons/
│ │ └── epic-online-services-godot/
│ │ ├── base_class.gd
│ │ ├── base_class.gd.uid
│ │ ├── bin/
│ │ │ └── .gitignore
│ │ ├── dataclass.gd
│ │ ├── dataclass.gd.uid
│ │ ├── eos.gd
│ │ ├── eos.gd.uid
│ │ ├── eosg.gdextension
│ │ ├── eosg.gdextension.uid
│ │ ├── export_plugin.gd
│ │ ├── export_plugin.gd.uid
│ │ ├── heos/
│ │ │ ├── hachievement_data.gd
│ │ │ ├── hachievement_data.gd.uid
│ │ │ ├── hachievements.gd
│ │ │ ├── hachievements.gd.uid
│ │ │ ├── hauth.gd
│ │ │ ├── hauth.gd.uid
│ │ │ ├── hcredentials.gd
│ │ │ ├── hcredentials.gd.uid
│ │ │ ├── hfriends.gd
│ │ │ ├── hfriends.gd.uid
│ │ │ ├── hleaderboards.gd
│ │ │ ├── hleaderboards.gd.uid
│ │ │ ├── hlobbies.gd
│ │ │ ├── hlobbies.gd.uid
│ │ │ ├── hlobby.gd
│ │ │ ├── hlobby.gd.uid
│ │ │ ├── hlobbymember.gd
│ │ │ ├── hlobbymember.gd.uid
│ │ │ ├── hlog.gd
│ │ │ ├── hlog.gd.uid
│ │ │ ├── hp2p.gd
│ │ │ ├── hp2p.gd.uid
│ │ │ ├── hplatform.gd
│ │ │ ├── hplatform.gd.uid
│ │ │ ├── hsessions.gd
│ │ │ ├── hsessions.gd.uid
│ │ │ ├── hstats.gd
│ │ │ └── hstats.gd.uid
│ │ ├── plugin.cfg
│ │ ├── plugin.gd
│ │ ├── plugin.gd.uid
│ │ ├── runtime.gd
│ │ └── runtime.gd.uid
│ ├── components/
│ │ └── StyledPopupWindow/
│ │ ├── StyledPopupWindow.gd
│ │ ├── StyledPopupWindow.gd.uid
│ │ ├── StyledPopupWindow.tscn
│ │ └── StyledPopupWindowTheme.tres
│ ├── dedicated_server_example/
│ │ ├── client_main.gd
│ │ ├── client_main.gd.uid
│ │ ├── client_main.tscn
│ │ ├── server_main.gd
│ │ ├── server_main.gd.uid
│ │ └── server_main.tscn
│ ├── default_bus_layout.tres
│ ├── default_env.tres
│ ├── fonts/
│ │ ├── roboto-13r.tres
│ │ ├── roboto-16b.tres
│ │ ├── roboto-16r.tres
│ │ └── roboto-32b.tres
│ ├── game/
│ │ ├── entities/
│ │ │ ├── bullet/
│ │ │ │ ├── bullet.gd
│ │ │ │ ├── bullet.gd.uid
│ │ │ │ └── bullet.tscn
│ │ │ ├── player/
│ │ │ │ ├── player.gd
│ │ │ │ ├── player.gd.uid
│ │ │ │ └── player.tscn
│ │ │ └── wall/
│ │ │ └── wall.tscn
│ │ └── maps/
│ │ ├── map_bellandur.tscn
│ │ ├── map_margao.tscn
│ │ └── map_new_york.tscn
│ ├── project.godot
│ ├── scenes/
│ │ ├── AchievementsView/
│ │ │ ├── AchievementPopup.gd
│ │ │ ├── AchievementPopup.gd.uid
│ │ │ ├── AchievementUnlockNotification.gd
│ │ │ ├── AchievementUnlockNotification.gd.uid
│ │ │ ├── AchievementUnlockNotification.tscn
│ │ │ ├── AchievementsList.gd
│ │ │ ├── AchievementsList.gd.uid
│ │ │ ├── AchievementsListAchievement.gd
│ │ │ ├── AchievementsListAchievement.gd.uid
│ │ │ ├── AchievementsListAchievement.tscn
│ │ │ ├── AchievementsView.gd
│ │ │ ├── AchievementsView.gd.uid
│ │ │ └── AchievementsView.tscn
│ │ ├── CustomInvitesView/
│ │ │ ├── CustomInvitesView.gd
│ │ │ ├── CustomInvitesView.gd.uid
│ │ │ └── CustomInvitesView.tscn
│ │ ├── FriendsView/
│ │ │ ├── FriendsView.gd
│ │ │ ├── FriendsView.gd.uid
│ │ │ └── FriendsView.tscn
│ │ ├── LeaderboardsView/
│ │ │ ├── LeaderboardsView.gd
│ │ │ ├── LeaderboardsView.gd.uid
│ │ │ └── LeaderboardsView.tscn
│ │ ├── LobbiesView/
│ │ │ ├── CreateLobbyPopup.gd
│ │ │ ├── CreateLobbyPopup.gd.uid
│ │ │ ├── CreateLobbyPopup.tscn
│ │ │ ├── CurrentLobby.gd
│ │ │ ├── CurrentLobby.gd.uid
│ │ │ ├── LobbiesView.gd
│ │ │ ├── LobbiesView.gd.uid
│ │ │ ├── LobbiesView.tscn
│ │ │ ├── SearchLobby.gd
│ │ │ ├── SearchLobby.gd.uid
│ │ │ ├── SearchLobbyResults.gd
│ │ │ └── SearchLobbyResults.gd.uid
│ │ ├── LoginView/
│ │ │ ├── EnterCredentials.gd
│ │ │ ├── EnterCredentials.gd.uid
│ │ │ ├── LoginView.gd
│ │ │ ├── LoginView.gd.uid
│ │ │ └── LoginView.tscn
│ │ ├── LogsView/
│ │ │ ├── LogsView.gd
│ │ │ ├── LogsView.gd.uid
│ │ │ └── LogsView.tscn
│ │ ├── MetricsView/
│ │ │ ├── MetricsView.gd
│ │ │ ├── MetricsView.gd.uid
│ │ │ └── MetricsView.tscn
│ │ ├── NotificationsView/
│ │ │ ├── NotificationsView.gd
│ │ │ └── NotificationsView.gd.uid
│ │ ├── StatsView/
│ │ │ ├── StatsView.gd
│ │ │ ├── StatsView.gd.uid
│ │ │ └── StatsView.tscn
│ │ ├── UI/
│ │ │ ├── NetworkImage.gd
│ │ │ ├── NetworkImage.gd.uid
│ │ │ ├── NetworkImage.tscn
│ │ │ ├── PrimaryButton.tscn
│ │ │ ├── joysticks.gd
│ │ │ ├── joysticks.gd.uid
│ │ │ ├── nat_type.gd
│ │ │ ├── nat_type.gd.uid
│ │ │ ├── nat_type.tscn
│ │ │ ├── ping.gd
│ │ │ ├── ping.gd.uid
│ │ │ ├── ping.tscn
│ │ │ ├── players_score.gd
│ │ │ ├── players_score.gd.uid
│ │ │ ├── players_score.tscn
│ │ │ ├── touch_screen_joystick.gd
│ │ │ └── touch_screen_joystick.gd.uid
│ │ └── UIView/
│ │ ├── UIView.gd
│ │ ├── UIView.gd.uid
│ │ └── UIView.tscn
│ ├── scripts/
│ │ ├── Env.gd
│ │ ├── Env.gd.uid
│ │ ├── Store.gd
│ │ ├── Store.gd.uid
│ │ ├── ViewManager.gd
│ │ ├── ViewManager.gd.uid
│ │ ├── network.gd
│ │ └── network.gd.uid
│ ├── styles/
│ │ └── ViewTitleLabelSettings.tres
│ ├── test.gd
│ ├── test.gd.uid
│ ├── test_manual_audio_output.gd
│ └── test_manual_audio_output.gd.uid
├── src/
│ ├── achievements_interface.cpp
│ ├── anticheat_client_interface.cpp
│ ├── anticheat_server_interface.cpp
│ ├── auth_interface.cpp
│ ├── connect_interface.cpp
│ ├── custom_invites_interface.cpp
│ ├── ecom_interface.cpp
│ ├── eosg_active_session.cpp
│ ├── eosg_active_session.h
│ ├── eosg_continuance_token.h
│ ├── eosg_file_transfer_request.h
│ ├── eosg_lobby_details.cpp
│ ├── eosg_lobby_details.h
│ ├── eosg_lobby_modification.cpp
│ ├── eosg_lobby_modification.h
│ ├── eosg_lobby_search.cpp
│ ├── eosg_lobby_search.h
│ ├── eosg_multiplayer_peer.cpp
│ ├── eosg_multiplayer_peer.h
│ ├── eosg_packet_peer_mediator.cpp
│ ├── eosg_packet_peer_mediator.h
│ ├── eosg_playerdatastorage_file_transfer_request.cpp
│ ├── eosg_playerdatastorage_file_transfer_request.h
│ ├── eosg_presence_modification.cpp
│ ├── eosg_presence_modification.h
│ ├── eosg_session_details.cpp
│ ├── eosg_session_details.h
│ ├── eosg_session_modification.cpp
│ ├── eosg_session_modification.h
│ ├── eosg_session_search.cpp
│ ├── eosg_session_search.h
│ ├── eosg_titlestorage_file_transfer_request.cpp
│ ├── eosg_titlestorage_file_transfer_request.h
│ ├── eosg_transaction.cpp
│ ├── eosg_transaction.h
│ ├── friends_interface.cpp
│ ├── ieos.cpp
│ ├── ieos.h
│ ├── kws_interface.cpp
│ ├── leaderboards_interface.cpp
│ ├── lobby_interface.cpp
│ ├── logging_interface.cpp
│ ├── metrics_interface.cpp
│ ├── mods_interface.cpp
│ ├── p2p_interface.cpp
│ ├── platform_interface.cpp
│ ├── playerdatastorage_interface.cpp
│ ├── presence_interface.cpp
│ ├── progression_snapshot_interface.cpp
│ ├── register_types.cpp
│ ├── register_types.h
│ ├── reports_interface.cpp
│ ├── rtc_audio_interface.cpp
│ ├── rtc_data_interface.cpp
│ ├── rtc_interface.cpp
│ ├── sanctions_interface.cpp
│ ├── sessions_interface.cpp
│ ├── stats_interface.cpp
│ ├── titlestorage_interface.cpp
│ ├── ui_interface.cpp
│ ├── user_info_interface.cpp
│ ├── utils.cpp
│ ├── utils.h
│ └── version_interface.cpp
└── thirdparty/
└── Paste the EOS C SDK here as eos-sdk
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
# Commented out parameters are those with the same value as base LLVM style.
# We can uncomment them if we want to change their value, or enforce the
# chosen value in case the base style changes (last sync: Clang 14.0).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
BreakConstructorInitializers: AfterColon
ColumnLimit: 0
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
SpacesInLineCommentPrefix:
Minimum: 0
Maximum: -1
TabWidth: 4
UseTab: false
---
### C++ specific config ###
Language: Cpp
Standard: c++17
---
### ObjC specific config ###
Language: ObjC
ObjCBlockIndentWidth: 4
---
### Java specific config ###
Language: Java
JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...
================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
[*.{h,hpp,cpp,gd}]
indent_style = tab
indent_size = 4
================================================
FILE: .gitattributes
================================================
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
================================================
FILE: .github/FUNDING.yml
================================================
github: 3ddelano
custom: https://www.buymeacoffee.com/3ddelano
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: 3ddelano
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Minimal steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
(or provide link to minimal reproducible project)
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Operating System:**
- Version: [e.g. iOS 18.2, macOS arm64 15.2]
**Plugin version:**
- Version [e.g. v2.1.5]
**Godot version:**
- Version [e.g. v4.2]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/build.yml
================================================
name: 🛠️ Builds
on:
workflow_dispatch:
push:
branches:
- "*"
tags:
- "*"
jobs:
build:
runs-on: ${{ matrix.runner }}
name: ${{ matrix.name }}
strategy:
fail-fast: false
matrix:
include:
- identifier: linux-x86-64-debug
name: 🐧 Linux x86_64 Debug
runner: ubuntu-24.04
target: template_debug
dev_build: yes
platform: linux
arch: x86_64
- identifier: linux-x86-64-release
name: 🐧Linux x86_64 Release
runner: ubuntu-24.04
target: template_release
dev_build: no
platform: linux
arch: x86_64
- identifier: linux-arm64-debug
name: 🐧 Linux arm64 Debug
runner: ubuntu-24.04-arm
target: template_debug
dev_build: yes
platform: linux
arch: arm64
- identifier: linux-arm64-release
name: 🐧Linux arm64 Release
runner: ubuntu-24.04-arm
target: template_release
dev_build: no
platform: linux
arch: arm64
- identifier: macos-debug
name: 🍎 macOS (universal) Debug
runner: macos-latest
target: template_debug
dev_build: yes
platform: macos
arch: universal
- identifier: macos-release
name: 🍎 macOS (universal) Release
runner: macos-latest
target: template_release
dev_build: no
platform: macos
arch: universal
- identifier: windows-debug
name: 🏁 Windows Debug
runner: windows-latest
target: template_debug
dev_build: yes
platform: windows
arch: x86_64
- identifier: windows-release
name: 🏁 Windows Release
runner: windows-latest
target: template_release
dev_build: no
platform: windows
arch: x86_64
- identifier: android-arm64-debug
name: 🤖 Android arm64 Debug
runner: ubuntu-24.04
target: template_debug
dev_build: yes
platform: android
arch: arm64
- identifier: android-arm64-release
name: 🤖 Android arm64 Release
runner: ubuntu-24.04
target: template_release
dev_build: no
platform: android
arch: arm64
- identifier: android-x86_64-debug
name: 🤖 Android x86_64 Debug
runner: ubuntu-24.04
target: template_debug
dev_build: yes
platform: android
arch: x86_64
- identifier: android-x86_64-release
name: 🤖 Android x86_64 Release
runner: ubuntu-24.04
target: template_release
dev_build: no
platform: android
arch: x86_64
- identifier: ios-arm64-all
name: 🍏 iOS (arm64) All
runner: macos-latest
platform: ios
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Set up SCons
shell: bash
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
scons --version
- name: Checkout project
uses: actions/checkout@v4
with:
submodules: false
- name: Checkout godot-cpp
uses: actions/checkout@v4
with:
repository: godotengine/godot-cpp
path: godot-cpp
submodules: recursive
ref: "godot-4.2-stable"
- name: Checkout private EOS SDK mirror repo
uses: actions/checkout@v4
with:
token: "${{secrets.EOS_SDK_MIRROR_PAT}}"
repository: 3ddelano/eos-sdk-mirror
path: thirdparty/eos-sdk
ref: "dd294d8d5d175840f61775a527332560ba81afa4"
- name: (Windows) Install mingw64
if: ${{ matrix.platform == 'windows' }}
# change to egor-tensin/setup-mingw@v2 once pr #16 is merged
uses: 3ddelano/setup-mingw@patch-1
- name: (Linux) Install dependencies
if: ${{ matrix.platform == 'linux' }}
run: |
sudo apt-get update -qq
sudo apt-get install -qqq build-essential pkg-config
- name: (Android) Install dependencies
if: ${{ matrix.platform == 'android' }}
uses: nttld/setup-ndk@v1
with:
ndk-version: r23c
link-to-sdk: true
- name: Setup build cache
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/.scons-cache/
key: ${{ matrix.identifier }}
restore-keys: |
${{ matrix.identifier }}
continue-on-error: true
- name: Compile extension
shell: sh
if: ${{ matrix.platform != 'ios' }}
env:
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
SCONS_CACHE_LIMIT: 7168
run: |
scons target='${{ matrix.target }}' platform='${{ matrix.platform }}' arch='${{ matrix.arch }}' dev_build='${{ matrix.dev_build }}'
- name: (iOS) Compile extension
shell: sh
if: ${{ matrix.platform == 'ios' }}
env:
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
SCONS_CACHE_LIMIT: 7168
run: |
chmod +x ./build-ios.sh && ./build-ios.sh
- name: Copy extra files to addon folder
shell: sh
run: |
cp -n '${{ github.workspace }}/README.md' '${{ github.workspace }}/LICENSE.md' '${{ github.workspace }}/sample/addons/epic-online-services-godot/'
- name: Create artifact folder
shell: sh
run: |
mkdir -p '${{ github.workspace }}/artifact-${{ matrix.identifier }}/${{ github.event.repository.name }}/'
- name: Copy addons folder to artifact folder
shell: sh
run: |
cp -n -r '${{ github.workspace }}/sample/addons' '${{ github.workspace }}/artifact-${{ matrix.identifier }}/${{ github.event.repository.name }}/'
- name: (Windows) Delete compilation files
if: ${{ matrix.platform == 'windows' }}
run: |
Remove-Item ${{ github.workspace }}/artifact-${{ matrix.identifier }}/${{ github.event.repository.name }}/addons/epic-online-services-godot/bin/windows/* -Include *.exp,*.lib,*.ilk -Force
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.repository.name }}-${{ matrix.identifier }}-${{ github.sha }}
path: |
${{ github.workspace }}/artifact-${{ matrix.identifier }}/
compression-level: 9
retention-days: 14
merge-platforms:
runs-on: ubuntu-latest
needs: build
strategy:
fail-fast: false
matrix:
include:
- identifier: linux-x86_64
name: 🐧 Linux
matchpattern: linux
- identifier: macos-universal
name: 🍎 macOS (universal)
matchpattern: macos
- identifier: windows
name: 🏁 Windows
matchpattern: windows
- identifier: android
name: 🤖 Android
matchpattern: android
- identifier: ios
name: 🍏 iOS
matchpattern: ios
steps:
- name: Merge artifacts for platform
uses: actions/upload-artifact/merge@v4
with:
name: ${{ github.event.repository.name }}-${{ matrix.matchpattern }}-${{ github.sha }}
pattern: ${{ github.event.repository.name }}-${{ matrix.matchpattern }}*
compression-level: 9
retention-days: 14
merge-all:
runs-on: ubuntu-latest
needs: merge-platforms
steps:
- name: Merge artifacts into single
uses: actions/upload-artifact/merge@v4
with:
name: ${{ github.event.repository.name }}-all-${{ github.sha }}
pattern: ${{ github.event.repository.name }}-*
compression-level: 9
retention-days: 14
upload-to-release:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
needs: merge-all
permissions:
contents: write
steps:
- name: Download 'all' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-all-${{ github.sha }}
path: artifact-all
- name: Download 'android' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-android-${{ github.sha }}
path: artifact-android
- name: Download 'macos' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-macos-${{ github.sha }}
path: artifact-macos
- name: Download 'linux' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-linux-${{ github.sha }}
path: artifact-linux
- name: Download 'windows' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-windows-${{ github.sha }}
path: artifact-windows
- name: Download 'ios' artifact
uses: actions/download-artifact@v4
with:
name: ${{ github.event.repository.name }}-ios-${{ github.sha }}
path: artifact-ios
- name: Zip 'all' artifact
run: |
cd artifact-all
zip -9 -r ../${{ github.event.repository.name }}-all-${{ github.sha }}.zip .
cd ..
- name: Zip 'android' artifact
run: |
cd artifact-android
zip -9 -r ../${{ github.event.repository.name }}-android-${{ github.sha }}.zip .
cd ..
- name: Zip 'macos' artifact
run: |
cd artifact-macos
zip -9 -r ../${{ github.event.repository.name }}-macos-${{ github.sha }}.zip .
cd ..
- name: Zip 'linux' artifact
run: |
cd artifact-linux
zip -9 -r ../${{ github.event.repository.name }}-linux-${{ github.sha }}.zip .
cd ..
- name: Zip 'windows' artifact
run: |
cd artifact-windows
zip -9 -r ../${{ github.event.repository.name }}-windows-${{ github.sha }}.zip .
cd ..
- name: Zip 'ios' artifact
run: |
cd artifact-ios
zip -9 -r ../${{ github.event.repository.name }}-ios-${{ github.sha }}.zip .
cd ..
- name: Create draft release and upload assets
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
tag_name: ${{ github.ref_name }}
draft: true
files: |
${{github.event.repository.name}}-all-${{ github.sha }}.zip
${{github.event.repository.name}}-android-${{ github.sha }}.zip
${{github.event.repository.name}}-macos-${{ github.sha }}.zip
${{github.event.repository.name}}-linux-${{ github.sha }}.zip
${{github.event.repository.name}}-windows-${{ github.sha }}.zip
${{github.event.repository.name}}-ios-${{ github.sha }}.zip
================================================
FILE: .github/workflows/deploy-docs.yml
================================================
name: Deploy Docs to GitHub Pages
on:
push:
branches:
- "*"
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
jobs:
build:
name: Build Docusaurus
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: cd docs && bun install
- name: Build website
run: cd docs && bun run build
- name: Upload Build Artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/build
deploy:
name: Deploy to GitHub Pages
needs: build
if: github.ref == 'refs/heads/main'
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .gitignore
================================================
# Godot logs
logs/
cache/
.cache/
sample/android
sample/android_debug.keystore
.DS_Store
.env
vc140.pdb
.sconsign.dblite
*.o
*.obj
*.os
**/*.tmp
temp/
.idea/
compile_commands.json
epic-online-services-godot-addon.zip
================================================
FILE: .gitmodules
================================================
[submodule "godot-cpp"]
path = godot-cpp
url = https://github.com/godotengine/godot-cpp
branch = 4.2
[submodule "thirdparty/eos-sdk"]
path = thirdparty/eos-sdk
url = https://github.com/3ddelano/eos-sdk-mirror.git
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/ssciwr/clang-format-hook
rev: v16.0.2
hooks:
- id: clang-format
================================================
FILE: .vscode/c_cpp_properties.json
================================================
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/godot-cpp/**",
"${workspaceFolder}/godot-cpp/gen/include/**",
"${workspaceFolder}/godot-cpp/include/**",
"${workspaceFolder}/godot-cpp/gdextension/**",
"${workspaceFolder}/thirdparty/eos-sdk/SDK/Include/",
"${workspaceFolder}/thirdparty/eos-sdk/SDK/Include/**",
"${workspaceFolder}/src/**",
"${workspaceFolder}/src"
],
"defines": ["_DEBUG", "UNICODE", "_UNICODE"],
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "cl.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}
================================================
FILE: .vscode/launch.json
================================================
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Project (Windows)",
"type": "cppvsdbg",
"request": "launch",
"program": "${config:godotTools.editorPath.godot4}",
"args": ["--debug"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/sample",
"environment": [],
"console": "integratedTerminal",
"preLaunchTask": "build"
},
{
"name": "Debug Project (Macos)",
"type": "cppdbg",
"request": "launch",
"program": "${config:godotTools.editorPath.godot4}",
"args": ["--debug"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/sample",
"environment": [],
"console": "integratedTerminal",
"MIMode": "lldb",
"preLaunchTask": "build"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"files.exclude": {
"**/*.obj": true,
"**/*.ilk": true,
"**/*.exp": true,
"**/*.pdb": true,
"**/__pycache__": true,
"**/*.os": true,
"**/*.o": true
},
"godot_tools.editor_path": "d:\\Projects\\Godot\\Godot_v4.exe",
"files.associations": {
"*.rmd": "markdown",
"utility": "cpp",
"sstream": "cpp",
"unordered_map": "cpp",
"algorithm": "cpp",
"chrono": "cpp",
"iterator": "cpp",
"xhash": "cpp",
"xtree": "cpp",
"xutility": "cpp",
"string": "cpp",
"type_traits": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"vector": "cpp",
"initializer_list": "cpp"
},
"grammarly.selectors": [
{
"language": "cpp",
"scheme": "file"
}
],
"cmake.ignoreCMakeListsMissing": true
}
================================================
FILE: .vscode/tasks.json
================================================
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"group": "build",
"type": "shell",
"command": "scons",
"args": ["dev_build=yes"],
"problemMatcher": "$msCompile"
},
{
"label": "build-release",
"group": "build",
"type": "shell",
"command": "scons",
"args": ["target=template_release"],
"problemMatcher": "$msCompile"
}
]
}
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2022 Delano Lourenco
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Epic Online Services Godot (EOSG)
<img alt="Project Logo" src="./_media/logo.png" height="150">
### Easiest way to use Epic Online Services in Godot 4.2+ (includes demo project)
<img alt="Godot3" src="https://img.shields.io/badge/-Godot 4.2+-478CBF?style=for-the-badge&logo=godotengine&logoWidth=20&logoColor=white" />
<img alt="Epic Online Services 1.18.1.2" src="https://img.shields.io/badge/-Epic Online Services 1.18.1.2-313131?style=for-the-badge&logo=epic-games&logoWidth=20&logoColor=white" />
> Supports Windows x64, Linux x64/arm64, Android x64/arm64, MacOS, iOS arm64 (iphone/simulator)
> Disclaimer: This project is NOT affiliated with Epic Games Inc or Godot Engine. It doesn't endorse Epic Online
> Services. This project and sample Godot scenes are provided solely for educational purposes and may or may not comply
> with Epic Games' Design Guidelines, if you plan to release a game make sure you read
> the [Guidelines](https://dev.epicgames.com/docs/services/en-US/EpicAccountServices/DesignGuidelines/index.html) and
> any
> other steps needed to release a public game like asking for user consent, option to delete user data, website with
> privacy policy and license, etc.
## This plugin has two main systems:
- ### High Level EOS (Recommended)
The High Level Epic Online Services provides easy to use methods and signals to interact with EOS recommended for
beginners.
- ### GDExtension EOS
The GDExtension EOS provides advanced EOS usage not recommended for beginners. See `EOS` and `IEOS` classes.
## [🚀 Check out out GDAI MCP from the creator of EOSG](https://gdaimcp.com?ref=eosg-readme)
<a href="https://gdaimcp.com?ref=eosg-readme" target="_blank">
<img src="https://gdaimcp.com/images/og/gdai-mcp.png" width="400" />
</a>
Supercharge your Godot 4.2+ workflow with GDAI MCP – the ultimate Godot MCP server that lets AI tools like Claude,
Cursor, Windsurf, VSCode and more automate scene creation, node editing, reading godot errors, creating scripts,
debugging, and more.
Vibe code like never before!
### 🔗 **[https://gdaimcp.com](https://gdaimcp.com?ref=eosg-readme)**
# High Level Epic Online Services
Following are the main classes in High Level Epic Online Services. They also have documentation in the Godot Editor:
- ### HPlatform
- ### HAuth
- ### HAchievements
- ### HFriends
- ### HStats
- ### HLeaderboards
- ### HLobbies
- ### HP2P
- ### HLog
A basic example of using High Level EOS:
```GDScript
# In main script
extends Node
func _ready() -> void:
# Setup HEOS Logs
HLog.log_level = HLog.LogLevel.INFO
var credentials = HCredentials.new()
credentials.product_name = "PRODUCT_NAME_NAME"
credentials.product_version = "PRODUCT_VERSION_HERE"
credentials.product_id = "PRODUCT_ID_HERE"
credentials.sandbox_id = "SANDBOX_ID_HERE"
credentials.deployment_id = "DEPLOYMENT_ID_HERE"
credentials.client_id = "CLIENT_ID_HERE"
credentials.client_secret = "CLIENT_SECRET_HERE"
# optional
#credentials.encryption_key = "ENCRYPTION_KEY_HERE"
var setup_success := await HPlatform.setup_eos_async(credentials)
if not setup_success:
printerr("Failed to setup EOS. See logs for more details")
return
# Setup Logs from EOS
HPlatform.log_msg.connect(_on_eos_log_msg)
var log_res := HPlatform.set_eos_log_level(EOS.Logging.LogCategory.AllCategories, EOS.Logging.LogLevel.Info)
if not EOS.is_success(log_res):
printerr("Failed to set logging level")
return
HAuth.logged_in.connect(_on_logged_in)
# During development use the devauth tool to login
HAuth.login_devtool_async("localhost:4545", "CREDENTIAL_NAME_HERE")
# Or login without any credentials
# await HAuth.login_anonymous_async()
func _on_logged_in():
print("Logged in successfully: product_user_id=%s" % HAuth.product_user_id)
# Example: Get top records for a leaderboard
var records := await HLeaderboards.get_leaderboard_records_async("LEADERBOARD_ID_HERE")
print(records)
func _on_eos_log_msg(msg: EOS.Logging.LogMessage) -> void:
print("SDK %s | %s" % [msg.category, msg.message])
```
# GDextension Epic Online Services
## Features
- Authentication (Epic Games, Steam, Discord, Anonymous etc)
- Social Overlay on Windows
- Achievements
- Stats & Leaderboards
- Lobby, Sessions and Multiplayer
- Voice
- Metrics
- Mods
- Player/Title data storage
- Progression Snapshot
- Reports and Sanctions
- Ecommerce (Ecom Epic Games Store)
- AntiCheat
#### [View Current Project Status](#current-project-status)
## Simple P2P Example
A simple demo showcasing P2P multiplayer using Epic Online
Services: [Click Here](https://github.com/3ddelano/EOSGP2PInterfaceTestGame)
## Support Development
#### Making this project took a lot of time and effort, reading the Epic Online Services documentation countless times and testing each method in Godot. I would really appreciate if you could support the project in any way.
<a href="https://www.buymeacoffee.com/3ddelano" target="_blank"><img height="41" width="174" src="https://cdn.buymeacoffee.com/buttons/v2/default-red.png" alt="Buy Me A Coffee" width="150" ></a>
<br>
<a href="https://github.com/sponsors/3ddelano" target="_blank">Github Sponsor</a>
#### Want to support in other ways? Contact me on Discord: `@3ddelano`
Join the Discord server for discussing suggestions or bugs: [3ddelano Cafe](https://discord.gg/FZY9TqW)
## [Demo Video (Youtube)](https://www.youtube.com/watch?v=ENyvF4yVjKg)
[Watch the playlist](https://www.youtube.com/playlist?list=PL5t0hR7ADzun5JYF4e2a2FtZEWYHxK83_)
[](https://www.youtube.com/playlist?list=PL5t0hR7ADzun5JYF4e2a2FtZEWYHxK83_)
## [Documentation](http://localhost:3000/epic-online-services-godot/docs/introduction)
## Screenshots
- Windows
<img src="./_media/windows_auth_success.png">
- Android
<img src="./_media/android_auth_success.jpg">
<img src="./_media/android_p2p_game.jpg">
- iOS
<img src="./_media/ios_simulator_auth_success.png">
- Cross platform lobbies
- iOS
<img src="./_media/ios_simulator_in_lobby.png">
- macOS
<img src="./_media/mac_in_lobby.png">
## How does it work
This project uses GDExtension to wrap the `Epic Online Services C SDK` so that it can be easily used in Godot using
GDScript, C#, etc with similar class hierarchy and static type support. It makes use of signals for sending events like
user login, logout, achievement unlock, etc.
## Installation
This is a regular plugin for `Godot 4.2+`. To install the plugin follow the steps below:
#### **Method 1: Install from Asset Library**
1. Asset Library link: [View the plugin on Godot Asset Library](https://godotengine.org/asset-library/asset/2453)
2. In the Godot editor, navigate to the `AssetLib` tab, and in the search bar type `EOSG`.
3. Click on the plugin with name `Epic Online Services Godot (EOSG)` by `3ddelano`
4. In the popup that opens, click the `Download` button.
5. Once the download is done, click the `Install` button.
6. Goto `Project->Project Settings->Plugins` and enable the `Epic Online Services Godot 4.2+ (EOSG)` plugin.
7. Restart the godot editor.
8. You can now use the plugin. Head to the [Documentation](#) for more information on how to use the plugin.
#### **Method 2: Install from GitHub**
1. Goto the Releases section and download
the [latest release](https://github.com/3ddelano/epic-online-services-godot/releases/latest)
2. Extract the zip file and copy the `addons/epic-online-services-godot` folder into the `res://addons/` folder of your
project. If the `res://addons` does not exist, create it.
3. In the Godot editor, goto `Project->Project Settings->Plugins` and enable the
`Epic Online Services Godot 4.2+ (EOSG)` plugin.
4. Restart the godot editor.
5. You can now use the plugin. Head to the [Documentation](#) for more information on how to use the plugin.
## Development Setup
#### Pre-requisites
- Godot Engine 4.2+ (Get it here [Godot Engine Download](https://godotengine.org/download/))
- Epic Online Services C SDK (Download from [Epic Developer Portal](https://dev.epicgames.com/portal/sdk))
- Make sure you have accepted the Terms and Conditions
for [Epic Online Services](https://www.epicgames.com/site/en-US/tos?lang=en-US)
- A product registered with Epic Games Services (Make one for
free [Epic Developer Portal](https://dev.epicgames.com/portal))
To develop this plugin, follow the below steps:
1. Download/clone the repository.
1. Run the command:
```bash
git submodule update --init --recursive
```
1. Extract the `EOS C SDK` zip downloaded from Epic Games, rename it to `eos-sdk` and paste it in the `thirdparty/`
folder. Refer to the below folder structure.
<img src="./_media/eos_folder_structure.png">
1. Build the GDExtension plugin in debug mode (With debug symbols)
```shell
# In root folder
scons platform=<platform> target=template_debug dev_build=yes
```
Eg. `scons platform=windows target=template_debug dev_build=yes`
1. Build the GDExtension plugin for release (Optimized)
```shell
# In root folder
scons platform=windows target=template_release
```
1. The built GDExtension library will be in the `res://addons/epic-online-services-godot/bin/` folder of the sample
project.
## Debugging GDExtension on MacOS
If you get an error `Not allowed to attach to process` trying to debug GDExtension on MacOS using LLDB. Run the below
command:
```bash
codesign --entitlements debug-entitlements.plist -f -s - /Applications/Godot.app/Contents/MacOS/Godot
```
### How to run the sample project?
> The sample Godot project is located in the **sample** folder
1. Clone/Download the repo.
2. Download the [latest release](https://github.com/3ddelano/epic-online-services-godot/releases/latest) from the
Releases section and replace the existing `/addons/epic-online-services-godot` with the one from the Release (this
includes the built shared libraries).
3. Copy your credentials (`Product Id`, `Sandbox Id`, `Deployment Id`, `Client Id`, `Client Secret`) of your Epic
Games "Product" from the Epic Games Dev Portal and paste them in `Main.gd` script in the relevant sections. The
encryption key is a random 64 character long string. These credentials need to be kept as private as possible. One
way is to make sure to encrypt all scripts when exporting the final game. (
See [Compiling with script key encryption](https://docs.godotengine.org/en/stable/development/compiling/compiling_with_script_encryption_key.html))
4. Configure your Product on the EOS Dev Portal with the following configuration:
- In the `Client Policies` section in `Product Settings`, for the Client policy type choose `Custom policy`, enable the
`User is required` and enable every features and action except `Connect` (Trusted Server Required). This will allow
the sample to access the different services provided by Epic Online Services. In your actual game, the client policy
is important and you should give minimal permissions to features.
- In the `Permissions` section of `Epic Account Services`, enable all three: `Basic Profile`, `Online Presence` and
`Friends`.
- (Optional if you want some pre-made achievements)
In the `Achievements` section in `Game Services`, use the `Bulk Import` option and import the `HelloProduct.zip` file
located at `res://HelloProduct.zip`
### Bootstrapping Godot executable with Epic Online Services
If you want to use the `Account Portal` login option in Epic Online Services, you need to bootstrap the Godot/Game
executable as needed by `EOS-SDK 1.15` and greater.
See [Redistributable Installer](https://dev.epicgames.com/docs/services/en-US/EpicAccountServices/Crossplayacrossplatforms/RedistributableInstaller/index.html)
A sample of the generated `.ini` file for the Godot Editor is shown below (during game development):
```
ApplicationPath=Godot_v4.2.0-stable_win64.exe
WorkingDirectory=
WaitForExit=0
NoOperation=0
```
Follow the instructions
in [Running the service for local development](https://dev.epicgames.com/docs/services/en-US/EpicAccountServices/Crossplayacrossplatforms/RedistributableInstaller/index.html#runningtheserviceforlocaldevelopment)
and:
- During game development
Bootstrap the Godot Editor executable (eg. `Godot_v4.2.0-stable_win64.exe`) to test the `Account Portal` login
- After exporting the game
Bootstrap the exported game executable (eg. `My Amazing Game.exe`)
## Exporting for Android
Use a community created [Android Export Plugin](https://github.com/uno1982/EOSG-android-exporter)
Or follow the steps below to manually export for Android.
### Pre-requisites
1. Setup the `Android Build Template` in your Godot project by following the
tutorial [Gradle builds for Andriod](https://docs.godotengine.org/en/stable/tutorials/export/android_gradle_build.html).
This will create an android project in `res://android/build`.
2. Now with reference to the
tutorial [Add the EOS SDK to Your Android Studio Project](https://dev.epicgames.com/docs/epic-online-services/platforms/android#4-add-the-eos-sdk-to-your-android-studio-project),
perform the following steps.
3. In the `res://android/build/build.gradle` file, add the following lines after the implementations in the
`dependencies` section.
Before
```gradle
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
... other code
```
After
```gradle
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
// EOS SDK dependencies
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.security:security-crypto:1.0.0'
implementation 'androidx.browser:browser:1.4.0'
implementation 'androidx.webkit:webkit:1.7.0'
// Update the path so that it points to eossdk-StaticSTDC-release.aar provided in addons/epic-online-services-godot/bin/android/
implementation files('../../addons/epic-online-services-godot/bin/android/eossdk-StaticSTDC-release.aar')
...other code
```
4. In the `res://android/build/build.gradle` file, add the following lines after the `defaultConfig` in the `android`
section.
Before
```gradle
android {
... other code
defaultConfig {
... other code
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
versionCode getExportVersionCode()
versionName getExportVersionName()
minSdkVersion getExportMinSdkVersion()
targetSdkVersion getExportTargetSdkVersion()
missingDimensionStrategy 'products', 'template'
}
... other code
```
After
```gradle
android {
... other code
defaultConfig {
... other code
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
versionCode getExportVersionCode()
versionName getExportVersionName()
minSdkVersion getExportMinSdkVersion()
targetSdkVersion getExportTargetSdkVersion()
missingDimensionStrategy 'products', 'template'
// This is needed by EOS Android SDK
String ClientId = "PUT YOUR EOS CLIENT ID HERE"
resValue("string", "eos_login_protocol_scheme", "eos." + ClientId.toLowerCase())
}
... other code
```
5. In the `res://android/build/config.gradle` file, update the `minSdk` to `23` to match with the requirements of the
`EOS Android SDK`.
Before
```gradle
minSdk : 21,
```
After
```gradle
minSdk : 23,
```
6. In the `res://android/build/src/com/godot/game/GodotGame.java` file, update it as follows.
```java
package com.godot.game;
import com.epicgames.mobile.eossdk.EOSSDK; // added
import org.godotengine.godot.GodotActivity;
import android.os.Bundle;
public class GodotApp extends GodotActivity {
static { // added
System.loadLibrary("EOSSDK"); // added
} // added
@Override
public void onCreate(Bundle savedInstanceState) {
EOSSDK.init(getActivity()); // added
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
}
}
```
7. Now open your project in the Godot Editor, and goto `Project -> Export` and create a new Android export profile.
8. In the `Gradle Build` section, enable `Use Gradle Build`. In the `Architectures` section enable `arm64-v8a`. In the
`Permissions` section ensure that `ACESSS_NETWORK_STATE`, `ACCESS_WIFI_STATE` and `INTERNET` are enabled. These
permissions are needed for the EOS SDK to work. Fill in the other details such as package name, etc as needed.
9. You can now export the Android APK by clicking the `Export Project` button.
## Exporting for iOS
Export the project from Godot editor for iOS target. You might get a build error during this process, ignore it. Open
the generated iOS project in XCode and build the project. The build should be successful. EOSG has support for iOS arm64
device and iOS arm64 simulator.
## Current Project Status
- Completed with sample
- Auth Interface
- Achievements Interface
- Connect Interface
- CustomInvites Interface
- Friends Interface
- Stats Interface
- UserInfo Interface
- Leaderboards Interface
- Metrics Interface
- Mods Interface
- Presence Interface
- ProgressionSnapshot Interface
- Reports Interface
- UI Interface
- Lobby Interface (Also sample for manual audio input/output)
- RTC Interface
- RTCAudio Interface
- P2P Interface
- Version Interface
- Completed without sample
- KWS Interface
- PlayerDataStorage Interface
- Sanctions Interface
- Sessions Interface
- TitleStorage Interface
- Ecom Interface
- AntiCheatServer Interface
- AntiCheatClient Interface
- Not completed
- Integrated Platform Interface
================================================
FILE: SConstruct
================================================
#!/usr/bin/env python
import os
import shutil
env = SConscript("godot-cpp/SConstruct")
lib_name = "libeosg"
plugin_bin_folder = "sample/addons/epic-online-services-godot/bin"
eos_sdk_folder = "thirdparty/eos-sdk/SDK/"
# Add source files
env.Append(CPPPATH=["src/", eos_sdk_folder + "Include/"])
sources = Glob("src/*.cpp")
platform = env["platform"]
build_target = env["target"]
def copy_file(from_path, to_path):
if not os.path.exists(os.path.dirname(to_path)):
os.makedirs(os.path.dirname(to_path))
shutil.copyfile(from_path, to_path)
def copy_folder(from_path, to_path):
if not os.path.exists(to_path):
os.makedirs(to_path)
shutil.rmtree(to_path, ignore_errors=True)
shutil.copytree(from_path, to_path)
def extract_eos_android_libraries():
libs_path = eos_sdk_folder + "Bin/Android/static-stdc++/libs/"
aar_file = eos_sdk_folder + "Bin/Android/static-stdc++/aar/eossdk-StaticSTDC-release.aar"
zip_file = libs_path + "eos-sdk.zip"
# Delete libs folder if exists
shutil.rmtree(libs_path, ignore_errors=True)
# Copy aar to zip file
copy_file(aar_file, zip_file)
# Copy aar to plugin bin/android
copy_file(aar_file, plugin_bin_folder + "/android/eossdk-StaticSTDC-release.aar")
# Create folder if doesnt exist
if not os.path.exists(libs_path + "extracted"):
os.makedirs(libs_path + "extracted")
# Unzip the file
shutil.unpack_archive(zip_file, libs_path + "extracted")
# Copy all folders from libs_path+"extracted/jni" to libs_path
for folder in os.listdir(libs_path + "extracted/jni"):
shutil.copytree(libs_path + "extracted/jni/" + folder, libs_path + folder)
# Delete extracted folder
shutil.rmtree(libs_path + "extracted", ignore_errors=True)
# Delete zip file
os.remove(zip_file)
genv = env
def on_complete(target, source, env):
if platform == "windows":
shutil.rmtree(plugin_bin_folder + "/windows/x64", ignore_errors=True)
shutil.copytree(eos_sdk_folder + "Bin/x64", plugin_bin_folder + "/windows/x64")
copy_file(eos_sdk_folder + "Bin/EOSSDK-Win64-Shipping.dll", plugin_bin_folder + "/windows/EOSSDK-Win64-Shipping.dll")
elif platform == "linux":
so_variant = "LinuxArm64" if genv["arch"] == "arm64" else "Linux"
copy_file(eos_sdk_folder + f"Bin/libEOSSDK-{so_variant}-Shipping.so", plugin_bin_folder + f"/linux/libEOSSDK-{so_variant}-Shipping.so")
elif platform == "macos":
framework_folder = plugin_bin_folder + f"/macos/{lib_name}.{platform}.{build_target}.framework"
# Copies EOS dylib inside framework folder
copy_file(eos_sdk_folder + "Bin/libEOSSDK-Mac-Shipping.dylib", framework_folder + f"/libEOSSDK-Mac-Shipping.dylib")
lib_path = f"{framework_folder}/{lib_name}.{platform}.{build_target}"
print(f"Updating libEOSSDK-Mac-Shipping.dylib path in {lib_path}")
os.system(f"install_name_tool -change @rpath/libEOSSDK-Mac-Shipping.dylib @loader_path/libEOSSDK-Mac-Shipping.dylib {lib_path}")
# For reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
env.Append(LIBPATH=[eos_sdk_folder + "Lib/"])
env.Append(LIBPATH=[eos_sdk_folder + "Bin/"])
if env["platform"] == "windows":
# TODO: dont ignore this warning
# this disables LINK : error LNK1218: warning treated as error;
# so that it can build in github action with scons cache
env.Append(LINKFLAGS=["/ignore:4099"])
env.Append(LIBS=["EOSSDK-Win64-Shipping"])
elif env["platform"] == "linux":
env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
if env["arch"] == "arm64":
env.Append(LIBS=["EOSSDK-LinuxArm64-Shipping"])
else:
env.Append(LIBS=["EOSSDK-Linux-Shipping"])
elif env["platform"] == "macos":
env.Append(LIBS=["EOSSDK-Mac-Shipping"])
elif env["platform"] == "ios":
if env["arch"] != "arm64":
raise Exception("Only arm64 is supported on iOS.")
copy_folder(eos_sdk_folder + "Bin/IOS/EOSSDK.xcframework", plugin_bin_folder + "/ios/EOSSDK.xcframework")
env.Append(ENV={'IPHONEOS_DEPLOYMENT_TARGET': '15.0'})
env.Append(LINKFLAGS=[
"-F", plugin_bin_folder + f"/ios/EOSSDK.xcframework/ios-arm64{"-simulator" if env["ios_simulator"] else ""}",
'-framework', 'AuthenticationServices',
'-framework', 'EOSSDK',
])
elif env["platform"] == "android":
eos_android_arch = "arm64-v8a"
if env["arch"] == "x86_64":
eos_android_arch = "x86_64"
extract_eos_android_libraries()
env.Append(LIBPATH=[eos_sdk_folder + "Bin/Android/static-stdc++/libs/" + eos_android_arch + "/"])
env.Append(LIBS=["EOSSDK"])
if env["platform"] == "macos":
library = env.SharedLibrary(
f"{plugin_bin_folder}/macos/{lib_name}.{platform}.{build_target}.framework/{lib_name}.{platform}.{build_target}",
source=sources,)
else:
library = env.SharedLibrary(
f"{plugin_bin_folder}/{platform}/{lib_name}{env['suffix']}{env['SHLIBSUFFIX']}",
source=sources,
)
# Disable scons cache for source files
# NoCache(sources)
complete_command = Command('complete', library, on_complete)
Depends(complete_command, library)
Default(complete_command)
================================================
FILE: build-ios.sh
================================================
#!/bin/sh
build=yes
if [ "$1" = "build=n" ] || [ "$1" = "build=N" ] || [ "$1" = "build=no" ] || [ "$1" = "build=0" ]; then
build=no
fi
dev_build=no
dev_build_ext=""
if [ "$2" = "dev_build=y" ] || [ "$2" = "dev_build=Y" ] || [ "$2" = "dev_build=yes" ] || [ "$2" = "dev_build=1" ]; then
dev_build=yes
dev_build_ext=".dev"
fi
echo "Config: dev_build=${dev_build}, build=${build}"
if [ "$build" = "yes" ]; then
echo "\nBuilding for iOS simulator template_debug target"
scons arch=arm64 ios_simulator=yes platform=ios target=template_debug dev_build=${dev_build}
echo "\nBuilding for iOS device template_debug target"
scons arch=arm64 ios_simulator=no platform=ios target=template_debug dev_build=${dev_build}
echo "\nBuilding for iOS simulator template_release target"
scons arch=arm64 ios_simulator=yes platform=ios target=template_release dev_build=no
echo "\nBuilding for iOS device template_release target"
scons arch=arm64 ios_simulator=no platform=ios target=template_release dev_build=no
fi
eosg_ios_bin_dir=./sample/addons/epic-online-services-godot/bin/ios
godotcpp_bin_dir=./godot-cpp/bin
echo "\nDeleting existing libgodot-cpp xcframework(s) if any"
rm -rf ${eosg_ios_bin_dir}/libgodot-cpp.ios.template*
echo "\nCreating libgodot-cpp xcframework for template_debug"
xcodebuild -create-xcframework \
-library ${godotcpp_bin_dir}/libgodot-cpp.ios.template_debug${dev_build_ext}.arm64.a \
-library ${godotcpp_bin_dir}/libgodot-cpp.ios.template_debug${dev_build_ext}.arm64.simulator.a \
-output ${eosg_ios_bin_dir}/libgodot-cpp.ios.template_debug.xcframework
echo "\nCreating libgodot-cpp xcframework for template_release"
xcodebuild -create-xcframework \
-library ${godotcpp_bin_dir}/libgodot-cpp.ios.template_release.arm64.a \
-library ${godotcpp_bin_dir}/libgodot-cpp.ios.template_release.arm64.simulator.a \
-output ${eosg_ios_bin_dir}/libgodot-cpp.ios.template_release.xcframework
echo "\nCreating libeosg xcframework for template_debug"
xcodebuild -create-xcframework \
-library ${eosg_ios_bin_dir}/libeosg.ios.template_debug${dev_build_ext}.arm64.dylib \
-library ${eosg_ios_bin_dir}/libeosg.ios.template_debug${dev_build_ext}.arm64.simulator.dylib \
-output ${eosg_ios_bin_dir}/libeosg.ios.template_debug.xcframework
echo "\nCreating libeosg xcframework for template_release"
xcodebuild -create-xcframework \
-library ${eosg_ios_bin_dir}/libeosg.ios.template_release.arm64.dylib \
-library ${eosg_ios_bin_dir}/libeosg.ios.template_release.arm64.simulator.dylib \
-output ${eosg_ios_bin_dir}/libeosg.ios.template_release.xcframework
echo "\nDeleting all .dylib files from eosg ios bin dir"
rm -rf ${eosg_ios_bin_dir}/*.dylib
================================================
FILE: debug-entitlements.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
================================================
FILE: debug.cmd
================================================
@echo off
scons dev_build=yes && godot4 --path sample
================================================
FILE: debug.sh
================================================
scons dev_build=yes && godot45 --path sample
================================================
FILE: docs/.gitignore
================================================
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
================================================
FILE: docs/README.md
================================================
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
================================================
FILE: docs/docs/installation.md
================================================
# Installation
## Method 1: Install from Asset Library (Recommended)
[View the plugin on Godot Asset Library](https://godotengine.org/asset-library/asset/2453)
1. In the Godot editor, navigate to the `AssetLib` tab at the top, and in the search bar type `EOSG`.
2. Click on the plugin with name `Epic Online Services Godot (EOSG)` by `3ddelano`
3. In the popup that opens, click the `Download` button.
4. Once the download is done, click the `Install` button.
5. Goto `Project -> Project Settings -> Plugins` and enable the `Epic Online Services Godot 4.2+ (EOSG)` plugin.
6. **Restart the godot editor.**
7. The plugin is now installeed. Check out the [Initialization](/docs/topics/initialization) guide next.
## Method 2: Install from GitHub
1. Goto the [Releases](https://github.com/3ddelano/epic-online-services-godot/releases) section and download the latest release. Here there are separate zip files for each platform which you can download if you are only looking to release on one platform or download the `epic-online-services-godot-all` that supports all platforms.
2. Extract the zip file and copy the `addons/epic-online-services-godot` folder into the `res://addons/` folder of your project. If the `res://addons` does not exist, create it.
3. In the Godot editor, goto `Project -> Project Settings -> Plugins` and enable the `Epic Online Services Godot 4.2+ (EOSG)` plugin.
4. **Restart the godot editor.**
5. The plugin is now installeed. Check out the [Initialization](/docs/topics/initialization) guide next.
================================================
FILE: docs/docs/introduction.md
================================================
# Introduction
Epic Online Services Godot (EOSG) is the easiest way to integrate Epic Online Services into your Godot project.
The plugin supports the following platforms:
- Windows x64
- Linux x64/arm64
- Android x64/arm64
- MacOS universal
- iOS arm64 (iPhone/simulator)
This plugin has two main ways in which you can interact with Epic Online Services:
1. High Level EOS (Recommended)
2. GDExtension EOS
### High Level EOS (Recommended)
The High Level Epic Online Services provides easy-to-use methods and signals to interact with EOS, making it ideal for beginners. This simplified API abstracts away many of the complexities of the EOS SDK while providing access to its core functionality.
### GDExtension EOS
The GDExtension EOS provides low-level access to the Epic Online Services SDK. This interface is not recommended for beginners but gives you full access to the underlying EOS functionality through the `EOS` and `IEOS` classes in Godot.
<br></br>
Here's the next steps;
- To get started with using the plugin, check out the [Installation](/docs/installation) guide.
- Checkout the [Games Showcase](/showcase)
================================================
FILE: docs/docs/sample-project.md
================================================
# Sample Project
To run the sample project which showcases most of the EOS features, follow these steps:
1. Clone/Download the [plugin repo](https://github.com/3ddelano/epic-online-services-godot)
2. You cannot directly open the ./sample folder and run the project, because the plugin binaries are not included. To include the plugin binaries. Download the [latest release](https://github.com/3ddelano/epic-online-services-godot/releases/latest) from the Releases section and replace the existing `sample/addons/epic-online-services-godot` folder with the one from the Release (this includes the built shared libraries). See the [Installation](/docs/installation) section for more information on how to install the plugin.
3. Copy your credentials (`Product Id`, `Sandbox Id`, `Deployment Id`, `Client Id`, `Client Secret`) of your Epic Games "Product" from the Epic Games Dev Portal and paste them in `./sample/Main.gd` script in the relevant sections. The encryption key is a random 64 character long string. These credentials need to be kept as private as possible. One way is to make sure to encrypt all scripts when exporting the final game. (See [Compiling with script key encryption](https://docs.godotengine.org/en/stable/development/compiling/compiling_with_script_encryption_key.html))
4. Configure your Product on the [EOS Dev Portal](https://dev.epicgames.com/portal) with the following configuration:
- In the `Client Policies` section in `Product Settings`, for the Client policy type choose `Custom policy`, enable the `User is required` and enable every features and action except `Connect` (Trusted Server Required). This will allow the sample to access the different services provided by Epic Online Services. In your actual game, the client policy is important and you should give minimal permissions to features.
- In the `Permissions` section of `Epic Account Services`, enable all three: `Basic Profile`, `Online Presence` and `Friends`.
- (Optional if you want some pre-made achievements)
In the `Achievements` section in `Game Services`, use the `Bulk Import` option and import the `HelloProduct.zip` file located at `res://HelloProduct.zip`
5. Finally open the `./sample` folder in Godot.
================================================
FILE: docs/docs/topics/authentication.md
================================================
# Authentication
WIP - Work In Progress
================================================
FILE: docs/docs/topics/initialization.md
================================================
import ReactPlayer from 'react-player'
# Initialization
Follow the steps below to initialize and use the plugin.
Check out the below video for a quick walkthrough.
<ReactPlayer controls url='https://www.youtube.com/watch?v=ENyvF4yVjKg' />
<br></br>
1. You will need the following from the EOS Developer Portal:
- `PRODUCT_ID`
- `SANDBOX_ID`
- `DEPLOYMENT_ID`
- `CLIENT_ID`
- `CLIENT_SECRET`
2. You also need to provide these values yourself:
- `PRODUCT_NAME` - A name chosen by you for the project
- `PRODUCT_VERSION` - A version chosen by you for the project
- `ENCRYPTION_KEY` - A random 64 character long string
Now at the start of your game, or when you want to initialize EOS. Use the following script:
```gdscript
extends Node
func _ready() -> void:
# This will control which logs you get from EOSG
HLog.log_level = HLog.LogLevel.INFO
var init_opts = EOS.Platform.InitializeOptions.new()
init_opts.product_name = "PRODUCT_NAME_HERE" # Change this
init_opts.product_version = "PRODUCT_VERSION_HERE" # Change this
var create_opts = EOS.Platform.CreateOptions.new()
create_opts.product_id = "PRODUCT_ID_HERE" # Change this
create_opts.sandbox_id = "SANDBOX_ID_HERE" # Change this
create_opts.deployment_id = "DEPLOYMENT_ID_HERE" # Change this
create_opts.client_id = "CLIENT_ID_HERE" # Change this
create_opts.client_secret = "CLIENT_SECRET_HERE" # Change this
create_opts.encryption_key = "ENCRYPTION_KEY_HERE" # Change this
# Enable Social Overlay on Windows
if OS.get_name() == "Windows":
HAuth.auth_login_flags = EOS.Auth.LoginFlags.None
create_opts.flags = EOS.Platform.PlatformFlags.WindowsEnableOverlayOpengl
# Initialize the SDK
var init_res := await HPlatform.initialize_async(init_opts)
if not EOS.is_success(init_res):
printerr("Failed to initialize EOS SDK: ", EOS.result_str(init_res))
return
# Create platform
var create_success := await HPlatform.create_platform_async(create_opts)
if not create_success:
printerr("Failed to create EOS Platform")
return
# Setup Logs from EOS
HPlatform.log_msg.connect(_on_eos_log_msg)
# This will control which logs you get from EOS SDK
var log_res := HPlatform.set_eos_log_level(EOS.Logging.LogCategory.AllCategories, EOS.Logging.LogLevel.Info)
if not EOS.is_success(log_res):
printerr("Failed to set logging level")
return
HAuth.logged_in.connect(_on_logged_in)
# During development use the devauth tool to login
HAuth.login_devtool_async("localhost:4545", "CREDENTIAL_NAME_HERE")
# Only on mobile device (Login without any credentials)
# await HAuth.login_anonymous_async()
func _on_logged_in():
print("Logged in successfully: product_user_id=%s" % HAuth.product_user_id)
# This method is called when we get a log message from EOS SDK
func _on_eos_log_msg(msg: EOS.Logging.LogMessage) -> void:
print("SDK %s | %s" % [msg.category, msg.message])
```
## Initialization on Windows
To use the `Account Portal` login option on Windows, you need to bootstrap Godot with EOS. See the steps below.
### Bootstrapping Godot with EOS for Windows
Follow the tutorial at [Redistributable Installer](https://dev.epicgames.com/docs/services/en-US/EpicAccountServices/Crossplayacrossplatforms/RedistributableInstaller/index.html) and also see the below steps.
A sample of the generated `.ini` file for the Godot Editor is shown below (during game development):
```
ApplicationPath=APPLICATION_PATH_HERE
WorkingDirectory=
WaitForExit=0
NoOperation=0
```
In the above `.ini` file, the `APPLICATION_PATH_HERE` can either be the path to your Godot Editor executable (Eg. `Godot_v4.2.0-stable_win64.exe`) when you are in development or the path to the exported game (Eg. `MyAmazingGame.exe`)
## Initialization on Android
The plugin supports the Android platform, but needs a few one-time steps to initialize and configure android exports.
### Pre-requisites
1. Setup the `Android Build Template` in your Godot project by following the tutorial [Gradle builds for Andriod](https://docs.godotengine.org/en/stable/tutorials/export/android_gradle_build.html). This will create an android project in `res://android/build`.
2. Now with reference to the tutorial [Add the EOS SDK to Your Android Studio Project](https://dev.epicgames.com/docs/epic-online-services/platforms/android#4-add-the-eos-sdk-to-your-android-studio-project), perform the following steps.
3. In the `res://android/build/build.gradle` file, add the following lines after the implementations in the `dependencies` section.
```gradle
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
// highlight-start
// Add these lines
// EOS SDK dependencies
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.security:security-crypto:1.0.0'
implementation 'androidx.browser:browser:1.4.0'
// Update the path so that it points to eossdk-StaticSTDC-release.aar provided in addons/epic-online-services-godot/bin/android/
implementation files('../../addons/epic-online-services-godot/bin/android/eossdk-StaticSTDC-release.aar')
// highlight-end
...other code
```
4. In the `res://android/build/build.gradle` file, add the following lines after the `defaultConfig` in the `android` section.
```gradle
android {
... other code
defaultConfig {
... other code
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
versionCode getExportVersionCode()
versionName getExportVersionName()
minSdkVersion getExportMinSdkVersion()
targetSdkVersion getExportTargetSdkVersion()
missingDimensionStrategy 'products', 'template'
// highlight-start
// Add these lines
// This is needed by EOS Android SDK
String ClientId = "PUT YOUR EOS CLIENT_ID HERE"
resValue("string", "eos_login_protocol_scheme", "eos." + ClientId.toLowerCase())
// highlight-end
}
... other code
```
5. In the `res://android/build/config.gradle` file, update the `minSdk` to `23` to match with the requirements of the `EOS Android SDK`.
Before
```gradle
minSdk : 21,
```
After
```gradle
minSdk : 23,
```
6. In the `res://android/build/src/com/godot/game/GodotGame.java` file, update it as follows.
```java
package com.godot.game;
// highlight-next-line
import com.epicgames.mobile.eossdk.EOSSDK; // added
import org.godotengine.godot.GodotActivity;
import android.os.Bundle;
public class GodotApp extends GodotActivity {
// highlight-next-line
static { // added
// highlight-next-line
System.loadLibrary("EOSSDK"); // added
// highlight-next-line
} // added
@Override
public void onCreate(Bundle savedInstanceState) {
EOSSDK.init(getActivity()); // added
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
}
}
```
7. Now open your project in the Godot Editor, and goto `Project -> Export` and create a new Android export profile.
8. In the `Gradle Build` section, enable `Use Gradle Build`. In the `Architectures` section enable `arm64-v8a`. In the `Permissions` section ensure that `ACESSS_NETWORK_STATE`, `ACCESS_WIFI_STATE` and `INTERNET` are enabled. These permissions are needed for the EOS SDK to work. Fill in the other details such as package name, etc as needed.
9. You can now export the Android APK by clicking the `Export Project` button.
## Initialization on iOS
Export the project from Godot editor for iOS target. **You might get a build error during this process, ignore it.** Open the generated iOS project in XCode and build the project. The build should be successful. EOSG has support for `iOS arm64 device` and `iOS arm64 simulator`.
================================================
FILE: docs/docs/update-guide.md
================================================
# Update Guide
Follow these steps to update to a newer version of the plugin:
1. Disable the plugin in the Editor in `Project -> Project Setings -> Plugins`.
2. Delete the `res://addons/epic-online-services-godot` folder.
3. Now you can install the newer version using any of the methods described in [Installation](/docs/installation) section
4. After installing, enable the plugin and restart the Editor.
================================================
FILE: docs/docusaurus.config.ts
================================================
import { themes as prismThemes } from "prism-react-renderer";
import type { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
const config: Config = {
title: "Epic Online Services Godot",
tagline: "Easiest way to use Epic Online Services in Godot 4.2+",
favicon: "img/favicon.ico",
url: "https://3ddelano.github.io",
baseUrl: "/epic-online-services-godot/",
// GitHub pages deployment config
organizationName: "3ddelano",
projectName: "epic-online-services-godot",
deploymentBranch: "gh-pages",
trailingSlash: false,
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
i18n: {
defaultLocale: "en",
locales: ["en"],
},
presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.ts",
editUrl:
"https://github.com/3ddelano/epic-online-services-godot/tree/main/docs",
},
theme: {
customCss: "./src/css/custom.css",
},
} satisfies Preset.Options,
],
],
themeConfig: {
colorMode: {
defaultMode: "dark",
disableSwitch: true,
respectPrefersColorScheme: false,
},
image: "img/og-image.jpg",
navbar: {
title: "Epic Online Services Godot",
logo: {
alt: "EOSG Logo",
src: "img/eosg-logo.svg",
},
items: [
{
type: "docSidebar",
sidebarId: "docsSidebar",
position: "left",
label: "Docs",
},
{
to: "showcase",
position: "left",
label: "Showcase",
},
{
href: "https://github.com/3ddelano/epic-online-services-godot",
label: "GitHub",
position: "right",
},
],
},
footer: {
style: "dark",
links: [
{
title: "Docs",
items: [
{
label: "Docs",
to: "/docs/introduction",
},
],
},
{
title: "Community",
items: [
{
label: "Discord",
href: "https://discord.gg/FZY9TqW",
},
],
},
{
title: "More",
items: [
{
label: "GitHub",
href: "https://github.com/facebook/docusaurus",
},
{
label: "Sponsor",
href: "https://github.com/sponsors/3ddelano",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Delano Lourenco`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
additionalLanguages: ["gdscript", "gradle", "java"],
},
} satisfies Preset.ThemeConfig,
plugins: ["./src/plugins/tailwind-config.ts"],
};
export default config;
================================================
FILE: docs/package.json
================================================
{
"name": "docs",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"dev": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^3.9.2",
"@docusaurus/preset-classic": "^3.9.2",
"@mdx-js/react": "^3.0.0",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001769",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-player": "^2.16.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.9.2",
"@docusaurus/tsconfig": "^3.9.2",
"@docusaurus/types": "^3.9.2",
"@tailwindcss/postcss": "^4.1.3",
"postcss": "^8.5.3",
"tailwindcss": "^4.1.3",
"typescript": "~5.6.2"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"engines": {
"node": ">=18.0"
}
}
================================================
FILE: docs/postcss.config.js
================================================
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
}
}
================================================
FILE: docs/sidebars.ts
================================================
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
const sidebars: SidebarsConfig = {
// By default, Docusaurus generates a sidebar from the docs folder structure
// docsSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
docsSidebar: [
'introduction',
'installation',
'update-guide',
'sample-project',
{
type: 'category',
label: 'Topics',
items: ['topics/initialization', 'topics/authentication'],
collapsed: false
},
],
};
export default sidebars;
================================================
FILE: docs/src/components/ExampleSection.tsx
================================================
import CodeBlock from "@theme/CodeBlock";
const codeExample = `
# In main script
extends Node
func _ready() -> void:
# Setup HEOS Logs
HLog.log_level = HLog.LogLevel.INFO
var init_opts = EOS.Platform.InitializeOptions.new()
init_opts.product_name = "PRODUCT_NAME_HERE"
init_opts.product_version = "PRODUCT_VERSION_HERE"
var create_opts = EOS.Platform.CreateOptions.new()
create_opts.product_id = "PRODUCT_ID_HERE"
create_opts.sandbox_id = "SANDBOX_ID_HERE"
create_opts.deployment_id = "DEPLOYMENT_ID_HERE"
create_opts.client_id = "CLIENT_ID_HERE"
create_opts.client_secret = "CLIENT_SECRET_HERE"
create_opts.encryption_key = "ENCRYPTION_KEY_HERE"
# Enable Social Overlay on Windows
if OS.get_name() == "Windows":
HAuth.auth_login_flags = EOS.Auth.LoginFlags.None
create_opts.flags = EOS.Platform.PlatformFlags.WindowsEnableOverlayOpengl
# Initialize the SDK
var init_res := await HPlatform.initialize_async(init_opts)
if not EOS.is_success(init_res):
printerr("Failed to initialize EOS SDK: ", EOS.result_str(init_res))
return
# Create platform
var create_success := await HPlatform.create_platform_async(create_opts)
if not create_success:
printerr("Failed to create EOS Platform")
return
# Setup Logs from EOS
HPlatform.log_msg.connect(_on_eos_log_msg)
var log_res := HPlatform.set_eos_log_level(EOS.Logging.LogCategory.AllCategories, EOS.Logging.LogLevel.Info)
if not EOS.is_success(log_res):
printerr("Failed to set logging level")
return
HAuth.logged_in.connect(_on_logged_in)
# During development use the devauth tool to login
HAuth.login_devtool_async("localhost:4545", "CREDENTIAL_NAME_HERE")
# Only on mobile device (Login without any credentials)
# await HAuth.login_anonymous_async()
func _on_logged_in():
print("Logged in successfully: product_user_id=%s" % HAuth.product_user_id)
# Example: Get top records for a leaderboard
var records := await HLeaderboards.get_leaderboard_records_async("LEADERBOARD_ID_HERE")
print(records)
func _on_eos_log_msg(msg: EOS.Logging.LogMessage) -> void:
print("SDK %s | %s" % [msg.category, msg.message])
`;
export function ExampleSection() {
return (
<section id="example" className="py-16 sm:py-20 bg-gray-900">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-8 text-center text-white">
Basic Usage Example (GDScript)
</h2>
<div className="max-w-4xl mx-auto">
<CodeBlock language="gdscript">{codeExample}</CodeBlock>
</div>
</div>
</section>
);
}
================================================
FILE: docs/src/components/FeaturesSection.tsx
================================================
const FEATURES = [
"Authentication",
"Social Overlay (Win)",
"Achievements",
"Stats & Leaderboards",
"Lobby & Sessions",
"Multiplayer (P2P)",
"Voice",
"Metrics",
"Mods",
"Player/Title Storage",
"Progression Snapshot",
"Reports & Sanctions",
"Ecommerce (EGS)",
"AntiCheat",
];
const HIGH_LEVEL_CLASSES = [
"HPlatform",
"HAuth",
"HAchievements",
"HFriends",
"HStats",
"HLeaderboards",
"HLobbies",
"HP2P",
"HLog",
];
export function FeaturesSection() {
return (
<section id="features" className="py-20 sm:py-24 bg-[#0a0f1e]">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-4 text-center text-white tracking-tight">
Core Features
</h2>
<p className="text-gray-400 text-center mb-14 max-w-2xl mx-auto font-light">
All the EOS features you need, wrapped in a clean GDScript API.
</p>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 max-w-6xl mx-auto">
{FEATURES.map((feature, index) => (
<div key={index} className="feature-card p-4 rounded-xl">
<span className="flex items-center text-sm">
<svg
className="w-4 h-4 mr-2 text-emerald-400 flex-shrink-0"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
></path>
</svg>
<span className="text-gray-200 font-medium">{feature}</span>
</span>
</div>
))}
</div>
</div>
</section>
);
}
export function HighLevelSection() {
return (
<section id="high-level" className="py-16 sm:py-20 bg-gray-950">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-10 text-center text-white">
High Level EOS Classes
</h2>
<p className="text-gray-300 mb-8 max-w-2xl mx-auto text-center">
These classes simplify interaction with EOS services. They include
built-in documentation accessible directly within the Godot Editor.
</p>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 max-w-5xl mx-auto">
{HIGH_LEVEL_CLASSES.map((cls, index) => (
<div
key={index}
className="bg-blue-900/80 hover:bg-blue-800/80 p-4 rounded-lg text-center shadow transition"
>
<span className="font-mono font-medium text-blue-100">{cls}</span>
</div>
))}
</div>
</div>
</section>
);
}
================================================
FILE: docs/src/components/HeroSection.tsx
================================================
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import { GodotIcon, EpicIcon } from "../components/Icons";
const VERSIONS = [
{ label: "Godot", value: "4.2+", icon: GodotIcon },
{ label: "EOS SDK", value: "1.18.1.2", icon: EpicIcon },
];
const PLATFORMS = [
{ label: "Windows x64/arm64", icon: "🖥️" },
{ label: "Linux x64/arm64", icon: "🐧" },
{ label: "Android x64/arm64", icon: "🤖" },
{ label: "MacOS x64/arm64", icon: "🍎" },
{ label: "iOS arm64", icon: "🍏" },
];
const HERO_ACTIONS = [
{
label: "Download Latest",
href: "https://github.com/3ddelano/epic-online-services-godot/releases/latest",
primary: true,
target: "_blank",
},
{
label: "Documentation",
href: "docs/introduction",
primary: false,
},
];
export function HeroSection() {
const { siteConfig } = useDocusaurusContext();
return (
<section
id="hero"
className="relative bg-[#030712] py-28 sm:py-36 overflow-hidden"
>
<div className="absolute inset-0 hero-image opacity-30"></div>
{/* Glow orbs */}
<div className="absolute top-20 left-1/4 w-96 h-96 bg-blue-600/20 rounded-full blur-[120px]"></div>
<div className="absolute bottom-20 right-1/4 w-80 h-80 bg-purple-600/15 rounded-full blur-[100px]"></div>
<div className="container px-6 relative z-10 grid lg:grid-cols-2 gap-12 items-center">
{/* Left col */}
<div className="max-w-xl">
<h1 className="text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl mb-6 text-white leading-tight">
{siteConfig.title}
</h1>
<p className="text-xl text-gray-400 mb-8 font-light leading-relaxed">
{siteConfig.tagline}
</p>
<div className="flex flex-wrap gap-3 mb-8">
{VERSIONS.map((v, i) => (
<span
key={i}
className="glass px-4 py-2 rounded-full flex items-center text-sm font-semibold text-gray-200"
>
<v.icon className="w-4 h-4 mr-2" />
{v.label} {v.value}
</span>
))}
</div>
<div className="flex flex-wrap gap-4 mb-10">
{HERO_ACTIONS.map((action, i) => (
<a
key={i}
href={action.href}
target={action.target}
rel={action.target === "_blank" ? "noopener noreferrer" : ""}
className={`${
action.primary ? "button-primary" : "button-secondary"
} px-7 py-3.5 rounded-xl text-sm font-bold uppercase tracking-wider no-underline`}
>
{action.label}
</a>
))}
</div>
<div className="text-gray-500">
<p className="mb-3 font-semibold text-gray-400 text-sm uppercase tracking-wider">
Supported Platforms
</p>
<div className="flex flex-wrap gap-2">
{PLATFORMS.map((platform, i) => (
<span
key={i}
className="glass px-3 py-1.5 rounded-full text-xs font-semibold text-gray-300 transition-transform duration-200 hover:scale-105"
>
{platform.icon} {platform.label}
</span>
))}
</div>
</div>
</div>
{/* Logo Column */}
<div className="flex-1 flex justify-center items-center">
<div className="relative">
<div className="absolute inset-0 bg-blue-500/20 rounded-full blur-[60px] scale-110"></div>
<img
src="img/eosg-logo.svg"
alt="Logo"
className="w-64 h-64 object-contain rounded-md relative z-10 drop-shadow-2xl"
/>
</div>
</div>
</div>
</section>
);
}
================================================
FILE: docs/src/components/Icons.tsx
================================================
export function GodotIcon({ className = "w-4 h-4" }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className={className}
viewBox="0 0 1024 1024"
>
<g fill="#fff">
<path d="M417.615 76.875c-42.392 9.424-84.326 22.545-123.642 42.334.899 34.716 3.143 67.98 7.693 101.768-15.268 9.782-31.315 18.177-45.576 29.628-14.49 11.148-29.29 21.813-42.41 34.85-26.212-17.337-53.955-33.63-82.535-48.012C100.337 270.6 71.53 306.383 48 346.428c18.493 29.029 38.33 58.205 56.7 80.959v245.765c.449.005.898.021 1.343.063l150.67 14.527a16.22 16.22 0 0 1 14.627 15.024l4.646 66.51 131.43 9.378 9.055-61.386a16.22 16.22 0 0 1 16.05-13.858h158.961c8.047 0 14.873 5.899 16.047 13.858l9.055 61.386 131.434-9.379 4.642-66.51a16.23 16.23 0 0 1 14.627-15.023l150.611-14.527c.446-.042.89-.058 1.34-.063v-19.611l.063-.02V427.387c21.216-26.71 41.307-56.172 56.699-80.96-23.523-40.044-52.345-75.828-83.152-108.984-28.573 14.382-56.325 30.675-82.537 48.012-13.117-13.037-27.89-23.702-42.4-34.85-14.258-11.45-30.324-19.846-45.563-29.628 4.537-33.788 6.78-67.052 7.683-101.768-39.32-19.79-81.249-32.91-123.662-42.334-16.933 28.46-32.42 59.28-45.906 89.408-15.993-2.672-32.06-3.662-48.149-3.853v-.026c-.112 0-.216.026-.312.026-.1 0-.205-.026-.305-.026v.026c-16.117.191-32.17 1.18-48.168 3.853-13.478-30.129-28.955-60.948-45.914-89.408M298.416 436.398c50.151 0 90.799 40.618 90.799 90.752 0 50.168-40.648 90.809-90.799 90.809-50.126 0-90.787-40.64-90.787-90.809 0-50.134 40.66-90.752 90.787-90.752m427.178 0c50.122 0 90.779 40.618 90.779 90.752 0 50.168-40.657 90.809-90.78 90.809-50.159 0-90.806-40.64-90.806-90.809 0-50.134 40.647-90.752 90.807-90.752m-213.6 53.11c16.143 0 29.254 11.908 29.254 26.56v83.59c0 14.665-13.111 26.563-29.254 26.563-16.142 0-29.226-11.898-29.226-26.563v-83.59c0-14.652 13.084-26.56 29.226-26.56"></path>
<path d="m784.071 718.723-4.666 66.864c-.562 8.059-6.972 14.474-15.031 15.052l-160.49 11.451q-.587.043-1.17.042c-7.975 0-14.856-5.853-16.034-13.861l-9.203-62.415H446.525l-9.203 62.415c-1.237 8.4-8.746 14.44-17.204 13.82l-160.49-11.452c-8.059-.578-14.469-6.993-15.03-15.052l-4.667-66.864-135.48-13.062c.062 14.56.249 30.512.249 33.688 0 143.085 181.51 211.86 407.024 212.651h.554c225.514-.79 406.962-69.566 406.962-212.651 0-3.234.195-19.119.262-33.688zM367.367 532.537c0 33.276-26.97 60.246-60.27 60.246-33.285 0-60.271-26.97-60.271-60.246s26.986-60.27 60.27-60.27c33.301 0 60.27 26.994 60.27 60.27M656.64 532.537c0 33.276 26.962 60.246 60.238 60.246 33.309 0 60.27-26.97 60.27-60.246s-26.961-60.27-60.27-60.27c-33.276 0-60.237 26.994-60.237 60.27"></path>
</g>
</svg>
);
}
export function EpicIcon({ className = "w-4 h-4" }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
className={className}
version="1.1"
viewBox="0 0 647.167 750.977"
>
<defs>
<clipPath id="a" clipPathUnits="userSpaceOnUse">
<path d="M0 790.889h900V0H0Z"></path>
</clipPath>
</defs>
<g transform="matrix(1.33333 0 0 -1.33333 -278.052 902.583)">
<g>
<g clipPath="url(#a)">
<g transform="translate(649.836 676.938)">
<path
fill="#2f2d2e"
fillOpacity="1"
fillRule="evenodd"
stroke="none"
d="M0 0h-397.219c-32.196 0-44.078-11.882-44.078-44.093v-388.676c0-3.645.147-7.031.469-10.168.733-7.031.871-13.844 7.41-21.601.639-.76 7.315-5.728 7.315-5.728 3.591-1.761 6.043-3.058 10.093-4.688l195.596-81.948c10.154-4.655 14.4-6.469 21.775-6.323v-.001h.058v.001c7.375-.146 11.621 1.668 21.776 6.323L18.79-474.954c4.051 1.63 6.502 2.927 10.094 4.688 0 0 6.676 4.968 7.314 5.728 6.539 7.757 6.677 14.57 7.41 21.601.322 3.137.47 6.523.47 10.168v388.676C44.078-11.882 32.195 0 0 0"
></path>
</g>
<g transform="translate(623.23 286.175)">
<path
fill="#fff"
fillOpacity="1"
fillRule="nonzero"
stroke="none"
d="m0 0-.09-.897-.089-.985-.18-.897-.268-.896-.174-.807-.27-.897-.358-.807-.359-.718-.353-.806-.448-.717-.448-.718-.533-.717-.449-.717-.532-.627-.628-.628-.533-.538-.716-.628-.623-.538-.717-.538-.712-.442-.712-.538-.807-.448-.802-.359-.801-.448-.897-.359-.891-.359-.891-.268-.891-.27-.807-.268-.891-.18-.802-.179-.801-.179-.897-.18-.892-.089-.801-.09-.897-.09-.98-.09-.892-.089h-3.749l-.892.089h-.98l-.892.09-.896.09-.981.09-.891.179-.891.09-.897.179-.892.179-.891.18-.891.179-.896.268-.802.18-.891.269-.892.269-.806.359-.891.269-.802.268-.892.359-.806.359-.802.359-.802.442-.806.359-.802.449-.712.447-.807.449-.712.448-.717.448-.712.538-.712.538-.717.538-.713.538-.627.538-.712.627.538.717.622.628.538.718.623.717.538.627.532.717.628.718.532.627.628.717.533.628.627.717.533.718.538.627.622.717.538.718.622.627.538.717.712-.538.802-.538.717-.538.802-.538.717-.448.802-.537.711-.449.808-.358.711-.449.802-.359.807-.358.801-.359.803-.269.806-.358.891-.269.892-.269.801-.269.897-.18.891-.179.891-.179.981-.09.896-.179h.892l.98-.089h1.962l.981.089.897.179.801.18.802.179.717.269.623.358.717.538.532.628.359.718.27.806.088.897v.179l-.088 1.076-.359.897-.449.627-.622.538-.718.538-.712.358-.801.359-.897.359-1.07.447-.623.18-.711.179-.807.27-.802.179-.891.269-.897.179-.98.269-.892.179-.981.269-.891.179-.897.269-.89.18-.892.269-.807.268-.89.18-.803.269-.801.269-.807.269-.981.359-.891.359-.892.358-.896.359-.801.448-.892.448-.717.448-.802.448-.712.538-.717.448-.622.539-.627.627-.623.628-.538.628-.532.627-.449.627-.443.718-.448.806-.359.622-.269.718-.263.807-.269.717-.18.897-.179.807-.09.896-.089.897-.09.985v2.063l.09.896.089.807.09.897.179.806.18.807.269.808.179.806.353.807.359.807.358.806.444.808.447.806.533.718.539.717.622.717.627.627.623.718.717.628.622.448.717.538.713.538.711.448.807.448.802.359.801.448.807.358.891.27.891.358.807.269.712.18.803.179.806.179.891.179.802.18.891.089.897.09.891.09.891.089h3.839l.981-.089.981-.09h.891l.986-.09.891-.179.981-.09.892-.179.807-.179.891-.179.891-.18.802-.179.896-.269.802-.269.802-.18.896-.358.802-.269.801-.358.802-.359.896-.359.802-.448.712-.359.807-.448.802-.448.712-.449.806-.538.713-.447.717-.539.712-.538.711-.537-.532-.718-.448-.717-.533-.717-.538-.718-.532-.806-.449-.717-.538-.718-.533-.717-.447-.717-.534-.718-.537-.717-.449-.717-.532-.807-.539-.717-.532-.717-.448-.717-.533-.717-.717.537-.801.449-.713.448-.717.538-.801.358-.718.449-.801.359-.712.358-.807.359-.712.358-.801.269-.717.359-.982.268-.891.27-.891.268-.897.18-.891.179-.891.18-.891.09-.897.089-.801.09h-1.962l-.981-.179-.897-.18-.801-.179-.712-.359-.628-.358-.802-.718-.538-.807-.352-.807-.091-.896v-.18l.091-1.165.442-.986.359-.538.622-.628.807-.448.712-.448.891-.359.986-.359 1.071-.358.712-.179.712-.269.807-.179.801-.269.891-.18.987-.269.981-.268.981-.27.98-.179.891-.269.981-.269.897-.179.892-.269.891-.269.801-.269.897-.269.802-.269.801-.269.986-.353.891-.449.891-.358.892-.448.807-.449.802-.448.711-.448.717-.538.713-.448.712-.628.717-.627.622-.718.627-.627.533-.718.538-.806.443-.717.449-.808.358-.717.269-.806.264-.807.179-.807.179-.897.179-.897.09-.896.09-.986V.986zm-62.594-17.926h-51.143v65.258h51.587V32.538h-34.543V21.87h31.062V7.979h-31.062V-3.137h34.991v-14.789zm-65.214 0h-16.333v38.589l-.447-.717-.533-.813-.449-.717-.532-.718-.448-.806-.539-.718-.442-.717-.449-.812-.532-.717-.449-.717-.537-.718-.443-.812-.538-.717-.443-.717-.449-.807-.538-.722-.443-.718-.538-.806-.442-.718-.538-.717-.443-.812-.449-.718-.537-.717-.443-.807-.538-.722-.443-.717-.538-.718-.449-.806-.443-.722-.537-.718-.443-.807-.538-.717-.448-.717-.533-.813-.448-.717h-.354l-.537.807-.449.723-.533.807-.448.717-.533.806-.448.723-.532.807-.449.718-.538.806-.443.717-.538.813-.442.717-.538.807-.449.717-.532.812-.449.717-.532.807-.538.717-.448.812-.533.717-.448.807-.533.717-.448.813-.533.717-.448.807-.538.717-.443.807-.538.723-.443.806-.538.718-.448.807-.532.716-.45.813-.532.717v-38.409h-16.96v65.258h18.3l.443-.718.448-.806.532-.712.449-.807.448-.717.443-.808.448-.711.534-.808.447-.717.449-.717.443-.801.448-.718.533-.806.448-.718.448-.801.443-.717.538-.717.449-.803.442-.716.448-.807.444-.718.538-.801.448-.718.442-.806.449-.712.443-.717.538-.807.448-.718.443-.807.448-.712.443-.807.539-.717.448-.801.443-.718.448.718.448.801.533.717.447.807.444.712.448.807.533.718.448.807.449.717.442.712.538.806.443.718.449.801.447.718.533.807.448.716.449.803.442.717.45.717.532.801.448.718.448.806.444.718.537.801.444.717.447.717.449.808.532.711.449.808.442.717.449.807.538.712.443.806.448.718h18.294v-65.258zM-231.367 8.965l-.269.812-.353.897-.359.807-.269.812-.353.807-.358.897-.27.812-.359.807-.352.806-.27.812-.359.897-.263.807-.359.812-.359.807-.268.807-.354.901-.358.808-.269.806-.359.812-.353.897-.269.812-.359.807-.353-.807-.268-.812-.359-.897-.359-.812-.264-.806-.358-.808-.359-.901-.353-.807-.27-.807-.358-.812-.359-.807-.264-.897-.358-.812-.359-.806-.268-.807-.354-.812-.359-.897-.358-.807-.263-.812-.359-.807-.359-.897-.269-.812-.353-.807h15.082zm28.03-26.891h-17.498l-.354.808-.269.807-.358.807-.359.896-.264.802-.358.806-.359.807-.264.807-.358.807-.359.807-.268.807-.354.896-.359.807-.269.807-.359.807h-25.614l-.353-.807-.269-.807-.359-.807-.358-.896-.264-.807-.358-.807-.359-.807-.269-.807-.353-.807-.359-.806-.269-.802-.354-.896-.358-.807-.269-.807-.359-.808h-18.025l.353.808.359.807.358.807.354.896.269.802.359.806.358.807.353.807.359.807.359.897.353.807.359.806.268.807.359.807.353.807.359.896.358.807.354.808.359.806.358.807.269.807.353.897.359.806.359.807.353.807.359.807.359.807.353.897.269.806.359.807.358.807.354.807.358.807.358.896.354.807.358.807.269.807.359.806.353.807.359.897.359.807.353.807.358.807.359.806.269.808.354.801.358.897.358.806.354.808.358.807.359.806.353.807.269.897.359.806.358.807.354.807.359.807.358.807.354.897.358.806.269.807.358.807.354.807.358.807.359.896.353.807.359.807.359.807.263.806.359.808.359.896.359.807.353.807.359.807.358.807.353.806.27.897.358.807.359.807.353.807h16.512l.358-.807.359-.807.354-.807.358-.897.269-.806.353-.807.359-.807.358-.807.359-.807.353-.896.359-.808.359-.806.263-.807.359-.807.359-.807.359-.896.353-.807.358-.807.359-.807.353-.807.269-.806.358-.897.354-.807.359-.807.358-.807.359-.807.353-.806.358-.897.27-.807.353-.806.358-.807.359-.808.359-.806.353-.897.359-.801.358-.808.264-.806.358-.807.359-.807.354-.807.358-.897.359-.807.359-.806.353-.807.269-.807.358-.807.354-.896.358-.807.359-.807.358-.807.354-.807.359-.806.268-.897.354-.807.358-.807.359-.807.353-.807.359-.806.359-.897.359-.807.263-.807.359-.806.359-.808.353-.807.358-.896.359-.807.358-.807.353-.807.27-.806.359-.807.353-.897.358-.807.358-.807.354-.807.358-.806.359-.802.27-.896.352-.807.359-.807.358-.808zm-78.193 8.334-.717-.538-.623-.449-.717-.538-.712-.448-.712-.538-.717-.448-.712-.449-.807-.447-.802-.449-.802-.448-.806-.353-.802-.449-.891-.358-.801-.359-.897-.358-.801-.359-.803-.269-.806-.269-.802-.27-.891-.268-.801-.27-.897-.179-.802-.179-.891-.179-.896-.179-.892-.09-.981-.09-.891-.09-.981-.089-.897-.09-.98-.089h-3.84l-.891.089-.981.09-.891.089-.891.09-.897.09-.891.179-.892.18-.801.179-.896.179-.802.269-.891.179-.807.27-.802.358-.802.269-.89.359-.807.358-.802.358-.801.359-.808.448-.711.444-.802.448-.717.449-.712.447-.717.539-.712.537-.713.538-.627.538-.622.538-.628.628-.622.537-.628.628-.622.628-.538.627-.533.717-.538.628-.448.717-.533.718-.447.716-.444.718-.448.807-.448.717-.353.807-.359.807-.358.807-.354.806-.269.717-.359.808-.179.807-.264.806-.179.896-.269.808-.179.896-.09.807-.18.897-.088.806-.091.897-.084.897-.089.896V15.6l.089.986v.896l.084.897.091.986.179.891.089.897.179.807.269.896.18.897.263.807.269.896.269.807.359.897.354.806.358.807.359.807.353.807.448.807.448.717.444.718.447.717.449.717.532.717.538.717.533.717.538.629.622.627.538.628.623.626.627.629.622.537.717.628.623.538.712.538.717.448.712.538.718.448.711.448.802.449.807.448.801.448.802.359.806.358.892.449.712.268.891.27.808.358.801.18.801.269.896.179.802.269.891.179.892.09.896.179.892.09.89.089.892.09.897.09h3.833l.987-.09.981-.09h.891l.891-.089.981-.18.807-.089.891-.18.892-.179.806-.179.801-.179.803-.18.807-.269.801-.179.712-.269.807-.269.802-.358.801-.359.807-.359.802-.448.801-.359.718-.448.801-.448.712-.448.807-.449.712-.537.712-.449.717-.538.712-.538.717-.627.712-.538-.538-.718-.622-.627-.538-.717-.622-.717-.538-.718-.533-.627-.628-.717-.532-.717-.538-.629-.623-.717-.537-.717-.623-.717-.538-.628-.532-.717-.627-.717-.534-.717-.627-.628-.533-.717-.717.538-.712.627-.717.449-.712.538-.712.448-.717.449-.713.447-.801.449-.717.358-.712.359-.717.269-.802.269-.801.269-.807.179-.891.18-.891.179-.892.089-.981.09-.986.089h-1.872l-.891-.089-.807-.09-.891-.179-.802-.18-.807-.268-.801-.269-.802-.359-.802-.358-.717-.448-.711-.449-.718-.449-.622-.537-.628-.538-.622-.538-.538-.627-.622-.628-.538-.717-.444-.628-.448-.717-.442-.807-.449-.717-.358-.807-.269-.807-.354-.807-.269-.896-.179-.892-.179-.806-.18-.987-.089-.896-.084-.896v-2.063l.084-.896.089-.807.09-.897.179-.806.18-.808.179-.806.269-.807.264-.717.359-.896.358-.808.443-.807.448-.717.448-.717.533-.718.538-.627.622-.628.539-.627.621-.538.718-.538.712-.538.711-.448.717-.448.803-.359.801-.359.806-.358.892-.269.891-.269.897-.18.891-.179.891-.089.981-.09h2.051l.987.09.981.089.891.09.891.18.897.179.891.268.801.18.803.358.717.359.801.359.627.358.713.449v8.158h-13.032v13.084h29.454V-9.055z"
></path>
</g>
<g transform="translate(312.995 481.16)">
<path
fill="#fff"
fillOpacity="1"
fillRule="nonzero"
stroke="none"
d="M0 0h38.683v29.922H0v61.086h40.223v29.922h-73.072V-95.021h73.684v29.923H0z"
></path>
</g>
<g transform="translate(590.07 474.677)">
<path
fill="#fff"
fillOpacity="1"
fillRule="nonzero"
stroke="none"
d="M0 0v-48.744c0-8.639-3.993-12.647-12.278-12.647h-6.144c-8.595 0-12.588 4.008-12.588 12.647V87.618c0 8.638 3.993 12.646 12.588 12.646h5.527c8.29 0 12.283-4.008 12.283-12.646V45.349h32.233v44.12c0 26.837-12.895 39.795-39.6 39.795h-15.969c-26.706 0-39.912-13.264-39.912-40.106V-50.284c0-26.843 13.206-40.106 39.912-40.106h16.274c26.712 0 39.911 13.263 39.911 40.106V0z"
></path>
</g>
<path
fill="#fff"
fillOpacity="1"
fillRule="nonzero"
stroke="none"
d="M475.995 386.138h32.854V602.09h-32.854z"
></path>
<g transform="translate(428.326 506.146)">
<path
fill="#fff"
fillOpacity="1"
fillRule="nonzero"
stroke="none"
d="M0 0c0-8.639-3.987-12.652-12.277-12.652h-13.511v79.596h13.511C-3.987 66.944 0 62.935 0 54.298Zm-7.061 95.944h-51.577v-215.952h32.85v78.362h18.727c26.711 0 39.911 13.263 39.911 40.1v57.384c0 26.842-13.2 40.106-39.911 40.106"
></path>
</g>
<g transform="translate(357.642 190.875)">
<path
fill="#fff"
fillOpacity="1"
fillRule="evenodd"
stroke="none"
d="M0 0h188.054L92.068-31.654Z"
></path>
</g>
</g>
</g>
</g>
</svg>
);
}
================================================
FILE: docs/src/components/InfoSections.tsx
================================================
export function HowItWorksSection() {
return (
<section id="how-it-works" className="py-16 sm:py-20 bg-gray-950">
<div className="container mx-auto px-6">
<div className="max-w-3xl mx-auto text-center">
<h2 className="text-3xl font-bold mb-6 text-white">How It Works</h2>
<p className="text-lg text-gray-300 leading-relaxed">
This project utilizes Godot's{" "}
<strong className="text-blue-400">GDExtension</strong> system to
wrap the official Epic Online Services C SDK. This allows seamless
integration and usage within Godot projects using GDScript, C#, or
other supported languages. It provides a familiar class hierarchy
and leverages Godot's signal system for handling asynchronous events
like user login, achievement unlocks, lobby updates, and more.
</p>
</div>
</div>
</section>
);
}
export function InstallationSection() {
return (
<section id="installation" className="py-16 sm:py-20 bg-gray-900">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-12 text-center text-white">
Installation
</h2>
<div className="grid md:grid-cols-2 gap-10 max-w-5xl mx-auto">
<div className="bg-gray-800 p-6 rounded-lg shadow-md border border-gray-700">
<h3 className="text-xl font-semibold mb-4 text-white">
Method 1: Asset Library (Recommended)
</h3>
<ol className="list-decimal list-inside space-y-2 text-gray-300">
<li>
Open the <strong className="text-white">AssetLib</strong> tab in
the Godot editor.
</li>
<li>
Search for{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
EOSG
</code>{" "}
or{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
Epic Online Services Godot
</code>
.
</li>
<li>
Find the plugin by{" "}
<strong className="text-white">3ddelano</strong> and click on
it.
</li>
<li>
Click <strong className="text-blue-400">Download</strong>, then{" "}
<strong className="text-blue-400">Install</strong>.
</li>
<li>
Go to{" "}
<strong className="text-white">
Project {"->"} Project Settings {"->"} Plugins
</strong>
.
</li>
<li>
Enable the{" "}
<strong className="text-white">
Epic Online Services Godot (EOSG)
</strong>{" "}
plugin.
</li>
<li>Restart the Godot editor.</li>
</ol>
<a
href="https://godotengine.org/asset-library/asset/2453"
target="_blank"
rel="noopener noreferrer"
className="inline-block mt-4 text-blue-400 hover:text-blue-300 underline"
>
View on Godot Asset Library
</a>
</div>
<div className="bg-gray-800 p-6 rounded-lg shadow-md border border-gray-700">
<h3 className="text-xl font-semibold mb-4 text-white">
Method 2: GitHub Release
</h3>
<ol className="list-decimal list-inside space-y-2 text-gray-300">
<li>
Download the latest release{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
.zip
</code>{" "}
file from GitHub.
</li>
<li>Extract the zip archive.</li>
<li>
Copy the{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
addons/epic-online-services-godot
</code>{" "}
folder into your project's{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
res://addons/
</code>{" "}
folder (create it if needed).
</li>
<li>
Go to{" "}
<strong className="text-white">
Project {"->"} Project Settings {"->"} Plugins
</strong>
.
</li>
<li>
Enable the{" "}
<strong className="text-white">
Epic Online Services Godot (EOSG)
</strong>{" "}
plugin.
</li>
<li>Restart the Godot editor.</li>
</ol>
<a
href="https://github.com/3ddelano/epic-online-services-godot/releases/latest"
target="_blank"
rel="noopener noreferrer"
className="inline-block mt-4 text-blue-400 hover:text-blue-300 underline"
>
Download from GitHub Releases
</a>
</div>
</div>
<p className="text-center mt-8 text-gray-400">
After installation, you can start using the{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
EOS
</code>{" "}
and{" "}
<code className="bg-gray-700 px-1.5 py-0.5 rounded text-gray-100">
H
</code>{" "}
classes in your scripts.
</p>
</div>
</section>
);
}
================================================
FILE: docs/src/components/Layout.tsx
================================================
import { useState } from "react";
// Navigation links data
const NAV_LINKS = [
{
label: "Docs",
href: "docs/introduction",
external: false,
},
{
label: "Showcase",
href: "showcase",
external: false,
},
{
label: "GitHub",
href: "https://github.com/3ddelano/epic-online-services-godot",
external: true,
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-4 h-4"
fill="#fff"
viewBox="0 0 256 256"
>
<path
d="M17.791 46.836A2 2 0 0 0 19 45v-5.4q.002-.297.041-.61L19 39h-3.6c-1.5 0-2.8-.6-3.4-1.8-.7-1.3-1-3.5-2.8-4.7-.3-.2-.1-.5.5-.5.6.1 1.9.9 2.7 2 .9 1.1 1.8 2 3.4 2 2.487 0 3.82-.125 4.622-.555C21.356 34.056 22.649 33 24 33v-.025c-5.668-.182-9.289-2.066-10.975-4.975-3.665.042-6.856.405-8.677.707a22 22 0 0 1-.151-.987c1.797-.296 4.843-.647 8.345-.714a8 8 0 0 1-.291-.849c-3.511-.178-6.541-.039-8.187.097-.02-.332-.047-.663-.051-.999 1.649-.135 4.597-.27 8.018-.111a10 10 0 0 1-.13-1.543c0-1.7.6-3.5 1.7-5-.5-1.7-1.2-5.3.2-6.6 2.7 0 4.6 1.3 5.5 2.1C21 13.4 22.9 13 25 13s4 .4 5.6 1.1c.9-.8 2.8-2.1 5.5-2.1 1.5 1.4.7 5 .2 6.6 1.1 1.5 1.7 3.2 1.6 5 0 .484-.045.951-.11 1.409 3.499-.172 6.527-.034 8.204.102-.002.337-.033.666-.051.999-1.671-.138-4.775-.28-8.359-.089a8 8 0 0 1-.325.98c3.546.046 6.665.389 8.548.689q-.064.498-.151.987c-1.912-.306-5.171-.664-8.879-.682-1.665 2.878-5.22 4.755-10.777 4.974V33c2.6 0 5 3.9 5 6.6V45c0 .823.498 1.53 1.209 1.836C41.37 43.804 48 35.164 48 25 48 12.318 37.683 2 25 2S2 12.318 2 25c0 10.164 6.63 18.804 15.791 21.836"
fontFamily="none"
fontSize="none"
fontWeight="none"
style={{ mixBlendMode: "normal" }}
textAnchor="none"
transform="scale(5.12)"
></path>
</svg>
),
},
];
export function NavBar() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
return (
<nav className="fixed top-0 left-0 right-0 z-[100] glass py-4 px-6 h-16 navbar">
<div className="container mx-auto flex items-center justify-between">
<a
href="/epic-online-services-godot/"
className="group flex items-center gap-3 no-underline"
>
<img
src="img/eosg-logo.svg"
alt="Logo"
className="w-8 h-8 group-hover:rotate-12 transition-transform duration-500"
/>
<span className="text-white text-sm font-bold tracking-tight uppercase group-hover:text-blue-400 transition-colors">
EOS Godot
</span>
</a>
{/* Desktop menu */}
<div className="hidden sm:flex items-center gap-8">
{NAV_LINKS.map((link) => (
<a
key={link.label}
href={link.href}
{...(link.external && {
rel: "noopener noreferrer",
target: "_blank",
})}
className={
link.label === "GitHub"
? "button-secondary px-4 py-2 rounded-lg text-xs font-bold uppercase tracking-widest no-underline flex items-center gap-2"
: "text-white hover:text-blue-400 active:text-blue-400 text-sm font-semibold uppercase tracking-wider transition-colors no-underline"
}
>
{link.icon}
{link.label}
</a>
))}
</div>
{/* Mobile menu button */}
<button
className="sm:hidden p-2 -mr-2"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
aria-label="Toggle menu"
>
<svg
className="w-6 h-6 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
{isMobileMenuOpen ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M6 18L18 6M6 6l12 12"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M4 6h16M4 12h16m-7 6h7"
/>
)}
</svg>
</button>
</div>
{/* Mobile menu dropdown */}
{isMobileMenuOpen && (
<div className="sm:hidden absolute top-16 left-0 right-0 backdrop-blur-xl bg-gray-900/95 border-t border-b border-white/10 p-4 shadow-lg">
<div className="container mx-auto px-6 py-4 flex flex-col gap-4">
{NAV_LINKS.map((link) => (
<a
key={link.label}
href={link.href}
{...(link.external && {
rel: "noopener noreferrer",
target: "_blank",
})}
className="text-white hover:text-blue-400 active:text-blue-400 text-sm font-semibold uppercase tracking-wider transition-colors no-underline flex items-center gap-2"
onClick={() => setIsMobileMenuOpen(false)}
>
{link.icon}
{link.label}
</a>
))}
</div>
</div>
)}
</nav>
);
}
export function Footer() {
return (
<footer className="bg-[#030712] border-t border-white/5 pt-12 pb-8">
<div className="container px-6">
<div className="glass rounded-xl text-yellow-300/80 text-xs p-5 max-w-3xl mb-10">
<p className="leading-relaxed">
<strong className="text-yellow-200">Disclaimer: </strong>This
project Epic Online Services Godot (EOSG) is <strong>NOT</strong>{" "}
affiliated with Epic Games Inc or Godot Engine. It does not endorse
Epic Online Services. This project and the sample Godot scenes are
provided solely for educational purposes and may or may not comply
with Epic Games' Design Guidelines. If you plan to release a game
using EOS, ensure you read the official{" "}
<a
href="https://dev.epicgames.com/docs/services/en-US/EpicAccountServices/DesignGuidelines/index.html"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-yellow-100 transition-colors"
>
Guidelines
</a>{" "}
and fulfill all requirements (user consent, data deletion, privacy
policy, etc.).
</p>
</div>
<p className="text-gray-500 text-sm">
Copyright © {new Date().getFullYear()}{" "}
<a
href="https://github.com/3ddelano"
target="_blank"
rel="noopener noreferrer"
className="text-blue-400/80 hover:text-blue-300 transition-colors"
>
Delano Lourenco
</a>
. All rights reserved.
</p>
<p className="text-gray-600 text-xs mt-2">
Epic Games, Epic Online Services, Godot Engine, and their respective
logos are trademarks or registered trademarks of their respective
owners.
</p>
</div>
</footer>
);
}
================================================
FILE: docs/src/components/MainSystemsSection.tsx
================================================
const MAIN_SYSTEMS = [
{
title: "High Level EOS",
tag: "Recommended",
description:
"Provides easy-to-use methods and signals to interact with EOS. Ideal for most cases and rapid development.",
link: "docs/introduction",
icon: (
<svg
className="w-6 h-6 text-blue-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M13 10V3L4 14h7v7l9-11h-7z"
></path>
</svg>
),
color: "blue",
},
{
title: "GDExtension EOS",
tag: "Advanced",
description:
"Offers advanced EOS usage with direct access to the C SDK via GDExtension. Suitable for complex needs.",
extra: (
<>
Provides{" "}
<code className="bg-purple-500/10 px-2 py-0.5 rounded text-purple-300 font-mono text-xs">
EOS
</code>{" "}
and{" "}
<code className="bg-purple-500/10 px-2 py-0.5 rounded text-purple-300 font-mono text-xs">
IEOS
</code>{" "}
classes.
</>
),
icon: (
<svg
className="w-6 h-6 text-purple-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
></path>
</svg>
),
color: "purple",
},
];
export function MainSystemsSection() {
return (
<section id="main-systems" className="py-20 sm:py-24 bg-[#030712] relative">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-4 text-center text-white tracking-tight">
Two Main Systems
</h2>
<p className="text-gray-400 text-center mb-14 max-w-2xl mx-auto font-light">
Choose the approach that fits your project's complexity.
</p>
<div className="grid md:grid-cols-2 gap-8 max-w-5xl mx-auto">
{MAIN_SYSTEMS.map((system, i) => (
<div
key={i}
className={`glass rounded-2xl p-8 transition-all duration-300 hover:-translate-y-1 hover:shadow-xl hover:shadow-${system.color}-500/5 border-${system.color}-500/20 hover:border-${system.color}-500/40`}
style={{
borderColor: `rgba(${
system.color === "blue" ? "59,130,246" : "168,85,247"
},0.2)`,
}}
>
<div
className={`mb-5 w-12 h-12 rounded-xl bg-${system.color}-500/10 flex items-center justify-center`}
>
{system.icon}
</div>
<h3 className="text-xl font-bold mb-3 text-white">
{system.title}
</h3>
<span
className={`inline-block mb-4 text-xs font-bold uppercase tracking-widest text-${system.color}-400 bg-${system.color}-500/10 px-3 py-1 rounded-full`}
>
{system.tag}
</span>
<p className="text-gray-400 mb-4 font-light leading-relaxed">
{system.description}
</p>
{system.link && (
<a
href={system.link}
className={`inline-flex items-center text-${system.color}-400 hover:text-${system.color}-300 font-semibold text-sm no-underline transition-colors`}
>
Learn more
<svg
className="w-4 h-4 ml-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 5l7 7-7 7"
></path>
</svg>
</a>
)}
{system.extra && (
<p className="text-gray-500 text-sm">{system.extra}</p>
)}
</div>
))}
</div>
</div>
</section>
);
}
================================================
FILE: docs/src/components/MediaSections.tsx
================================================
const SCREENSHOTS_DATA = [
{
category: "Windows",
images: [
{
src: "img/screenshots/windows_auth_success.png",
alt: "Windows Auth Success Screenshot",
},
],
},
{
category: "Android",
images: [
{
src: "img/screenshots/android_auth_success.jpg",
alt: "Android Auth Success Screenshot",
},
{
src: "img/screenshots/android_p2p_game.jpg",
alt: "Android P2P Game Screenshot",
},
],
},
{
category: "iOS / macOS",
images: [
{
src: "img/screenshots/ios_simulator_auth_success.png",
alt: "iOS Simulator Auth Success Screenshot",
},
{
src: "img/screenshots/ios_simulator_in_lobby.png",
alt: "iOS Simulator In Lobby Screenshot",
subtitle: "Cross-Platform Lobbies",
},
{
src: "img/screenshots/mac_in_lobby.png",
alt: "macOS In Lobby Screenshot",
},
],
},
];
const TUTORIALS_DATA = {
playlist_url:
"https://www.youtube.com/playlist?list=PL5t0hR7ADzun5JYF4e2a2FtZEWYHxK83_",
thumbnail_url: "https://img.youtube.com/vi/ENyvF4yVjKg/0.jpg",
thumbnail_alt: "Epic Online Services Tutorial Series Thumbnail",
};
export function ScreenshotsSection() {
return (
<section id="screenshots" className="py-20 sm:py-24 bg-[#030712]">
<div className="container mx-auto px-6">
<h2 className="text-3xl font-bold mb-4 text-center text-white tracking-tight">
Screenshots & Demos
</h2>
<p className="text-gray-400 text-center mb-14 max-w-2xl mx-auto font-light">
See the plugin running on multiple platforms.
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
{SCREENSHOTS_DATA.map((platform, i) => (
<div key={i} className="flex items-center flex-col">
<h3 className="text-lg font-bold mb-4 text-center text-gray-200 uppercase tracking-wider">
{platform.category}
</h3>
{platform.images.map((image, j) => (
<div key={j} className="flex flex-col items-center w-full">
{image.subtitle && (
<h4 className="text-sm font-bold my-3 text-center text-gray-400 uppercase tracking-wider">
{image.subtitle}
</h4>
)}
<img
src={image.src}
alt={image.alt}
className={`w-full max-w-[800px] h-auto rounded-xl glass border-white/10 hover:brightness-110 transition-all duration-300 ${
j < platform.images.length - 1 ? "mb-4" : ""
}`}
/>
</div>
))}
</div>
))}
</div>
</div>
</section>
);
}
export function DemoSection() {
return (
<section id="demo" className="py-20 sm:py-24 bg-[#0a0f1e]">
<div className="container mx-auto px-6 text-center">
<h2 className="text-3xl font-bold mb-4 text-white tracking-tight">
Video Tutorials
</h2>
<p className="text-gray-400 mb-10 max-w-2xl mx-auto font-light">
Watch the tutorial playlist on YouTube for a visual guide and
examples.
</p>
<div className="max-w-3xl mx-auto aspect-video rounded-2xl overflow-hidden glass">
<a
href={TUTORIALS_DATA.playlist_url}
target="_blank"
rel="noopener noreferrer"
className="block relative group"
>
<img
src={TUTORIALS_DATA.thumbnail_url}
alt={TUTORIALS_DATA.thumbnail_alt}
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<div className="w-20 h-20 rounded-full bg-white/10 backdrop-blur-sm flex items-center justify-center border border-white/20">
<svg
className="w-10 h-10 text-white ml-1"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M6.5 5.5v9l7-4.5-7-4.5z"></path>
</svg>
</div>
</div>
</a>
</div>
<a
href={TUTORIALS_DATA.playlist_url}
target="_blank"
rel="noopener noreferrer"
className="inline-block mt-8 text-blue-400 hover:text-blue-300 font-semibold text-sm no-underline transition-colors"
>
Watch the playlist on YouTube →
</a>
</div>
</section>
);
}
================================================
FILE: docs/src/components/SupportSection.tsx
================================================
const SUPPORT_DATA = {
bmc_url: "https://www.buymeacoffee.com/3ddelano",
github_sponsor_url: "https://github.com/sponsors/3ddelano",
discord_url: "https://discord.gg/FZY9TqW",
username: "@3ddelano",
};
export function SupportSection() {
return (
<section
id="support"
className="py-20 sm:py-24 bg-[#030712] relative overflow-hidden"
>
{/* Background glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[400px] bg-blue-600/5 rounded-full blur-[120px]"></div>
<div className="container mx-auto px-6 text-center relative z-10">
<h2 className="text-3xl font-bold mb-4 text-white tracking-tight">
Support Development
</h2>
<p className="text-gray-400 mb-10 max-w-2xl mx-auto font-light leading-relaxed">
Creating and maintaining this plugin requires significant time and
effort. If you find this project helpful, please consider supporting
its development.
</p>
<div className="flex flex-wrap justify-center items-center gap-6 mb-10">
<a
href={SUPPORT_DATA.bmc_url}
target="_blank"
rel="noopener noreferrer"
className="inline-block transition transform hover:scale-105"
>
<img
height="45"
width="180"
src="https://cdn.buymeacoffee.com/buttons/v2/default-red.png"
alt="Buy Me A Coffee"
/>
</a>
<a
href={SUPPORT_DATA.github_sponsor_url}
target="_blank"
rel="noopener noreferrer"
className="button-primary px-6 py-3 rounded-xl text-sm font-bold no-underline inline-flex items-center gap-2"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 16 16">
<path
fillRule="evenodd"
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"
/>
</svg>
GitHub Sponsor
</a>
</div>
<div className="glass rounded-2xl p-8 max-w-xl mx-auto">
<p className="text-gray-300 mb-4 font-medium">
Need help, have suggestions, or found a bug?
</p>
<div className="flex flex-wrap justify-center items-center gap-4">
<a
href={SUPPORT_DATA.discord_url}
target="_blank"
rel="noopener noreferrer"
className="button-secondary px-5 py-2.5 rounded-xl text-sm font-bold no-underline inline-flex items-center gap-2"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M19.27 5.33C17.94 4.71 16.5 4.26 15 4a.09.09 0 0 0-.07.03c-.18.33-.39.76-.53 1.09a16.09 16.09 0 0 0-4.8 0c-.14-.34-.35-.76-.54-1.09a.09.09 0 0 0-.07-.03c-1.5.26-2.93.71-4.27 1.33a.07.07 0 0 0-.05.08c-.67 1.9-.94 3.9-.94 6s.27 4.09.94 6a.07.07 0 0 0 .05.08c1.34.61 2.77 1.07 4.27 1.33a.09.09 0 0 0 .07-.03c.19-.34.4-.77.54-1.1a16.28 16.28 0 0 0 5.34-.01c.14.33.35.76.53 1.1a.09.09 0 0 0 .07.03c1.5-.26 2.93-.71 4.27-1.33a.07.07 0 0 0 .05-.08c.67-1.91.94-3.91.94-6s-.28-4.09-.94-6a.07.07 0 0 0-.05-.08zM8.5 13.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm7 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" />
</svg>
Join Discord
</a>
<span className="text-gray-500 text-sm">
or DM{" "}
<code className="glass px-2 py-0.5 rounded text-gray-300 font-mono text-xs">
{SUPPORT_DATA.username}
</code>
</span>
</div>
</div>
</div>
</section>
);
}
================================================
FILE: docs/src/css/custom.css
================================================
@import "tailwindcss";
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap");
:root {
--ifm-font-family-base: "Outfit", sans-serif;
--ifm-font-family-monospace: "JetBrains Mono", monospace;
--ifm-color-primary: #3b82f6;
--ifm-color-primary-dark: #2563eb;
--ifm-color-primary-darker: #1d4ed8;
--ifm-color-primary-darkest: #1e40af;
--ifm-color-primary-light: #60a5fa;
--ifm-color-primary-lighter: #93c5fd;
--ifm-color-primary-lightest: #bfdbfe;
--ifm-code-font-size: 90%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
--brand-gradient: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
--glass-bg: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.08);
}
[data-theme='dark'] {
--ifm-background-color: #030712;
--ifm-navbar-background-color: rgba(3, 7, 18, 0.8);
--ifm-footer-background-color: #030712;
--ifm-color-primary: #60a5fa;
--ifm-color-primary-dark: #3b82f6;
--ifm-color-primary-darker: #2563eb;
--ifm-color-primary-darkest: #1d4ed8;
--ifm-color-primary-light: #93c5fd;
--ifm-color-primary-lighter: #bfdbfe;
--ifm-color-primary-lightest: #dbeafe;
--docusaurus-highlighted-code-line-bg: rgba(255, 255, 255, 0.1);
}
/* Glassmorphism utility */
.glass {
background: var(--glass-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--glass-border);
}
.hero-image {
background-color: #030712;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='192' height='192' viewBox='0 0 192 192'%3E%3Cpath fill='%233b82f6' fill-opacity='0.04' d='M192 15v2a11 11 0 0 0-11 11c0 1.94 1.16 4.75 2.53 6.11l2.36 2.36a6.93 6.93 0 0 1 1.22 7.56l-.43.84a8.08 8.08 0 0 1-6.66 4.13H145v35.02a6.1 6.1 0 0 0 3.03 4.87l.84.43c1.58.79 4 .4 5.24-.85l2.36-2.36a12.04 12.04 0 0 1 7.51-3.11 13 13 0 1 1 .02 26 12 12 0 0 1-7.53-3.11l-2.36-2.36a4.93 4.93 0 0 0-5.24-.85l-.84.43a6.1 6.1 0 0 0-3.03 4.87V143h35.02a8.08 8.08 0 0 1 6.66 4.13l.43.84a6.91 6.91 0 0 1-1.22 7.56l-2.36 2.36A10.06 10.06 0 0 0 181 164a11 11 0 0 0 11 11v2a13 13 0 0 1-13-13 12 12 0 0 1 3.11-7.53l2.36-2.36a4.93 4.93 0 0 0 .85-5.24l-.43-.84a6.1 6.1 0 0 0-4.87-3.03H145v35.02a8.08 8.08 0 0 1-4.13 6.66l-.84.43a6.91 6.91 0 0 1-7.56-1.22l-2.36-2.36A10.06 10.06 0 0 0 124 181a11 11 0 0 0-11 11h-2a13 13 0 0 1 13-13c2.47 0 5.79 1.37 7.53 3.11l2.36 2.36a4.94 4.94 0 0 0 5.24.85l.84-.43a6.1 6.1 0 0 0 3.03-4.87V145h-35.02a8.08 8.08 0 0 1-6.66-4.13l-.43-.84a6.91 6.91 0 0 1 1.22-7.56l2.36-2.36A10.06 10.06 0 0 0 107 124a11 11 0 0 0-22 0c0 1.94 1.16 4.75 2.53 6.11l2.36 2.36a6.93 6.93 0 0 1 1.22 7.56l-.43.84a8.08 8.08 0 0 1-6.66 4.13H49v35.02a6.1 6.1 0 0 0 3.03 4.87l.84.43c1.58.79 4 .4 5.24-.85l2.36-2.36a12.04 12.04 0 0 1 7.51-3.11A13 13 0 0 1 81 192h-2a11 11 0 0 0-11-11c-1.94 0-4.75 1.16-6.11 2.53l-2.36 2.36a6.93 6.93 0 0 1-7.56 1.22l-.84-.43a8.08 8.08 0 0 1-4.13-6.66V145H11.98a6.1 6.1 0 0 0-4.87 3.03l-.43.84c-.79 1.58-.4 4 .85 5.24l2.36 2.36a12.04 12.04 0 0 1 3.11 7.51A13 13 0 0 1 0 177v-2a11 11 0 0 0 11-11c0-1.94-1.16-4.75-2.53-6.11l-2.36-2.36a6.93 6.93 0 0 1-1.22-7.56l.43-.84a8.08 8.08 0 0 1 6.66-4.13H47v-35.02a6.1 6.1 0 0 0-3.03-4.87l-.84-.43c-1.59-.8-4-.4-5.24.85l-2.36 2.36A12 12 0 0 1 28 109a13 13 0 1 1 0-26c2.47 0 5.79 1.37 7.53 3.11l2.36 2.36a4.94 4.94 0 0 0 5.24.85l.84-.43A6.1 6.1 0 0 0 47 84.02V49H11.98a8.08 8.08 0 0 1-6.66-4.13l-.43-.84a6.91 6.91 0 0 1 1.22-7.56l2.36-2.36A10.06 10.06 0 0 0 11 28 11 11 0 0 0 0 17v-2a13 13 0 0 1 13 13c0 2.47-1.37 5.79-3.11 7.53l-2.36 2.36a4.94 4.94 0 0 0-.85 5.24l.43.84A6.1 6.1 0 0 0 11.98 47H47V11.98a8.08 8.08 0 0 1 4.13-6.66l.84-.43a6.91 6.91 0 0 1 7.56 1.22l2.36 2.36A10.06 10.06 0 0 0 68 11 11 11 0 0 0 79 0h2a13 13 0 0 1-13 13 12 12 0 0 1-7.53-3.11l-2.36-2.36a4.93 4.93 0 0 0-5.24-.85l-.84.43A6.1 6.1 0 0 0 49 11.98V47h35.02a8.08 8.08 0 0 1 6.66 4.13l.43.84a6.91 6.91 0 0 1-1.22 7.56l-2.36 2.36A10.06 10.06 0 0 0 85 68a11 11 0 0 0 22 0c0-1.94-1.16-4.75-2.53-6.11l-2.36-2.36a6.93 6.93 0 0 1-1.22-7.56l.43-.84a8.08 8.08 0 0 1 6.66-4.13H143V11.98a6.1 6.1 0 0 0-3.03-4.87l-.84-.43c-1.59-.8-4-.4-5.24.85l-2.36 2.36A12 12 0 0 1 124 13a13 13 0 0 1-13-13h2a11 11 0 0 0 11 11c1.94 0 4.75-1.16 6.11-2.53l2.36-2.36a6.93 6.93 0 0 1 7.56-1.22l.84.43a8.08 8.08 0 0 1 4.13 6.66V47h35.02a6.1 6.1 0 0 0 4.87-3.03l.43-.84c.8-1.59.4-4-.85-5.24l-2.36-2.36A12 12 0 0 1 179 28a13 13 0 0 1 13-13zM84.02 143a6.1 6.1 0 0 0 4.87-3.03l.43-.84c.8-1.59.4-4-.85-5.24l-2.36-2.36A12 12 0 0 1 83 124a13 13 0 1 1 26 0c0 2.47-1.37 5.79-3.11 7.53l-2.36 2.36a4.94 4.94 0 0 0-.85 5.24l.43.84a6.1 6.1 0 0 0 4.87 3.03H143v-35.02a8.08 8.08 0 0 1 4.13-6.66l.84-.43a6.91 6.91 0 0 1 7.56 1.22l2.36 2.36A10.06 10.06 0 0 0 164 107a11 11 0 0 0 0-22c-1.94 0-4.75 1.16-6.11 2.53l-2.36 2.36a6.93 6.93 0 0 1-7.56 1.22l-.84-.43a8.08 8.08 0 0 1-4.13-6.66V49h-35.02a6.1 6.1 0 0 0-4.87 3.03l-.43.84c-.79 1.58-.4 4 .85 5.24l2.36 2.36a12.04 12.04 0 0 1 3.11 7.51A13 13 0 1 1 83 68a12 12 0 0 1 3.11-7.53l2.36-2.36a4.93 4.93 0 0 0 .85-5.24l-.43-.84A6.1 6.1 0 0 0 84.02 49H49v35.02a8.08 8.08 0 0 1-4.13 6.66l-.84.43a6.91 6.91 0 0 1-7.56-1.22l-2.36-2.36A10.06 10.06 0 0 0 28 85a11 11 0 0 0 0 22c1.94 0 4.75-1.16 6.11-2.53l2.36-2.36a6.93 6.93 0 0 1 7.56-1.22l.84.43a8.08 8.08 0 0 1 4.13 6.66V143h35.02z'%3E%3C/path%3E%3C/svg%3E");
}
/* Navbar glassmorphism */
.navbar {
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid var(--glass-border);
/* Override Docusaurus link color variables */
--ifm-link-color: white;
--ifm-link-hover-color: #60a5fa;
--ifm-link-decoration: none;
--ifm-link-hover-decoration: none;
}
/* Override Docusaurus link colors in navbar */
.navbar a:not(.button-secondary) {
color: white !important;
}
.navbar a:not(.button-secondary):hover,
.navbar a:not(.button-secondary):active {
color: #60a5fa !important;
}
/* Button system */
.button-primary {
background: var(--brand-gradient);
border: none;
color: white;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
}
.button-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.5);
color: white !important;
text-decoration: none;
}
.button-secondary {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
color: white;
backdrop-filter: blur(8px);
transition: all 0.3s ease;
}
.button-secondary:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.2);
color: white !important;
text-decoration: none;
}
/* Feature cards */
.feature-card {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
backdrop-filter: blur(8px);
transition: all 0.3s ease;
}
.feature-card:hover {
border-color: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
================================================
FILE: docs/src/pages/index.tsx
================================================
import { HeroSection } from "../components/HeroSection";
import { MainSystemsSection } from "../components/MainSystemsSection";
import { FeaturesSection } from "../components/FeaturesSection";
import { ScreenshotsSection, DemoSection } from "../components/MediaSections";
import { SupportSection } from "../components/SupportSection";
import { Footer, NavBar } from "../components/Layout";
export default function App() {
return (
<div className="min-h-screen bg-[#030712] text-gray-200 antialiased font-[Outfit,sans-serif]">
<NavBar />
<main className="pt-16">
<HeroSection />
<MainSystemsSection />
<FeaturesSection />
<ScreenshotsSection />
<DemoSection />
<SupportSection />
</main>
<Footer />
</div>
);
}
================================================
FILE: docs/src/pages/showcase.md
================================================
---
---
# Showcase
Here is a list of games using the Epic Online Services Godot plugin. If you are using this plugin and want to list your game in this list. Create an Issue on the [Github Repo](https://github.com/3ddelano/epic-online-services-godot/issues) with your game URL and which features of the plugin you used, or leave a message in the [Discord server](https://discord.gg/FZY9TqW).
- ### Kamaeru: A Frog Refuge
Foster a sanctuary for frogs and restore the biodiversity of the wetlands in Kamaeru, a cozy frog collecting game, where you take pictures of frogs, play mini-games and decorate your habitat. Hop right to it!
Links: [Steam](https://store.epicgames.com/en-US/p/kamaeru-0c301e)

> Features Used: Achievements, Cloud Saves / PlayerDataStorage
<br></br>
- ### Kitchen Together
Get ready to stir up some fun in the ultimate cooking challenge! Join your friends in this engaging multiplayer game where teamwork meets culinary creativity. Choose your kitchen role, from chopping and frying to decorating and serving, as you race against the clock to prepare delicious dishes.
Links: [Android Play Store](https://play.google.com/store/apps/details?id=com.kitchentogether) | [iOS App Store](https://apps.apple.com/us/app/kitchen-together-2/id6748915442)

> Features Used: Voice Chat, P2P, Lobby
<br></br>
- ### Hamsteria
Hamsteria is a short (~1-2 hours) difficult two player co-op game where you're each a hamster in attached wheels. You can only spin your individual wheel forwards or backwards. There is no jump button, and there is no turn action. To escape, you must work together.
Links: [Itch.io](https://2wheelerdev.itch.io/hamsteria)

> Features Used: P2P, Lobby
================================================
FILE: docs/src/plugins/tailwind-config.ts
================================================
module.exports = function tailwindPlugin(context, options) {
return {
name: 'tailwind-plugin',
configurePostCss(postcssOptions) {
postcssOptions.plugins = [require('@tailwindcss/postcss')]
return postcssOptions
}
}
}
================================================
FILE: docs/static/.nojekyll
================================================
================================================
FILE: docs/tsconfig.json
================================================
{
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
},
"exclude": [".docusaurus", "build"]
}
================================================
FILE: function_analyzer.py
================================================
# eos_function_usage_checker.py
import os
import re
# Function to extract function names from the EOS C SDK header files
def extract_function_names(sdk_path):
function_declarations = {}
pattern = re.compile(r"EOS_DECLARE_FUNC\(\w+\)\s+(EOS_\w+)\(")
for root, _, files in os.walk(sdk_path):
for file in files:
if file.endswith(".h"):
with open(os.path.join(root, file), 'r', encoding='utf-8') as f:
content = f.read()
matches = pattern.findall(content)
for match in matches:
function_declarations[match] = os.path.join(root, file)
return function_declarations
# Function to search for function names in the src folder
def find_function_calls(src_path, function_names):
function_usage = {name: [] for name in function_names}
pattern = re.compile(r"(\bEOS_\w+\b)")
for root, _, files in os.walk(src_path):
for file in files:
if file.endswith(".h") or file.endswith(".cpp"):
with open(os.path.join(root, file), 'r', encoding='utf-8') as f:
content = f.read()
matches = pattern.findall(content)
for match in matches:
if match in function_usage:
function_usage[match].append(os.path.join(root, file))
return function_usage
def main():
sdk_path = 'thirdparty/eos-sdk/SDK' # Replace with the actual path to the EOS C SDK folder
src_path = 'src' # Replace with the actual path to the src folder
whitelist = ['EOS_Achievements_CopyAchievementDefinitionByIndex',
'EOS_Achievements_CopyAchievementDefinitionByAchievementId',
'EOS_Achievements_GetUnlockedAchievementCount',
'EOS_Achievements_CopyUnlockedAchievementByIndex',
'EOS_Achievements_CopyUnlockedAchievementByAchievementId',
'EOS_Achievements_AddNotifyAchievementsUnlocked',
'EOS_AntiCheatClient_PollStatus',
'EOS_ByteArray_ToString',
'EOS_EpicAccountId_IsValid',
'EOS_ProductUserId_IsValid',
]
# Step 1: Extract function names from SDK header files
function_declarations = extract_function_names(sdk_path)
function_names = list(function_declarations.keys())
print(f"Extracted {len(function_names)} function names from SDK headers.")
# Step 2: Search for these function names in the src folder
function_usage = find_function_calls(src_path, function_names)
# Print the results
print("SDK functions not called by the plugin:")
uncalled_count = 0
for function, files in function_usage.items():
if files: continue
if function in whitelist: continue
if "RemoveNotify" in function: continue
uncalled_count += 1
print(f"{function} : {function_declarations[function]}")
print(f"\nTotal number of SDK functions not called by the plugin: {uncalled_count}")
if __name__ == "__main__":
main()
================================================
FILE: sample/.gitignore
================================================
.import/
export.cfg
export_presets.cfg
*.translation
.godot/
*.env
*.import
================================================
FILE: sample/AntiCheatServerMain.gd
================================================
class_name AntiCheatServerMain
extends Node
@onready var PRODUCT_NAME: String = Env.get_var("PRODUCT_NAME")
@onready var PRODUCT_VERSION: String = Env.get_var("PRODUCT_VERSION")
@onready var PRODUCT_ID: String = Env.get_var("PRODUCT_ID")
@onready var SANDBOX_ID: String = Env.get_var("SANDBOX_ID")
@onready var DEPLOYMENT_ID: String = Env.get_var("DEPLOYMENT_ID")
@onready var CLIENT_ID: String = Env.get_var("CLIENT_ID")
@onready var CLIENT_SECRET: String = Env.get_var("CLIENT_SECRET")
@onready var ENCRYPTION_KEY: String = Env.get_var("ENCRYPTION_KEY")
const PORT = 12345
func _ready() -> void:
print("AntiCheatServer _ready")
var init_success = await _load_and_init_sdk()
if not init_success:
return
_begin_session()
_start_server()
func _load_and_init_sdk() -> bool:
# -----
# EOS Setup
# -----
# Initialize the SDK
var init_opts = EOS.Platform.InitializeOptions.new()
init_opts.product_name = PRODUCT_NAME
init_opts.product_version = PRODUCT_VERSION
var init_res := EOS.Platform.PlatformInterface.initialize(init_opts)
var init_retry_count = 10
while not EOS.is_success(init_res) and init_retry_count > 0:
init_res = EOS.Platform.PlatformInterface.initialize(init_opts)
init_retry_count -= 1
await get_tree().create_timer(0.2).timeout
if not EOS.is_success(init_res):
print("Failed to initialize EOS SDK: ", EOS.result_str(init_res))
return false
print("Initialized EOS platform")
# Create platform
var create_opts = EOS.Platform.CreateOptions.new()
create_opts.product_id = PRODUCT_ID
create_opts.sandbox_id = SANDBOX_ID
create_opts.deployment_id = DEPLOYMENT_ID
create_opts.client_id = CLIENT_ID
create_opts.client_secret = CLIENT_SECRET
create_opts.encryption_key = ENCRYPTION_KEY
create_opts.is_server = true
create_opts.flags = EOS.Platform.PlatformFlags.DisableOverlay
var create_success: bool = EOS.Platform.PlatformInterface.create(create_opts)
var create_retry_count = 10
while not create_success&&create_retry_count > 0:
create_success = EOS.Platform.PlatformInterface.create(create_opts)
create_retry_count -= 1
await get_tree().create_timer(0.2).timeout
if not create_success:
print("Failed to create EOS Platform")
return false
print("Created EOS platform")
return true
func _begin_session():
IEOS.anticheatserver_interface_message_to_client_callback.connect(func(data):
print("--- AntiCheatServer: message_to_client_callback: ", data)
)
IEOS.anticheatserver_interface_client_action_required_callback.connect(func(data):
print("--- AntiCheatServer: client_action_required_callback: ", data)
)
IEOS.anticheatserver_interface_client_auth_status_changed_callback.connect(func(data):
print("--- AntiCheatServer: client_auth_status_changed_callback: ", data)
)
var begin_sess_opts = EOS.AntiCheatServer.BeginSessionOptions.new()
begin_sess_opts.register_timeout_seconds = 60
begin_sess_opts.server_name = "Godot 4.2 server"
begin_sess_opts.enable_gameplay_data = false
print("--- AntiCheatServer: begin_session: ", EOS.AntiCheatServer.AntiCheatServerInterface.begin_session(begin_sess_opts))
func _verify_id_token(_peer_id: int, product_user_id: String, connect_id_jwt: String):
var id_token = EOS.Connect.IdToken.new()
id_token.json_web_token = connect_id_jwt
id_token.product_user_id = product_user_id
var verify_token_opts = EOS.Connect.VerifyIdTokenOptions.new()
verify_token_opts.id_token = id_token
EOS.Connect.ConnectInterface.verify_id_token(verify_token_opts)
print("--- AntiCheatServer: verify_id_token: ", await IEOS.connect_interface_verify_id_token_callback)
func _start_server():
multiplayer.peer_connected.connect(func(id: int):
print("--- AntiCheatServer:: peer_connected: ", id)
)
multiplayer.peer_disconnected.connect(func(id: int):
print("--- AntiCheatServer:: peer_disconnected: ", id)
)
var peer = ENetMultiplayerPeer.new()
peer.create_server(PORT)
multiplayer.multiplayer_peer = peer
print("Listening for clients on port: ", PORT)
func on_client_message_receive(peer_id: int, type: String, data: Dictionary):
if type == "register":
_verify_id_token(peer_id, data.local_user_id, data.jwt)
================================================
FILE: sample/AntiCheatServerMain.gd.uid
================================================
uid://clbqhgyalkxuw
================================================
FILE: sample/Main.gd
================================================
extends Control
@onready var PRODUCT_NAME: String = Env.get_var("PRODUCT_NAME") # Paste your own instead of Env.get_var
@onready var PRODUCT_VERSION: String = Env.get_var("PRODUCT_VERSION") # Paste your own
@onready var PRODUCT_ID: String = Env.get_var("PRODUCT_ID") # Paste your own
@onready var SANDBOX_ID: String = Env.get_var("SANDBOX_ID") # Paste your own
@onready var DEPLOYMENT_ID: String = Env.get_var("DEPLOYMENT_ID") # Paste your own
@onready var CLIENT_ID: String = Env.get_var("CLIENT_ID") # Paste your own
@onready var CLIENT_SECRET: String = Env.get_var("CLIENT_SECRET") # Paste your own
@onready var ENCRYPTION_KEY: String = Env.get_var("ENCRYPTION_KEY") # Paste your own
@export var _views_path: NodePath
@onready var views = get_node(_views_path) as VBoxContainer
func _ready() -> void:
if _check_for_dedicated_server_sample():
return
print("Ready!")
Store._main_node = self
HLog.log_level = HLog.LogLevel.INFO
# -----
# EOS Setup
# -----
var credentials = HCredentials.new()
credentials.product_name = PRODUCT_NAME
credentials.product_version = PRODUCT_VERSION
credentials.product_id = PRODUCT_ID
credentials.sandbox_id = SANDBOX_ID
credentials.deployment_id = DEPLOYMENT_ID
credentials.client_id = CLIENT_ID
credentials.client_secret = CLIENT_SECRET
credentials.encryption_key = ENCRYPTION_KEY
print("Setting up EOS...")
var setup_success := await HPlatform.setup_eos_async(credentials)
if not setup_success:
printerr("Failed to setup EOS. See logs for error details")
return
var sdk_constants := EOS.Version.VersionInterface.get_constants()
print("EOS SDK Version: %s (%s)" % [EOS.Version.VersionInterface.get_version(), sdk_constants.copyright_string])
# See LoginView.gd for the user login flow
_parse_cmdline_user_args()
func get_view_manager():
return views
func _notification(what: int) -> void:
if what == NOTIFICATION_WM_CLOSE_REQUEST:
print("Shutting down EOS...")
EOS.Platform.PlatformInterface.release()
var res := EOS.Platform.PlatformInterface.shutdown()
if not EOS.is_success(res):
printerr("Failed to shutdown EOS: ", EOS.result_str(res))
func _check_for_dedicated_server_sample() -> bool:
# Ignore this method
# This is for the sample project to dynamically load the
# dedicated server example when certain cli flags are passed
var args = OS.get_cmdline_user_args()
for arg in args:
if arg.begins_with("--screenpos="):
var rows = 2
var cols = 2
var pos := int(arg.replace("--screenpos=", ""))
var screen_size = DisplayServer.screen_get_size()
var scale_x = screen_size.x / cols
var scale_y = screen_size.y / rows
var x = (pos - 1) % cols
@warning_ignore("integer_division")
var y = (pos - 1) / rows
get_window().position = Vector2(x * scale_x, y * scale_y)
get_window().size = Vector2(screen_size.x / cols, screen_size.y / rows)
if "--eosg-dedicated-server-example" in args:
if "--eosg-server" in args:
_load_dedicated_server_script()
return true
if "--eosg-client" in args:
_load_dedicated_client_script()
return true
return false
func _load_dedicated_server_script():
var SCENE := load("res://dedicated_server_example/server_main.tscn") as PackedScene
var server = SCENE.instantiate()
add_child(server)
func _load_dedicated_client_script():
var SCENE := load("res://dedicated_server_example/client_main.tscn") as PackedScene
var client = SCENE.instantiate()
add_child(client)
func _parse_cmdline_user_args():
var args = OS.get_cmdline_user_args()
for arg in args:
if arg.begins_with("--devuser="):
var login_view = Store.get_view("Login")
var username = arg.replace("--devuser=", "")
login_view._set_login_status("Logging in with devtool using cli arg...")
login_view._set_login_state(LoginView.States.Pending)
HAuth.login_devtool_async("localhost:4545", username)
if arg.begins_with("--screenpos="):
var rows = 2
var cols = 2
var pos := int(arg.replace("--screenpos=", ""))
var screen_size = DisplayServer.screen_get_size()
var scale_x = screen_size.x / cols
var scale_y = screen_size.y / rows
var x = (pos - 1) % cols
@warning_ignore("integer_division")
var y = (pos - 1) / rows
get_window().position = Vector2(x * scale_x, y * scale_y)
get_window().size = Vector2(screen_size.x / cols, screen_size.y / rows)
================================================
FILE: sample/Main.gd.uid
================================================
uid://cf8kvjx2nbysy
================================================
FILE: sample/Main.tscn
================================================
[gd_scene load_steps=25 format=3 uid="uid://gcoi8ld0uvkl"]
[ext_resource type="Theme" uid="uid://dwns7wwoyi1hy" path="res://components/StyledPopupWindow/StyledPopupWindowTheme.tres" id="1_dhxmx"]
[ext_resource type="PackedScene" uid="uid://d3hxdkoy73pf1" path="res://scenes/AchievementsView/AchievementsView.tscn" id="2"]
[ext_resource type="Script" uid="uid://cf8kvjx2nbysy" path="res://Main.gd" id="3"]
[ext_resource type="Script" uid="uid://b8dbhfvrewi8w" path="res://scripts/ViewManager.gd" id="3_j157n"]
[ext_resource type="PackedScene" uid="uid://cl2qvlvdhn2iw" path="res://scenes/LogsView/LogsView.tscn" id="4"]
[ext_resource type="PackedScene" uid="uid://bht0ln2ftshrw" path="res://scenes/LoginView/LoginView.tscn" id="5"]
[ext_resource type="PackedScene" uid="uid://t8s6xh1ax7uy" path="res://scenes/UI/PrimaryButton.tscn" id="6"]
[ext_resource type="PackedScene" uid="uid://d2bkej1dakv6s" path="res://scenes/CustomInvitesView/CustomInvitesView.tscn" id="9"]
[ext_resource type="PackedScene" uid="uid://dgi7j5qx3xt84" path="res://scenes/StatsView/StatsView.tscn" id="10"]
[ext_resource type="PackedScene" uid="uid://5xrk7nvpwosj" path="res://scenes/LeaderboardsView/LeaderboardsView.tscn" id="11"]
[ext_resource type="PackedScene" uid="uid://t016k2yh382d" path="res://scenes/FriendsView/FriendsView.tscn" id="12"]
[ext_resource type="PackedScene" uid="uid://b51w7a6ofuubp" path="res://scenes/UIView/UIView.tscn" id="13"]
[ext_resource type="PackedScene" uid="uid://dsiyt23hnmngd" path="res://scenes/LobbiesView/LobbiesView.tscn" id="13_eyvcp"]
[ext_resource type="PackedScene" uid="uid://bd06h3ufkhfd7" path="res://scenes/MetricsView/MetricsView.tscn" id="14"]
[ext_resource type="Script" uid="uid://6tlvlmuarqub" path="res://scenes/NotificationsView/NotificationsView.gd" id="14_v0jrb"]
[ext_resource type="Script" uid="uid://bb2nerxdrhped" path="res://test.gd" id="16_4rltv"]
[ext_resource type="Script" uid="uid://d0vgtesnrato5" path="res://scripts/network.gd" id="17_ailes"]
[ext_resource type="Script" uid="uid://k3lb65sounwm" path="res://test_manual_audio_output.gd" id="17_bg4s2"]
[ext_resource type="PackedScene" uid="uid://bdlcslag0jdj1" path="res://scenes/UI/nat_type.tscn" id="18_vylep"]
[ext_resource type="PackedScene" uid="uid://c37wtoikc8pgp" path="res://scenes/UI/ping.tscn" id="19_enhih"]
[ext_resource type="PackedScene" uid="uid://8kmyoi08gr22" path="res://scenes/UI/players_score.tscn" id="20_i3cca"]
[ext_resource type="Script" uid="uid://cgmpdyovn5vfm" path="res://scenes/UI/touch_screen_joystick.gd" id="21_5h21x"]
[ext_resource type="Script" uid="uid://dygslh2f7uw40" path="res://scenes/UI/joysticks.gd" id="21_einjf"]
[sub_resource type="StyleBoxEmpty" id="5"]
[node name="Main" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_dhxmx")
script = ExtResource("3")
_views_path = NodePath("MC/ViewManager")
[node name="ColorRect" type="ColorRect" parent="."]
layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.121569, 0.121569, 0.121569, 1)
[node name="MC" type="MarginContainer" parent="."]
layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="ViewManager" type="VBoxContainer" parent="MC"]
layout_mode = 2
script = ExtResource("3_j157n")
[node name="HB" type="HFlowContainer" parent="MC/ViewManager"]
layout_mode = 2
size_flags_horizontal = 3
[node name="AuthBtn" parent="MC/ViewManager/HB" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Auth"
[node name="NeedsLoginBtns" type="HFlowContainer" parent="MC/ViewManager/HB"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
[node name="AchievementsBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Achievements"
[node name="CustomInvitesBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Custom Invites"
[node name="StatsBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Stats"
[node name="LeaderboardsBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Leaderboards"
[node name="FriendsBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Friends"
[node name="UIBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "UI"
[node name="MetricsBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Metrics"
[node name="LobbiesBtn" parent="MC/ViewManager/HB/NeedsLoginBtns" instance=ExtResource("6")]
unique_name_in_owner = true
layout_mode = 2
text = "Lobbies"
[node name="VSC" type="VSplitContainer" parent="MC/ViewManager"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/autohide = 0
[node name="VB" type="VBoxContainer" parent="MC/ViewManager/VSC"]
layout_mode = 2
theme_override_constants/separation = 52
[node name="LoginView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("5")]
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="AchievementsView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("2")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="CustomInvitesView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("9")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="StatsView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("10")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="LeaderboardsView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("11")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="FriendsView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("12")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="UIView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("13")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="MetricsView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("14")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="LobbiesView" parent="MC/ViewManager/VSC/VB" instance=ExtResource("13_eyvcp")]
visible = false
custom_minimum_size = Vector2(0, 200)
layout_mode = 2
[node name="NotificationsLayer" type="CanvasLayer" parent="MC/ViewManager/VSC/VB"]
[node name="NotificationsView" type="MarginContainer" parent="MC/ViewManager/VSC/VB/NotificationsLayer"]
offset_top = 270.0
offset_right = 366.0
offset_bottom = 600.0
mouse_filter = 2
script = ExtResource("14_v0jrb")
[node name="SC" type="ScrollContainer" parent="MC/ViewManager/VSC/VB/NotificationsLayer/NotificationsView"]
custom_minimum_size = Vector2(350, 0)
layout_mode = 2
mouse_filter = 2
[node name="PC" type="PanelContainer" parent="MC/ViewManager/VSC/VB/NotificationsLayer/NotificationsView/SC"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 10
mouse_filter = 2
theme_override_styles/panel = SubResource("5")
[node name="MC" type="MarginContainer" parent="MC/ViewManager/VSC/VB/NotificationsLayer/NotificationsView/SC/PC"]
layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 8
[node name="VB" type="VBoxContainer" parent="MC/ViewManager/VSC/VB/NotificationsLayer/NotificationsView/SC/PC/MC"]
layout_mode = 2
mouse_filter = 2
theme_override_constants/separation = 8
[node name="LogsView" parent="MC/ViewManager/VSC" instance=ExtResource("4")]
layout_mode = 2
[node name="Test" type="Node" parent="."]
script = ExtResource("16_4rltv")
[node name="ManualAudioOutput" type="Node" parent="Test"]
script = ExtResource("17_bg4s2")
[node name="Network" type="Node2D" parent="."]
script = ExtResource("17_ailes")
[node name="Game" type="Node2D" parent="Network"]
[node name="NetworkSpawn" type="Node2D" parent="Network/Game"]
[node name="MapSpawner" type="MultiplayerSpawner" parent="Network/Game"]
_spawnable_scenes = PackedStringArray("uid://d25abb5oqolnx", "uid://cq20ci5f675b8", "uid://cutu8g5suwurd")
spawn_path = NodePath("../NetworkSpawn")
[node name="PlayerSpawner" type="MultiplayerSpawner" parent="Network/Game"]
_spawnable_scenes = PackedStringArray("uid://d25l4fa1sffqk")
spawn_path = NodePath("../NetworkSpawn")
[node name="CanvasLayer" type="CanvasLayer" parent="Network/Game"]
visible = false
[node name="NatType" parent="Network/Game/CanvasLayer" instance=ExtResource("18_vylep")]
offset_left = -196.0
text = "NAT TYPE: Moderate"
[node name="Ping" parent="Network/Game/CanvasLayer" instance=ExtResource("19_enhih")]
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -305.0
offset_top = -30.0
offset_right = -213.0
offset_bottom = -7.0
grow_horizontal = 0
grow_vertical = 0
[node name="PlayersScore" parent="Network/Game/CanvasLayer" instance=ExtResource("20_i3cca")]
[node name="Joysticks" type="Control" parent="Network/Game/CanvasLayer"]
visible = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("21_einjf")
[node name="MoveJoystick" type="Control" parent="Network/Game/CanvasLayer/Joysticks"]
anchors_preset = 0
offset_left = 181.0
offset_top = 390.0
offset_right = 221.0
offset_bottom = 430.0
pivot_offset = Vector2(20, 20)
script = ExtResource("21_5h21x")
knob_color = Color(0.560955, 0.560955, 0.560955, 1)
base_color = Color(0.560784, 0.560784, 0.560784, 1)
anti_aliased = true
mode = 1
use_input_actions = true
action_left = "move_left"
action_right = "move_right"
action_up = "move_up"
action_down = "move_down"
[node name="ShootJoystick" type="Control" parent="Network/Game/CanvasLayer/Joysticks"]
anchors_preset = 0
offset_left = 938.0
offset_top = 401.0
offset_right = 978.0
offset_bottom = 441.0
pivot_offset = Vector2(20, 20)
script = ExtResource("21_5h21x")
knob_color = Color(0.560784, 0.560784, 0.560784, 1)
base_color = Color(0.560784, 0.560784, 0.560784, 1)
anti_aliased = true
mode = 1
================================================
FILE: sample/addons/epic-online-services-godot/base_class.gd
================================================
## Copyright (c) 2022-present Delano Lourenco
## https://github.com/3ddelano/dataclasses-godot
## MIT License
## See License.md
class_name BaseClass extends Dataclass
func _init(p_name: String, p_options: Dictionary = {}):
p_options["print_newline"] = true
p_options["print_exclude"] = ["base_class.gd", "_log"]
super._init(p_name, p_options)
================================================
FILE: sample/addons/epic-online-services-godot/base_class.gd.uid
================================================
uid://g1ij604ak57v
================================================
FILE: sample/addons/epic-online-services-godot/bin/.gitignore
================================================
*
!.gitignore
================================================
FILE: sample/addons/epic-online-services-godot/dataclass.gd
================================================
## Copyright (c) 2022-present Delano Lourenco
## https://github.com/3ddelano/dataclasses-godot
## MIT License
## See License.md
class_name Dataclass extends RefCounted
const __DEFAULT_OPTIONS__ = {
# Whether to sort properties when printing
"sort_keys": true,
# Whether to include properties with null values in the to_dict() method
"include_null_in_dict": true,
# Whether to include properties with null values when printing
"include_null_in_print": true,
# Whether to print properties on newlines when printing
"print_newline": false,
# Names of properties to exclude when printing
"print_exclude": []
}
const __TYPE_STRING_CAPITAL = ["TYPE_NIL", "TYPE_BOOL", "TYPE_INT", "TYPE_FLOAT", "TYPE_STRING", "TYPE_VECTOR2", "TYPE_VECTOR2I", "TYPE_RECT2", "TYPE_RECT2I", "TYPE_VECTOR3", "TYPE_VECTOR3I", "TYPE_TRANSFORM2D", "TYPE_VECTOR4", "TYPE_VECTOR4I", "TYPE_PLANE", "TYPE_QUATERNION", "TYPE_AABB", "TYPE_BASIS", "TYPE_TRANSFORM3D", "TYPE_PROJECTION", "TYPE_COLOR", "TYPE_STRING_NAME", "TYPE_NODE_PATH", "TYPE_RID", "TYPE_OBJECT", "TYPE_CALLABLE", "TYPE_SIGNAL", "TYPE_DICTIONARY", "TYPE_ARRAY", "TYPE_PACKED_BYTE_ARRAY", "TYPE_PACKED_INT32_ARRAY", "TYPE_PACKED_INT64_ARRAY", "TYPE_PACKED_FLOAT32_ARRAY", "TYPE_PACKED_FLOAT64_ARRAY", "TYPE_PACKED_STRING_ARRAY", "TYPE_PACKED_VECTOR2_ARRAY", "TYPE_PACKED_VECTOR3_ARRAY", "TYPE_PACKED_COLOR_ARRAY", "TYPE_MAX"]
const __TYPE_STRING_NORMAL = ["Nil", "Bool", "Int", "Float", "String", "Vector2", "Vector2i", "Rect2", "Rect2i", "Vector3", "Vector3i", "Transform2D", "Vector4", "Vector4i", "Plane", "Quaternion", "AABB", "Basis", "Transform3D", "Projection", "Color", "StringName", "NodePath", "Rid", "Object", "Callable", "Signal", "Dictionary", "Array", "PackedByteArray", "PackedInt32Array", "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array", "PackedStringArray", "PackedVector2Array", "PackedVector3Array", "PackedColorArray", "Max"]
func from_dict(p_dict: Dictionary):
for key in p_dict:
if not key in self:
printerr("Dataclass:from_dict: Error: Key \"%s\" not found in dataclass \"%s\"" % [key, __name__])
continue
# Check for types match
var typeof_expected = typeof(get(key))
var typeof_received = typeof(p_dict[key])
if typeof_expected != TYPE_NIL and typeof_received != typeof_expected and (
(not typeof_expected in [TYPE_INT, TYPE_FLOAT]) and
(not typeof_received in [TYPE_INT, TYPE_FLOAT])
):
printerr("Dataclass:from_dict: Warning: Key \"%s\" has type %s but expected type %s in dataclass \"%s\"" % [key, __type_to_string(typeof_received), __type_to_string(typeof_expected), __name__])
set(key, p_dict[key])
return self
func to_dict() -> Dictionary:
var ret = {}
var all_props = __get_props()
for prop in all_props:
var value = get(prop.name)
if value != null or __options__.include_null_in_dict:
ret[prop.name] = value
return ret
var __name__: String
var __options__: Dictionary
func _init(p_name: String, p_options: Dictionary = {}):
__name__ = p_name
__options__ = __DEFAULT_OPTIONS__.duplicate()
set_meta("is_dataclass", true)
# Override options
for key in p_options:
__options__[key] = p_options[key]
func get_class() -> String:
return __name__
func __get_props() -> Array:
var all_props = get_property_list()
all_props = all_props.slice(3, all_props.size() - 4)
if __options__.sort_keys:
all_props.sort_custom(func sort_ascending(a, b):
return a.name < b.name)
return all_props
func __type_to_string(p_type: int, p_capital = true) -> String:
if p_capital:
return __TYPE_STRING_CAPITAL[p_type]
return __TYPE_STRING_NORMAL[p_type]
func __variant_to_string(value, indent_level = 0, visited_objects = []) -> String:
var type = typeof(value)
var newline = ""
var tab = ""
var dict_join = ", "
if __options__.print_newline:
tab = "\t"
newline = "\n"
dict_join = ",\n"
match type:
TYPE_STRING:
return "\"" + value.c_escape() + "\""
TYPE_NIL, TYPE_INT, TYPE_FLOAT, TYPE_BOOL:
return str(value)
TYPE_QUATERNION, TYPE_VECTOR2, TYPE_RECT2, TYPE_VECTOR3, TYPE_TRANSFORM2D, TYPE_BASIS:
return "%s%s" % [__type_to_string(type, false), value]
TYPE_RID:
return "RID(%s)" % value.get_id()
TYPE_OBJECT:
if value == null:
return "Object(null)"
elif (not value is Script) and value.has_meta("is_dataclass") and value.get_meta("is_dataclass"):
# Check for circular reference to prevent infinite recursion
if value in visited_objects:
return "%s(<circular reference>)" % value.__name__
# Create new visited_objects array with current object added
visited_objects.append(value)
# Manually construct the string representation to avoid calling _to_string()
var all_props = value.__get_props()
var props = PackedStringArray()
for prop in all_props:
if prop.name in value.__options__.print_exclude:
continue
var prop_value = value.get(prop.name)
var prop_type = typeof(prop_value)
if prop_value != null or value.__options__.include_null_in_print:
props.append("%s = %s" % [prop.name, __variant_to_string(prop_value, indent_level + 1, visited_objects)])
var separator = ", "
var prop_newline = ""
var prop_newline_end = ""
if value.__options__.print_newline:
prop_newline = "\n\t"
prop_newline_end = "\n"
var result = value.__name__ + "(" + prop_newline + (separator + prop_newline).join(props) + prop_newline_end + ")"
return result.indent(tab.repeat(indent_level)).trim_prefix(tab.repeat(indent_level))
return str(value)
TYPE_DICTIONARY:
var keys = value.keys()
if keys.size() == 0: return "{}"
var dict_string = PackedStringArray()
for key in keys:
dict_string.append("%s: %s" % [key, __variant_to_string(value[key], 0, visited_objects)])
dict_string = "{" + newline + dict_join.join(dict_string).indent(tab) + newline + "}"
return dict_string.indent(tab.repeat(indent_level)).trim_prefix(tab.repeat(indent_level))
TYPE_ARRAY, TYPE_PACKED_BYTE_ARRAY, TYPE_PACKED_INT32_ARRAY, TYPE_PACKED_INT64_ARRAY, TYPE_PACKED_FLOAT32_ARRAY, TYPE_PACKED_FLOAT64_ARRAY, TYPE_PACKED_STRING_ARRAY, TYPE_PACKED_VECTOR2_ARRAY, TYPE_PACKED_VECTOR3_ARRAY, TYPE_PACKED_COLOR_ARRAY:
var ret = PackedStringArray()
for elm in value:
ret.append(__variant_to_string(elm, 1, visited_objects))
ret = "[" + ", ".join(ret) + "]"
if type == TYPE_ARRAY: return ret
return __type_to_string(type, false) + "(" + ret + ")"
TYPE_COLOR:
return "%s%s" % [__type_to_string(type, false), value]
_:
return "%s(%s)" % [__type_to_string(type, false), value]
func _to_string() -> String:
var all_props = __get_props()
var props = PackedStringArray()
for prop in all_props:
if prop.name in __options__.print_exclude:
continue
var value = get(prop.name)
var type = typeof(value)
if value != null or __options__.include_null_in_print:
props.append("%s = %s" % [prop.name, __variant_to_string(value, 1, [self])])
var separator = ", "
var newline = ""
var newline_end = ""
if __options__.print_newline:
newline = "\n\t"
newline_end = "\n"
return __name__ + "(" + newline + (separator + newline).join(props) + newline_end + ")"
================================================
FILE: sample/addons/epic-online-services-godot/dataclass.gd.uid
================================================
uid://d4hmupfn3ooqp
================================================
FILE: sample/addons/epic-online-services-godot/eos.gd
================================================
# Copyright (c) 2023-present Delano Lourenco
# https://github.com/3ddelano/epic-online-services-godot/
# MIT License
## The main class to interact with Epic Online Services
class_name EOS
extends RefCounted
static func get_instance():
return IEOS
## Pretty prints the [enum Result] code and its string representation.[br]
## [code]p_result[/code] is a [enum Result] or a [Dictionary] with a [code]result_code[/code] key
static func print_result(p_result) -> void:
print_rich("[b]EOS_Result[/b]:%s[code](%s)[/code]" % [result_str(p_result), p_result])
## Returns a string representation of the [enum Result] code.[br]
## [code]p_result[/code] is a [enum Result] or a [Dictionary] with a [code]result_code[/code] key
static func result_str(p_result) -> String:
if typeof(p_result) == TYPE_DICTIONARY:
p_result = p_result["result_code"]
var idx := Result.values().find(p_result)
return Result.keys()[idx]
## Returns whether the operation was completed.[br]
## [code]p_result[/code] is a [enum Result] or a [Dictionary] with a [code]result_code[/code] key
static func is_operation_complete(p_result) -> bool:
if typeof(p_result) == TYPE_DICTIONARY:
p_result = p_result["result_code"]
return IEOS.is_operation_complete(p_result)
## Returns whether the operation was successful.[br]
## [code]p_result[/code] is a [enum Result] or a [Dictionary] with a [code]result_code[/code] key
static func is_success(p_result) -> bool:
if typeof(p_result) == TYPE_BOOL:
return p_result == true
if typeof(p_result) == TYPE_DICTIONARY:
p_result = p_result["result_code"]
return p_result == Result.Success
class Achievements:
const UNLOCK_TIME_UNDEFINED = -1
class CopyAchievementDefinitionV2ByAchievementIdOptions extends BaseClass:
func _init():
super._init("CopyAchievementDefinitionV2ByAchievementIdOptions")
var achievement_id: String
class CopyAchievementDefinitionV2ByIndexOptions extends BaseClass:
func _init():
super._init("CopyAchievementDefinitionV2ByIndexOptions")
var achievement_index: int
class CopyPlayerAchievementByAchievementIdOptions extends BaseClass:
func _init():
super._init("CopyPlayerAchievementByAchievementIdOptions")
var achievement_id: String
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id = EOSGRuntime.local_product_user_id
class CopyPlayerAchievementByIndexOptions extends BaseClass:
func _init():
super._init("CopyPlayerAchievementByIndexOptions")
var achievement_index: int
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id: String
class GetAchievementDefinitionCountOptions extends BaseClass:
func _init():
super._init("GetAchievementDefinitionCountOptions")
class QueryDefinitionsOptions extends BaseClass:
func _init():
super._init("QueryDefinitionsOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class GetPlayerAchievementCountOptions extends BaseClass:
func _init():
super._init("GetPlayerAchievementCountOptions")
var user_id: String
class QueryPlayerAchievementsOptions extends BaseClass:
func _init():
super._init("QueryPlayerAchievementsOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class UnlockAchievementsOptions extends BaseClass:
func _init():
super._init("UnlockAchievementsOptions")
var user_id: String
var achievement_ids: Array # Array[String]
var client_data = null
class AchievementsInterface:
static func query_definitions(options: QueryDefinitionsOptions) -> void:
IEOS.achievements_interface_query_definitions(options)
static func get_achievement_definition_count(options: GetAchievementDefinitionCountOptions) -> int:
return IEOS.achievements_interface_get_achievement_definition_count(options)
static func copy_achievement_definition_v2_by_achievement_id(
options: CopyAchievementDefinitionV2ByAchievementIdOptions
) -> Dictionary:
return IEOS.achievements_interface_copy_achievement_definition_v2_by_achievement_id(
options
)
static func copy_achievement_definition_v2_by_index(
options: CopyAchievementDefinitionV2ByIndexOptions
) -> Dictionary:
return IEOS.achievements_interface_copy_achievement_definition_v2_by_index(options)
static func query_player_achievements(options: QueryPlayerAchievementsOptions) -> void:
IEOS.achievements_interface_query_player_achievements(options)
static func get_player_achievement_count(options: GetPlayerAchievementCountOptions) -> int:
return IEOS.achievements_interface_get_player_achievement_count(options)
static func copy_player_achievement_by_achievement_id(
options: CopyPlayerAchievementByAchievementIdOptions
) -> Dictionary:
return IEOS.achievements_interface_copy_player_achievement_by_achievement_id(options)
static func copy_player_achievement_by_index(options: CopyPlayerAchievementByIndexOptions) -> Dictionary:
return IEOS.achievements_interface_copy_player_achievement_by_index(options)
static func unlock_achievements(options: UnlockAchievementsOptions) -> void:
IEOS.achievements_interface_unlock_achievements(options)
class Connect:
const CONNECT_TIME_UNDEFINED = -1
class Credentials extends BaseClass:
func _init():
super._init("Credentials")
var type: ExternalCredentialType = -1
var token = null
class UserLoginInfo extends BaseClass:
func _init():
super._init("UserLoginInfo")
var display_name: String
var nsa_id_token: String
class LoginOptions extends BaseClass:
func _init():
super._init("LoginOptions")
var credentials: Credentials
var user_login_info: UserLoginInfo
var client_data = null
class LogoutOptions extends BaseClass:
func _init():
super._init("LogoutOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class CopyIdTokenOptions extends BaseClass:
func _init():
super._init("CopyIdTokenOptions")
var local_user_id = EOSGRuntime.local_product_user_id
class CopyProductUserExternalAccountByAccountIdOptions extends BaseClass:
func _init():
super._init("CopyProductUserExternalAccountByAccountIdOptions")
var target_user_id = EOSGRuntime.local_product_user_id
var account_id: String
class CopyProductUserExternalAccountByAccountTypeOptions extends BaseClass:
func _init():
super._init("CopyProductUserExternalAccountByAccountTypeOptions")
var target_user_id = EOSGRuntime.local_product_user_id
var account_id_type: ExternalAccountType
class CopyProductUserExternalAccountByIndexOptions extends BaseClass:
func _init():
super._init("CopyProductUserExternalAccountByIndexOptions")
var target_user_id = EOSGRuntime.local_product_user_id
var external_account_info_index: int
class CopyProductUserInfoOptions extends BaseClass:
func _init():
super._init("CopyProductUserInfoOptions")
var target_user_id = EOSGRuntime.local_product_user_id
class CreateDeviceIdOptions extends BaseClass:
func _init():
super._init("CreateDeviceIdOptions")
var device_model: String
var client_data = null
class DeleteDeviceIdOptions extends BaseClass:
func _init():
super._init("DeleteDeviceIdOptions")
var client_data = null
class CreateUserOptions extends BaseClass:
func _init():
super._init("CreateUserOptions")
var continuance_token: EOSGContinuanceToken
var client_data = null
class QueryExternalAccountMappingsOptions extends BaseClass:
func _init():
super._init("QueryExternalAccountMappingsOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var account_id_type: ExternalAccountType
var external_account_ids: Array # Array[String]
class GetExternalAccountMappingsOptions extends BaseClass:
func _init():
super._init("GetExternalAccountMappingsOptions")
var account_id_type: ExternalAccountType
var local_user_id = EOSGRuntime.local_product_user_id
var target_external_user_id: String
class GetProductUserExternalAccountCountOptions extends BaseClass:
func _init():
super._init("GetProductUserExternalAccountCountOptions")
var target_user_id = EOSGRuntime.local_product_user_id
class QueryProductUserIdMappingsOptions extends BaseClass:
func _init():
super._init("QueryProductUserIdMappingsOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var product_user_ids: Array # Array[String]
class GetProductUserIdMappingOptions extends BaseClass:
func _init():
super._init("GetProductUserIdMappingOptions")
var account_id_type: ExternalAccountType
var local_user_id = EOSGRuntime.local_product_user_id
var target_product_user_id = EOSGRuntime.local_product_user_id
class LinkAccountOptions extends BaseClass:
func _init():
super._init("LinkAccountOptions")
var continuance_token = null # ContinuanceTokenWrapper
var local_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class IdToken extends BaseClass:
func _init():
super._init("IdToken")
var product_user_id: String
var json_web_token: String
class VerifyIdTokenOptions extends BaseClass:
func _init():
super._init("VerifyIdTokenOptions")
var id_token: IdToken
var client_data = null
class TransferDeviceIdAccountOptions extends BaseClass:
func _init():
super._init("TransferDeviceIdAccountOptions")
var primary_local_user_id = EOSGRuntime.local_product_user_id
var local_device_user_id = EOSGRuntime.local_product_user_id
var product_user_id_to_preserve: String
var client_data = null
class UnlinkAccountOptions extends BaseClass:
func _init():
super._init("UnlinkAccountOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class ConnectInterface:
static func login(options: LoginOptions) -> void:
IEOS.connect_interface_login(options)
static func logout(options: LogoutOptions) -> void:
IEOS.connect_interface_logout(options)
static func copy_id_token(options: CopyIdTokenOptions) -> Dictionary:
return IEOS.connect_interface_copy_id_token(options)
static func copy_product_user_external_account_by_account_id(options: CopyProductUserExternalAccountByAccountIdOptions) -> Dictionary:
return IEOS.connect_interface_copy_product_user_external_account_by_account_id(options)
static func copy_product_user_external_account_by_account_type(options: CopyProductUserExternalAccountByAccountTypeOptions) -> Dictionary:
return IEOS.connect_interface_copy_product_user_external_account_by_account_type(options)
static func copy_product_user_external_account_by_index(options: CopyProductUserExternalAccountByIndexOptions) -> Dictionary:
return IEOS.connect_interface_copy_product_user_external_account_by_index(options)
static func copy_product_user_info(options: CopyProductUserInfoOptions) -> Dictionary:
return IEOS.connect_interface_copy_product_user_info(options)
static func create_device_id(options: CreateDeviceIdOptions) -> void:
IEOS.connect_interface_create_device_id(options)
static func create_user(options: CreateUserOptions) -> void:
IEOS.connect_interface_create_user(options)
static func delete_device_id(options: DeleteDeviceIdOptions) -> void:
IEOS.connect_interface_delete_device_id(options)
static func query_external_account_mappings(options: QueryExternalAccountMappingsOptions) -> void:
IEOS.connect_interface_query_external_account_mappings(options)
static func get_external_account_mapping(options: GetExternalAccountMappingsOptions) -> String:
return IEOS.connect_interface_get_external_account_mapping(options)
static func get_logged_in_user_by_index(index: int) -> String:
return IEOS.connect_interface_get_logged_in_user_by_index(index)
static func get_logged_in_users_count() -> int:
return IEOS.connect_interface_get_logged_in_users_count()
static func get_login_status(local_user_id := EOSGRuntime.local_product_user_id) -> LoginStatus:
return IEOS.connect_interface_get_login_status(local_user_id)
static func get_product_user_external_account_count(options: GetProductUserExternalAccountCountOptions = GetProductUserExternalAccountCountOptions.new()) -> int:
return IEOS.connect_interface_get_product_user_external_account_count(options)
static func query_product_user_id_mappings(options: QueryProductUserIdMappingsOptions) -> void:
IEOS.connect_interface_query_product_user_id_mappings(options)
static func get_product_user_id_mapping(options: GetProductUserIdMappingOptions) -> Dictionary:
return IEOS.connect_interface_get_product_user_id_mapping(options)
static func link_account(options: LinkAccountOptions) -> void:
IEOS.connect_interface_link_account(options)
static func verify_id_token(options: VerifyIdTokenOptions) -> void:
IEOS.connect_interface_verify_id_token(options)
static func transfer_device_id_account(options: TransferDeviceIdAccountOptions) -> void:
IEOS.connect_interface_transfer_device_id_account(options)
static func unlink_account(options: UnlinkAccountOptions) -> void:
IEOS.connect_interface_unlink_account(options)
class Auth:
enum ScopeFlags {
NoFlags = 0x0,
BasicProfile = 0x1,
FriendsList = 0x2,
Presence = 0x4,
FriendsManagement = 0x8,
Email = 0x10,
Country = 0x20,
}
enum AuthTokenType {Client = 0, User = 1}
enum LinkAccountFlags {NoFlags = 0x0, NintendoNsaId = 0x1}
enum LoginCredentialType {
None = -1,
Password = 0,
ExchangeCode = 1,
PersistentAuth = 2,
DeviceCode = 3,
Developer = 4,
RefreshToken = 5,
AccountPortal = 6,
ExternalAuth = 7
}
enum LoginFlags {
None = 0,
NoUserInterface = 1
}
class Credentials extends BaseClass:
func _init():
super._init("Credentials")
var external_type: ExternalCredentialType = -1
var id: String
var token: String
var type: LoginCredentialType = -1
class LoginOptions extends BaseClass:
func _init():
super._init("LoginOptions")
var credentials: Credentials
var login_flags: LoginFlags = LoginFlags.None
var scope_flags: ScopeFlags = ScopeFlags.NoFlags
var client_data = null
class LogoutOptions extends BaseClass:
func _init():
super._init("LogoutOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var client_data = null
class CopyIdTokenOptions extends BaseClass:
func _init():
super._init("CopyIdTokenOptions")
var account_id = EOSGRuntime.local_epic_account_id
class CopyUserAuthTokenOptions extends BaseClass:
func _init():
super._init("CopyUserAuthTokenOptions")
class DeletePersistentAuthOptions extends BaseClass:
func _init():
super._init("DeletePersistentAuthOptions")
var refresh_token = null
var client_data = null
class LinkAccountOptions extends BaseClass:
func _init():
super._init("LinkAccountOptions")
var continuance_token: EOSGContinuanceToken
var link_account_flags: LinkAccountFlags = LinkAccountFlags.NoFlags
var local_user_id = EOSGRuntime.local_epic_account_id
var client_data = null
class QueryIdTokenOptions extends BaseClass:
func _init():
super._init("QueryIdTokenOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var target_account_id = EOSGRuntime.local_epic_account_id
var client_data = null
class IdToken extends BaseClass:
func _init():
super._init("IdToken")
var account_id: String
var json_web_token: String
class VerifyIdTokenOptions extends BaseClass:
func _init():
super._init("VerifyIdTokenOptions")
var id_token: IdToken
var client_data = null
class Token extends BaseClass:
func _init():
super._init("Token")
var access_token: String
var account_id: String
var app: String
var auth_type: int
var client_id: String
var expires_at: String
var expires_in: float
var refresh_expires_at: String
var refresh_expires_in: float
var refresh_token: String
class VerifyUserAuthOptions extends BaseClass:
func _init():
super._init("VerifyUserAuthOptions")
var auth_token: Token
var client_data = null
class AuthInterface:
static func login(options: LoginOptions) -> void:
IEOS.auth_interface_login(options)
static func logout(options: LogoutOptions) -> void:
IEOS.auth_interface_logout(options)
static func copy_id_token(options: CopyIdTokenOptions) -> Dictionary:
return IEOS.auth_interface_copy_id_token(options)
static func copy_user_auth_token(options: CopyUserAuthTokenOptions, local_user_id := EOSGRuntime.local_epic_account_id) -> Dictionary:
var func_result: Dictionary = IEOS.auth_interface_copy_user_auth_token(
options, local_user_id
)
var token: Token = Token.new()
if func_result.token:
var token_dict = func_result.token
token.access_token = token_dict.access_token
token.account_id = token_dict.account_id
token.app = token_dict.app
token.auth_type = token_dict.auth_type
token.client_id = token_dict.client_id
token.expires_at = token_dict.expires_at
token.expires_in = token_dict.expires_in
token.refresh_expires_at = token_dict.refresh_expires_at
token.refresh_expires_in = token_dict.refresh_expires_in
token.refresh_token = token_dict.refresh_token
return {result_code = func_result.result_code, token = token}
static func delete_persistent_auth(options: DeletePersistentAuthOptions) -> void:
IEOS.auth_interface_delete_persistent_auth(options)
static func get_logged_in_account_by_index(index: int) -> String:
return IEOS.auth_interface_get_logged_in_account_by_index(index)
static func get_logged_in_accounts_count() -> int:
return IEOS.auth_interface_get_logged_in_accounts_count()
static func get_login_status(local_user_id := EOSGRuntime.local_epic_account_id) -> LoginStatus:
return IEOS.auth_interface_get_login_status(local_user_id)
static func get_merged_account_by_index(local_user_id: String, index: int) -> String:
return IEOS.auth_interface_get_merged_account_by_index(local_user_id, index)
static func get_merged_accounts_count(local_user_id := EOSGRuntime.local_epic_account_id) -> int:
return IEOS.auth_interface_get_merged_accounts_count(local_user_id)
static func get_selected_account_id(local_user_id := EOSGRuntime.local_epic_account_id) -> Dictionary:
return IEOS.auth_interface_get_selected_account_id(local_user_id)
static func link_account(options: LinkAccountOptions) -> void:
IEOS.auth_interface_link_account(options)
static func query_id_token(options: QueryIdTokenOptions) -> void:
IEOS.auth_interface_query_id_token(options)
static func verify_id_token(options: VerifyIdTokenOptions) -> void:
IEOS.auth_interface_verify_id_token(options)
static func verify_user_auth(options: VerifyUserAuthOptions) -> void:
IEOS.auth_interface_verify_user_auth(options)
class CustomInvites:
enum ResquestToJoinResponse {
Accepted = 0,
Rejected = 1,
}
class SetCustomInviteOptions extends BaseClass:
func _init():
super._init("SetCustomInviteOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var payload: String
class SendCustomInviteOptions extends BaseClass:
func _init():
super._init("SendCustomInviteOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_ids: Array # Array[String]
var client_data = null
class FinalizeInviteOptions extends BaseClass:
func _init():
super._init("FinalizeInviteOptions")
var custom_invite_id: String
var local_user_id = EOSGRuntime.local_product_user_id
var processing_result: Result
var target_user_id: String
class SendRequestToJoinOptions extends BaseClass:
func _init():
super._init("SendRequestToJoinOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id: String
var client_data = null
class AcceptRequestToJoinOptions extends BaseClass:
func _init():
super._init("AcceptRequestToJoinOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id: String
var client_data = null
class RejectRequestToJoinOptions extends BaseClass:
func _init():
super._init("RejectRequestToJoinOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id: String
var client_data = null
class CustomInvitesInterface:
static func set_custom_invite(options: SetCustomInviteOptions) -> Result:
return IEOS.custom_invites_interface_set_custom_invite(options)
static func send_custom_invite(options: SendCustomInviteOptions) -> void:
IEOS.custom_invites_interface_send_custom_invite(options)
static func finalize_invite(options: FinalizeInviteOptions) -> Result:
return IEOS.custom_invites_interface_finalize_invite(options)
static func send_request_to_join(options: SendRequestToJoinOptions) -> void:
IEOS.custom_invites_interface_send_request_to_join(options)
static func accept_request_to_join(options: SendRequestToJoinOptions) -> void:
IEOS.custom_invites_interface_accept_request_to_join(options)
static func reject_request_to_join(options: SendRequestToJoinOptions) -> void:
IEOS.custom_invites_interface_reject_request_to_join(options)
class Stats:
const STATS_TIME_UNDEFINED = -1
class CopyStatByIndexOptions extends BaseClass:
func _init():
super._init("CopyStatByIndexOptions")
var target_user_id = EOSGRuntime.local_product_user_id
var stat_index: int
class CopyStatByNameOptions extends BaseClass:
func _init():
super._init("CopyStatByNameOptions")
var target_user_id = EOSGRuntime.local_product_user_id
var name: String
class GetStatsCountOptions extends BaseClass:
func _init():
super._init("GetStatsCountOptions")
var target_user_id = EOSGRuntime.local_product_user_id
class IngestStatOptions extends BaseClass:
func _init():
super._init("IngestStatOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var stats: Array # Array[Dictionary] {stat_name: String, ingest_amount: int}
var target_user_id = EOSGRuntime.local_product_user_id
var client_data = null
class QueryStatsOptions extends BaseClass:
func _init():
super._init("QueryStatsOptions")
var local_user_id = EOSGRuntime.local_product_user_id
var target_user_id = EOSGRuntime.local_product_user_id
var stat_names: Array # Array[String]
var start_time = STATS_TIME_UNDEFINED
var end_time = STATS_TIME_UNDEFINED
var client_data = null
class StatsInterface:
static func copy_stat_by_index(options: CopyStatByIndexOptions) -> Dictionary:
return IEOS.stats_interface_copy_stat_by_index(options)
static func copy_stat_by_name(options: CopyStatByNameOptions) -> Dictionary:
return IEOS.stats_interface_copy_stat_by_name(options)
static func get_stats_count(options: GetStatsCountOptions) -> int:
return IEOS.stats_interface_get_stats_count(options)
static func ingest_stat(options: IngestStatOptions) -> void:
IEOS.stats_interface_ingest_stat(options)
static func query_stats(options: QueryStatsOptions) -> void:
IEOS.stats_interface_query_stats(options)
class Platform:
enum PlatformFlags {
None = 0x0,
LoadingInEditor = 0x00001,
DisableOverlay = 0x00002,
DisableSocialOverlay = 0x00004,
Reserved1 = 0x00008,
WindowsEnableOverlayD3D9 = 0x00010,
WindowsEnableOverlayD3D10 = 0x00020,
WindowsEnableOverlayOpengl = 0x00040,
ConsoleEnableOverlayAutomaticUnloading = 0x00080,
}
enum ApplicationStatus {
BackgroundConstrained = 0,
BackgroundUnconstrained = 1,
BackgroundSuspended = 2,
Foreground = 3
}
enum NetworkStatus {
Disabled = 0,
Offline = 1,
Online = 2
}
enum DesktopCrossplayStatus {
OK = 0,
ApplicationNotBootstrapped = 1,
ServiceNotInstalled = 2,
ServiceStartFailed = 3,
ServiceNotRunning = 4,
OverlayDisabled = 5,
OverlayNotInstalled = 6,
OverlayTrustCheckFailed = 7,
OverlayLoadFailed = 8
}
enum RTCBackgroundMode {
LeaveRooms = 0,
KeepRoomsAlive = 1,
}
class InitializeOptions extends BaseClass:
func _init():
super._init("InitializeOptions")
var product_name: String
var product_version: String
class RTCOptions extends BaseClass:
func _init():
super._init("RTCOptions")
var background_mode = null ## See [enum EOS.Platform.RTCBackgroundMode]
class CreateOptions extends BaseClass:
func _init():
super._init("CreateOptions")
var client_id: String
var client_secret: String
var deployment_id: String
var encryption_key: String
var product_id: String
var sandbox_id: String
var cache_directory = ProjectSettings.globalize_path("user://eosg-cache")
var flags: int = 0 ## See [enum EOS.Platform.PlatformFlags]
var is_server: bool
var override_country_code: String
var override_locale_code: String
var tick_budget_in_milliseconds: int
var task_network_timeout_seconds = null # float
var rtc_options := RTCOptions.new()
class PlatformInterface:
static func create(options: CreateOptions) -> bool:
return IEOS.platform_interface_create(options)
static func get_active_country_code(user_id: String) -> Dictionary:
return IEOS.platform_interface_get_active_country_code(user_id)
static func get_active_locale_code(user_id: String) -> Dictionary:
return IEOS.platform_interface_get_active_locale_code(user_id)
static func get_override_country_code() -> Dictionary:
return IEOS.platform_interface_get_override_country_code()
static func get_override_locale_code() -> Dictionary:
return IEOS.platform_interface_get_override_locale_code()
static func set_override_country_code(country_code: String) -> Result:
return IEOS.platform_interface_set_override_country_code(country_code)
static func set_override_locale_code(locale_code: String) -> Result:
return IEOS.platform_interface_set_override_locale_code(locale_code)
static func check_for_launcher_and_restart() -> Result:
return IEOS.platform_interface_check_for_launcher_and_restart()
static func initialize(options: InitializeOptions) -> Result:
return IEOS.platform_interface_initialize(options)
static func get_desktop_crossplay_status_info() -> Dictionary:
return IEOS.platform_interface_get_desktop_crossplay_status_info()
static func set_application_status(status: ApplicationStatus) -> Result:
return IEOS.platform_interface_set_application_status(status)
static func get_application_status() -> ApplicationStatus:
return IEOS.platform_interface_get_application_status()
static func set_network_status(status: NetworkStatus) -> Result:
return IEOS.platform_interface_set_network_status(status)
static func get_network_status() -> NetworkStatus:
return IEOS.platform_interface_get_network_status()
static func release() -> void:
IEOS.platform_interface_release()
static func shutdown() -> Result:
return IEOS.platform_interface_shutdown()
class Ecom:
enum ItemType {
## This entitlement is intended to persist.
Durable = 0,
## This entitlement is intended to be transient and redeemed.
Consumable = 1,
## This entitlement has a type that is not currently intended for an in-game store.
Other = 2
}
enum OwnershipStatus {
## The catalog item is not owned by the local user
NotOwned = 0,
## The catalog item is owned by the local user
Owned = 1
}
enum CheckoutOrientation {
## Current orientation will be used
Default = 0,
## Portrait orientation
Portrait = 1,
## Landscape orientation
Landscape = 2
}
class CheckoutOptions extends BaseClass:
func _init():
super._init("CheckoutOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entries: Array # Array[Dictionary] {offer_id: String}
var override_catalog_namespace: String
var preferred_orientation = CheckoutOrientation.Default
class CopyEntitlementByIdOptions extends BaseClass:
func _init():
super._init("CopyEntitlementByIdOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_id: String
class CopyEntitlementByIndexOptions extends BaseClass:
func _init():
super._init("CopyEntitlementByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_index: int
class CopyEntitlementByNameAndIndexOptions extends BaseClass:
func _init():
super._init("CopyEntitlementByNameAndIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_name: String
var index: int
class CopyItemByIdOptions extends BaseClass:
func _init():
super._init("CopyItemByIdOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
class CopyItemImageInfoByIndexOptions extends BaseClass:
func _init():
super._init("CopyItemImageInfoByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
var image_info_index: int
class CopyItemReleaseByIndexOptions extends BaseClass:
func _init():
super._init("CopyItemReleaseByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
var release_index: int
class CopyOfferByIdOptions extends BaseClass:
func _init():
super._init("CopyOfferByIdOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_id: String
class CopyOfferByIndexOptions extends BaseClass:
func _init():
super._init("CopyOfferByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_index: int
class CopyOfferImageInfoByIndexOptions extends BaseClass:
func _init():
super._init("CopyOfferImageInfoByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_id: String
var image_info_index: int
class CopyOfferItemByIndexOptions extends BaseClass:
func _init():
super._init("CopyOfferItemByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_id: String
var item_index: int
class CopyTransactionByIdOptions extends BaseClass:
func _init():
super._init("CopyTransactionByIdOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var transaction_id: String
class CopyTransactionByIndexOptions extends BaseClass:
func _init():
super._init("CopyTransactionByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var transaction_index: int
class GetEntitlementsByNameCountOptions extends BaseClass:
func _init():
super._init("GetEntitlementsByNameCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_name: String
class GetEntitlementsCountOptions extends BaseClass:
func _init():
super._init("GetEntitlementsCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
class GetItemImageInfoCountOptions extends BaseClass:
func _init():
super._init("GetItemImageInfoCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
class GetItemReleaseCountOptions extends BaseClass:
func _init():
super._init("GetItemReleaseCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var item_id: String
class GetOfferCountOptions extends BaseClass:
func _init():
super._init("GetOfferCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
class GetOfferImageInfoCountOptions extends BaseClass:
func _init():
super._init("GetOfferImageInfoCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_id: String
class GetOfferItemCountOptions extends BaseClass:
func _init():
super._init("GetOfferItemCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var offer_id: String
class GetTransactionCountOptions extends BaseClass:
func _init():
super._init("GetTransactionCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
class QueryEntitlementsOptions extends BaseClass:
func _init():
super._init("QueryEntitlementsOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_names: Array # Array[String]
var include_redeemed: bool
var override_catalog_namespace: String
class QueryOffersOptions extends BaseClass:
func _init():
super._init("QueryOffersOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var override_catalog_namespace: String
var client_data = null
class QueryOwnershipOptions extends BaseClass:
func _init():
super._init("QueryOwnershipOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var catalog_item_ids: Array # Array[String]
var catalog_namespace: String
var client_data = null
class QueryOwnershipTokenOptions extends BaseClass:
func _init():
super._init("QueryOwnershipTokenOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var catalog_item_ids: Array # Array[String]
var catalog_namespace = null # String
var client_data = null
class RedeemEntitlementsOptions extends BaseClass:
func _init():
super._init("RedeemEntitlementsOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var entitlement_ids: Array # Array[String]
var client_data = null
class GetLastRedeemedEntitlementsCountOptions extends BaseClass:
func _init():
super._init("GetLastRedeemedEntitlementsCountOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
class CopyLastRedeemedEntitlementByIndexOptions extends BaseClass:
func _init():
super._init("CopyLastRedeemedEntitlementByIndexOptions")
var local_user_id = EOSGRuntime.local_epic_account_id
var redeemed_entitlement_index: String
class EcomInterface:
static func checkout(options: CheckoutOptions) -> void:
IEOS.ecom_interface_checkout(options)
static func copy_entitlement_by_id(options: CopyEntitlementByIdOptions) -> Dictionary:
return IEOS.ecom_interface_copy_entitlement_by_id(options)
static func copy_entitlement_by_index(options: CopyEntitlementByIndexOptions) -> Dictionary:
return IEOS.ecom_interface_copy_entitlement_by_index(options)
static func copy_entitlement_by_name_and_index(options: CopyEntitlementByNameAndIndexOptions) -> Dictionary:
return IEOS.ecom_interface_copy_entitlement_by_name_and_index(options)
static func copy_item_by_id(options: CopyItemByIdOptions) -> Dictionary:
return IEOS.ecom_interface_copy_item_by_id(options)
static func copy_item_image_
gitextract_ngm7nid4/
├── .clang-format
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ ├── build.yml
│ └── deploy-docs.yml
├── .gitignore
├── .gitmodules
├── .pre-commit-config.yaml
├── .vscode/
│ ├── c_cpp_properties.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── LICENSE.md
├── README.md
├── SConstruct
├── build-ios.sh
├── debug-entitlements.plist
├── debug.cmd
├── debug.sh
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── bun.lockb
│ ├── docs/
│ │ ├── installation.md
│ │ ├── introduction.md
│ │ ├── sample-project.md
│ │ ├── topics/
│ │ │ ├── authentication.md
│ │ │ └── initialization.md
│ │ └── update-guide.md
│ ├── docusaurus.config.ts
│ ├── package.json
│ ├── postcss.config.js
│ ├── sidebars.ts
│ ├── src/
│ │ ├── components/
│ │ │ ├── ExampleSection.tsx
│ │ │ ├── FeaturesSection.tsx
│ │ │ ├── HeroSection.tsx
│ │ │ ├── Icons.tsx
│ │ │ ├── InfoSections.tsx
│ │ │ ├── Layout.tsx
│ │ │ ├── MainSystemsSection.tsx
│ │ │ ├── MediaSections.tsx
│ │ │ └── SupportSection.tsx
│ │ ├── css/
│ │ │ └── custom.css
│ │ ├── pages/
│ │ │ ├── index.tsx
│ │ │ └── showcase.md
│ │ └── plugins/
│ │ └── tailwind-config.ts
│ ├── static/
│ │ └── .nojekyll
│ └── tsconfig.json
├── function_analyzer.py
├── sample/
│ ├── .gitignore
│ ├── AntiCheatServerMain.gd
│ ├── AntiCheatServerMain.gd.uid
│ ├── Main.gd
│ ├── Main.gd.uid
│ ├── Main.tscn
│ ├── addons/
│ │ └── epic-online-services-godot/
│ │ ├── base_class.gd
│ │ ├── base_class.gd.uid
│ │ ├── bin/
│ │ │ └── .gitignore
│ │ ├── dataclass.gd
│ │ ├── dataclass.gd.uid
│ │ ├── eos.gd
│ │ ├── eos.gd.uid
│ │ ├── eosg.gdextension
│ │ ├── eosg.gdextension.uid
│ │ ├── export_plugin.gd
│ │ ├── export_plugin.gd.uid
│ │ ├── heos/
│ │ │ ├── hachievement_data.gd
│ │ │ ├── hachievement_data.gd.uid
│ │ │ ├── hachievements.gd
│ │ │ ├── hachievements.gd.uid
│ │ │ ├── hauth.gd
│ │ │ ├── hauth.gd.uid
│ │ │ ├── hcredentials.gd
│ │ │ ├── hcredentials.gd.uid
│ │ │ ├── hfriends.gd
│ │ │ ├── hfriends.gd.uid
│ │ │ ├── hleaderboards.gd
│ │ │ ├── hleaderboards.gd.uid
│ │ │ ├── hlobbies.gd
│ │ │ ├── hlobbies.gd.uid
│ │ │ ├── hlobby.gd
│ │ │ ├── hlobby.gd.uid
│ │ │ ├── hlobbymember.gd
│ │ │ ├── hlobbymember.gd.uid
│ │ │ ├── hlog.gd
│ │ │ ├── hlog.gd.uid
│ │ │ ├── hp2p.gd
│ │ │ ├── hp2p.gd.uid
│ │ │ ├── hplatform.gd
│ │ │ ├── hplatform.gd.uid
│ │ │ ├── hsessions.gd
│ │ │ ├── hsessions.gd.uid
│ │ │ ├── hstats.gd
│ │ │ └── hstats.gd.uid
│ │ ├── plugin.cfg
│ │ ├── plugin.gd
│ │ ├── plugin.gd.uid
│ │ ├── runtime.gd
│ │ └── runtime.gd.uid
│ ├── components/
│ │ └── StyledPopupWindow/
│ │ ├── StyledPopupWindow.gd
│ │ ├── StyledPopupWindow.gd.uid
│ │ ├── StyledPopupWindow.tscn
│ │ └── StyledPopupWindowTheme.tres
│ ├── dedicated_server_example/
│ │ ├── client_main.gd
│ │ ├── client_main.gd.uid
│ │ ├── client_main.tscn
│ │ ├── server_main.gd
│ │ ├── server_main.gd.uid
│ │ └── server_main.tscn
│ ├── default_bus_layout.tres
│ ├── default_env.tres
│ ├── fonts/
│ │ ├── roboto-13r.tres
│ │ ├── roboto-16b.tres
│ │ ├── roboto-16r.tres
│ │ └── roboto-32b.tres
│ ├── game/
│ │ ├── entities/
│ │ │ ├── bullet/
│ │ │ │ ├── bullet.gd
│ │ │ │ ├── bullet.gd.uid
│ │ │ │ └── bullet.tscn
│ │ │ ├── player/
│ │ │ │ ├── player.gd
│ │ │ │ ├── player.gd.uid
│ │ │ │ └── player.tscn
│ │ │ └── wall/
│ │ │ └── wall.tscn
│ │ └── maps/
│ │ ├── map_bellandur.tscn
│ │ ├── map_margao.tscn
│ │ └── map_new_york.tscn
│ ├── project.godot
│ ├── scenes/
│ │ ├── AchievementsView/
│ │ │ ├── AchievementPopup.gd
│ │ │ ├── AchievementPopup.gd.uid
│ │ │ ├── AchievementUnlockNotification.gd
│ │ │ ├── AchievementUnlockNotification.gd.uid
│ │ │ ├── AchievementUnlockNotification.tscn
│ │ │ ├── AchievementsList.gd
│ │ │ ├── AchievementsList.gd.uid
│ │ │ ├── AchievementsListAchievement.gd
│ │ │ ├── AchievementsListAchievement.gd.uid
│ │ │ ├── AchievementsListAchievement.tscn
│ │ │ ├── AchievementsView.gd
│ │ │ ├── AchievementsView.gd.uid
│ │ │ └── AchievementsView.tscn
│ │ ├── CustomInvitesView/
│ │ │ ├── CustomInvitesView.gd
│ │ │ ├── CustomInvitesView.gd.uid
│ │ │ └── CustomInvitesView.tscn
│ │ ├── FriendsView/
│ │ │ ├── FriendsView.gd
│ │ │ ├── FriendsView.gd.uid
│ │ │ └── FriendsView.tscn
│ │ ├── LeaderboardsView/
│ │ │ ├── LeaderboardsView.gd
│ │ │ ├── LeaderboardsView.gd.uid
│ │ │ └── LeaderboardsView.tscn
│ │ ├── LobbiesView/
│ │ │ ├── CreateLobbyPopup.gd
│ │ │ ├── CreateLobbyPopup.gd.uid
│ │ │ ├── CreateLobbyPopup.tscn
│ │ │ ├── CurrentLobby.gd
│ │ │ ├── CurrentLobby.gd.uid
│ │ │ ├── LobbiesView.gd
│ │ │ ├── LobbiesView.gd.uid
│ │ │ ├── LobbiesView.tscn
│ │ │ ├── SearchLobby.gd
│ │ │ ├── SearchLobby.gd.uid
│ │ │ ├── SearchLobbyResults.gd
│ │ │ └── SearchLobbyResults.gd.uid
│ │ ├── LoginView/
│ │ │ ├── EnterCredentials.gd
│ │ │ ├── EnterCredentials.gd.uid
│ │ │ ├── LoginView.gd
│ │ │ ├── LoginView.gd.uid
│ │ │ └── LoginView.tscn
│ │ ├── LogsView/
│ │ │ ├── LogsView.gd
│ │ │ ├── LogsView.gd.uid
│ │ │ └── LogsView.tscn
│ │ ├── MetricsView/
│ │ │ ├── MetricsView.gd
│ │ │ ├── MetricsView.gd.uid
│ │ │ └── MetricsView.tscn
│ │ ├── NotificationsView/
│ │ │ ├── NotificationsView.gd
│ │ │ └── NotificationsView.gd.uid
│ │ ├── StatsView/
│ │ │ ├── StatsView.gd
│ │ │ ├── StatsView.gd.uid
│ │ │ └── StatsView.tscn
│ │ ├── UI/
│ │ │ ├── NetworkImage.gd
│ │ │ ├── NetworkImage.gd.uid
│ │ │ ├── NetworkImage.tscn
│ │ │ ├── PrimaryButton.tscn
│ │ │ ├── joysticks.gd
│ │ │ ├── joysticks.gd.uid
│ │ │ ├── nat_type.gd
│ │ │ ├── nat_type.gd.uid
│ │ │ ├── nat_type.tscn
│ │ │ ├── ping.gd
│ │ │ ├── ping.gd.uid
│ │ │ ├── ping.tscn
│ │ │ ├── players_score.gd
│ │ │ ├── players_score.gd.uid
│ │ │ ├── players_score.tscn
│ │ │ ├── touch_screen_joystick.gd
│ │ │ └── touch_screen_joystick.gd.uid
│ │ └── UIView/
│ │ ├── UIView.gd
│ │ ├── UIView.gd.uid
│ │ └── UIView.tscn
│ ├── scripts/
│ │ ├── Env.gd
│ │ ├── Env.gd.uid
│ │ ├── Store.gd
│ │ ├── Store.gd.uid
│ │ ├── ViewManager.gd
│ │ ├── ViewManager.gd.uid
│ │ ├── network.gd
│ │ └── network.gd.uid
│ ├── styles/
│ │ └── ViewTitleLabelSettings.tres
│ ├── test.gd
│ ├── test.gd.uid
│ ├── test_manual_audio_output.gd
│ └── test_manual_audio_output.gd.uid
├── src/
│ ├── achievements_interface.cpp
│ ├── anticheat_client_interface.cpp
│ ├── anticheat_server_interface.cpp
│ ├── auth_interface.cpp
│ ├── connect_interface.cpp
│ ├── custom_invites_interface.cpp
│ ├── ecom_interface.cpp
│ ├── eosg_active_session.cpp
│ ├── eosg_active_session.h
│ ├── eosg_continuance_token.h
│ ├── eosg_file_transfer_request.h
│ ├── eosg_lobby_details.cpp
│ ├── eosg_lobby_details.h
│ ├── eosg_lobby_modification.cpp
│ ├── eosg_lobby_modification.h
│ ├── eosg_lobby_search.cpp
│ ├── eosg_lobby_search.h
│ ├── eosg_multiplayer_peer.cpp
│ ├── eosg_multiplayer_peer.h
│ ├── eosg_packet_peer_mediator.cpp
│ ├── eosg_packet_peer_mediator.h
│ ├── eosg_playerdatastorage_file_transfer_request.cpp
│ ├── eosg_playerdatastorage_file_transfer_request.h
│ ├── eosg_presence_modification.cpp
│ ├── eosg_presence_modification.h
│ ├── eosg_session_details.cpp
│ ├── eosg_session_details.h
│ ├── eosg_session_modification.cpp
│ ├── eosg_session_modification.h
│ ├── eosg_session_search.cpp
│ ├── eosg_session_search.h
│ ├── eosg_titlestorage_file_transfer_request.cpp
│ ├── eosg_titlestorage_file_transfer_request.h
│ ├── eosg_transaction.cpp
│ ├── eosg_transaction.h
│ ├── friends_interface.cpp
│ ├── ieos.cpp
│ ├── ieos.h
│ ├── kws_interface.cpp
│ ├── leaderboards_interface.cpp
│ ├── lobby_interface.cpp
│ ├── logging_interface.cpp
│ ├── metrics_interface.cpp
│ ├── mods_interface.cpp
│ ├── p2p_interface.cpp
│ ├── platform_interface.cpp
│ ├── playerdatastorage_interface.cpp
│ ├── presence_interface.cpp
│ ├── progression_snapshot_interface.cpp
│ ├── register_types.cpp
│ ├── register_types.h
│ ├── reports_interface.cpp
│ ├── rtc_audio_interface.cpp
│ ├── rtc_data_interface.cpp
│ ├── rtc_interface.cpp
│ ├── sanctions_interface.cpp
│ ├── sessions_interface.cpp
│ ├── stats_interface.cpp
│ ├── titlestorage_interface.cpp
│ ├── ui_interface.cpp
│ ├── user_info_interface.cpp
│ ├── utils.cpp
│ ├── utils.h
│ └── version_interface.cpp
└── thirdparty/
└── Paste the EOS C SDK here as eos-sdk
SYMBOL INDEX (257 symbols across 64 files)
FILE: docs/src/components/ExampleSection.tsx
function ExampleSection (line 68) | function ExampleSection() {
FILE: docs/src/components/FeaturesSection.tsx
constant FEATURES (line 1) | const FEATURES = [
constant HIGH_LEVEL_CLASSES (line 18) | const HIGH_LEVEL_CLASSES = [
function FeaturesSection (line 30) | function FeaturesSection() {
function HighLevelSection (line 65) | function HighLevelSection() {
FILE: docs/src/components/HeroSection.tsx
constant VERSIONS (line 4) | const VERSIONS = [
constant PLATFORMS (line 9) | const PLATFORMS = [
constant HERO_ACTIONS (line 17) | const HERO_ACTIONS = [
function HeroSection (line 31) | function HeroSection() {
FILE: docs/src/components/Icons.tsx
function GodotIcon (line 1) | function GodotIcon({ className = "w-4 h-4" }) {
function EpicIcon (line 16) | function EpicIcon({ className = "w-4 h-4" }) {
FILE: docs/src/components/InfoSections.tsx
function HowItWorksSection (line 1) | function HowItWorksSection() {
function InstallationSection (line 22) | function InstallationSection() {
FILE: docs/src/components/Layout.tsx
constant NAV_LINKS (line 4) | const NAV_LINKS = [
function NavBar (line 40) | function NavBar() {
function Footer (line 139) | function Footer() {
FILE: docs/src/components/MainSystemsSection.tsx
constant MAIN_SYSTEMS (line 1) | const MAIN_SYSTEMS = [
function MainSystemsSection (line 62) | function MainSystemsSection() {
FILE: docs/src/components/MediaSections.tsx
constant SCREENSHOTS_DATA (line 1) | const SCREENSHOTS_DATA = [
constant TUTORIALS_DATA (line 44) | const TUTORIALS_DATA = {
function ScreenshotsSection (line 51) | function ScreenshotsSection() {
function DemoSection (line 91) | function DemoSection() {
FILE: docs/src/components/SupportSection.tsx
constant SUPPORT_DATA (line 1) | const SUPPORT_DATA = {
function SupportSection (line 8) | function SupportSection() {
FILE: docs/src/pages/index.tsx
function App (line 8) | function App() {
FILE: docs/src/plugins/tailwind-config.ts
method configurePostCss (line 4) | configurePostCss(postcssOptions) {
FILE: function_analyzer.py
function extract_function_names (line 8) | def extract_function_names(sdk_path):
function find_function_calls (line 25) | def find_function_calls(src_path, function_names):
function main (line 42) | def main():
FILE: src/achievements_interface.cpp
function Dictionary (line 5) | Dictionary IEOS::achievements_interface_copy_achievement_definition_v2_b...
function Dictionary (line 23) | Dictionary IEOS::achievements_interface_copy_achievement_definition_v2_b...
function Dictionary (line 39) | Dictionary IEOS::achievements_interface_copy_player_achievement_by_achie...
function Dictionary (line 61) | Dictionary IEOS::achievements_interface_copy_player_achievement_by_index...
FILE: src/anticheat_client_interface.cpp
function Dictionary (line 51) | Dictionary IEOS::anticheat_client_interface_get_protect_message_output_l...
function Dictionary (line 74) | Dictionary IEOS::anticheat_client_interface_protect_message(Ref<RefCount...
function Dictionary (line 107) | Dictionary IEOS::anticheat_client_interface_unprotect_message(Ref<RefCou...
FILE: src/anticheat_server_interface.cpp
function Dictionary (line 123) | Dictionary IEOS::anticheat_server_interface_get_protect_message_output_l...
function Dictionary (line 146) | Dictionary IEOS::anticheat_server_interface_protect_message(Ref<RefCount...
function Dictionary (line 179) | Dictionary IEOS::anticheat_server_interface_unprotect_message(Ref<RefCou...
FILE: src/auth_interface.cpp
function Dictionary (line 79) | Dictionary IEOS::auth_interface_copy_id_token(Ref<RefCounted> p_options) {
function Dictionary (line 97) | Dictionary IEOS::auth_interface_copy_user_auth_token(Ref<RefCounted> p_o...
function String (line 139) | String IEOS::auth_interface_get_logged_in_account_by_index(int index) {
function String (line 157) | String IEOS::auth_interface_get_merged_account_by_index(const String &p_...
function Dictionary (line 172) | Dictionary IEOS::auth_interface_get_selected_account_id(const String &p_...
FILE: src/connect_interface.cpp
function Dictionary (line 94) | Dictionary IEOS::connect_interface_copy_id_token(Ref<RefCounted> p_optio...
function Dictionary (line 112) | Dictionary IEOS::connect_interface_copy_product_user_external_account_by...
function Dictionary (line 133) | Dictionary IEOS::connect_interface_copy_product_user_external_account_by...
function Dictionary (line 153) | Dictionary IEOS::connect_interface_copy_product_user_external_account_by...
function Dictionary (line 172) | Dictionary IEOS::connect_interface_copy_product_user_info(Ref<RefCounted...
function String (line 251) | String IEOS::connect_interface_get_external_account_mapping(Ref<RefCount...
function String (line 267) | String IEOS::connect_interface_get_logged_in_user_by_index(int p_index) {
function Dictionary (line 297) | Dictionary IEOS::connect_interface_get_product_user_id_mapping(Ref<RefCo...
FILE: src/ecom_interface.cpp
function Dictionary (line 46) | Dictionary IEOS::ecom_interface_copy_entitlement_by_id(Ref<RefCounted> p...
function Dictionary (line 65) | Dictionary IEOS::ecom_interface_copy_entitlement_by_index(Ref<RefCounted...
function Dictionary (line 83) | Dictionary IEOS::ecom_interface_copy_entitlement_by_name_and_index(Ref<R...
function Dictionary (line 103) | Dictionary IEOS::ecom_interface_copy_item_by_id(Ref<RefCounted> p_option...
function Dictionary (line 122) | Dictionary IEOS::ecom_interface_copy_item_image_info_by_index(Ref<RefCou...
function Dictionary (line 143) | Dictionary IEOS::ecom_interface_copy_item_release_by_index(Ref<RefCounte...
function Dictionary (line 164) | Dictionary IEOS::ecom_interface_copy_offer_by_id(Ref<RefCounted> p_optio...
function Dictionary (line 183) | Dictionary IEOS::ecom_interface_copy_offer_by_index(Ref<RefCounted> p_op...
function Dictionary (line 202) | Dictionary IEOS::ecom_interface_copy_offer_image_info_by_index(Ref<RefCo...
function Dictionary (line 223) | Dictionary IEOS::ecom_interface_copy_offer_item_by_index(Ref<RefCounted>...
function Dictionary (line 244) | Dictionary IEOS::ecom_interface_copy_transaction_by_id(Ref<RefCounted> p...
function Dictionary (line 263) | Dictionary IEOS::ecom_interface_copy_transaction_by_index(Ref<RefCounted...
function Dictionary (line 581) | Dictionary IEOS::ecom_interface_copy_last_redeemed_entitlement_by_index(...
FILE: src/eosg_active_session.cpp
function Dictionary (line 12) | Dictionary EOSGActiveSession::copy_info() {
function String (line 36) | String EOSGActiveSession::get_registered_player_by_index(int p_player_in...
FILE: src/eosg_active_session.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_continuance_token.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_file_transfer_request.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_lobby_details.cpp
function String (line 21) | String EOSGLobbyDetails::get_lobby_owner() {
function Dictionary (line 29) | Dictionary EOSGLobbyDetails::copy_info() {
function Dictionary (line 52) | Dictionary EOSGLobbyDetails::copy_attribute_by_index(int p_index) {
function Dictionary (line 68) | Dictionary EOSGLobbyDetails::copy_attribute_by_key(const String &p_key) {
function String (line 94) | String EOSGLobbyDetails::get_member_by_index(int p_index) {
function Dictionary (line 115) | Dictionary EOSGLobbyDetails::copy_member_attribute_by_index(const String...
function Dictionary (line 134) | Dictionary EOSGLobbyDetails::copy_member_attribute_by_key(const String &...
function Dictionary (line 154) | Dictionary EOSGLobbyDetails::copy_member_info(const String &p_target_use...
FILE: src/eosg_lobby_details.h
function namespace (line 6) | namespace godot {
FILE: src/eosg_lobby_modification.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_lobby_search.cpp
function Dictionary (line 124) | Dictionary EOSGLobbySearch::copy_search_result_by_index(int p_index) {
FILE: src/eosg_lobby_search.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_multiplayer_peer.cpp
function Error (line 66) | Error EOSGMultiplayerPeer::create_server(const String &socket_id) {
function Error (line 102) | Error EOSGMultiplayerPeer::create_client(const String &socket_id, const ...
function Error (line 152) | Error EOSGMultiplayerPeer::create_mesh(const String &socket_id) {
function Error (line 186) | Error EOSGMultiplayerPeer::add_mesh_peer(const String &remote_user_id) {
function String (line 208) | String EOSGMultiplayerPeer::get_socket() const {
function Array (line 217) | Array EOSGMultiplayerPeer::get_all_connection_requests() {
function String (line 232) | String EOSGMultiplayerPeer::get_peer_user_id(int p_id) {
function Dictionary (line 307) | Dictionary EOSGMultiplayerPeer::get_all_peers() {
function Error (line 466) | Error EOSGMultiplayerPeer::_get_packet(const uint8_t **r_buffer, int32_t...
function Error (line 486) | Error EOSGMultiplayerPeer::_put_packet(const uint8_t *p_buffer, int32_t ...
function String (line 853) | String EOSGMultiplayerPeer::get_local_user_id() {
function Error (line 868) | Error EOSGMultiplayerPeer::_broadcast(const EOSGPacket &packet, int excl...
function Error (line 905) | Error EOSGMultiplayerPeer::_send_to(const EOS_ProductUserId &remote_peer...
function EOS_EPacketReliability (line 956) | EOS_EPacketReliability EOSGMultiplayerPeer::_convert_transfer_mode_to_eo...
FILE: src/eosg_multiplayer_peer.h
function namespace (line 9) | namespace godot {
FILE: src/eosg_packet_peer_mediator.h
function namespace (line 7) | namespace godot {
function size (line 25) | int size() {
function get_channel (line 29) | int get_channel() {
function String (line 33) | String get_sender() {
function set_channel (line 37) | void set_channel(int channel) {
function set_sender (line 41) | void set_sender(EOS_ProductUserId sender) {
function PackedByteArray (line 45) | PackedByteArray *get_data() {
function class (line 50) | class EOSGPacketPeerMediator : public Object {
function get_packet_count_for_socket (line 98) | int get_packet_count_for_socket(const String &socket_id) {
function Array (line 103) | Array get_sockets() {
FILE: src/eosg_playerdatastorage_file_transfer_request.cpp
function Dictionary (line 20) | Dictionary EOSGPlayerDataStorageFileTransferRequest::get_filename() {
FILE: src/eosg_playerdatastorage_file_transfer_request.h
function namespace (line 6) | namespace godot {
FILE: src/eosg_presence_modification.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_session_details.cpp
function Dictionary (line 12) | Dictionary EOSGSessionDetails::copy_info() {
function Dictionary (line 27) | Dictionary EOSGSessionDetails::copy_session_attribute_by_index(int p_att...
function Dictionary (line 43) | Dictionary EOSGSessionDetails::copy_session_attribute_by_key(const Strin...
FILE: src/eosg_session_details.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_session_modification.h
function namespace (line 4) | namespace godot {
FILE: src/eosg_session_search.cpp
function Dictionary (line 17) | Dictionary EOSGSessionSearch::copy_search_result_by_index(int p_index) {
FILE: src/eosg_session_search.h
function namespace (line 5) | namespace godot {
FILE: src/eosg_titlestorage_file_transfer_request.cpp
function Dictionary (line 20) | Dictionary EOSGTitleStorageFileTransferRequest::get_filename() {
FILE: src/eosg_titlestorage_file_transfer_request.h
function namespace (line 6) | namespace godot {
FILE: src/eosg_transaction.cpp
function String (line 13) | String EOSGTransaction::get_id() {
function Dictionary (line 30) | Dictionary EOSGTransaction::copy_entitlement_by_index(int p_entitlement_...
FILE: src/eosg_transaction.h
function namespace (line 5) | namespace godot {
FILE: src/friends_interface.cpp
function String (line 28) | String IEOS::friends_interface_get_friend_at_index(Ref<RefCounted> p_opt...
function String (line 148) | String IEOS::friends_interface_get_blocked_user_at_index(Ref<RefCounted>...
FILE: src/ieos.cpp
function IEOS (line 534) | IEOS *IEOS::get_singleton() { return singleton; }
FILE: src/ieos.h
function namespace (line 45) | namespace godot {
FILE: src/kws_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::kws_interface_copy_permission_by_index(Ref<RefCounted> ...
function Dictionary (line 50) | Dictionary IEOS::kws_interface_get_permission_by_key(Ref<RefCounted> p_o...
FILE: src/leaderboards_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_definition_by_i...
function Dictionary (line 20) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_definition_by_l...
function Dictionary (line 37) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_record_by_index...
function Dictionary (line 53) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_record_by_user_...
function Dictionary (line 71) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_user_score_by_i...
function Dictionary (line 90) | Dictionary IEOS::leaderboards_interface_copy_leaderboard_user_score_by_u...
FILE: src/lobby_interface.cpp
function Dictionary (line 229) | Dictionary IEOS::lobby_interface_update_lobby_modification(Ref<RefCounte...
function Dictionary (line 435) | Dictionary IEOS::lobby_interface_get_invite_id_by_index(Ref<RefCounted> ...
function Dictionary (line 455) | Dictionary IEOS::lobby_interface_create_lobby_search(Ref<RefCounted> p_o...
function Dictionary (line 471) | Dictionary IEOS::lobby_interface_copy_lobby_details_by_invite_id(Ref<Ref...
function Dictionary (line 489) | Dictionary IEOS::lobby_interface_copy_lobby_details_by_ui_event_id(Ref<R...
function Dictionary (line 505) | Dictionary IEOS::lobby_interface_copy_lobby_details(Ref<RefCounted> p_op...
function Dictionary (line 527) | Dictionary IEOS::lobby_interface_get_rtc_room_name(Ref<RefCounted> p_opt...
function Dictionary (line 549) | Dictionary IEOS::lobby_interface_is_rtc_room_connected(Ref<RefCounted> p...
function Dictionary (line 569) | Dictionary IEOS::lobby_interface_get_connect_string(Ref<RefCounted> p_op...
function Dictionary (line 594) | Dictionary IEOS::lobby_interface_parse_connect_string(Ref<RefCounted> p_...
FILE: src/mods_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::mods_interface_copy_mod_info(Ref<RefCounted> p_options) {
FILE: src/p2p_interface.cpp
function Dictionary (line 15) | Dictionary IEOS::p2p_interface_get_nat_type() {
function Dictionary (line 43) | Dictionary IEOS::p2p_interface_get_relay_control() {
function Dictionary (line 71) | Dictionary IEOS::p2p_interface_get_port_range() {
function Dictionary (line 102) | Dictionary IEOS::p2p_interface_get_packet_queue_info() {
function EOS_EResult (line 121) | EOS_EResult IEOS::_p2p_send_packet(const EOS_P2P_SendPacketOptions *opti...
function EOS_EResult (line 127) | EOS_EResult IEOS::_p2p_receive_packet(const EOS_P2P_ReceivePacketOptions...
function EOS_EResult (line 135) | EOS_EResult IEOS::_p2p_accept_connection(const EOS_P2P_AcceptConnectionO...
function EOS_EResult (line 141) | EOS_EResult IEOS::_p2p_close_connection(const EOS_P2P_CloseConnectionOpt...
function EOS_EResult (line 147) | EOS_EResult IEOS::_p2p_close_all_connections(const EOS_P2P_CloseConnecti...
function EOS_EResult (line 153) | EOS_EResult IEOS::_p2p_get_next_packet_size(const EOS_P2P_GetNextReceive...
function EOS_EResult (line 159) | EOS_EResult IEOS::_p2p_clear_packet_queue(const EOS_P2P_ClearPacketQueue...
function EOS_NotificationId (line 165) | EOS_NotificationId IEOS::_p2p_add_notify_peer_connection_established(con...
function EOS_NotificationId (line 172) | EOS_NotificationId IEOS::_p2p_add_notify_peer_connection_closed(const EO...
function EOS_NotificationId (line 179) | EOS_NotificationId IEOS::_p2p_add_notify_peer_connection_request(const E...
function EOS_NotificationId (line 186) | EOS_NotificationId IEOS::_p2p_add_notify_peer_connection_interrupted(con...
FILE: src/platform_interface.cpp
function Dictionary (line 687) | Dictionary IEOS::platform_interface_get_active_country_code(const String...
function Dictionary (line 705) | Dictionary IEOS::platform_interface_get_active_locale_code(const String ...
function Dictionary (line 723) | Dictionary IEOS::platform_interface_get_override_country_code() {
function Dictionary (line 740) | Dictionary IEOS::platform_interface_get_override_locale_code() {
function Dictionary (line 808) | Dictionary IEOS::platform_interface_get_desktop_crossplay_status_info() {
FILE: src/playerdatastorage_interface.cpp
function Dictionary (line 51) | Dictionary IEOS::playerdatastorage_interface_copy_file_metadata_by_filen...
function Dictionary (line 71) | Dictionary IEOS::playerdatastorage_interface_get_file_metadata_count(Ref...
function Dictionary (line 89) | Dictionary IEOS::playerdatastorage_interface_copy_file_metadata_at_index...
function Variant (line 180) | Variant IEOS::playerdatastorage_interface_read_file(Ref<RefCounted> p_op...
function Variant (line 239) | Variant IEOS::playerdatastorage_interface_write_file(Ref<RefCounted> p_o...
FILE: src/presence_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::presence_interface_copy_presence(Ref<RefCounted> p_opti...
function Dictionary (line 24) | Dictionary IEOS::presence_interface_create_presence_modification(Ref<Ref...
function Dictionary (line 42) | Dictionary IEOS::presence_interface_get_join_info(Ref<RefCounted> p_opti...
FILE: src/progression_snapshot_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::progression_snapshot_interface_begin_snapshot(Ref<RefCo...
FILE: src/register_types.cpp
function initialize_eosg_module (line 25) | void initialize_eosg_module(ModuleInitializationLevel p_level) {
function uninitialize_eosg_module (line 55) | void uninitialize_eosg_module(ModuleInitializationLevel p_level) {
function GDExtensionBool (line 72) | GDExtensionBool GDE_EXPORT eosg_library_init(GDExtensionInterfaceGetProc...
FILE: src/rtc_audio_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::rtc_audio_interface_copy_input_device_information_by_in...
function Dictionary (line 22) | Dictionary IEOS::rtc_audio_interface_copy_output_device_information_by_i...
FILE: src/sanctions_interface.cpp
function Dictionary (line 41) | Dictionary IEOS::sanctions_interface_copy_player_sanction_by_index(Ref<R...
FILE: src/sessions_interface.cpp
function Dictionary (line 3) | Dictionary IEOS::sessions_interface_copy_active_session_details(Ref<RefC...
function Dictionary (line 21) | Dictionary IEOS::sessions_interface_copy_session_details_by_invite_id(Re...
function Dictionary (line 39) | Dictionary IEOS::sessions_interface_copy_session_details_by_ui_event_id(...
function Dictionary (line 57) | Dictionary IEOS::sessions_interface_copy_session_details_for_presence(Re...
function Dictionary (line 75) | Dictionary IEOS::sessions_interface_create_session_modification(Ref<RefC...
function Dictionary (line 116) | Dictionary IEOS::sessions_interface_create_session_search(Ref<RefCounted...
function Dictionary (line 146) | Dictionary IEOS::sessions_interface_get_invite_id_by_index(Ref<RefCounte...
function Dictionary (line 180) | Dictionary IEOS::sessions_interface_update_session_modification(Ref<RefC...
FILE: src/stats_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::stats_interface_copy_stat_by_index(Ref<RefCounted> p_op...
function Dictionary (line 23) | Dictionary IEOS::stats_interface_copy_stat_by_name(Ref<RefCounted> p_opt...
FILE: src/titlestorage_interface.cpp
function Dictionary (line 60) | Dictionary IEOS::titlestorage_interface_copy_file_metadata_by_filename(R...
function Dictionary (line 92) | Dictionary IEOS::titlestorage_interface_copy_file_metadata_at_index(Ref<...
function Variant (line 135) | Variant IEOS::titlestorage_interface_read_file(Ref<RefCounted> p_options) {
FILE: src/user_info_interface.cpp
function Dictionary (line 4) | Dictionary IEOS::user_info_interface_copy_external_user_info_by_account_...
function Dictionary (line 26) | Dictionary IEOS::user_info_interface_copy_external_user_info_by_account_...
function Dictionary (line 47) | Dictionary IEOS::user_info_interface_copy_external_user_info_by_index(Re...
function Dictionary (line 68) | Dictionary IEOS::user_info_interface_copy_user_info(Ref<RefCounted> p_op...
function Dictionary (line 178) | Dictionary IEOS::user_info_interface_copy_best_display_name(Ref<RefCount...
function Dictionary (line 198) | Dictionary IEOS::user_info_interface_copy_best_display_name_with_platfor...
FILE: src/utils.cpp
function String (line 3) | String eosg_epic_account_id_to_string(EOS_EpicAccountId accountId) {
function String (line 23) | String eosg_product_user_id_to_string(EOS_ProductUserId localUserId) {
FILE: src/utils.h
function EOS_EpicAccountId (line 53) | static EOS_EpicAccountId eosg_string_to_epic_account_id(const char *p_ac...
function EOS_ProductUserId (line 60) | static EOS_ProductUserId eosg_string_to_product_user_id(const char *p_ac...
function Variant (line 65) | static Variant eosg_auth_pin_grant_info_to_dict(const EOS_Auth_PinGrantI...
function Variant (line 78) | static Variant eosg_continuance_token_to_wrapper(EOS_ContinuanceToken p_...
function Variant (line 82) | static Variant eosg_auth_id_token_to_dict_and_release(EOS_Auth_IdToken *...
function Variant (line 93) | static Variant eosg_connect_id_token_to_dict_and_release(EOS_Connect_IdT...
function Variant (line 104) | static Variant eosg_auth_token_to_dict_and_release(EOS_Auth_Token *authT...
function Variant (line 123) | static Variant eosg_connect_external_account_info_to_dict_and_release(EO...
function Variant (line 138) | static Variant eosg_ecom_entitlement_to_dict_and_release(EOS_Ecom_Entitl...
function Variant (line 154) | static Variant eosg_ecom_catalog_item_to_dict_and_release(EOS_Ecom_Catal...
function Variant (line 174) | static Variant eosg_ecom_key_image_info_to_dict_and_release(EOS_Ecom_Key...
function Variant (line 188) | static Variant eosg_ecom_catalog_release_to_dict_and_release(EOS_Ecom_Ca...
function Variant (line 209) | static Variant eosg_ecom_catalog_offer_to_dict_and_release(EOS_Ecom_Cata...
function Variant (line 236) | static Variant eosg_ecom_transaction_to_wrapper(EOS_Ecom_HTransaction p_...
function Variant (line 240) | static Variant eosg_user_info_external_user_info_to_dict_and_release(EOS...
function Variant (line 254) | static Variant eosg_user_info_user_info_to_dict_and_release(EOS_UserInfo...
function Variant (line 270) | static Variant eosg_user_info_best_display_name_to_dict_and_release(EOS_...
function Variant (line 285) | static Variant eosg_mods_mod_info_to_dict_and_release(EOS_Mods_ModInfo *...
function Variant (line 313) | static Variant eosg_mods_mod_identifier_to_dict(const EOS_Mod_Identifier...
function Variant (line 326) | static Variant eosg_presence_presence_info_to_dict_and_release(EOS_Prese...
function Variant (line 355) | static Variant eosg_presence_presence_modification_to_wrapper(EOS_HPrese...
function Variant (line 359) | static Variant eosg_achievements_definition_to_dict_and_release(EOS_Achi...
function Variant (line 386) | static Variant eosg_achievements_player_achievement_to_dict_and_release(...
function Variant (line 411) | static Variant eosg_stats_stat_to_dict_and_release(EOS_Stats_Stat *stat) {
function Variant (line 424) | static Variant eosg_leaderboards_definition_to_dict_and_release(EOS_Lead...
function Variant (line 438) | static Variant eosg_leaderboards_leaderboard_record_to_dict_and_release(...
function Variant (line 451) | static Variant eosg_leaderboards_leaderboard_user_score_to_dict_and_rele...
function Variant (line 462) | static Variant eosg_kws_permission_status_to_dict_and_release(EOS_KWS_Pe...
function Variant (line 473) | static Variant eosg_lobby_details_info_to_dict_and_release(EOS_LobbyDeta...
function Variant (line 499) | static Variant eosg_lobby_details_member_info_to_dict_and_release(EOS_Lo...
function Variant (line 511) | static Variant eosg_lobby_attribute_data_to_dict(EOS_Lobby_AttributeData...
function Variant (line 540) | static Variant eosg_lobby_attribute_to_dict_and_release(EOS_Lobby_Attrib...
function Variant (line 551) | static Variant eosg_lobby_lobby_modification_to_wrapper(EOS_HLobbyModifi...
function Variant (line 555) | static Variant eosg_lobby_lobby_search_to_wrapper(EOS_HLobbySearch lobby...
function Variant (line 559) | static Variant eosg_lobby_lobby_details_to_wrapper(EOS_HLobbyDetails lob...
function EOS_Lobby_LocalRTCOptions (line 563) | static EOS_Lobby_LocalRTCOptions eosg_variant_to_lobby_local_rtc_options...
function Variant (line 594) | static Variant eosg_playerdatastorage_file_metadata_to_dict_and_release(...
function Variant (line 609) | static Variant eosg_playerdatastorage_file_tranfer_request_to_wrapper(EO...
function Variant (line 613) | static Variant eosg_titlestorage_file_metadata_to_dict_and_release(EOS_T...
function Variant (line 627) | static Variant eosg_titlestorage_file_tranfer_request_to_wrapper(EOS_HTi...
function Variant (line 631) | static Variant eosg_sanctions_player_sanction_to_dict_and_release(EOS_Sa...
function Variant (line 645) | static Variant eosg_sessions_session_details_settings_to_dict(const EOS_...
function Variant (line 666) | static Variant eosg_sessions_session_details_info_to_dict(const EOS_Sess...
function Variant (line 681) | static Variant eosg_sessions_session_details_info_to_dict_and_release(EO...
function Variant (line 687) | static Variant eosg_sessions_active_session_info_to_dict_and_release(EOS...
function Variant (line 701) | static Variant eosg_sessions_attribute_data_to_dict(EOS_Sessions_Attribu...
function Variant (line 727) | static Variant eosg_sessions_session_details_attribute_to_dict_and_relea...
function Variant (line 739) | static Variant eosg_sessions_active_session_to_wrapper(EOS_HActiveSessio...
function Variant (line 743) | static Variant eosg_sessions_session_details_to_wrapper(EOS_HSessionDeta...
function Variant (line 747) | static Variant eosg_sessions_session_modification_to_wrapper(EOS_HSessio...
function Variant (line 751) | static Variant eosg_sessions_session_search_to_wrapper(EOS_HSessionSearc...
function Variant (line 755) | static Variant eosg_rtc_audio_input_device_information_to_dict_and_relea...
function Variant (line 768) | static Variant eosg_rtc_audio_output_device_information_to_dict_and_rele...
function Variant (line 781) | static Variant eosg_rtc_audio_audio_buffer_to_dict(EOS_RTCAudio_AudioBuf...
FILE: src/version_interface.cpp
function String (line 4) | String IEOS::version_interface_get_version() {
function Dictionary (line 8) | Dictionary IEOS::version_interface_get_constants() {
Condensed preview — 276 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,833K chars).
[
{
"path": ".clang-format",
"chars": 1353,
"preview": "# Commented out parameters are those with the same value as base LLVM style.\n# We can uncomment them if we want to chang"
},
{
"path": ".editorconfig",
"chars": 285,
"preview": "# EditorConfig is awesome: https://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n[*]\nindent_style = space\n"
},
{
"path": ".gitattributes",
"chars": 79,
"preview": "# Normalize EOL for all files that Git considers text files.\n* text=auto eol=lf"
},
{
"path": ".github/FUNDING.yml",
"chars": 63,
"preview": "github: 3ddelano\ncustom: https://www.buymeacoffee.com/3ddelano\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 756,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: 3ddelano\n\n---\n\n**Describe"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/workflows/build.yml",
"chars": 11418,
"preview": "name: 🛠️ Builds\non:\n workflow_dispatch:\n push:\n branches:\n - \"*\"\n tags:\n - \"*\"\njobs:\n build:\n runs"
},
{
"path": ".github/workflows/deploy-docs.yml",
"chars": 1274,
"preview": "name: Deploy Docs to GitHub Pages\n\non:\n push:\n branches:\n - \"*\"\n # Review gh actions docs if you want to fur"
},
{
"path": ".gitignore",
"chars": 226,
"preview": "# Godot logs\nlogs/\n\ncache/\n.cache/\n\nsample/android\nsample/android_debug.keystore\n\n.DS_Store\n\n.env\nvc140.pdb\n.sconsign.db"
},
{
"path": ".gitmodules",
"chars": 218,
"preview": "[submodule \"godot-cpp\"]\n\tpath = godot-cpp\n\turl = https://github.com/godotengine/godot-cpp\n\tbranch = 4.2\n[submodule \"thir"
},
{
"path": ".pre-commit-config.yaml",
"chars": 113,
"preview": "repos:\n- repo: https://github.com/ssciwr/clang-format-hook\n rev: v16.0.2\n hooks:\n - id: clang-format"
},
{
"path": ".vscode/c_cpp_properties.json",
"chars": 873,
"preview": "{\n \"configurations\": [\n {\n \"name\": \"Win32\",\n \"includePath\": [\n \"${workspa"
},
{
"path": ".vscode/launch.json",
"chars": 713,
"preview": "{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"Debug Project (Windows)\",\n\t\t\t\"type\": \"cppvsdbg\",\n\t\t\t\"request"
},
{
"path": ".vscode/settings.json",
"chars": 807,
"preview": "{\n \"files.exclude\": {\n \"**/*.obj\": true,\n \"**/*.ilk\": true,\n \"**/*.exp\": true,\n \"**/*.pdb\": true,\n \"**/_"
},
{
"path": ".vscode/tasks.json",
"chars": 514,
"preview": "{\n \"version\": \"2.0.0\",\n \"tasks\": [\n {\n \"label\": \"build\",\n \"group\": \"build\",\n "
},
{
"path": "LICENSE.md",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2022 Delano Lourenco\n\nPermission is hereby granted, free of charge, to any person obtaining a"
},
{
"path": "README.md",
"chars": 18262,
"preview": "# Epic Online Services Godot (EOSG)\n\n<img alt=\"Project Logo\" src=\"./_media/logo.png\" height=\"150\">\n\n### Easiest way to u"
},
{
"path": "SConstruct",
"chars": 5164,
"preview": "#!/usr/bin/env python\nimport os\nimport shutil\n\nenv = SConscript(\"godot-cpp/SConstruct\")\nlib_name = \"libeosg\"\nplugin_bin_"
},
{
"path": "build-ios.sh",
"chars": 2693,
"preview": "#!/bin/sh\n\nbuild=yes\nif [ \"$1\" = \"build=n\" ] || [ \"$1\" = \"build=N\" ] || [ \"$1\" = \"build=no\" ] || [ \"$1\" = \"build=0\" ]; t"
},
{
"path": "debug-entitlements.plist",
"chars": 248,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "debug.cmd",
"chars": 53,
"preview": "@echo off\nscons dev_build=yes && godot4 --path sample"
},
{
"path": "debug.sh",
"chars": 44,
"preview": "scons dev_build=yes && godot45 --path sample"
},
{
"path": "docs/.gitignore",
"chars": 233,
"preview": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\n\n# Misc\n.DS_Store\n.env.lo"
},
{
"path": "docs/README.md",
"chars": 768,
"preview": "# Website\n\nThis website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.\n\n### Ins"
},
{
"path": "docs/docs/installation.md",
"chars": 1531,
"preview": "# Installation\n\n## Method 1: Install from Asset Library (Recommended)\n\n[View the plugin on Godot Asset Library](https://"
},
{
"path": "docs/docs/introduction.md",
"chars": 1136,
"preview": "# Introduction\n\nEpic Online Services Godot (EOSG) is the easiest way to integrate Epic Online Services into your Godot p"
},
{
"path": "docs/docs/sample-project.md",
"chars": 2228,
"preview": "# Sample Project\n\nTo run the sample project which showcases most of the EOS features, follow these steps:\n\n1. Clone/Down"
},
{
"path": "docs/docs/topics/authentication.md",
"chars": 40,
"preview": "# Authentication\n\nWIP - Work In Progress"
},
{
"path": "docs/docs/topics/initialization.md",
"chars": 8258,
"preview": "import ReactPlayer from 'react-player'\n\n# Initialization\n\nFollow the steps below to initialize and use the plugin.\n\nChec"
},
{
"path": "docs/docs/update-guide.md",
"chars": 408,
"preview": "# Update Guide\n\nFollow these steps to update to a newer version of the plugin:\n\n1. Disable the plugin in the Editor in `"
},
{
"path": "docs/docusaurus.config.ts",
"chars": 2951,
"preview": "import { themes as prismThemes } from \"prism-react-renderer\";\nimport type { Config } from \"@docusaurus/types\";\nimport ty"
},
{
"path": "docs/package.json",
"chars": 1383,
"preview": "{\n \"name\": \"docs\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"scripts\": {\n \"docusaurus\": \"docusaurus\",\n \"start\":"
},
{
"path": "docs/postcss.config.js",
"chars": 65,
"preview": "module.exports = {\n\tplugins: {\n\t\t'@tailwindcss/postcss': {},\n\t}\n}"
},
{
"path": "docs/sidebars.ts",
"chars": 936,
"preview": "import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';\n\n// This runs in Node.js - Don't use client-side "
},
{
"path": "docs/src/components/ExampleSection.tsx",
"chars": 2718,
"preview": "import CodeBlock from \"@theme/CodeBlock\";\n\nconst codeExample = `\n# In main script\nextends Node\n\nfunc _ready() -> void:\n "
},
{
"path": "docs/src/components/FeaturesSection.tsx",
"chars": 2907,
"preview": "const FEATURES = [\n \"Authentication\",\n \"Social Overlay (Win)\",\n \"Achievements\",\n \"Stats & Leaderboards\",\n \"Lobby & "
},
{
"path": "docs/src/components/HeroSection.tsx",
"chars": 3872,
"preview": "import useDocusaurusContext from \"@docusaurus/useDocusaurusContext\";\nimport { GodotIcon, EpicIcon } from \"../components/"
},
{
"path": "docs/src/components/Icons.tsx",
"chars": 15416,
"preview": "export function GodotIcon({ className = \"w-4 h-4\" }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n "
},
{
"path": "docs/src/components/InfoSections.tsx",
"chars": 5773,
"preview": "export function HowItWorksSection() {\n return (\n <section id=\"how-it-works\" className=\"py-16 sm:py-20 bg-gray-950\">\n"
},
{
"path": "docs/src/components/Layout.tsx",
"chars": 7177,
"preview": "import { useState } from \"react\";\n\n// Navigation links data\nconst NAV_LINKS = [\n {\n label: \"Docs\",\n href: \"docs/i"
},
{
"path": "docs/src/components/MainSystemsSection.tsx",
"chars": 4249,
"preview": "const MAIN_SYSTEMS = [\n {\n title: \"High Level EOS\",\n tag: \"Recommended\",\n description:\n \"Provides easy-to"
},
{
"path": "docs/src/components/MediaSections.tsx",
"chars": 4759,
"preview": "const SCREENSHOTS_DATA = [\n {\n category: \"Windows\",\n images: [\n {\n src: \"img/screenshots/windows_auth"
},
{
"path": "docs/src/components/SupportSection.tsx",
"chars": 3797,
"preview": "const SUPPORT_DATA = {\n bmc_url: \"https://www.buymeacoffee.com/3ddelano\",\n github_sponsor_url: \"https://github.com/spo"
},
{
"path": "docs/src/css/custom.css",
"chars": 6915,
"preview": "@import \"tailwindcss\";\n\n@import url(\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=Jet"
},
{
"path": "docs/src/pages/index.tsx",
"chars": 795,
"preview": "import { HeroSection } from \"../components/HeroSection\";\nimport { MainSystemsSection } from \"../components/MainSystemsSe"
},
{
"path": "docs/src/pages/showcase.md",
"chars": 1904,
"preview": "---\n---\n\n# Showcase\n\nHere is a list of games using the Epic Online Services Godot plugin. If you are using this plugin a"
},
{
"path": "docs/src/plugins/tailwind-config.ts",
"chars": 233,
"preview": "module.exports = function tailwindPlugin(context, options) {\n\treturn {\n\t name: 'tailwind-plugin',\n\t configurePostCss(p"
},
{
"path": "docs/static/.nojekyll",
"chars": 0,
"preview": ""
},
{
"path": "docs/tsconfig.json",
"chars": 215,
"preview": "{\n // This file is not used in compilation. It is here just for a nice editor experience.\n \"extends\": \"@docusaurus/tsc"
},
{
"path": "function_analyzer.py",
"chars": 3119,
"preview": "# eos_function_usage_checker.py\n\nimport os\nimport re\n\n\n# Function to extract function names from the EOS C SDK header fi"
},
{
"path": "sample/.gitignore",
"chars": 77,
"preview": ".import/\nexport.cfg\nexport_presets.cfg\n*.translation\n\n.godot/\n\n*.env\n*.import"
},
{
"path": "sample/AntiCheatServerMain.gd",
"chars": 4139,
"preview": "class_name AntiCheatServerMain\nextends Node\n\n@onready var PRODUCT_NAME: String = Env.get_var(\"PRODUCT_NAME\")\n@onready va"
},
{
"path": "sample/AntiCheatServerMain.gd.uid",
"chars": 20,
"preview": "uid://clbqhgyalkxuw\n"
},
{
"path": "sample/Main.gd",
"chars": 4349,
"preview": "extends Control\n\n@onready var PRODUCT_NAME: String = Env.get_var(\"PRODUCT_NAME\") # Paste your own instead of Env.get_var"
},
{
"path": "sample/Main.gd.uid",
"chars": 20,
"preview": "uid://cf8kvjx2nbysy\n"
},
{
"path": "sample/Main.tscn",
"chars": 10648,
"preview": "[gd_scene load_steps=25 format=3 uid=\"uid://gcoi8ld0uvkl\"]\n\n[ext_resource type=\"Theme\" uid=\"uid://dwns7wwoyi1hy\" path=\"r"
},
{
"path": "sample/addons/epic-online-services-godot/base_class.gd",
"chars": 348,
"preview": "## Copyright (c) 2022-present Delano Lourenco\n## https://github.com/3ddelano/dataclasses-godot\n## MIT License\n## See Lic"
},
{
"path": "sample/addons/epic-online-services-godot/base_class.gd.uid",
"chars": 19,
"preview": "uid://g1ij604ak57v\n"
},
{
"path": "sample/addons/epic-online-services-godot/bin/.gitignore",
"chars": 13,
"preview": "*\n!.gitignore"
},
{
"path": "sample/addons/epic-online-services-godot/dataclass.gd",
"chars": 7188,
"preview": "## Copyright (c) 2022-present Delano Lourenco\n## https://github.com/3ddelano/dataclasses-godot\n## MIT License\n## See Lic"
},
{
"path": "sample/addons/epic-online-services-godot/dataclass.gd.uid",
"chars": 20,
"preview": "uid://d4hmupfn3ooqp\n"
},
{
"path": "sample/addons/epic-online-services-godot/eos.gd",
"chars": 136207,
"preview": "# Copyright (c) 2023-present Delano Lourenco\n# https://github.com/3ddelano/epic-online-services-godot/\n# MIT License\n\n##"
},
{
"path": "sample/addons/epic-online-services-godot/eos.gd.uid",
"chars": 19,
"preview": "uid://idtj8sepvkjw\n"
},
{
"path": "sample/addons/epic-online-services-godot/eosg.gdextension",
"chars": 2084,
"preview": "[configuration]\n\nentry_symbol = \"eosg_library_init\"\ncompatibility_minimum = 4.1\n\n[libraries]\nlinux.debug.x86_64 = \"bin/l"
},
{
"path": "sample/addons/epic-online-services-godot/eosg.gdextension.uid",
"chars": 20,
"preview": "uid://dwyvkkxk32w36\n"
},
{
"path": "sample/addons/epic-online-services-godot/export_plugin.gd",
"chars": 860,
"preview": "# Copyright (c) 2023-present Delano Lourenco\n# https://github.com/3ddelano/epic-online-services-godot/\n# MIT License\n@to"
},
{
"path": "sample/addons/epic-online-services-godot/export_plugin.gd.uid",
"chars": 20,
"preview": "uid://bydaf5hf76858\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hachievement_data.gd",
"chars": 2598,
"preview": "## Achievement data from Epic Online Services\nclass_name HAchievementData\nextends BaseClass\n\n\nfunc _init() -> void:\n\tsup"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hachievement_data.gd.uid",
"chars": 19,
"preview": "uid://we6ap3yuu378\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hachievements.gd",
"chars": 5810,
"preview": "extends Node\n\n#region Signals\n\n## Emitted when an achievement is unlocked\n## data has the following keys: achievement_id"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hachievements.gd.uid",
"chars": 20,
"preview": "uid://bis404dty5u5c\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hauth.gd",
"chars": 21418,
"preview": "# Good article about the EOS login flows: https://eoshelp.epicgames.com/s/article/What-is-the-correct-login-flow-for-a-g"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hauth.gd.uid",
"chars": 19,
"preview": "uid://786t1jiowvvg\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hcredentials.gd",
"chars": 898,
"preview": "## Credentials required by Epic Online Services. Get these values from the [url=https://dev.epicgames.com/portal/en-US/]"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hcredentials.gd.uid",
"chars": 20,
"preview": "uid://dh3dlxnt075r2\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hfriends.gd",
"chars": 1313,
"preview": "extends Node\n\n#region Signals\n\n#endregion\n\n\n#region Public vars\n\n#endregion\n\n\n#region Private vars \n\nvar _log = HLog.log"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hfriends.gd.uid",
"chars": 19,
"preview": "uid://uumqbey8ji5t\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hleaderboards.gd",
"chars": 3572,
"preview": "extends Node\n\n#region Signals\n\n#endregion\n\n\n#region Public vars\n\n#endregion\n\n\n#region Private vars \n\nvar _log = HLog.log"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hleaderboards.gd.uid",
"chars": 20,
"preview": "uid://b06khhf20mplm\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobbies.gd",
"chars": 6769,
"preview": "extends Node\n\n\n#region Public vars\n\n## The maximum number of lobbies to return in search calls.[br]\n## Except for [metho"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobbies.gd.uid",
"chars": 19,
"preview": "uid://6iqvm33q0tb1\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobby.gd",
"chars": 25390,
"preview": "## A high-level lobby wrapper for EOSG\nclass_name HLobby\nextends BaseClass\n\n\n#region Signals\n\n## Emitted when anything a"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobby.gd.uid",
"chars": 20,
"preview": "uid://dk65c5tvqlm1a\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobbymember.gd",
"chars": 5900,
"preview": "## A high-level lobby member wrapper for EOSG\nclass_name HLobbyMember\nextends BaseClass\n\n\n#region Signals\n\n## Emitted wh"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlobbymember.gd.uid",
"chars": 20,
"preview": "uid://brdkf3u56ylbk\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlog.gd",
"chars": 3113,
"preview": "## Used for logging by HEOS classes\n##\n## See also [EOS.Logging] for EOS SDK logging\nclass_name HLog\nextends RefCounted\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hlog.gd.uid",
"chars": 20,
"preview": "uid://cke8udaaf4kka\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hp2p.gd",
"chars": 2727,
"preview": "extends Node\n\n\n#region Public vars\n\n\n#endregion\n\n\n#region Private vars \n\nvar _log = HLog.logger(\"HP2P\")\n\n#endregion\n\n\n#r"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hp2p.gd.uid",
"chars": 19,
"preview": "uid://u6ae5fpm6l8q\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hplatform.gd",
"chars": 6301,
"preview": "extends Node\n\n#region Signals\n\n## Emitted when the EOS platform was initialized successfully\nsignal platform_initialized"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hplatform.gd.uid",
"chars": 19,
"preview": "uid://yl2muvqrdiud\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hsessions.gd",
"chars": 4376,
"preview": "extends Node\n\n\n#region Public vars\n\nvar max_search_results = 25\n\n#endregion\n\n\n#region Private vars \n\nvar _log = HLog.log"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hsessions.gd.uid",
"chars": 20,
"preview": "uid://bieh2rxxahuu2\n"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hstats.gd",
"chars": 2113,
"preview": "extends Node\n\n#region Signals\n\n#endregion\n\n\n#region Public vars\n\n#endregion\n\n\n#region Private vars \n\nvar _log = HLog.log"
},
{
"path": "sample/addons/epic-online-services-godot/heos/hstats.gd.uid",
"chars": 20,
"preview": "uid://dbckdip83oone\n"
},
{
"path": "sample/addons/epic-online-services-godot/plugin.cfg",
"chars": 203,
"preview": "[plugin]\n\nname = \"Epic Online Services Godot 4.2+ (EOSG)\"\ndescription = \"Unofficial Epic Online Services for Godot 4.2+ "
},
{
"path": "sample/addons/epic-online-services-godot/plugin.gd",
"chars": 1683,
"preview": "# Copyright (c) 2023-present Delano Lourenco\n# https://github.com/3ddelano/epic-online-services-godot/\n# MIT License\n@to"
},
{
"path": "sample/addons/epic-online-services-godot/plugin.gd.uid",
"chars": 20,
"preview": "uid://c2bh2munh5110\n"
},
{
"path": "sample/addons/epic-online-services-godot/runtime.gd",
"chars": 959,
"preview": "# Copyright (c) 2023-present Delano Lourenco\n# https://github.com/3ddelano/epic-online-services-godot/\n# MIT License\n## "
},
{
"path": "sample/addons/epic-online-services-godot/runtime.gd.uid",
"chars": 19,
"preview": "uid://7saywdx0ipep\n"
},
{
"path": "sample/components/StyledPopupWindow/StyledPopupWindow.gd",
"chars": 213,
"preview": "class_name StyledPopupWindow\nextends PopupPanel\n\n\n@onready var _close_btn = %CloseBtn\n@onready var _title = %Title\n\n\nfun"
},
{
"path": "sample/components/StyledPopupWindow/StyledPopupWindow.gd.uid",
"chars": 19,
"preview": "uid://467nklflb1n8\n"
},
{
"path": "sample/components/StyledPopupWindow/StyledPopupWindow.tscn",
"chars": 2191,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://dkprjbptror6n\"]\n\n[ext_resource type=\"Theme\" uid=\"uid://dwns7wwoyi1hy\" path=\"r"
},
{
"path": "sample/components/StyledPopupWindow/StyledPopupWindowTheme.tres",
"chars": 485208,
"preview": "[gd_resource type=\"Theme\" load_steps=26 format=4 uid=\"uid://dwns7wwoyi1hy\"]\n\n[ext_resource type=\"Texture2D\" uid=\"uid://b"
},
{
"path": "sample/dedicated_server_example/client_main.gd",
"chars": 2816,
"preview": "extends Control\n\n@onready var PRODUCT_NAME: String = Env.get_var(\"PRODUCT_NAME\")\n@onready var PRODUCT_VERSION: String = "
},
{
"path": "sample/dedicated_server_example/client_main.gd.uid",
"chars": 19,
"preview": "uid://3nyw0hwkkgmg\n"
},
{
"path": "sample/dedicated_server_example/client_main.tscn",
"chars": 377,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://dve4hhbpclrm5\"]\n\n[ext_resource type=\"Script\" uid=\"uid://3nyw0hwkkgmg\" path=\"r"
},
{
"path": "sample/dedicated_server_example/server_main.gd",
"chars": 3242,
"preview": "extends Control\n\n\n@onready var PRODUCT_NAME: String = Env.get_var(\"PRODUCT_NAME\")\n@onready var PRODUCT_VERSION: String ="
},
{
"path": "sample/dedicated_server_example/server_main.gd.uid",
"chars": 20,
"preview": "uid://bneij5syrcl1f\n"
},
{
"path": "sample/dedicated_server_example/server_main.tscn",
"chars": 378,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://dyuj4qlamg7b5\"]\n\n[ext_resource type=\"Script\" uid=\"uid://bneij5syrcl1f\" path=\""
},
{
"path": "sample/default_bus_layout.tres",
"chars": 422,
"preview": "[gd_resource type=\"AudioBusLayout\" load_steps=2 format=3 uid=\"uid://dfiyvl4a8dbhr\"]\n\n[sub_resource type=\"AudioEffectCapt"
},
{
"path": "sample/default_env.tres",
"chars": 170,
"preview": "[gd_resource type=\"Environment\" load_steps=2 format=3 uid=\"uid://cdoy56rtiqovw\"]\n\n[sub_resource type=\"Sky\" id=\"1\"]\n\n[res"
},
{
"path": "sample/fonts/roboto-13r.tres",
"chars": 391,
"preview": "[gd_resource type=\"FontFile\" load_steps=2 format=3 uid=\"uid://da6bpapjl4a5k\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://"
},
{
"path": "sample/fonts/roboto-16b.tres",
"chars": 544,
"preview": "[gd_resource type=\"FontFile\" load_steps=2 format=3 uid=\"uid://bghbav6kh0lsl\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://"
},
{
"path": "sample/fonts/roboto-16r.tres",
"chars": 546,
"preview": "[gd_resource type=\"FontFile\" load_steps=2 format=3 uid=\"uid://bxcl265jykrk0\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://"
},
{
"path": "sample/fonts/roboto-32b.tres",
"chars": 543,
"preview": "[gd_resource type=\"FontFile\" load_steps=2 format=3 uid=\"uid://njn2rf7rj4ph\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://d"
},
{
"path": "sample/game/entities/bullet/bullet.gd",
"chars": 599,
"preview": "class_name Bullet\nextends Area2D\n\n\nconst SPEED = 2000.0\n\n\nvar dmg_amt = 25\nvar owner_peer_id: int\nvar owner_puid: String"
},
{
"path": "sample/game/entities/bullet/bullet.gd.uid",
"chars": 19,
"preview": "uid://83g60od7sqbn\n"
},
{
"path": "sample/game/entities/bullet/bullet.tscn",
"chars": 1127,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://b8clmnksfigve\"]\n\n[ext_resource type=\"Script\" uid=\"uid://83g60od7sqbn\" path=\"r"
},
{
"path": "sample/game/entities/player/player.gd",
"chars": 2333,
"preview": "class_name Player\nextends CharacterBody2D\n\n\nsignal health_changed\nsignal died(player, killing_peer_id: int)\n\n\nconst SPEE"
},
{
"path": "sample/game/entities/player/player.gd.uid",
"chars": 20,
"preview": "uid://cwybnfn6dv66t\n"
},
{
"path": "sample/game/entities/player/player.tscn",
"chars": 1908,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://d25l4fa1sffqk\"]\n\n[ext_resource type=\"Script\" uid=\"uid://cwybnfn6dv66t\" path=\""
},
{
"path": "sample/game/entities/wall/wall.tscn",
"chars": 785,
"preview": "[gd_scene load_steps=3 format=3 uid=\"uid://dnt3dorvwuw5y\"]\n\n[sub_resource type=\"RectangleShape2D\" id=\"RectangleShape2D_0"
},
{
"path": "sample/game/maps/map_bellandur.tscn",
"chars": 3439,
"preview": "[gd_scene load_steps=4 format=4 uid=\"uid://cq20ci5f675b8\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://dnt3dorvwuw5y\" p"
},
{
"path": "sample/game/maps/map_margao.tscn",
"chars": 3081,
"preview": "[gd_scene load_steps=4 format=4 uid=\"uid://d25abb5oqolnx\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://dnt3dorvwuw5y\" p"
},
{
"path": "sample/game/maps/map_new_york.tscn",
"chars": 3884,
"preview": "[gd_scene load_steps=4 format=4 uid=\"uid://cutu8g5suwurd\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://dnt3dorvwuw5y\" p"
},
{
"path": "sample/project.godot",
"chars": 4148,
"preview": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go her"
},
{
"path": "sample/scenes/AchievementsView/AchievementPopup.gd",
"chars": 2345,
"preview": "class_name AchievementPopup\nextends StyledPopupWindow\n\n@onready var id_label = $VB/MC/VB/GridContainer/IdLabel\n@onready "
},
{
"path": "sample/scenes/AchievementsView/AchievementPopup.gd.uid",
"chars": 20,
"preview": "uid://b8fpdhlcd5vf2\n"
},
{
"path": "sample/scenes/AchievementsView/AchievementUnlockNotification.gd",
"chars": 848,
"preview": "class_name AchievementUnlockNotification\nextends Control\n\nvar _data: HAchievementData\n\n@onready var id_label = $MC/HB/VB"
},
{
"path": "sample/scenes/AchievementsView/AchievementUnlockNotification.gd.uid",
"chars": 20,
"preview": "uid://dnm64cf611a0h\n"
},
{
"path": "sample/scenes/AchievementsView/AchievementUnlockNotification.tscn",
"chars": 3264,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://b7hrrwwvjqycs\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://djhhnis3ksdjk\" p"
},
{
"path": "sample/scenes/AchievementsView/AchievementsList.gd",
"chars": 766,
"preview": "class_name AchievementsList\nextends MarginContainer\n\nsignal achievement_pressed(node)\n\nconst ACHIEVEMENTS_LIST_ACHIEVEME"
},
{
"path": "sample/scenes/AchievementsView/AchievementsList.gd.uid",
"chars": 18,
"preview": "uid://27jk4xa1yfq\n"
},
{
"path": "sample/scenes/AchievementsView/AchievementsListAchievement.gd",
"chars": 663,
"preview": "class_name AchievementsListAchievement\nextends MarginContainer\n\n# warning-ignore:unused_signal\nsignal pressed(_self)\n\n@o"
},
{
"path": "sample/scenes/AchievementsView/AchievementsListAchievement.gd.uid",
"chars": 20,
"preview": "uid://cuosdhat5m7tg\n"
},
{
"path": "sample/scenes/AchievementsView/AchievementsListAchievement.tscn",
"chars": 2215,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://blvi28uiveh0a\"]\n\n[ext_resource type=\"Script\" uid=\"uid://cuosdhat5m7tg\" path=\""
},
{
"path": "sample/scenes/AchievementsView/AchievementsView.gd",
"chars": 1894,
"preview": "class_name AchievementsView\nextends VBoxContainer\n\n# Local cache of achievements\nvar achievements = {}\n\n@onready var _ac"
},
{
"path": "sample/scenes/AchievementsView/AchievementsView.gd.uid",
"chars": 20,
"preview": "uid://cjhi71075hj1y\n"
},
{
"path": "sample/scenes/AchievementsView/AchievementsView.tscn",
"chars": 7293,
"preview": "[gd_scene load_steps=12 format=3 uid=\"uid://d3hxdkoy73pf1\"]\n\n[ext_resource type=\"Script\" uid=\"uid://cjhi71075hj1y\" path="
},
{
"path": "sample/scenes/CustomInvitesView/CustomInvitesView.gd",
"chars": 3515,
"preview": "class_name CustomInvitesView\nextends VBoxContainer\n\n@onready var payload_textedit = %PayloadTextEdit\n@onready var send_i"
},
{
"path": "sample/scenes/CustomInvitesView/CustomInvitesView.gd.uid",
"chars": 20,
"preview": "uid://ddkxgj5m43swv\n"
},
{
"path": "sample/scenes/CustomInvitesView/CustomInvitesView.tscn",
"chars": 1182,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://d2bkej1dakv6s\"]\n\n[ext_resource type=\"Script\" uid=\"uid://ddkxgj5m43swv\" path=\""
},
{
"path": "sample/scenes/FriendsView/FriendsView.gd",
"chars": 1275,
"preview": "class_name FriendsView\nextends VBoxContainer\n\n# Local cache of friends data\nvar friends = []\n\n@onready var list_title_ri"
},
{
"path": "sample/scenes/FriendsView/FriendsView.gd.uid",
"chars": 20,
"preview": "uid://dx8eth83tfuvn\n"
},
{
"path": "sample/scenes/FriendsView/FriendsView.tscn",
"chars": 1782,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://t016k2yh382d\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dx8eth83tfuvn\" path=\"r"
},
{
"path": "sample/scenes/LeaderboardsView/LeaderboardsView.gd",
"chars": 2370,
"preview": "class_name LeaderboardsView\nextends VBoxContainer\n\n# Local cache of leaderboard data\nvar leaderboards = []\n\n@onready var"
},
{
"path": "sample/scenes/LeaderboardsView/LeaderboardsView.gd.uid",
"chars": 20,
"preview": "uid://dkhn2a8wdwx21\n"
},
{
"path": "sample/scenes/LeaderboardsView/LeaderboardsView.tscn",
"chars": 1922,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://5xrk7nvpwosj\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dkhn2a8wdwx21\" path=\"r"
},
{
"path": "sample/scenes/LobbiesView/CreateLobbyPopup.gd",
"chars": 3131,
"preview": "class_name CreateLobbyPopup\nextends StyledPopupWindow\n\n\n@onready var _bucket_id: LineEdit = %BucketId\n@onready var _map_"
},
{
"path": "sample/scenes/LobbiesView/CreateLobbyPopup.gd.uid",
"chars": 20,
"preview": "uid://csdajb1e07h18\n"
},
{
"path": "sample/scenes/LobbiesView/CreateLobbyPopup.tscn",
"chars": 2562,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://bmxf7kdhjlip6\"]\n\n[ext_resource type=\"PackedScene\" uid=\"uid://dkprjbptror6n\" p"
},
{
"path": "sample/scenes/LobbiesView/CurrentLobby.gd",
"chars": 10790,
"preview": "class_name CurrentLobby\nextends VBoxContainer\n\n@onready var id_label: LineEdit = %IdLabel\n@onready var owner_label: Line"
},
{
"path": "sample/scenes/LobbiesView/CurrentLobby.gd.uid",
"chars": 20,
"preview": "uid://dscovu6epeb5t\n"
},
{
"path": "sample/scenes/LobbiesView/LobbiesView.gd",
"chars": 1589,
"preview": "class_name LobbiesView\nextends VBoxContainer\n\n\nenum Maps {\n\tMargao,\n\tBellandur,\n\tNewYork,\n}\n\nconst Skins = {\n\tHuman = \"H"
},
{
"path": "sample/scenes/LobbiesView/LobbiesView.gd.uid",
"chars": 20,
"preview": "uid://c3mc2b4nqvb5v\n"
},
{
"path": "sample/scenes/LobbiesView/LobbiesView.tscn",
"chars": 10723,
"preview": "[gd_scene load_steps=11 format=3 uid=\"uid://dsiyt23hnmngd\"]\n\n[ext_resource type=\"Script\" uid=\"uid://c3mc2b4nqvb5v\" path="
},
{
"path": "sample/scenes/LobbiesView/SearchLobby.gd",
"chars": 2674,
"preview": "extends HBoxContainer\n\n#region Enums\n\nconst SearchType = {\n\tMap = \"Map\",\n\tBucketId = \"BucketId\",\n\tLobbyId = \"LobbyId\",\n\t"
},
{
"path": "sample/scenes/LobbiesView/SearchLobby.gd.uid",
"chars": 20,
"preview": "uid://bjqvw2f6qq5vu\n"
},
{
"path": "sample/scenes/LobbiesView/SearchLobbyResults.gd",
"chars": 1944,
"preview": "class_name SearchLobbyResults\nextends VBoxContainer\n\nconst GRID_CONTAINER_LABELS_COUNT = 4\n\n\nvar search_results: Array[H"
},
{
"path": "sample/scenes/LobbiesView/SearchLobbyResults.gd.uid",
"chars": 20,
"preview": "uid://c42grjipjn5g0\n"
},
{
"path": "sample/scenes/LoginView/EnterCredentials.gd",
"chars": 1214,
"preview": "extends VBoxContainer\n\n\nsignal perform_login\n\n@onready var id_label = $IdLabel\n@onready var token_label = $TokenLabel\n\n@"
},
{
"path": "sample/scenes/LoginView/EnterCredentials.gd.uid",
"chars": 20,
"preview": "uid://bx0bhh73kw3q7\n"
},
{
"path": "sample/scenes/LoginView/LoginView.gd",
"chars": 5745,
"preview": "class_name LoginView\nextends CenterContainer\n\n#region Enums\n\nenum States {\n\tChooseMethod,\n\tEnterCredentials,\n\tPending,\n\t"
},
{
"path": "sample/scenes/LoginView/LoginView.gd.uid",
"chars": 20,
"preview": "uid://dwpfnhluy8h4e\n"
},
{
"path": "sample/scenes/LoginView/LoginView.tscn",
"chars": 6514,
"preview": "[gd_scene load_steps=15 format=3 uid=\"uid://bht0ln2ftshrw\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://njn2rf7rj4ph\" path"
},
{
"path": "sample/scenes/LogsView/LogsView.gd",
"chars": 1347,
"preview": "class_name LogsView\nextends VBoxContainer\n\n@onready var logs_label = %LogsLabel\n\nfunc _ready() -> void:\n\tHPlatform.log_m"
},
{
"path": "sample/scenes/LogsView/LogsView.gd.uid",
"chars": 20,
"preview": "uid://b54ebdyvahtmv\n"
},
{
"path": "sample/scenes/LogsView/LogsView.tscn",
"chars": 1712,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://cl2qvlvdhn2iw\"]\n\n[ext_resource type=\"FontFile\" uid=\"uid://da6bpapjl4a5k\" path"
},
{
"path": "sample/scenes/MetricsView/MetricsView.gd",
"chars": 1692,
"preview": "class_name MetricView\nextends VBoxContainer\n\n@onready var begin_player_session_btn = %BeginPlayerSessionBtn\n@onready var"
},
{
"path": "sample/scenes/MetricsView/MetricsView.gd.uid",
"chars": 20,
"preview": "uid://b081ugrjtk51r\n"
},
{
"path": "sample/scenes/MetricsView/MetricsView.tscn",
"chars": 1179,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://bd06h3ufkhfd7\"]\n\n[ext_resource type=\"Script\" uid=\"uid://b081ugrjtk51r\" path=\""
},
{
"path": "sample/scenes/NotificationsView/NotificationsView.gd",
"chars": 157,
"preview": "class_name NotificationsView\nextends MarginContainer\n\n@onready var vb = $SC/PC/MC/VB\n\nfunc add_notification(node: Node):"
},
{
"path": "sample/scenes/NotificationsView/NotificationsView.gd.uid",
"chars": 19,
"preview": "uid://6tlvlmuarqub\n"
},
{
"path": "sample/scenes/StatsView/StatsView.gd",
"chars": 2174,
"preview": "class_name StatsView\nextends VBoxContainer\n\n# Local cache of stats\nvar stats = []\n\n@onready var stat_name = %StatNameLin"
},
{
"path": "sample/scenes/StatsView/StatsView.gd.uid",
"chars": 19,
"preview": "uid://svry6i6h3yam\n"
},
{
"path": "sample/scenes/StatsView/StatsView.tscn",
"chars": 2898,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://dgi7j5qx3xt84\"]\n\n[ext_resource type=\"Script\" uid=\"uid://svry6i6h3yam\" path=\"r"
},
{
"path": "sample/scenes/UI/NetworkImage.gd",
"chars": 1531,
"preview": "class_name NetworkImage\nextends MarginContainer\n\nvar LOADING_TEXTURE = preload(\"res://scenes/UI/loading-icon.png\")\n\n@onr"
},
{
"path": "sample/scenes/UI/NetworkImage.gd.uid",
"chars": 20,
"preview": "uid://bxtewm8nybcvn\n"
},
{
"path": "sample/scenes/UI/NetworkImage.tscn",
"chars": 1865,
"preview": "[gd_scene load_steps=6 format=3 uid=\"uid://djhhnis3ksdjk\"]\n\n[ext_resource type=\"Script\" uid=\"uid://bxtewm8nybcvn\" path=\""
},
{
"path": "sample/scenes/UI/PrimaryButton.tscn",
"chars": 1500,
"preview": "[gd_scene load_steps=5 format=3 uid=\"uid://t8s6xh1ax7uy\"]\n\n[sub_resource type=\"StyleBoxFlat\" id=\"6\"]\ncontent_margin_left"
},
{
"path": "sample/scenes/UI/joysticks.gd",
"chars": 189,
"preview": "extends Control\n\n@onready var shoot_joystick: TouchScreenJoystick = $ShootJoystick\n\n\nfunc _ready() -> void:\n\thide()\n\t\n\ti"
},
{
"path": "sample/scenes/UI/joysticks.gd.uid",
"chars": 20,
"preview": "uid://dygslh2f7uw40\n"
},
{
"path": "sample/scenes/UI/nat_type.gd",
"chars": 680,
"preview": "extends RichTextLabel\n\n\n#region built-in methods\n\nfunc _ready() -> void:\n\tHAuth.logged_in.connect(_on_logged_in)\n\tHAuth."
},
{
"path": "sample/scenes/UI/nat_type.gd.uid",
"chars": 19,
"preview": "uid://ft2lvpnnwl8k\n"
},
{
"path": "sample/scenes/UI/nat_type.tscn",
"chars": 494,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://bdlcslag0jdj1\"]\n\n[ext_resource type=\"Script\" uid=\"uid://ft2lvpnnwl8k\" path=\"r"
},
{
"path": "sample/scenes/UI/ping.gd",
"chars": 948,
"preview": "extends Label\n\n\nconst COUNT = 5\n\n\nvar _pings = []\nvar _ping_in_progress = false\nvar _last_ping_time = 0\n\n\nfunc _ready() "
},
{
"path": "sample/scenes/UI/ping.gd.uid",
"chars": 20,
"preview": "uid://diilhyvdor4ym\n"
},
{
"path": "sample/scenes/UI/ping.tscn",
"chars": 462,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://c37wtoikc8pgp\"]\n\n[ext_resource type=\"Script\" uid=\"uid://diilhyvdor4ym\" path=\""
},
{
"path": "sample/scenes/UI/players_score.gd",
"chars": 617,
"preview": "extends Label\n\n\nfunc _ready() -> void:\n\tStore.player_score_changed.connect(_on_players_score_changed)\n\n\nfunc _on_players"
},
{
"path": "sample/scenes/UI/players_score.gd.uid",
"chars": 20,
"preview": "uid://co6ig2d1xliiu\n"
},
{
"path": "sample/scenes/UI/players_score.tscn",
"chars": 358,
"preview": "[gd_scene load_steps=2 format=3 uid=\"uid://8kmyoi08gr22\"]\n\n[ext_resource type=\"Script\" uid=\"uid://co6ig2d1xliiu\" path=\"r"
},
{
"path": "sample/scenes/UI/touch_screen_joystick.gd",
"chars": 14403,
"preview": "## RESPONSIVE TOUCHSCREEN JOYSTICK 1.0.2 ##\n\n# From https://github.com/kntCyc1230/TouchScreenJoystick\n# MIT License\n# C"
},
{
"path": "sample/scenes/UI/touch_screen_joystick.gd.uid",
"chars": 20,
"preview": "uid://cgmpdyovn5vfm\n"
},
{
"path": "sample/scenes/UIView/UIView.gd",
"chars": 2875,
"preview": "class_name UIView\nextends VBoxContainer\n\n@onready var friends_visible_label = %FriendsVisibleLabel\n\n@onready var notific"
},
{
"path": "sample/scenes/UIView/UIView.gd.uid",
"chars": 20,
"preview": "uid://dja7fd2sotvig\n"
},
{
"path": "sample/scenes/UIView/UIView.tscn",
"chars": 2793,
"preview": "[gd_scene load_steps=4 format=3 uid=\"uid://b51w7a6ofuubp\"]\n\n[ext_resource type=\"Script\" uid=\"uid://dja7fd2sotvig\" path=\""
},
{
"path": "sample/scripts/Env.gd",
"chars": 612,
"preview": "extends Node\n\nvar _env = {}\n\n\nfunc load_env(p_path := \"res://.env\"):\n\tif not FileAccess.file_exists(p_path):\n\t\treturn {}"
},
{
"path": "sample/scripts/Env.gd.uid",
"chars": 20,
"preview": "uid://bjyq7tcpdc3ac\n"
},
{
"path": "sample/scripts/Store.gd",
"chars": 1016,
"preview": "extends Node\n\n\n@warning_ignore(\"unused_signal\")\nsignal player_score_changed\n\n\nconst GAME_SOCKET_NAME = \"EOSGSAMPLE\"\ncons"
}
]
// ... and 76 more files (download for full content)
About this extraction
This page contains the full source code of the 3ddelano/epic-online-services-godot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 276 files (1.7 MB), approximately 620.3k tokens, and a symbol index with 257 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.