Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

15 changed files with 43 additions and 197 deletions

View File

@ -132,9 +132,8 @@ namespace Client
bool b = !p.Value.StartsWith("ERROR");
if (b) // Set proper state before notifying listener
{
sessionID = p.Value;
RefreshTimeout();
SetAutoRefresh(true);
sessionID = p.Value;
}
PostPromise(p.handler, b);
return false;
@ -204,7 +203,7 @@ namespace Client
RefreshTimeout();
return RegisterEventPromise(pID, p =>
{
PostPromise(p.handler, !p.Value.StartsWith("ERROR"));
p.handler.Value = p.Value.StartsWith("ERROR").ToString();
return false;
});
}
@ -351,7 +350,8 @@ namespace Client
protected void SetAutoRefresh(bool doAR)
{
if (RefreshSessions = doAR && (sessionChecker==null || sessionChecker.Status!=TaskStatus.Running))
if (RefreshSessions == doAR) return;
if (RefreshSessions = doAR)
{
triggerRefreshCancel = false;
sessionChecker = new Task(DoRefresh);
@ -367,14 +367,7 @@ namespace Client
return;
}
// Refresher calls refresh 1500ms before expiry (or asap if less time is available)
try
{
Task.Delay((int)Math.Max(1, ((loginTimeout - DateTime.Now.Ticks) / TimeSpan.TicksPerMillisecond) - 1500)).Wait();
}
catch
{
System.Diagnostics.Debug.WriteLine("OOF");
}
Task.Delay((int)((Math.Min(0, loginTimeout - DateTime.Now.Ticks - 1500)) / TimeSpan.TicksPerMillisecond));
if (triggerRefreshCancel)
{
triggerRefreshCancel = false;
@ -384,21 +377,18 @@ namespace Client
{
try
{
Promise p = Promise.AwaitPromise(Refresh());
p.Subscribe = refreshResult =>
{
if (RefreshSessions && bool.Parse(refreshResult.Value))
{
sessionChecker = new Task(DoRefresh);
sessionChecker.Start();
}
};
Refresh();
}
catch
{
// Session probably died
return;
}
if (RefreshSessions)
{
sessionChecker = new Task(DoRefresh);
sessionChecker.Start();
}
}
}

View File

@ -11,8 +11,6 @@
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>

View File

@ -78,12 +78,6 @@ namespace Client.ConsoleForms
Draw(false);
}
public void CloseIf(Predicate<View> p)
{
for(int i = renderQueue.Count - 1; i>=0; --i)
if (p(renderQueue[i].Item1))
CloseView(i);
}
public void CloseTop() => CloseView(renderQueue[renderQueue.Count - 1].Item1);
public void CloseView(int idx) => CloseView(renderQueue[idx].Item1);
public void CloseView(View v, bool redraw = true, int maxCloses = -1)

View File

@ -13,7 +13,6 @@ namespace Client.ConsoleForms.Graphics
public delegate void SelectListener(DialogView view, int selectionIndex, string selection);
protected readonly ViewData[] options;
protected readonly int optionsWidth;
protected int select;
protected SelectListener listener;
@ -22,18 +21,6 @@ namespace Client.ConsoleForms.Graphics
get => select;
set => select = value < 0 ? 0 : value >= options.Length ? options.Length - 1 : value;
}
public override string Text
{
get => base.Text;
set
{
base.Text = value;
// Since setting the text triggers a rendering recomputation for TextView, we have to recompute rendering for options too
if (optionsWidth > ContentWidth) ContentWidth = optionsWidth;
ContentHeight += 2;
}
}
/*
public override Region Occlusion => new Region(
new Rectangle(
@ -60,26 +47,27 @@ namespace Client.ConsoleForms.Graphics
ViewData optionsData = parameters.Get("Options");
this.options = optionsData.nestedData.Filter(p => p.Name.Equals("Option")).ToArray();
this.select = parameters.AttribueAsInt("select");
//ContentHeight += 2;
ContentHeight += 2;
select = select < 0 ? 0 : select >= options.Length ? 0 : select;
SelectColor = (ConsoleColor)parameters.AttribueAsInt("select_color", (int)ConsoleColor.Gray);
NotSelectColor = (ConsoleColor)parameters.AttribueAsInt("unselect_color", (int)ConsoleColor.White);
optionsWidth = ComputeLength(parameters.Get("Options")?.CollectSub("Option") ?? new Tuple<string, string>[0]);
if (optionsWidth > ContentWidth) ContentWidth = optionsWidth;
}
protected override void _Draw(int left, ref int top)
{
//DrawEmptyPadding(left, ref top, padding.Top());
base.DrawContent(left, ref top);
DrawEmptyPadding(left, ref top, 1);
DrawOptions(left, ref top);
//DrawEmptyPadding(left, ref top, padding.Bottom());
}
protected virtual void DrawOptions(int left, ref int top)
{
int pl = padding.Left(), pr = padding.Right();
Console.SetCursorPosition(left, top++);
int pad = ContentWidth - options.CollectiveLength() - options.Length;
int pad = ContentWidth - options.CollectiveLength() - options.Length;// + pl + pr;
int lpad = (int)(pad / 2f);
Console.BackgroundColor = BackgroundColor;
Console.Write(Filler(' ', lpad));

View File

@ -13,13 +13,12 @@ namespace Client.ConsoleForms.Graphics
protected string[] text;
protected string[] text_render;
protected int maxWidth, maxHeight;
protected readonly bool enforceWidth;
private string _text;
public virtual string Text
public string Text
{
get => _text;
set
protected set
{
_text = value;
text = _text.Split(' ');
@ -28,7 +27,7 @@ namespace Client.ConsoleForms.Graphics
text_render = ComputeTextDimensions(this.text);
int actualWidth = 0;
foreach (var t in text_render) if (actualWidth < t.Length) actualWidth = t.Length;
ContentWidth = enforceWidth ? maxWidth : actualWidth;// + padding.Left() + padding.Right();
ContentWidth = maxWidth;// + padding.Left() + padding.Right();
ContentHeight = text_render.Length;// + padding.Top() + padding.Bottom();
Dirty = true;
}
@ -43,8 +42,6 @@ namespace Client.ConsoleForms.Graphics
)
);
//TODO: Add contentocclusion
//public char Border { get; set; }
//public ConsoleColor BorderColor { get; set; }
@ -55,8 +52,7 @@ namespace Client.ConsoleForms.Graphics
foreach (var t in parameters.NestedText("Text").Split('\n'))
if (t.Length > widest)
widest = t.Length;
enforceWidth = parameters.AttribueAsInt("width") > 0;
this.maxWidth = enforceWidth ? parameters.AttribueAsInt("width") : widest;
this.maxWidth = parameters.AttribueAsInt("width") < 1 ? widest : parameters.AttribueAsInt("width");
this.maxHeight = parameters.AttribueAsInt("height", -1);
this.text = (Text = parameters.NestedText("Text")).Split(' ');

View File

@ -28,12 +28,11 @@ namespace Client.ConsoleForms.Graphics
public ConsoleColor TextColor { get; set; }
public int ContentWidth { get; protected set; }
public int ContentHeight { get; protected set; }
public abstract Region Occlusion { get; } // Reports dimensions of entire view
public Region ContentOcclusion { get => Occlusion; }// Reports dimensions of contents (SHOULD for most applications be smaller than or equal in size to Occlusion)
public bool Dirty { get; set; } // Flag for whether or not view requires re-rendering
public LangManager I18n { get; private set; } // Translation
public ViewEvent OnBackEvent { get; set; } // Callback for [ESC] key
public ViewEvent OnClose { get; set; } // Callback called immediately before controller removes view from render queue
public abstract Region Occlusion { get; }
public bool Dirty { get; set; }
public LangManager I18n { get; private set; }
public ViewEvent OnBackEvent { get; set; }
public ViewEvent OnClose { get; set; }
public View(ViewData parameters, LangManager lang)
{

View File

@ -248,7 +248,7 @@ namespace Client
accountsGetter.Unsubscribe();
Hide("data_fetch");
Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), ViewAccountListener));
Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), SubmitListener));
};
});
@ -518,7 +518,7 @@ namespace Client
}
}
private void ViewAccountListener(View listener)
private void SubmitListener(View listener)
{
ButtonView view = listener as ButtonView;
@ -536,7 +536,7 @@ namespace Client
.SetAttribute("border", (int)ConsoleColor.DarkGreen)
// Option buttons
.AddNested(new ViewData("Options").AddNestedSimple("Option", GetIntlString("GENERIC_dismiss")).AddNestedSimple("Option", GetIntlString("SE_account_delete")))
.AddNested(new ViewData("Options").AddNestedSimple("Option", GetIntlString("GENERIC_dismiss")))
// Message
.AddNestedSimple("Text",
@ -548,40 +548,7 @@ namespace Client
// No translation (it's already handled)
LangManager.NO_LANG);
show.RegisterSelectListener((_, s, l) =>
{
if(s==0) Hide(show);
else
{
var ynDialog = GetView<DialogView>("yn");
ynDialog.Text = GetIntlString("SE_account_delete_warn");
ynDialog.RegisterSelectListener((v, i, str) =>
{
var stall = GetView<TextView>("stall");
stall.Text = GetIntlString("SE_account_delete_stall");
Show(stall);
if (i == 1)
{
Promise p = Promise.AwaitPromise(interactor.CloseAccount(name));
p.Subscribe = deleteAwait =>
{
if (bool.Parse(deleteAwait.Value))
{
accountChange = true;
controller.Popup(GetIntlString("SE_account_delete_success"), 1500, ConsoleColor.Green, () => {
bool closed = false;
controller.CloseIf(predV => closed = !closed && predV is ListView);
Hide(show);
});
}
else controller.Popup(GetIntlString("SE_account_delete_fail"), 2000, ConsoleColor.Red);
Hide(stall);
};
}
});
Show(ynDialog);
}
});
show.RegisterSelectListener((_, s, l) => Hide(show));
Show(show);
}

View File

@ -52,23 +52,4 @@
<Text>@string/NC_quit</Text>
</DialogView>
<DialogView id="yn"
padding_left="2"
padding_right="2"
padding_top="1"
padding_bottom="1"
border="4">
<Options>
<Option close="true">@string/GENERIC_negative</Option>
<Option close="true">@string/GENERIC_positive</Option>
</Options>
<Text></Text>
</DialogView>
<TextView id="stall"
padding_left="2"
padding_right="2"
padding_top="1"
padding_bottom="1">
</TextView>
</Resources>

View File

@ -125,11 +125,6 @@ Balance: $2 SEK</Entry>
<Entry name="SE_account_stall">Creating account...</Entry>
<Entry name="SE_account_exists">Account "$0" already exists!</Entry>
<Entry name="SE_account_success">Account successfully created!</Entry>
<Entry name="SE_account_delete">Delete account</Entry>
<Entry name="SE_account_delete_warn">Are you sure you want to delete this account?</Entry>
<Entry name="SE_account_delete_success">Account successfully deleted!</Entry>
<Entry name="SE_account_delete_fail">Account couldn't be deleted!</Entry>
<Entry name="SE_account_delete_stall">Deleting...</Entry>
<Entry name="SE_exit_prompt">Are you sure you would like log out and exit?</Entry>
<Entry name="GENERIC_fetch">Fetching data...</Entry>

View File

@ -124,11 +124,6 @@ Balance: $1 SEK</Entry>
<Entry name="SE_account_stall">Creating account...</Entry>
<Entry name="SE_account_exists">Account "$0" already exists!</Entry>
<Entry name="SE_account_success">Account successfully created!</Entry>
<Entry name="SE_account_delete">Delete account</Entry>
<Entry name="SE_account_delete_warn">Are you sure you want to delete this account?</Entry>
<Entry name="SE_account_delete_success">Account successfully deleted!</Entry>
<Entry name="SE_account_delete_fail">Account couldn't be deleted!</Entry>
<Entry name="SE_account_delete_stall">Deleting...</Entry>
<Entry name="SE_exit_prompt">Are you sure you would like log out and exit?</Entry>
<Entry name="GENERIC_fetch">Fetching data...</Entry>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<Strings label="Svenska">
<Entry name="WS_welcome">Hej och välkommen till ConsoleForms bankprojektet!
Om du är ovan vid ConsoleForms-gränssnittet och vill
@ -62,7 +62,6 @@ programmet, tryck [ESC].</Entry>
<Entry name="NC_identity">Verifierar serverns identitet...</Entry>
<Entry name="NC_verified">Serveridentitet verifierad!</Entry>
<Entry name="NC_verror">Serveridentitet kunde inte verifieras!</Entry>
<Entry name="NC_quit">Vill du avsluta programmet?</Entry>
<Entry name="SU_welcome">Välkommen till Tofvessons banksystem!
För att fortsätta, tryck [ENTER]
@ -130,11 +129,6 @@ Kontobalans: $1 SEK</Entry>
<Entry name="SE_account_stall">Skapar konto...</Entry>
<Entry name="SE_account_exists">Kontot "$0" finns redan!</Entry>
<Entry name="SE_account_success">Konto skapat!</Entry>
<Entry name="SE_account_delete">Radera konto</Entry>
<Entry name="SE_account_delete_warn">Är du säker på att du vill radera kontot?</Entry>
<Entry name="SE_account_delete_success">Kontot raderat</Entry>
<Entry name="SE_account_delete_fail">Konto kunde inte raderas!</Entry>
<Entry name="SE_account_delete_stall">Raderar...</Entry>
<Entry name="SE_exit_prompt">Är du säker på att du vill logga ut och stänga?</Entry>
<Entry name="GENERIC_fetch">Hämtar data...</Entry>

View File

@ -74,7 +74,6 @@ namespace Server
bool wasFlag = true;
for (int i = 1; i<parts.Length; ++i)
{
if (parts[i].Length == 0) continue;
if (parts[i].StartsWith("-") && parts[i].Length==2)
{
if (reconstruct.Length != 0)

View File

@ -32,32 +32,6 @@ namespace Server
public bool HandleCommand(string cmd)
{
// Find leading and trailing spaces
int pre = 0, post = cmd.Length;
bool preS = false, postS = false;
for(int i = 0; i<cmd.Length; ++i)
{
if(cmd[i]!=' ')
{
pre = i;
if (postS) break;
else preS = true;
}
if(cmd[cmd.Length - 1 - i]!=' ')
{
post = cmd.Length - i;
if (preS) break;
else postS = true;
}
}
// The entire command is just blank spaces
if (post < 2 || pre>post) return false;
// Trim leading and trailing spaces
cmd = cmd.Substring(pre, post - pre);
foreach (var command in commands)
if (command.Item1.Invoke(cmd))
return true;

View File

@ -471,37 +471,21 @@ Use command 'help' to get a list of available commands";
}), "Get or set verbosity level: DEBUG, INFO, FATAL (alternatively enter 0, 1 or 2 respectively)")
.Append(new Command("sess") // Display active sessions
.WithParameter("sessionID", 'r', Parameter.ParamType.STRING, true)
.WithParameter("username", 'u', Parameter.ParamType.STRING, true)
.SetAction(
(c, l) => {
StringBuilder builder = new StringBuilder();
manager.Update(); // Ensure that we don't show expired sessions (artifacts exist until it is necessary to remove them)
bool r = l.HasFlag('r'), u = l.HasFlag('u');
if(r && u)
{
Output.Error("Cannot refresh session by username AND SessionID!");
return;
}
if((r||u) && !manager.HasSession(l[0].Item1, u))
{
Output.Error("Session could not be found!");
return;
}
if (r||u) Output.Raw($"Session refreshed: {manager.Refresh(l[0].Item1, u)}");
else
{
foreach (var session in manager.Sessions)
builder
.Append(session.user.Name)
.Append(" : ")
.Append(session.sessionID)
.Append(" : ")
.Append((session.expiry - DateTime.Now.Ticks) / TimeSpan.TicksPerMillisecond)
.Append('\n');
if (builder.Length == 0) builder.Append("There are no active sessions at the moment");
else --builder.Insert(0, "Active sessions:\n").Length;
Output.Raw(builder);
}
foreach (var session in manager.Sessions)
builder
.Append(session.user.Name)
.Append(" : ")
.Append(session.sessionID)
.Append(" : ")
.Append((session.expiry-DateTime.Now.Ticks) /TimeSpan.TicksPerMillisecond)
.Append('\n');
if (builder.Length == 0) builder.Append("There are no active sessions at the moment");
else --builder.Insert(0, "Active sessions:\n").Length;
Output.Raw(builder);
}), "List or refresh active client sessions")
.Append(new Command("list").WithParameter(Parameter.Flag('a')).SetAction( // Display users
(c, l) => {

View File

@ -19,14 +19,6 @@ namespace Server
this.sidLength = sidLength < 10 ? 10 : sidLength;
}
public bool HasSession(string sess, bool byUserName = false)
{
foreach (var session in Sessions)
if ((byUserName && session.user.Name.Equals(sess)) || (!byUserName && session.sessionID.Equals(sess)))
return true;
return false;
}
public string GetSession(Database.User user, string invalidSID)
{
Update();
@ -78,11 +70,11 @@ namespace Server
return;
}
public bool Refresh(string sid, bool asUser = false)
public bool Refresh(string sid)
{
Update();
for (int i = sessions.Count - 1; i >= 0; --i)
if ((asUser && sessions[i].user.Name.Equals(sid)) || (!asUser && sessions[i].sessionID.Equals(sid)))
if (sessions[i].sessionID.Equals(sid))
{
Session s = sessions[i];
s.expiry = DateTime.Now.Ticks + timeout;