1 /**
2 Copyright: Copyright (c) 2016-2017 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.session.sessionman;
7 
8 import std..string : format;
9 import netlib : SessionId;
10 import datadriven : EntityId;
11 
12 enum SessionType
13 {
14 	unknownClient, // client that is not yet logged in
15 	registeredClient // logged in client
16 }
17 
18 struct Session
19 {
20 	SessionId sessionId;
21 	SessionType type;
22 
23 	bool isLoggedIn() {
24 		return type == SessionType.registeredClient;
25 	}
26 
27 	string name()
28 	{
29 		return isLoggedIn ? _name : format("%s", sessionId);
30 	}
31 
32 	// used when type is registeredClient
33 	string _name;
34 	EntityId dbKey; // ditto
35 }
36 
37 struct SessionManager
38 {
39 	Session*[SessionId] bySessionId;
40 	Session*[string] byClientName;
41 
42 	void put(SessionId sessionId, SessionType type) {
43 		assert(sessionId !in bySessionId, "Session already exists");
44 		auto session = new Session(sessionId, type);
45 		bySessionId[session.sessionId] = session;
46 	}
47 
48 	size_t length() {
49 		return bySessionId.length;
50 	}
51 
52 	string sessionName(SessionId sessionId)
53 	{
54 		auto session = this[sessionId];
55 		return session ? session.name : format("%s", sessionId);
56 	}
57 
58 	void identifySession(SessionId sessionId, string newName, EntityId clientId) {
59 		Session* session = bySessionId.get(sessionId, null);
60 		assert(session);
61 
62 		if (session.name == newName) return;
63 
64 		assert(session.name !in byClientName);
65 		byClientName.remove(session.name);
66 		if (newName) {
67 			byClientName[newName] = session;
68 		}
69 		session._name = newName;
70 		session.dbKey = clientId;
71 		session.type = SessionType.registeredClient;
72 	}
73 
74 	Session* opIndex(string name) {
75 		return byClientName.get(name, null);
76 	}
77 
78 	Session* opIndex(SessionId sessionId) {
79 		return bySessionId.get(sessionId, null);
80 	}
81 
82 	void remove(SessionId sessionId) {
83 		auto session = bySessionId.get(sessionId, null);
84 		if (session) {
85 			if (session.type != SessionType.unknownClient)
86 				byClientName.remove(session.name);
87 			bySessionId.remove(sessionId);
88 		}
89 	}
90 
91 	auto byValue() {
92 		return bySessionId.byValue;
93 	}
94 }