steam api implementation

This commit is contained in:
MarcoHampel
2023-11-12 21:08:23 -05:00
parent f05ae959ea
commit 60e1ae4219
1614 changed files with 31598 additions and 142081 deletions

View File

@ -4,6 +4,7 @@ using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Steamworks;
public class MainMenuManager : MonoBehaviour
{
@ -37,6 +38,9 @@ public class MainMenuManager : MonoBehaviour
textList[0].GetComponent<Button>().onClick.AddListener(LoadFirstLevel);
textList[2].GetComponent<Button>().onClick.AddListener(ExitApp);
Cursor.visible = true;
Cursor.lockState = CursorLockMode.Confined;
}
@ -55,6 +59,18 @@ public class MainMenuManager : MonoBehaviour
private void LoadFirstLevel()
{
if (SteamManager.Initialized)
{
Steamworks.SteamUserStats.GetAchievement("ENTER_THE_STATION", out bool achievementCompleted);
if (!achievementCompleted)
{
SteamUserStats.SetAchievement("ENTER_THE_STATION");
SteamUserStats.StoreStats();
SteamAPI.RunCallbacks();
}
}
if (!transitioning)
{
cover.Play("Cover_load_out");

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6e954a9a26b1f7447a8a8a8aeafa34bb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,30 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Steamworks;
public class FriendObject : MonoBehaviour
{
public SteamId steamid;
public async void Invite()
{
if (SteamLobbyManager.UserInLobby)
{
SteamLobbyManager.CurrentLobby.InviteFriend(steamid);
Debug.Log("Invited " + steamid);
}
else
{
bool result = await SteamLobbyManager.CreateLobby();
if (result)
{
SteamLobbyManager.CurrentLobby.InviteFriend(steamid);
Debug.Log("Invited " + steamid + " Created a new lobby");
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 57db693cbe9a46345add801ae22e1e2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,74 +0,0 @@
using Steamworks;
using UnityEngine;
using UnityEngine.UI;
public class SteamFriendsManager : MonoBehaviour
{
public RawImage playerprofile;
public Text playername;
public Transform friendsContent;
public GameObject friendObj;
async void Start()
{
if (!SteamClient.IsValid) return;
playername.text = SteamClient.Name;
InitFriendsAsync();
var img = await SteamFriends.GetLargeAvatarAsync(SteamClient.SteamId);
playerprofile.texture = GetTextureFromImage(img.Value);
}
public static Texture2D GetTextureFromImage(Steamworks.Data.Image image)
{
Texture2D texture = new Texture2D((int)image.Width, (int)image.Height);
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
var p = image.GetPixel(x, y);
texture.SetPixel(x, (int)image.Height - y, new Color(p.r / 255.0f, p.g / 255.0f, p.b / 255.0f, p.a / 255.0f));
}
}
texture.Apply();
return texture;
}
public void InitFriendsAsync()
{
foreach (var friend in SteamFriends.GetFriends())
{
GameObject f = Instantiate(friendObj, friendsContent);
f.GetComponentInChildren<Text>().text = friend.Name;
f.GetComponent<FriendObject>().steamid = friend.Id;
AssingFriendImage(f, friend.Id);
}
}
public async void AssingFriendImage(GameObject f, SteamId id)
{
var img = await SteamFriends.GetLargeAvatarAsync(id);
f.GetComponentInChildren<RawImage>().texture = GetTextureFromImage(img.Value);
}
public static async System.Threading.Tasks.Task<Texture2D> GetTextureFromSteamIdAsync(SteamId id)
{
var img = await SteamFriends.GetLargeAvatarAsync(SteamClient.SteamId);
Steamworks.Data.Image image = img.Value;
Texture2D texture = new Texture2D((int)image.Width, (int)image.Height);
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
var p = image.GetPixel(x, y);
texture.SetPixel(x, (int)image.Height - y, new Color(p.r / 255.0f, p.g / 255.0f, p.b / 255.0f, p.a / 255.0f));
}
}
texture.Apply();
return texture;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3e1287d29b0590b4086746e0ea190f4e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,183 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class SteamLobbyManager : MonoBehaviour
{
public static Lobby CurrentLobby;
public static bool UserInLobby;
public UnityEvent onLobbyCreated;
public UnityEvent onLobbyJoined;
public UnityEvent onLobbyLeave;
public GameObject inLobbyFriend;
public Transform content;
public Dictionary<SteamId, GameObject> inLobby = new();
private void Start()
{
DontDestroyOnLoad(this);
SteamMatchmaking.OnLobbyCreated += OnLobbyCreatedCallBack;
SteamMatchmaking.OnLobbyEntered += OnLobbyEntered;
SteamMatchmaking.OnLobbyMemberJoined += OnLobbyMemberJoined;
SteamMatchmaking.OnChatMessage += OnChatMessage;
SteamMatchmaking.OnLobbyMemberDisconnected += OnLobbyMemberDisconnected;
SteamMatchmaking.OnLobbyMemberLeave += OnLobbyMemberDisconnected;
SteamMatchmaking.OnLobbyGameCreated += OnLobbyGameCreated;
SteamFriends.OnGameLobbyJoinRequested += OnGameLobbyJoinRequest;
SteamMatchmaking.OnLobbyInvite += OnLobbyInvite;
}
private void OnLobbyInvite(Friend friend, Lobby lobby)
{
Debug.Log($"{friend.Name} invited you to his lobby.");
}
private void OnLobbyGameCreated(Lobby lobby, uint ip, ushort port, SteamId id)
{
}
private async void OnLobbyMemberJoined(Lobby lobby, Friend friend)
{
Debug.Log($"{friend.Name} joined the lobby");
var obj = Instantiate(inLobbyFriend, content);
obj.GetComponentInChildren<Text>().text = friend.Name;
obj.GetComponentInChildren<RawImage>().texture =
await SteamFriendsManager.GetTextureFromSteamIdAsync(friend.Id);
inLobby.Add(friend.Id, obj);
}
private void OnLobbyMemberDisconnected(Lobby lobby, Friend friend)
{
Debug.Log($"{friend.Name} left the lobby");
Debug.Log($"New lobby owner is {CurrentLobby.Owner}");
if (inLobby.ContainsKey(friend.Id))
{
Destroy(inLobby[friend.Id]);
inLobby.Remove(friend.Id);
}
}
private void OnChatMessage(Lobby lobby, Friend friend, string message)
{
Debug.Log($"incoming chat message from {friend.Name} : {message}");
}
private async void OnGameLobbyJoinRequest(Lobby joinedLobby, SteamId id)
{
var joinedLobbySuccess = await joinedLobby.Join();
if (joinedLobbySuccess != RoomEnter.Success)
Debug.Log("failed to join lobby : " + joinedLobbySuccess);
else
CurrentLobby = joinedLobby;
}
private void OnLobbyCreatedCallBack(Result result, Lobby lobby)
{
if (result != Result.OK)
{
Debug.Log("lobby creation result not ok : " + result);
}
else
{
onLobbyCreated.Invoke();
Debug.Log("lobby creation result ok");
}
}
private async void OnLobbyEntered(Lobby lobby)
{
Debug.Log("Client joined the lobby");
UserInLobby = true;
foreach (var user in inLobby.Values) Destroy(user);
inLobby.Clear();
var obj = Instantiate(inLobbyFriend, content);
obj.GetComponentInChildren<Text>().text = SteamClient.Name;
obj.GetComponentInChildren<RawImage>().texture =
await SteamFriendsManager.GetTextureFromSteamIdAsync(SteamClient.SteamId);
inLobby.Add(SteamClient.SteamId, obj);
foreach (var friend in CurrentLobby.Members)
if (friend.Id != SteamClient.SteamId)
{
var obj2 = Instantiate(inLobbyFriend, content);
obj2.GetComponentInChildren<Text>().text = friend.Name;
obj2.GetComponentInChildren<RawImage>().texture =
await SteamFriendsManager.GetTextureFromSteamIdAsync(friend.Id);
inLobby.Add(friend.Id, obj2);
}
onLobbyJoined.Invoke();
}
public async void CreateLobbyAsync()
{
var result = await CreateLobby();
if (!result)
{
//Invoke a error message.
}
}
public static async Task<bool> CreateLobby()
{
try
{
var createLobbyOutput = await SteamMatchmaking.CreateLobbyAsync();
if (!createLobbyOutput.HasValue)
{
Debug.Log("Lobby created but not correctly instantiated.");
return false;
}
CurrentLobby = createLobbyOutput.Value;
CurrentLobby.SetPublic();
//currentLobby.SetPrivate();
CurrentLobby.SetJoinable(true);
return true;
}
catch (Exception exception)
{
Debug.Log("Failed to create multiplayer lobby : " + exception);
return false;
}
}
public void LeaveLobby()
{
try
{
UserInLobby = false;
CurrentLobby.Leave();
onLobbyLeave.Invoke();
foreach (var user in inLobby.Values) Destroy(user);
inLobby.Clear();
}
catch
{
}
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Return)) {
print("OWNER?:"+CurrentLobby.Owner);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d4b922de688dc97428e1fcaec4244b9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,164 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class SteamLobbyWithPlayer : MonoBehaviour
{
public static Lobby CurrentLobby;
public static bool UserInLobby;
public UnityEvent onLobbyCreated;
public UnityEvent onLobbyJoined;
public UnityEvent onLobbyLeave;
public Dictionary<SteamId, GameObject> inLobby = new();
public GameObject playerPrefab;
private void Start()
{
DontDestroyOnLoad(this);
SteamMatchmaking.OnLobbyCreated += OnLobbyCreatedCallBack;
SteamMatchmaking.OnLobbyEntered += OnLobbyEntered;
SteamMatchmaking.OnLobbyMemberJoined += OnLobbyMemberJoined;
// SteamMatchmaking.OnChatMessage += OnChatMessage;
SteamMatchmaking.OnLobbyMemberDisconnected += OnLobbyMemberDisconnected;
SteamMatchmaking.OnLobbyMemberLeave += OnLobbyMemberDisconnected;
SteamMatchmaking.OnLobbyGameCreated += OnLobbyGameCreated;
SteamFriends.OnGameLobbyJoinRequested += OnGameLobbyJoinRequest;
SteamMatchmaking.OnLobbyInvite += OnLobbyInvite;
CreateLobbyAsync();
}
private void OnLobbyInvite(Friend friend, Lobby lobby)
{
Debug.Log($"{friend.Name} invited you to his lobby.");
}
private void OnLobbyGameCreated(Lobby lobby, uint ip, ushort port, SteamId id)
{
}
private async void OnLobbyMemberJoined(Lobby lobby, Friend friend)
{
Debug.Log($"{friend.Name} joined the lobby");
GameObject obj = Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
inLobby.Add(friend.Id, obj);
}
private void OnLobbyMemberDisconnected(Lobby lobby, Friend friend)
{
Debug.Log($"{friend.Name} left the lobby");
Debug.Log($"New lobby owner is {CurrentLobby.Owner}");
if (inLobby.ContainsKey(friend.Id))
{
Destroy(inLobby[friend.Id]);
inLobby.Remove(friend.Id);
}
}
private async void OnGameLobbyJoinRequest(Lobby joinedLobby, SteamId id)
{
var joinedLobbySuccess = await joinedLobby.Join();
if (joinedLobbySuccess != RoomEnter.Success)
Debug.Log("failed to join lobby : " + joinedLobbySuccess);
else
CurrentLobby = joinedLobby;
}
private void OnLobbyCreatedCallBack(Result result, Lobby lobby)
{
if (result != Result.OK)
{
Debug.Log("lobby creation result not ok : " + result);
}
else
{
onLobbyCreated.Invoke();
Debug.Log("lobby creation result ok");
}
}
private async void OnLobbyEntered(Lobby lobby)
{
Debug.Log("Client joined the lobby");
UserInLobby = true;
foreach (var user in inLobby.Values) Destroy(user);
inLobby.Clear();
GameObject player = Instantiate(playerPrefab);
if(player == null)
Debug.Log("Player is null");
player.SetActive(true);
inLobby.Add(SteamClient.SteamId, player);
foreach (var friend in CurrentLobby.Members)
if (friend.Id != SteamClient.SteamId)
{
GameObject other_player = Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
inLobby.Add(friend.Id, other_player);
}
onLobbyJoined.Invoke();
}
public async void CreateLobbyAsync()
{
var result = await CreateLobby();
if (!result)
{
Debug.Log("Failed to create lobby");
}
else
{
Debug.Log("Lobby created");
}
}
public static async Task<bool> CreateLobby()
{
try
{
var createLobbyOutput = await SteamMatchmaking.CreateLobbyAsync();
if (!createLobbyOutput.HasValue)
{
Debug.Log("Lobby created but not correctly instantiated.");
return false;
}
CurrentLobby = createLobbyOutput.Value;
CurrentLobby.SetPublic();
//currentLobby.SetPrivate();
CurrentLobby.SetJoinable(true);
return true;
}
catch (Exception exception)
{
Debug.Log("Failed to create multiplayer lobby : " + exception);
return false;
}
}
public void LeaveLobby()
{
try
{
UserInLobby = false;
CurrentLobby.Leave();
onLobbyLeave.Invoke();
foreach (var user in inLobby.Values) Destroy(user);
inLobby.Clear();
}
catch
{
}
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Return)) {
print("OWNER?:"+CurrentLobby.Owner);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4a9cdaa19da06c243b851b524d9e182a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,39 +0,0 @@
using System;
using Steamworks;
using UnityEngine;
using UnityEngine.Events;
public class SteamManager : MonoBehaviour
{
public uint appId;
public UnityEvent onSteamFailed;
private void Awake()
{
DontDestroyOnLoad(this);
try
{
SteamClient.Init(appId);
Debug.Log("Steam is up and running!");
}
catch (Exception e)
{
Debug.Log(e.Message);
onSteamFailed.Invoke();
}
}
private void OnApplicationQuit()
{
try
{
Debug.Log("Steam is shutting down!");
SteamClient.Shutdown();
}
catch
{
Debug.Log("Steam is not running!");
}
}
}

View File

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 62ddefd95a62cbc4ea1a2aabc009a378
folderAsset: yes
DefaultImporter:
userData:

View File

@ -0,0 +1,182 @@
// The SteamManager is designed to work with Steamworks.NET
// This file is released into the public domain.
// Where that dedication is not recognized you are granted a perpetual,
// irrevocable license to copy and modify this file as you see fit.
//
// Version: 1.0.13
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX)
#define DISABLESTEAMWORKS
#endif
using UnityEngine;
#if !DISABLESTEAMWORKS
using System.Collections;
using Steamworks;
#endif
//
// The SteamManager provides a base implementation of Steamworks.NET on which you can build upon.
// It handles the basics of starting up and shutting down the SteamAPI for use.
//
[DisallowMultipleComponent]
public class SteamManager : MonoBehaviour {
#if !DISABLESTEAMWORKS
protected static bool s_EverInitialized = false;
protected static SteamManager s_instance;
protected static SteamManager Instance {
get {
if (s_instance == null) {
return new GameObject("SteamManager").AddComponent<SteamManager>();
}
else {
return s_instance;
}
}
}
protected bool m_bInitialized = false;
public static bool Initialized {
get {
return Instance.m_bInitialized;
}
}
protected SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook;
[AOT.MonoPInvokeCallback(typeof(SteamAPIWarningMessageHook_t))]
protected static void SteamAPIDebugTextHook(int nSeverity, System.Text.StringBuilder pchDebugText) {
Debug.LogWarning(pchDebugText);
}
#if UNITY_2019_3_OR_NEWER
// In case of disabled Domain Reload, reset static members before entering Play Mode.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void InitOnPlayMode()
{
s_EverInitialized = false;
s_instance = null;
}
#endif
protected virtual void Awake() {
// Only one instance of SteamManager at a time!
if (s_instance != null) {
Destroy(gameObject);
return;
}
s_instance = this;
if(s_EverInitialized) {
// This is almost always an error.
// The most common case where this happens is when SteamManager gets destroyed because of Application.Quit(),
// and then some Steamworks code in some other OnDestroy gets called afterwards, creating a new SteamManager.
// You should never call Steamworks functions in OnDestroy, always prefer OnDisable if possible.
throw new System.Exception("Tried to Initialize the SteamAPI twice in one session!");
}
// We want our SteamManager Instance to persist across scenes.
DontDestroyOnLoad(gameObject);
if (!Packsize.Test()) {
Debug.LogError("[Steamworks.NET] Packsize Test returned false, the wrong version of Steamworks.NET is being run in this platform.", this);
}
if (!DllCheck.Test()) {
Debug.LogError("[Steamworks.NET] DllCheck Test returned false, One or more of the Steamworks binaries seems to be the wrong version.", this);
}
try {
// If Steam is not running or the game wasn't started through Steam, SteamAPI_RestartAppIfNecessary starts the
// Steam client and also launches this game again if the User owns it. This can act as a rudimentary form of DRM.
// Note that this will run which ever version you have installed in steam. Which may not be the precise executable
// we were currently running.
// Once you get a Steam AppID assigned by Valve, you need to replace AppId_t.Invalid with it and
// remove steam_appid.txt from the game depot. eg: "(AppId_t)480" or "new AppId_t(480)".
// See the Valve documentation for more information: https://partner.steamgames.com/doc/sdk/api#initialization_and_shutdown
if (SteamAPI.RestartAppIfNecessary((AppId_t)2694500)) {
Debug.Log("[Steamworks.NET] Shutting down because RestartAppIfNecessary returned true. Steam will restart the application.");
Application.Quit();
return;
}
}
catch (System.DllNotFoundException e) { // We catch this exception here, as it will be the first occurrence of it.
Debug.LogError("[Steamworks.NET] Could not load [lib]steam_api.dll/so/dylib. It's likely not in the correct location. Refer to the README for more details.\n" + e, this);
Application.Quit();
return;
}
// Initializes the Steamworks API.
// If this returns false then this indicates one of the following conditions:
// [*] The Steam client isn't running. A running Steam client is required to provide implementations of the various Steamworks interfaces.
// [*] The Steam client couldn't determine the App ID of game. If you're running your application from the executable or debugger directly then you must have a [code-inline]steam_appid.txt[/code-inline] in your game directory next to the executable, with your app ID in it and nothing else. Steam will look for this file in the current working directory. If you are running your executable from a different directory you may need to relocate the [code-inline]steam_appid.txt[/code-inline] file.
// [*] Your application is not running under the same OS user context as the Steam client, such as a different user or administration access level.
// [*] Ensure that you own a license for the App ID on the currently active Steam account. Your game must show up in your Steam library.
// [*] Your App ID is not completely set up, i.e. in Release State: Unavailable, or it's missing default packages.
// Valve's documentation for this is located here:
// https://partner.steamgames.com/doc/sdk/api#initialization_and_shutdown
m_bInitialized = SteamAPI.Init();
if (!m_bInitialized) {
Debug.LogError("[Steamworks.NET] SteamAPI_Init() failed. Refer to Valve's documentation or the comment above this line for more information.", this);
return;
}
s_EverInitialized = true;
}
// This should only ever get called on first load and after an Assembly reload, You should never Disable the Steamworks Manager yourself.
protected virtual void OnEnable() {
if (s_instance == null) {
s_instance = this;
}
if (!m_bInitialized) {
return;
}
if (m_SteamAPIWarningMessageHook == null) {
// Set up our callback to receive warning messages from Steam.
// You must launch with "-debug_steamapi" in the launch args to receive warnings.
m_SteamAPIWarningMessageHook = new SteamAPIWarningMessageHook_t(SteamAPIDebugTextHook);
SteamClient.SetWarningMessageHook(m_SteamAPIWarningMessageHook);
}
}
// OnApplicationQuit gets called too early to shutdown the SteamAPI.
// Because the SteamManager should be persistent and never disabled or destroyed we can shutdown the SteamAPI here.
// Thus it is not recommended to perform any Steamworks work in other OnDestroy functions as the order of execution can not be garenteed upon Shutdown. Prefer OnDisable().
protected virtual void OnDestroy() {
if (s_instance != this) {
return;
}
s_instance = null;
if (!m_bInitialized) {
return;
}
SteamAPI.Shutdown();
}
protected virtual void Update() {
if (!m_bInitialized) {
return;
}
// Run Steam client callbacks
SteamAPI.RunCallbacks();
}
#else
public static bool Initialized {
get {
return false;
}
}
#endif // !DISABLESTEAMWORKS
}

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: c790abd20c22fc348ac5c95c419527bb
guid: ef4bffeda13d7a748973ff9204401c07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: