Przeglądaj źródła

FCM Message multi, new game, next player

Axel Nordh 5 lat temu
rodzic
commit
e2d7bab296

+ 27 - 8
Assets/Material/Plastic.mat → Assets/Material/FrostingMaterial.mat

@@ -7,9 +7,9 @@ Material:
   m_CorrespondingSourceObject: {fileID: 0}
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
-  m_Name: Plastic
-  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
-  m_ShaderKeywords: 
+  m_Name: FrostingMaterial
+  m_Shader: {fileID: 4800000, guid: 0436188d17d73cd429ca6997bc2edde1, type: 3}
+  m_ShaderKeywords: IS_BLUR_ALPHA_MASKED
   m_LightmapFlags: 4
   m_EnableInstancingVariants: 0
   m_DoubleSidedGI: 0
@@ -20,7 +20,7 @@ Material:
     serializedVersion: 3
     m_TexEnvs:
     - _BumpMap:
-        m_Texture: {fileID: 0}
+        m_Texture: {fileID: 2800000, guid: 4b8d081e9d114c7f1100f5ab44295342, type: 3}
         m_Scale: {x: 1, y: 1}
         m_Offset: {x: 0, y: 0}
     - _DetailAlbedoMap:
@@ -28,7 +28,7 @@ Material:
         m_Scale: {x: 1, y: 1}
         m_Offset: {x: 0, y: 0}
     - _DetailMask:
-        m_Texture: {fileID: 2800000, guid: 58a7fe73af5ad13408c42a300d9df31d, type: 3}
+        m_Texture: {fileID: 0}
         m_Scale: {x: 1, y: 1}
         m_Offset: {x: 0, y: 0}
     - _DetailNormalMap:
@@ -47,6 +47,10 @@ Material:
         m_Texture: {fileID: 0}
         m_Scale: {x: 1, y: 1}
         m_Offset: {x: 0, y: 0}
+    - _Noise:
+        m_Texture: {fileID: 2800000, guid: 710548c670aa3814ea179e1fc9fdf233, type: 3}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
     - _OcclusionMap:
         m_Texture: {fileID: 0}
         m_Scale: {x: 1, y: 1}
@@ -56,22 +60,37 @@ Material:
         m_Scale: {x: 1, y: 1}
         m_Offset: {x: 0, y: 0}
     m_Floats:
+    - _Blur: 1
+    - _BumpAmt: 71.6
     - _BumpScale: 1
-    - _Cutoff: 0.5
+    - _ColorMask: 15
+    - _Cutoff: 0.709803
     - _DetailNormalMapScale: 1
     - _DstBlend: 0
     - _GlossMapScale: 1
-    - _Glossiness: 0.55
+    - _Glossiness: 0.5
     - _GlossyReflections: 1
+    - _IsAlphaMasked: 1
+    - _IsSpriteVisible: 0
     - _Metallic: 0
     - _Mode: 0
     - _OcclusionStrength: 1
     - _Parallax: 0.02
+    - _Radius: 10
+    - _Range: 0.02
+    - _Shininess: 0.051
     - _SmoothnessTextureChannel: 0
     - _SpecularHighlights: 1
     - _SrcBlend: 1
+    - _Stencil: 0
+    - _StencilComp: 8
+    - _StencilOp: 0
+    - _StencilReadMask: 255
+    - _StencilWriteMask: 255
     - _UVSec: 0
+    - _UseUIAlphaClip: 0
     - _ZWrite: 1
     m_Colors:
-    - _Color: {r: 0.6603774, g: 0.21493416, b: 0.21493416, a: 1}
+    - _Color: {r: 0.8773585, g: 0, b: 0, a: 0.25490198}
     - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _OverlayColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}

+ 1 - 1
Assets/Material/Plastic.mat.meta → Assets/Material/FrostingMaterial.mat.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 21b0b4d6b30cb19438cd65eec9394c06
+guid: 0fd71462391ecb247bf89a924b18569e
 NativeFormatImporter:
   externalObjects: {}
   mainObjectFileID: 0

+ 90 - 1
Assets/Prefab/AnswerlineQuestion.prefab

@@ -183,6 +183,7 @@ MonoBehaviour:
   safeColor:
     serializedVersion: 2
     rgba: 3458698286
+  frosting: {fileID: 1130121227948233853}
 --- !u!114 &5242752221404020469
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -236,6 +237,7 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children:
   - {fileID: 5145380997340698410}
+  - {fileID: 6381293940991122038}
   m_Father: {fileID: 311079892285430443}
   m_RootOrder: 1
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -334,7 +336,7 @@ MeshRenderer:
   m_RenderingLayerMask: 1
   m_RendererPriority: 0
   m_Materials:
-  - {fileID: 2100000, guid: 21b0b4d6b30cb19438cd65eec9394c06, type: 2}
+  - {fileID: 0}
   m_StaticBatchInfo:
     firstSubMesh: 0
     subMeshCount: 0
@@ -623,6 +625,93 @@ MonoBehaviour:
     m_VerticalOverflow: 0
     m_LineSpacing: 1
   m_Text: This is a new question
+--- !u!1 &5177668919849068552
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6381293940991122038}
+  - component: {fileID: 3555725356691519508}
+  - component: {fileID: 6600976662145200931}
+  - component: {fileID: 1130121227948233853}
+  m_Layer: 5
+  m_Name: Frosting
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &6381293940991122038
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5177668919849068552}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 5145380995516278080}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0.000015258789, y: 17.4}
+  m_SizeDelta: {x: 0, y: 34.848633}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3555725356691519508
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5177668919849068552}
+  m_CullTransparentMesh: 0
+--- !u!114 &6600976662145200931
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5177668919849068552}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 2100000, guid: 0fd71462391ecb247bf89a924b18569e, type: 2}
+  m_Color: {r: 0.6603774, g: 0.109024554, b: 0.109024554, a: 0.9647059}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!225 &1130121227948233853
+CanvasGroup:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5177668919849068552}
+  m_Enabled: 1
+  m_Alpha: 0
+  m_Interactable: 0
+  m_BlocksRaycasts: 0
+  m_IgnoreParentGroups: 0
 --- !u!1 &5307012865466936910
 GameObject:
   m_ObjectHideFlags: 0

+ 1 - 43
Assets/Scenes/narKampen.unity

@@ -3096,49 +3096,6 @@ MonoBehaviour:
   m_OnValueChanged:
     m_PersistentCalls:
       m_Calls: []
---- !u!1 &1805246927
-GameObject:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  serializedVersion: 6
-  m_Component:
-  - component: {fileID: 1805246929}
-  - component: {fileID: 1805246928}
-  m_Layer: 0
-  m_Name: FirebaseController
-  m_TagString: Untagged
-  m_Icon: {fileID: 0}
-  m_NavMeshLayer: 0
-  m_StaticEditorFlags: 0
-  m_IsActive: 1
---- !u!114 &1805246928
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 1805246927}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 6dba90c1b32c37c43b0cb61d9dd0280c, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
---- !u!4 &1805246929
-Transform:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 1805246927}
-  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: 960, y: 540, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
-  m_Children: []
-  m_Father: {fileID: 0}
-  m_RootOrder: 4
-  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1 &1810792917
 GameObject:
   m_ObjectHideFlags: 0
@@ -4003,6 +3960,7 @@ MonoBehaviour:
   cardFront: {fileID: 4841476718879058384}
   NewQuestionCard: {fileID: 5342259222199889197}
   startParent: {fileID: 1119394964}
+  gameManager: {fileID: 225506176}
 --- !u!1 &5619997247734449657
 GameObject:
   m_ObjectHideFlags: 0

+ 39 - 13
Assets/Scripts/Database/OnlineDatabase.cs

@@ -6,6 +6,7 @@ using System.Data;
 using System;
 using UnityEngine.Networking;
 using System.IO;
+using System.Text;
 
 public class OnlineDatabase : MonoBehaviour {
     private const string onlineQuestionsUrl = "narkampen.nordh.xyz/narKampen/dbFiles/Question.php";
@@ -44,7 +45,7 @@ public class OnlineDatabase : MonoBehaviour {
         return list;
     }
 
-    internal void SetupNewOnlineGame(int limitPerQuestion, int limitPerPlayer, int toWin, List<InviteSearchResult> inviteUsers) {
+    internal int SetupNewOnlineGame(int limitPerQuestion, int limitPerPlayer, int toWin, List<InviteSearchResult> inviteUsers) {
         List<int> playerIds = new List<int>();
         inviteUsers.ForEach(i => playerIds.Add(i.GetId()));
         int currentUser = Database.Instance.GetSignedInUser().Key;
@@ -59,9 +60,16 @@ public class OnlineDatabase : MonoBehaviour {
 
         string response = CallOnlineDatabaseWithResponse("NewOnlineGame.php", form);
 
-        if (!response.Equals("")) {
-            Debug.Log(response);
+        if (response.Equals("")) {
+            Debug.Log("Expected gameId in response for creating new game but did not get one");
+        }
+
+        if (Int32.TryParse(response, out int newGameId)) {
+            return newGameId; 
+        } else {
+            Debug.Log("Failed to get new game id with response " + response);
         }
+
     }
 
     [Serializable]
@@ -584,16 +592,34 @@ public class OnlineDatabase : MonoBehaviour {
 
     internal void SendNextPlayerMessage(int gameId, String nextPlayer)
     {
-        String filename = "FCMNextPlayer.php";
-        String postUrl = serverUrl + filename;
-
-        postUrl += "?gameId=" + gameId + "&playerName=" + nextPlayer;
-
-        UnityWebRequest www = UnityWebRequest.Get(postUrl);
-        www.SendWebRequest();
+        WWWForm form = new WWWForm();
+        form.AddField("gameId", gameId);
+        form.AddField("playerName", nextPlayer);
+        form.AddField("title", LocalizationManager.Instance.GetText("FCM_NextPlayerTitle"));
+        List<KeyValuePair<string, int>> players = OnlineDatabase.Instance.GetPlayersForGame(gameId);
+        StringBuilder sb = new StringBuilder();
+        foreach (KeyValuePair<String, int> player in players)
+        {
+            sb.AppendLine(player.Key + " <" + player.Value + ">");
+            
+        }
+        String message = String.Format(LocalizationManager.Instance.GetText("FCM_NEXT_PLAYER_MESSAGE"),sb.ToString());
+        form.AddField("message", message);
+        form.AddField("type", "FCMNextPlayer");
+        
+        //string response = CallOnlineDatabaseWithResponse("FCMNextPlayer.php", form);
+        CallDatabase("FCMMessage.php", form);
+    }
 
-        if (www.isNetworkError || www.isHttpError) {
-            Debug.Log(www.error);
-        } 
+    internal void SendInviteForNewGame(int gameId, List<String> Players, String inviter) {
+        WWWForm form = new WWWForm();
+        form.AddField("gameId", gameId);
+        int index = 0;
+        foreach(String player in Players) {
+            form.AddField("player" + index++, player);
+        }
+        form.AddField("message", String.Format(LocalizationManager.Instance.GetText("FCM_NEW_GAME_MESSAGE"), inviter));
+        form.AddField("type", "InviteMessage");
+        CallDatabase("FCMMessage.php", form);
     }
 }

+ 17 - 2
Assets/Scripts/MainGame/NewQuestionCardController.cs

@@ -14,11 +14,13 @@ public class NewQuestionCardController : MonoBehaviour, IPointerClickHandler {
     public GameObject NewQuestionCard;
 
     bool rotateDone = true;
+    bool backClickable = true;
 
     [SerializeField] GameObject startParent;
+    [SerializeField] GameObject gameManager;
 
     public void OnPointerClick(PointerEventData eventData) {
-        if (cardBack.activeSelf && rotateDone)
+        if (cardBack.activeSelf && rotateDone && backClickable)
         {
             RotateCard();
         }
@@ -73,9 +75,22 @@ public class NewQuestionCardController : MonoBehaviour, IPointerClickHandler {
     }
 
     public void GenerateNewQuestion() {
+        KeyValuePair<int, string> SignedInUser = Database.Instance.GetSignedInUser();
+        string currentPlayer = GameManagerScript.GetCurrentPlayer();
+
         resetPosition();
         ShowBackside();
-        transform.parent.GetComponent<NewQuestionsPanel>().generateNewQuestion();
+        string gameMode = gameManager.GetComponent<GameManagerScript>().GetGameMode();
+        if (gameMode.Equals("Online")) {
+            if (currentPlayer.Equals(SignedInUser.Value)) {
+                backClickable = true;
+            } else {
+                backClickable = false;
+            }
+        } else {
+            backClickable =  true;
+        }
+        transform.parent.GetComponent<NewQuestionsPanel>().generateNewQuestion(backClickable);
     }
 
     private void resetPosition() {

+ 20 - 15
Assets/Scripts/MainGame/NewQuestionsPanel.cs

@@ -39,7 +39,7 @@ public class NewQuestionsPanel : MonoBehaviour
             gameManagerScript = gameManager.GetComponent<GameManagerScript>();
         }
         if (Database.Instance.GetRoundValue(gameManagerScript.GameId, gameManagerScript.GameMode) > 1) {
-            generateNewQuestion();
+            generateNewQuestion(true);
         }
     }
     // Update is called once per frame
@@ -48,22 +48,27 @@ public class NewQuestionsPanel : MonoBehaviour
         
     }
 
-    public void generateNewQuestion() {
-        AnswerLineQuestionCard[] answerLineQuestions = QuestionAnswerLine.GetComponentsInChildren<AnswerLineQuestionCard>();
-        List<int> answerIds = new List<int>();
-        foreach (var aq in answerLineQuestions) {
-            answerIds.Add(aq.GetId());
-        }
+    public void generateNewQuestion(bool setQuestionActive) {
+        if (setQuestionActive) {
+            AnswerLineQuestionCard[] answerLineQuestions = QuestionAnswerLine.GetComponentsInChildren<AnswerLineQuestionCard>();
+            List<int> answerIds = new List<int>();
+            foreach (var aq in answerLineQuestions) {
+                answerIds.Add(aq.GetId());
+            }
 
-        string user = Database.Instance.GetSignedInUser().Value;
-        QuestionData = Database.Instance.GetNewQuestion(answerIds, user,gameManager.GetComponent<GameManagerScript>().GameMode);
-        // QuestionData = OnlineDatabase.Instance.GetNewQuestion(answerIds, user);
+            string user = Database.Instance.GetSignedInUser().Value;
+            QuestionData = Database.Instance.GetNewQuestion(answerIds, user,gameManager.GetComponent<GameManagerScript>().GameMode);
 
-        AnswerText.text = "???? - ????";
-        QuestionText.text = QuestionData.Question;
-        backCategoryText.text = QuestionData.CategoryName;
-        QuestioncardBackside.GetComponent<Image>().color = QuestionData.CategoryColor;
-        
+            AnswerText.text = "???? - ????";
+            QuestionText.text = QuestionData.Question;
+            backCategoryText.text = QuestionData.CategoryName;
+            QuestioncardBackside.GetComponent<Image>().color = QuestionData.CategoryColor;
+            GetComponentInChildren<Button>().interactable = true;
+        } else {
+            backCategoryText.text = LocalizationManager.Instance.GetText("NOT_YOUR_TURN");
+            QuestioncardBackside.GetComponent<Image>().color = new Color(130f,130f,130f,255f);
+            GetComponentInChildren<Button>().interactable = false;
+        }
     }
 
 }

+ 10 - 0
Assets/Scripts/MainGame/QuestionCard.cs

@@ -20,6 +20,8 @@ public class QuestionCard : MonoBehaviour {
     public Color32 unsafeColor;
     public Color32 safeColor;
 
+    [SerializeField] CanvasGroup frosting;
+
     public void SetQuestionSafe() {
         this.GetComponent<Image>().color = safeColor;
     }
@@ -91,4 +93,12 @@ public class QuestionCard : MonoBehaviour {
         }
         return backCategoryText.text;
     }
+
+    public void SetFrostingActive(Boolean value) {
+        if (value) {
+            frosting.alpha = 1f;
+        } else {
+            frosting.alpha = 0f;
+        }
+    }
 }

+ 11 - 2
Assets/Scripts/MainGame/ScrollViewScript.cs

@@ -70,6 +70,8 @@ public class ScrollViewScript : MonoBehaviour {
         ldz.transform.SetSiblingIndex(i++);
         ldz.transform.localScale = new Vector3(1,1,1);
 
+        KeyValuePair<int, string> signedInUser = Database.Instance.GetSignedInUser();
+
         foreach (NewQuestionData q in questions) {
             GameObject answerLineQuestion = Instantiate(answerlineQuestionPrefab, Vector3.zero, Quaternion.identity);
             answerLineQuestion.transform.SetParent(contentPanel, false);
@@ -82,6 +84,14 @@ public class ScrollViewScript : MonoBehaviour {
             answerLineQuestionCard.SetId(q.Id);
             answerLineQuestionCard.SetQuestionSafe();
 
+            if (gameMode.Equals("Online")) {
+                if (signedInUser.Value.Equals(currentPlayer)) {
+                    answerLineQuestionCard.SetFrostingActive(false);
+                } else {
+                    answerLineQuestionCard.SetFrostingActive(true);
+                }
+            }
+
             GameObject mdz = Instantiate(middleDropZone, Vector3.zero, Quaternion.identity);
             mdz.transform.SetParent(contentPanel);
             mdz.transform.SetSiblingIndex(i++);
@@ -146,7 +156,7 @@ public class ScrollViewScript : MonoBehaviour {
         int lostQuestions = 0;
         for (int i = 0; i < contentPanel.childCount; i++) {
             AnswerLineQuestionCard q = contentPanel.GetChild(i).GetComponent<AnswerLineQuestionCard>();
-            if (!q.IsQuestionSafe()) {
+            if (q is AnswerLineQuestionCard && !q.IsQuestionSafe()) {
                 lostQuestions++;
                 Destroy(q);
                 Destroy(q.gameObject);
@@ -207,7 +217,6 @@ public class ScrollViewScript : MonoBehaviour {
             statsScript.MakeBold(currentPlayer);
             Database.Instance.SetCurrentPlayer(gameId, currentPlayer, GetGameMode());
             ips.SetCurrentPlayer(currentPlayer);
-            //ResetNewQuestionPosition();
             dialog.Hide();
         });
         dialog.SetOnDecline("", () => dialog.Hide());

+ 6 - 1
Assets/Scripts/NewGameScene/NewOnlineGame.cs

@@ -47,7 +47,12 @@ public class NewOnlineGame : MonoBehaviour
         int timeLimitPlayer = GetInputFieldValue(timeLimitPerPlayer);
         int correctToWin = GetInputFieldValue(correctAnswersToWin);
         List<InviteSearchResult> inviteUsers = ips.GetSelectedUsersForInvite();
-        OnlineDatabase.Instance.SetupNewOnlineGame(timeLimitQuestion, timeLimitPlayer, correctToWin, inviteUsers);
+        int newGameId = OnlineDatabase.Instance.SetupNewOnlineGame(timeLimitQuestion, timeLimitPlayer, correctToWin, inviteUsers);
+        List<String> invitePlayerNames = new List<String>();
+        foreach (InviteSearchResult isr in inviteUsers) {
+            invitePlayerNames.Add(isr.GetName())
+        }
+        OnlineDatabase.Instance.SendInviteForNewGame(newGameId, invitePlayerNames, Database.Instance.GetSignedInUser().Value);
     }
 
     private int GetInputFieldValue(InputField inputField) {

+ 8 - 0
Assets/Shaders.meta

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

+ 95 - 0
Assets/Shaders/Frost.shader

@@ -0,0 +1,95 @@
+// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
+
+Shader "Custom/Frost" 
+{
+	Properties
+	{
+		_Color("Color", Color) = (1, 1, 1, 1)
+
+		_MainTex("Diffuse", 2D) = "white" {}
+		_Noise("Noise", 2D) = "black" {}
+
+		_Range("Range", Float) = 0.025
+		_Blur("Blur", Float) = 0.005
+	}
+
+	SubShader
+	{
+		Cull Back
+
+		GrabPass{ "_Frost" }
+
+		CGINCLUDE
+		#include "UnityCG.cginc"
+
+		half4 _Color;
+
+		sampler2D _MainTex;
+		float4 _MainTex_ST;
+
+		sampler2D _Frost;
+		sampler2D _Noise;
+		float4 _Noise_ST;
+
+		half _Range;
+		half _Blur;
+
+		ENDCG
+
+		Pass
+		{
+			CGPROGRAM
+			#pragma target 3.0
+			#pragma vertex vert
+			#pragma fragment frag
+
+			struct v2f
+			{
+				float4 pos : SV_POSITION;
+
+				float3 uv : TEXCOORD;
+				float4 screenPos : TEXCOORD1;
+				float3 ray : TEXCOORD2;
+			};
+
+			v2f vert(appdata_full v)
+			{
+				v2f o;
+				o.pos = UnityObjectToClipPos(v.vertex);
+				o.uv = v.texcoord;
+				o.screenPos = ComputeScreenPos(o.pos);
+				o.ray = mul(UNITY_MATRIX_MV, v.vertex).xyz * float3(-1, -1, 1);
+				return o;
+			}
+
+			half4 frag(v2f i) : SV_Target
+			{
+				i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
+				float2 uv = i.screenPos.xy / i.screenPos.w;
+
+				float2 frostUV = tex2D(_Noise, i.uv * _Noise_ST.xy + _Noise_ST.zw).xy;
+
+				frostUV -= 0.5;
+				frostUV *= _Range;
+				frostUV += uv;
+
+				half4 frost = tex2D(_Frost, frostUV);
+				frost += tex2D(_Frost, frostUV + float2(_Blur, _Blur));
+				frost += tex2D(_Frost, frostUV + float2(_Blur, -_Blur));
+				frost += tex2D(_Frost, frostUV + float2(-_Blur, _Blur));
+				frost += tex2D(_Frost, frostUV + float2(-_Blur, -_Blur));
+				frost *= 0.2;
+
+				half4 diffuse = tex2D(_MainTex, i.uv * _MainTex_ST.xy + _MainTex_ST.zw);
+
+				half alpha = _Color.a * diffuse.a;
+
+				return half4(frost.xyz + (diffuse.rgb * _Color.rgb * alpha), 1);
+			}
+
+			ENDCG
+		}
+	}
+
+	Fallback Off
+}

+ 11 - 0
Assets/Shaders/Frost.shader.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fd7990cc88314e94db057e67324c9b20
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures:
+  - _MainTex: {instanceID: 0}
+  - _Noise: {fileID: 2800000, guid: 58a7fe73af5ad13408c42a300d9df31d, type: 3}
+  nonModifiableTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 139 - 0
Assets/Shaders/UIBlur.shader

@@ -0,0 +1,139 @@
+Shader "Custom/UIBlur"
+{
+
+    Properties
+    {
+        [Toggle(IS_BLUR_ALPHA_MASKED)] _IsAlphaMasked("Image Alpha Masks Blur", Float) = 1
+        [Toggle(IS_SPRITE_VISIBLE)] _IsSpriteVisible("Show Image", Float) = 1
+
+        // Internally enforced by MAX_RADIUS
+        _Radius("Blur Radius", Range(0, 64)) = 1
+        _OverlayColor("Blurred Overlay/Opacity", Color) = (0.5, 0.5, 0.5, 1)
+
+        // see Stencil in UI/Default
+        [HideInInspector][PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
+        [HideInInspector]_StencilComp ("Stencil Comparison", Float) = 8
+        [HideInInspector]_Stencil ("Stencil ID", Float) = 0
+        [HideInInspector]_StencilOp ("Stencil Operation", Float) = 0
+        [HideInInspector]_StencilWriteMask ("Stencil Write Mask", Float) = 255
+        [HideInInspector]_StencilReadMask ("Stencil Read Mask", Float) = 255
+        [HideInInspector]_ColorMask ("Color Mask", Float) = 15
+        [HideInInspector]_UseUIAlphaClip ("Use Alpha Clip", Float) = 0
+    }
+
+    Category
+    {
+        Tags
+        {
+            "Queue" = "Transparent"
+            "IgnoreProjector" = "True"
+            "RenderType" = "Transparent"
+            "PreviewType" = "Plane"
+            "CanUseSpriteAtlas" = "True"
+        }
+
+        Stencil
+        {
+            Ref [_Stencil]
+            Comp [_StencilComp]
+            Pass [_StencilOp]
+            ReadMask [_StencilReadMask]
+            WriteMask [_StencilWriteMask]
+        }
+
+        Cull Off
+        Lighting Off
+        ZWrite Off
+        ZTest [unity_GUIZTestMode]
+        Blend SrcAlpha OneMinusSrcAlpha
+        ColorMask [_ColorMask]
+
+        SubShader
+        {
+
+            GrabPass
+            {
+                Tags
+                { 
+                    "LightMode" = "Always"
+                    "Queue" = "Background"  
+                }
+            }
+
+            Pass
+            {
+                Name "UIBlur_Y"
+                Tags{ "LightMode" = "Always" }
+
+            CGPROGRAM
+                #pragma vertex vert
+                #pragma fragment frag
+                #pragma fragmentoption ARB_precision_hint_fastest
+                #pragma multi_compile __ IS_BLUR_ALPHA_MASKED
+                #pragma multi_compile __ IS_SPRITE_VISIBLE
+                #pragma multi_compile __ UNITY_UI_ALPHACLIP
+
+                #include "UIBlur_Shared.cginc"
+
+                sampler2D _GrabTexture;
+                float4 _GrabTexture_TexelSize;
+
+                half4 frag(v2f IN) : COLOR
+                {
+                    half4 pixel_raw = tex2D(_MainTex, IN.uvmain);
+                    return GetBlurInDir(IN, pixel_raw, _GrabTexture, _GrabTexture_TexelSize, 0, 1);
+                }
+            ENDCG
+            }
+
+            
+            GrabPass
+            {
+                Tags
+                { 
+                    "LightMode" = "Always"
+                    "Queue" = "Background"  
+                }
+            }
+            Pass
+            {
+                Name "UIBlur_X"
+                Tags{ "LightMode" = "Always" }
+
+
+            CGPROGRAM
+                #pragma vertex vert
+                #pragma fragment frag
+                #pragma fragmentoption ARB_precision_hint_fastest
+                #pragma multi_compile __ IS_BLUR_ALPHA_MASKED
+                #pragma multi_compile __ IS_SPRITE_VISIBLE
+                #pragma multi_compile __ UNITY_UI_ALPHACLIP
+
+                #include "UIBlur_Shared.cginc"
+
+
+                sampler2D _GrabTexture;
+                float4 _GrabTexture_TexelSize;
+
+                half4 frag(v2f IN) : COLOR
+                {
+                    half4 pixel_raw = tex2D(_MainTex, IN.uvmain);
+
+#if IS_SPRITE_VISIBLE
+                    return layerBlend(
+                            // Layer 0 : The blurred background
+                            GetBlurInDir(IN, pixel_raw, _GrabTexture, _GrabTexture_TexelSize, 1, 0), 
+                            // Layer 1 : The sprite itself
+                            pixel_raw * IN.color
+                        );
+#else
+                    return GetBlurInDir(IN, pixel_raw, _GrabTexture, _GrabTexture_TexelSize, 1, 0);
+#endif
+                }
+            ENDCG
+            }
+
+        }
+    }
+    Fallback "UI/Default"
+}

+ 9 - 0
Assets/Shaders/UIBlur.shader.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 0436188d17d73cd429ca6997bc2edde1
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures: []
+  nonModifiableTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 125 - 0
Assets/Shaders/UIBlur_Shared.cginc

@@ -0,0 +1,125 @@
+static const float MAX_RADIUS = 64;
+static const float ITER_STEP = 2;
+
+#include "UnityCG.cginc"
+#include "UnityUI.cginc"
+
+struct appdata_t
+{
+    float4 vertex : POSITION;
+    float2 texcoord: TEXCOORD0;
+    float4 color : COLOR;
+};
+
+struct v2f
+{
+    float4 vertex : POSITION;
+    float4 uvgrab : TEXCOORD0;
+    float4 worldpos : TEXCOORD1;
+    float2 uvmain : TEXCOORD2;
+    float4 color : COLOR;
+};
+
+sampler2D _MainTex;
+float4 _MainTex_ST;
+
+v2f vert(appdata_t v)
+{
+    v2f OUT;
+    UNITY_SETUP_INSTANCE_ID(v);
+    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
+    OUT.worldpos = v.vertex;
+    OUT.vertex = UnityObjectToClipPos(v.vertex);
+#if UNITY_UV_STARTS_AT_TOP
+    float scale = -1.0;
+#else
+    float scale = 1.0;
+#endif
+    OUT.uvgrab.xy = (float2(OUT.vertex.x, OUT.vertex.y*scale) + OUT.vertex.w) * 0.5;
+    OUT.uvgrab.zw = OUT.vertex.zw;
+    OUT.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
+    OUT.color = v.color;
+
+    return OUT;
+}
+
+float4 _OverlayColor;
+float _Radius;
+float4 _ClipRect;
+
+half4 layerBlend(half4 back, half4 front)
+{
+    half a0 = front.a;
+    half a1 = back.a;
+    half a01 = (1 - a0)*a1 + a0;
+
+    return half4(
+        ((1 - a0)*a1*back.r + a0*front.r) / a01,
+        ((1 - a0)*a1*back.g + a0*front.g) / a01,
+        ((1 - a0)*a1*back.b + a0*front.b) / a01,
+        a01);
+}
+
+// Like Photoshop, see http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html
+#define BLEND_OVERLAY(a, b) b <= 0.5 ? (2*b)*a : (1 - (1-2*(b-0.5)) * (1-a)) 
+half3 overlayBlend(half3 back, half3 front)
+{
+    return
+        half3(
+            BLEND_OVERLAY(back.r, front.r),
+            BLEND_OVERLAY(back.g, front.g),
+            BLEND_OVERLAY(back.b, front.b)
+        );
+}
+
+half4 GrabPixel(sampler2D tex, float4 uv)
+{
+    half4 pixel = tex2Dproj(tex, UNITY_PROJ_COORD(uv));
+    return half4(pixel.rgb, 1);
+}
+
+half4 GrabPixelXY(sampler2D tex, float4 uv, float4 size, half kernelx, half kernely)
+{
+    half4 pixel = tex2Dproj(
+        tex,
+        UNITY_PROJ_COORD(
+            float4(
+                uv.x + size.x * kernelx,
+                uv.y + size.y * kernely,
+                uv.z,
+                uv.w)
+        )
+    );
+    return half4(pixel.rgb, 1);
+}
+
+half4 GetBlurInDir(v2f IN, half4 pixel, sampler2D tex, float4 size, half dirx, half diry)
+{
+#ifdef UNITY_COLORSPACE_GAMMA
+    float4 color = _OverlayColor;
+#else
+    float4 color = float4(LinearToGammaSpace(_OverlayColor.rgb), _OverlayColor.a);
+#endif
+
+#if IS_BLUR_ALPHA_MASKED
+    float visibility = color.a*pixel.a;
+#else
+    float visibility = color.a;
+#endif
+
+    float radius = clamp(_Radius, 0, MAX_RADIUS);
+    visibility *= UnityGet2DClipping(IN.worldpos.xy, _ClipRect);
+
+    float4 sum = GrabPixel(tex, IN.uvgrab);
+
+    half steps = 1;
+    for (half range = ITER_STEP; range <= radius; range += ITER_STEP)
+    {
+        sum += GrabPixelXY(tex, IN.uvgrab, size, range*dirx, range*diry);
+        sum += GrabPixelXY(tex, IN.uvgrab, size, -range*dirx, -range*diry);
+        steps += 2;
+    }
+
+    half4 result = sum/steps;
+    return half4(overlayBlend(result.rgb, color.rgb), result.a*visibility);
+}

+ 9 - 0
Assets/Shaders/UIBlur_Shared.cginc.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4347520f53355e646a0bc9a91066609e
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures: []
+  nonModifiableTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 6 - 0
Assets/Translations/ENGLISH.xml

@@ -87,4 +87,10 @@
   <text key="ONLINE_PLAYER_STATUS_ACCEPTED">Accepted</text>
   <text key="ONLINE_PLAYER_STATUS_DECLINED">Denied</text>
   <text key="LOCK_QUESTIONS">Lock questions</text>
+  <text key="FCM_NEXT_PLAYER_TITLE">It's your turn</text>
+  <text key="FCM_NEXT_PLAYER_MESSAGE">It is your turn to play in the match against {0}</text>
+  <text key="NOT_YOUR_TURN">It's not your turn</text>
+  <text key="FCM_NEW_GAME_MESSAGE">You have been invited to a new game with {0}</text>
+  <text key="FCM_NEW_GAME_TITLE">Want to play a game?</text>
+  
 </Language>

+ 5 - 0
Assets/Translations/SWEDISH.xml

@@ -88,4 +88,9 @@
   <text key="ONLINE_PLAYER_STATUS_ACCEPTED">Accepterad</text>
   <text key="ONLINE_PLAYER_STATUS_DECLINED">Nekat</text>
   <text key="LOCK_QUESTIONS">Lås frågor</text>
+  <text key="FCM_NEXT_PLAYER_TITLE">Det är din tur</text>
+  <text key="FCM_NEXT_PLAYER_MESSAGE">Det är din tur i matchen mot {0}</text>
+  <text key="NOT_YOUR_TURN">Det är inte din tur</text>
+  <text key="FCM_NEW_GAME_MESSAGE">Du är inbjuden till ett nytt spel mot {0}</text>
+  <text key="FCM_NEW_GAME_TITLE">Vill du spela?</text>
 </Language>

BIN
Assets/narKampenLocal.db


+ 0 - 4
ProjectSettings/GvhProjectSettings.xml

@@ -1,8 +1,4 @@
 <projectSettings>
-  <projectSetting name="com.google.external-dependency-managerAnalyticsCookie" value="45165508978c4cac8d2379b67f2e8c55" />
-  <projectSetting name="com.google.external-dependency-managerAnalyticsEnabled" value="True" />
-  <projectSetting name="com.google.firebaseAnalyticsCookie" value="39211148ff1a496f963f242aa3654651" />
-  <projectSetting name="com.google.firebaseAnalyticsEnabled" value="True" />
   <projectSetting name="Google.IOSResolver.VerboseLoggingEnabled" value="False" />
   <projectSetting name="Google.PackageManagerResolver.VerboseLoggingEnabled" value="False" />
   <projectSetting name="Google.VersionHandler.VerboseLoggingEnabled" value="False" />

+ 63 - 47
dbFiles/FCMMessageing.php

@@ -1,51 +1,67 @@
 <?php
+/* FCM - Messageing */
 
-// Send notifications One device
+	$hostname = 'localhost';
+	$username = 'narKampen';
+	$pass = 'IfRLzj2HJBXA9eei';
+	$database = 'narKampen';
+	
+	$conn = new mysqli($hostname, $username, $pass, $database);
+	if (!$conn) {
+		die("Connection Failed. ". mysqli_connect_error());
+	}
+	mysqli_set_charset($conn,'utf8');
+	
+	$messageType = $conn->real_escape_string(isset($_POST['type'])?$_POST['type']:"");
+	
+	$title = $conn->real_escape_string($_POST['title']);
+	$messageToSend = $conn->real_escape_string($_POST['message']);
+	$gameId = $conn->real_escape_string($_POST['gameId']);
+	
+	if ($messageType === "FCMNextPlayer") {
+		$playerName = $conn->real_escape_string($_POST['playerName']);
+		$token = getToken();
+		
+		if ($token != null && $token != "") {
+			sendMessage($token);
+		}
+	} else if ($messageType === "InviteMessage") {
+		$i = 0;
+		while ($_POST['player' + $i] != null) {
+			$token = getToken($gameId, $conn->real_escape_string($_POST['player' $i]));
+			sendMessage($token);
+		}
 
-// Hämta token från sql användaren
-$token = "eMvkzPwkTheSeFLFAE5fho:APA91bE-pb5_0xoMn_Bza6-HrgpI5ufKPZ7zhF4NM_leYdfgYTk4MZJdfpfiKDkijUuQAiK7iaT7rXJucF20uh1GvmgjiomiuQehnDHcjUkGjaSvkQtVfj_s0AtLSPjIJz8EQ5Aujkfk";
-$message = "TEST MEDDELANDE FRÅN SERVERN";
-$title = "TEST TITEL";
-$url = "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send";
+	}
+	
+	function getToken($gameId, $playerName) {
+		$sql = "SELECT messageToken FROM `gamePlayers` INNER JOIN users ON users.id = playerId WHERE gameId = $gameId and users.username = '$playerName'";
 
-$fields = array(
-	"message" => array(
-		"token" => $token,
-		"notification" => 
-			array(
-				"body" => $message,
-				"title" => $title
-			)
-		)
-	);
-$fields = json_encode($fields);
-
-$headers = array(
-			'Content-Type: application/json',
-            'Authorization: Bearer ' . "AAAAGStp88I:APA91bERuLuU7DuAyW2yhoLQeiJizGZVsezzEdLhRa9v9Ehy7uYmHFvBTMrQooMDg0oaGNZE3DXd3Tl3E10JP58OCtuL7z1UQWo071tOCR8Ede3YUXDErs6Zkt8z1VxcBAkOxzVInId3"
-			);
-
-$curl = curl_init();
-
-curl_setopt($curl, CURLOPT_URL, $url);
-curl_setopt($curl, CURLOPT_POST, true);
-curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
-
-$response = curl_exec($curl);
-
-var_dump($response);
-
-curl_close($curl);
-
-/*
-curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
-"message":{
-   "notification":{
-     "title":"FCM Message",
-     "body":"This is an FCM Message"
-   },
-   "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
-}}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send
-*/
+		$result = $conn->query($sql);
+		if ($result->num_rows == 1) {
+			$returnArray = array();
+			$data = $result->fetch_assoc();
+			$token = $data['messageToken'];
+		} else {
+			echo "No games found for user";
+		}
+		
+		return $token;
+	}
+	
+	function sendMessage($token) {
+		// Your Firebase project ID
+		$project = "narkampen";
+		// Creates a notification for subscribers to the debug topic
+		$message = [
+			"message" => [
+				"token" => $token,
+				"notification" => [
+					"body" => $messageToSend,
+					"title" => $title,
+				]
+			]
+		];
+		// Send the Push Notification - use $response to inspect success or errors
+		$response = $httpClient->post("https://fcm.googleapis.com/v1/projects/{$project}/messages:send", ['json' => $message]);
+	}

+ 5 - 5
dbFiles/FCMNextPlayer.php

@@ -8,9 +8,6 @@ $client->useApplicationDefaultCredentials();
 $client->addScope('https://www.googleapis.com/auth/firebase.messaging');
 $httpClient = $client->authorize();
 
-/*
-$token = "eMvkzPwkTheSeFLFAE5fho:APA91bE-pb5_0xoMn_Bza6-HrgpI5ufKPZ7zhF4NM_leYdfgYTk4MZJdfpfiKDkijUuQAiK7iaT7rXJucF20uh1GvmgjiomiuQehnDHcjUkGjaSvkQtVfj_s0AtLSP>
-*/
 $hostname = 'localhost';
 $username = 'narKampen';
 $pass = 'IfRLzj2HJBXA9eei';
@@ -25,6 +22,9 @@ mysqli_set_charset($conn,'utf8');
 $gameId = $conn->real_escape_string($_POST['gameId']);
 $playerName = $conn->real_escape_string($_POST['playerName']);
 
+$title = $conn->real_escape_string($_POST['title']);
+$message = $conn->real_escape_string($_POST['message']);
+
 $sql = "SELECT messageToken FROM `gamePlayers` INNER JOIN users ON users.id = playerId WHERE gameId = $gameId and users.username = '$playerName'";
 
 $result = $conn->query($sql);
@@ -44,8 +44,8 @@ $message = [
     "message" => [
         "token" => $token,
         "notification" => [
-            "body" => "This is an FCM notification message!",
-            "title" => "FCM Message",
+            "body" => $message,
+            "title" => $title,
         ]
     ]
 ];

+ 2 - 0
dbFiles/NewOnlineGame.php

@@ -65,6 +65,8 @@
 	
 	$result = mysqli_query($conn,$playerSql);
 	$error = mysqli_error($conn);
+	
+	echo $gameId;
 	if ($error !== "") {
 		echo $error . " from sql " . $playerSql;
 	}

+ 1 - 1
dbFiles/OnlineGames.php

@@ -135,7 +135,7 @@
 		}
 		
 	} else if ($callFunction === "SetCurrentPlayer") {
-		$currentPlayer = $_POST['currentPlayer'];
+		$currentPlayer = $_POST['userName'];
 		$sql = "UPDATE game SET currentPlayer = $userId WHERE id = $gameId";
 		$result = $conn->query($sql);
 		if (!$result) {