Files
Telegram-Final-Project/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java
T
2025-06-08 14:21:09 +03:30

183 lines
9.3 KiB
Java

package org.to.telegramfinalproject.Server;
import org.json.JSONArray;
import org.json.JSONObject;
import org.to.telegramfinalproject.Database.*;
import org.to.telegramfinalproject.Models.*;
import java.io.*;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.*;
public class ClientHandler implements Runnable {
private final Socket socket;
private final AuthService authService = new AuthService();
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
JSONObject requestJson = new JSONObject(inputLine);
String action = requestJson.getString("action");
ResponseModel response = null;
System.out.println("Received action: '" + action + "'");
System.out.println("Full request: " + requestJson.toString());
if (!requestJson.has("action") || requestJson.isNull("action")) {
ResponseModel errorResponse = new ResponseModel("error", "Missing 'action' in request.");
JSONObject responseJson = new JSONObject();
responseJson.put("status", errorResponse.getStatus());
responseJson.put("message", errorResponse.getMessage());
responseJson.put("data", JSONObject.NULL);
out.println(responseJson.toString());
continue;
}
switch (action) {
case "register":
case "login": {
RequestModel request = new RequestModel(
action,
requestJson.optString("user_id"),
requestJson.optString("username"),
requestJson.optString("password"),
requestJson.optString("profile_name")
);
if (action.equals("register")) {
boolean registered = authService.register(
request.getUser_id(),
request.getUsername(),
request.getPassword(),
request.getProfile_name()
);
response = registered
? new ResponseModel("success", "Registration successful.")
: new ResponseModel("error", "Registration failed.");
} else {
User user = authService.login(request.getUsername(), request.getPassword());
if (user == null) {
response = new ResponseModel("error", "Login failed.");
break;
}
SessionManager.addUser(user.getInternal_uuid(), this.socket);
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
List<Message> unreadMessages = MessageDatabase.getUnreadMessages(user.getInternal_uuid());
user.setContactList(contacts);
user.setGroupList(groups);
user.setChannelList(channels);
user.setUnreadMessages(unreadMessages);
List<ChatEntry> chatList = new ArrayList<>();
for (Contact contact : contacts) {
User target = userDatabase.findByInternalUUID(contact.getContact_id());
if (target == null) continue;
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
chatList.add(new ChatEntry(target.getUser_id(), target.getProfile_name(), target.getImage_url(), "private", last));
}
for (Group group : groups) {
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last));
}
for (Channel channel : channels) {
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last));
}
chatList.sort((a, b) -> {
if (a.getLastMessageTime() == null) return 1;
if (b.getLastMessageTime() == null) return -1;
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
});
JSONObject userData = JsonUtil.userToJson(user);
userData.put("chat_list", JsonUtil.chatListToJson(chatList));
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
}
break;
}
case "logout": {
String userId = requestJson.optString("user_id");
if (userId != null && !userId.isEmpty()) {
UUID uuid = UUID.fromString(userId);
userDatabase.updateUserStatus(uuid, "offline");
userDatabase.updateLastSeen(uuid);
SessionManager.removeUser(uuid);
response = new ResponseModel("success", "Logged out.");
} else {
response = new ResponseModel("error", "Invalid user_id for logout.");
}
break;
}
case "search": {
String keyword = requestJson.optString("keyword");
List<JSONObject> results = new ArrayList<>();
for (User u : new userDatabase().searchUsers(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "user");
obj.put("id", u.getUser_id());
obj.put("name", u.getProfile_name());
results.add(obj);
}
for (Group g : GroupDatabase.searchGroups(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "group");
obj.put("id", g.getGroup_id());
obj.put("name", g.getGroup_name());
results.add(obj);
}
for (Channel c : ChannelDatabase.searchChannels(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "channel");
obj.put("id", c.getChannel_id());
obj.put("name", c.getChannel_name());
results.add(obj);
}
JSONObject data = new JSONObject();
data.put("results", new JSONArray(results));
response = new ResponseModel("success", "Search results found", data);
break;
}
default:
response = new ResponseModel("error", "Unknown action: " + action);
}
JSONObject responseJson = new JSONObject();
responseJson.put("status", response.getStatus());
responseJson.put("message", response.getMessage());
responseJson.put("data", response.getData() != null ? response.getData() : JSONObject.NULL);
out.println(responseJson.toString());
}
} catch (IOException e) {
System.out.println("Connection with client lost.");
UUID userId = SessionManager.getUserIdBySocket(this.socket);
if (userId != null) {
userDatabase.updateUserStatus(userId, "offline");
userDatabase.updateLastSeen(userId);
SessionManager.removeUser(userId);
}
}
}
}