Skip to content

Commit 4809563

Browse files
authored
Merge pull request #1105 from PlayEveryWare/fix/display-encryption-key
feat: Display & Make editable the Encryption Key for Client Credentials
2 parents 66a5041 + d49d862 commit 4809563

File tree

7 files changed

+392
-10
lines changed

7 files changed

+392
-10
lines changed

Assets/Plugins/Source/Editor/EditorWindows/EOSEditorWindow.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ public RetainPreference(string key)
103103
/// </summary>
104104
protected static Font MonoFont;
105105

106-
protected EOSEditorWindow(string windowTitle, float minimumHeight = 50f, float minimumWidth = 50f,
106+
protected EOSEditorWindow(
107+
string windowTitle,
108+
float minimumHeight = 50f,
109+
float minimumWidth = 50f,
110+
bool needsInitialization = true,
107111
string preferencesOverrideKey = null)
108112
{
109113
// Set the preferences key either to the full name of the deriving type, or the provided override value.
@@ -114,6 +118,8 @@ protected EOSEditorWindow(string windowTitle, float minimumHeight = 50f, float m
114118
AbsoluteMinimumWindowHeight = minimumHeight;
115119
AbsoluteMinimumWindowWidth = minimumWidth;
116120

121+
_initialized = !needsInitialization;
122+
117123
WindowTitle = windowTitle;
118124
}
119125

@@ -128,7 +134,7 @@ protected virtual void OnEnable()
128134
EditorApplication.update += CheckForInitialized;
129135
}
130136

131-
private void OnDisable()
137+
protected virtual void OnDisable()
132138
{
133139
EditorApplication.update -= CheckForInitialized;
134140
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2024 PlayEveryWare
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
namespace PlayEveryWare.EpicOnlineServices.Editor.Windows
24+
{
25+
using PlayEveryWare.EpicOnlineServices.Editor.Utility;
26+
using PlayEveryWare.EpicOnlineServices;
27+
using System;
28+
using UnityEditor;
29+
using UnityEngine;
30+
31+
/// <summary>
32+
/// Represents a modal window used to display and edit the encryption key field of a set of client credentials.
33+
/// </summary>
34+
public sealed class EncryptionKeyWindow : ModalEOSEditorWindow<string>
35+
{
36+
public EncryptionKeyWindow() : base("Client Credential Encryption Key", 600f, 50f)
37+
{
38+
}
39+
40+
/// <summary>
41+
/// Helper function to show the modal window.
42+
/// </summary>
43+
/// <param name="input">
44+
/// The encryption key string.
45+
/// </param>
46+
/// <param name="onSubmitCallback">
47+
/// The action to take when the modal window is submitted.
48+
/// </param>
49+
public static void Show(string input, Action<string> onSubmitCallback)
50+
{
51+
ScheduleShow<EncryptionKeyWindow>(
52+
input,
53+
onSubmitCallback,
54+
EOSClientCredentials.IsEncryptionKeyValid,
55+
"Enter the encryption key for these client credentials here:",
56+
"Invalid encryption key. Encryption key must be 64 characters long and contain only alphanumeric characters.");
57+
}
58+
59+
/// <summary>
60+
/// Renders the fields necessary to edit the encryption key.
61+
/// </summary>
62+
protected override void RenderModalContents()
63+
{
64+
GUILayout.BeginHorizontal();
65+
66+
_input = GUILayout.TextField(_input, GUILayout.Width(GUIEditorUtility.MeasureLabelWidth(64)), GUILayout.Height(20));
67+
68+
GUILayout.Space(5f);
69+
70+
if (GUILayout.Button(
71+
new GUIContent(EditorGUIUtility.IconContent("Refresh").image,
72+
"Click here to generate a new encryption key."), GUILayout.Height(20), GUILayout.Width(50)))
73+
{
74+
_input = EOSClientCredentials.GenerateEncryptionKey();
75+
}
76+
GUILayout.EndHorizontal();
77+
}
78+
}
79+
80+
}

Assets/Plugins/Source/Editor/EditorWindows/EncryptionKeyWindow.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*
2+
* Copyright (c) 2024 PlayEveryWare
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
24+
namespace PlayEveryWare.EpicOnlineServices.Editor.Windows
25+
{
26+
using PlayEveryWare.EpicOnlineServices.Editor.Utility;
27+
using System;
28+
using UnityEditor;
29+
using UnityEngine;
30+
31+
/// <summary>
32+
/// Represents an editor window that is modal in nature - it is designed to
33+
/// only provide input for a single value, and not be dismissed from focus
34+
/// unless canceled or closed.
35+
/// </summary>
36+
/// <typeparam name="TInputType">
37+
/// The type of value that the modal window is designed to edit.
38+
/// </typeparam>
39+
public abstract class ModalEOSEditorWindow<TInputType> : EOSEditorWindow
40+
{
41+
/// <summary>
42+
/// The value being edited.
43+
/// </summary>
44+
protected TInputType _input;
45+
46+
/// <summary>
47+
/// The prompt to display indicating what the value means.
48+
/// </summary>
49+
private string _inputPrompt;
50+
51+
/// <summary>
52+
/// The prompt to display if the input is not valid.
53+
/// </summary>
54+
private string _errorPrompt;
55+
56+
/// <summary>
57+
/// The action to take when the modal window is submitted.
58+
/// </summary>
59+
private Action<TInputType> _onSubmit;
60+
61+
/// <summary>
62+
/// The function used to validate the input.
63+
/// </summary>
64+
private Func<TInputType, bool> _validateFunction;
65+
66+
/// <summary>
67+
/// Flag that indicates whether the error prompt should be displayed.
68+
/// </summary>
69+
private bool _showError;
70+
71+
// Keep a reference to prevent focus loss
72+
private static ModalEOSEditorWindow<TInputType> s_currentWindow;
73+
74+
/// <summary>
75+
/// Constructs a noew modal eos editor window.
76+
/// </summary>
77+
/// <param name="windowTitle">Window title.</param>
78+
/// <param name="width">The fixed width of the window.</param>
79+
/// <param name="height">The fixed height of the window.</param>
80+
protected ModalEOSEditorWindow(string windowTitle, float width, float height) : base(windowTitle, height, width, false)
81+
{
82+
}
83+
84+
/// <summary>
85+
/// Helper to schedule the showing of the modal window.
86+
/// </summary>
87+
/// <typeparam name="TWindowType">Type of value modal window is designed to edit.</typeparam>
88+
/// <param name="input">The value that the modal window provides editing of.</param>
89+
/// <param name="onSubmitCallback">The action that takes place when the modal window is submitted with a valid value.</param>
90+
/// <param name="validateFunction">Function used to validate the input.</param>
91+
/// <param name="inputPrompt">The prompt to display in the modal window.</param>
92+
/// <param name="errorPrompt">The error to display if the input value is invalid.</param>
93+
protected static void ScheduleShow<TWindowType>(
94+
TInputType input,
95+
Action<TInputType> onSubmitCallback,
96+
Func<TInputType, bool> validateFunction,
97+
string inputPrompt,
98+
string errorPrompt
99+
) where TWindowType : ModalEOSEditorWindow<TInputType>
100+
{
101+
void ShowAndUnsubscribe()
102+
{
103+
// Unsubscribe first to ensure it runs only once
104+
EditorApplication.update -= ShowAndUnsubscribe;
105+
106+
// Open the modal window
107+
ShowWindow<TWindowType>(input, onSubmitCallback, validateFunction, inputPrompt, errorPrompt);
108+
}
109+
110+
// Subscribe the delegate to execute on the next frame
111+
EditorApplication.update += ShowAndUnsubscribe;
112+
}
113+
114+
public static void ShowWindow<TWindowType>(
115+
TInputType input,
116+
Action<TInputType> onSubmitCallback,
117+
Func<TInputType, bool> validateFunction,
118+
string inputPrompt,
119+
string errorPrompt) where TWindowType : ModalEOSEditorWindow<TInputType>
120+
{
121+
if (s_currentWindow != null)
122+
{
123+
s_currentWindow.Focus();
124+
return;
125+
}
126+
127+
ModalEOSEditorWindow<TInputType> window = CreateInstance<TWindowType>();
128+
window._input = input;
129+
window._inputPrompt = inputPrompt;
130+
window._onSubmit = onSubmitCallback;
131+
window._validateFunction = validateFunction;
132+
window._errorPrompt = errorPrompt;
133+
134+
// Center the modal window relative to the parent window
135+
if (focusedWindow != null)
136+
{
137+
Rect parentRect = focusedWindow.position;
138+
float width = 300f; // Width of the modal window
139+
float height = 150f; // Height of the modal window
140+
window.position = new Rect(
141+
parentRect.x + (parentRect.width - width) / 2,
142+
parentRect.y + (parentRect.height - height) / 2,
143+
width,
144+
height
145+
);
146+
}
147+
else
148+
{
149+
// Default size and position if no parent is specified
150+
window.position = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 75, 300, 150);
151+
}
152+
153+
window.ShowModalUtility(); // Makes it modal-like
154+
window.SetIsEmbedded(false);
155+
156+
s_currentWindow = window;
157+
}
158+
159+
private void OnLostFocus()
160+
{
161+
// Refocus if the window loses focus
162+
Focus();
163+
}
164+
165+
protected new void OnEnable()
166+
{
167+
// Overridden to remove base functionality.
168+
}
169+
170+
protected new void OnDisable()
171+
{
172+
// Overridden to remove base functionality.
173+
}
174+
175+
protected override void OnDestroy()
176+
{
177+
s_currentWindow = null;
178+
base.OnDestroy();
179+
}
180+
181+
/// <summary>
182+
/// Deriving modal window implementations should implement this function
183+
/// to render the contents of the input.
184+
/// </summary>
185+
protected abstract void RenderModalContents();
186+
187+
protected override void RenderWindow()
188+
{
189+
bool shouldClose = false;
190+
191+
// Render the prompt text
192+
EditorGUILayout.LabelField(_inputPrompt, GUILayout.Width(
193+
GUIEditorUtility.MeasureLabelWidth(_inputPrompt))
194+
);
195+
196+
// Display error if it needs to be displayed.
197+
if (_showError)
198+
{
199+
EditorGUILayout.HelpBox(_errorPrompt, MessageType.Warning);
200+
}
201+
202+
// Render the contents that are unique to the modal window implementation.
203+
RenderModalContents();
204+
205+
EditorGUILayout.Space();
206+
207+
GUILayout.BeginHorizontal();
208+
if (GUILayout.Button("Save"))
209+
{
210+
// Try to validate the value being submitted
211+
if (_validateFunction(_input))
212+
{
213+
// If successful, then call the submit action.
214+
_onSubmit?.Invoke(_input);
215+
shouldClose = true;
216+
}
217+
else
218+
{
219+
// Otherwise, turn on the flag that indicates the error should be displayed.
220+
_showError = true;
221+
}
222+
}
223+
224+
GUI.SetNextControlName("CancelButton");
225+
if (GUILayout.Button("Cancel"))
226+
{
227+
shouldClose = true;
228+
}
229+
GUILayout.EndHorizontal();
230+
231+
// Close if it should be.
232+
if (shouldClose)
233+
{
234+
Close();
235+
}
236+
237+
// Force focus back to the window
238+
if (s_currentWindow != this)
239+
{
240+
Focus();
241+
s_currentWindow = this;
242+
}
243+
}
244+
}
245+
}

Assets/Plugins/Source/Editor/EditorWindows/ModalEOSEditorWindow.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)