From f1c7aa3726aebc0eb92c4ee6a8121798b6ab05d1 Mon Sep 17 00:00:00 2001
From: David Salz <me@davidsalz.de>
Date: Tue, 27 Feb 2018 18:39:46 +0100
Subject: [PATCH] Client.Overlay: fixed potential null-ref exception in
 Overlay.Enabled and added documentation Server.ServerInit: added helper
 function and additional constructor to help with IP address format
 Server.Stats: added ClearUserAchievement, SetUserAchievement,
 GetUserAchievement

---
 Facepunch.Steamworks/Client/Overlay.cs    |  9 +++++-
 Facepunch.Steamworks/Server/ServerInit.cs | 26 ++++++++++++++++
 Facepunch.Steamworks/Server/Stats.cs      | 37 +++++++++++++++++++++++
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/Facepunch.Steamworks/Client/Overlay.cs b/Facepunch.Steamworks/Client/Overlay.cs
index 73da7fd..aefae2d 100644
--- a/Facepunch.Steamworks/Client/Overlay.cs
+++ b/Facepunch.Steamworks/Client/Overlay.cs
@@ -25,9 +25,16 @@ namespace Facepunch.Steamworks
     {
         internal Client client;
 
+        /// <summary>
+        /// Returns true if the Steam Overlay is actually available, false if it was not injected properly.
+        /// Note that it may take some time after Steam_Init() until the overlay injection is complete.
+        /// Also note that the overlay will only work if the Steam API is initialized before the rendering device is initialized. That means that 
+        /// for Unity3D games the overlay is only available if the game was launched directly through Steam. Calling Steam_Init() from Mono
+        /// code is too late.  
+        /// </summary>
         public bool Enabled
         {
-            get { return client.native.utils.IsOverlayEnabled(); }
+            get { return client.native != null ? client.native.utils.IsOverlayEnabled() : false; }
         }
 
         public void OpenUserPage( string name, ulong steamid ) { client.native.friends.ActivateGameOverlayToUser( name, steamid ); }
diff --git a/Facepunch.Steamworks/Server/ServerInit.cs b/Facepunch.Steamworks/Server/ServerInit.cs
index b4787a2..cb37dee 100644
--- a/Facepunch.Steamworks/Server/ServerInit.cs
+++ b/Facepunch.Steamworks/Server/ServerInit.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net;
 using System.Runtime.InteropServices;
 using System.Text;
 
@@ -42,6 +43,31 @@ namespace Facepunch.Steamworks
             GameDescription = gameDesc;
         }
 
+        public ServerInit(IPAddress ip, string modDir, string gameDesc)
+        {
+            IpAddress = ip.IpToInt32();
+            ModDir = modDir;
+            GameDescription = gameDesc;
+        }
+
+        /// <summary>
+        /// set the server ip
+        /// </summary>
+        public ServerInit Ip(string ip)
+        {
+            IpAddress = IPAddress.Parse(ip).IpToInt32();
+            return this;
+        }
+
+        /// <summary>
+        /// set the server ip
+        /// </summary>
+        public ServerInit Ip(IPAddress ip)
+        {
+            IpAddress = ip.IpToInt32();
+            return this;
+        }
+
         /// <summary>
         /// Set the Steam quert port 
         /// </summary>
diff --git a/Facepunch.Steamworks/Server/Stats.cs b/Facepunch.Steamworks/Server/Stats.cs
index 0a28aa4..22c25ec 100644
--- a/Facepunch.Steamworks/Server/Stats.cs
+++ b/Facepunch.Steamworks/Server/Stats.cs
@@ -111,5 +111,42 @@ namespace Facepunch.Steamworks
 
             return data;
         }
+
+        /// <summary>
+        /// Resets the unlock state of an achievement for the given user. Useful mainly for testing purposes.
+        /// If the "set by" field says "Official GS", only a registerd server IP may do this.
+        /// You should have called Refresh for this userid - which downloads the stats from the backend. 
+        /// If you didn't call it this will always return false.
+        /// </summary>
+        public bool ClearUserAchievement(ulong steamid, string name)
+        {
+            return server.native.gameServerStats.ClearUserAchievement(steamid, name);
+        }
+
+        /// <summary>
+        /// Awards an achievement for the given user. The achievement must have been set up in the steam backand.
+        /// If the "set by" field says "Official GS", only a registerd server IP may do this.
+        /// You should have called Refresh for this userid - which downloads the stats from the backend. 
+        /// If you didn't call it this will always return false.
+        /// </summary>
+        public bool SetUserAchievement(ulong steamid, string name)
+        {
+            return server.native.gameServerStats.SetUserAchievement(steamid, name);
+        }
+
+        /// <summary>
+        /// Returns true if the given user has the given achievement unlocked. The achievement must have been set up in the steam backand.
+        /// You should have called Refresh for this userid - which downloads the stats from the backend. 
+        /// If you didn't call it this will always return false.
+        /// </summary>
+        public bool GetUserAchievement(ulong steamid, string name)
+        {
+            bool result = false;
+            if(!server.native.gameServerStats.GetUserAchievement(steamid, name, ref result))
+                return false;
+
+            return result;
+        }
+
     }
 }