diff --git a/README.md b/README.md index e6929b8..036fb56 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ 안드로이드 카카오톡 25.9.2 기반 비공식 카카오톡 클라이언트 (태블릿 서브 디바이스 로그인) -절대 본계정으로 돌려보지마세요. +되도록이면 부계정으로 돌리길 추천합니다. -**device uuid 무조건 바꾸시오.** +예제에 있는 uuid 그대로 쓰지 마세요. + +자바 21 이상에서 작동합니다. ## Example @@ -15,58 +17,50 @@ Main.java 파일 참고 TalkClient client = new TalkClient(email, password, deviceName, deviceUuid, new TalkHandler() { @Override public void onMessage(Message msg) { - if (msg.getType() != 1) return; // 1이 그냥 채팅, 그냥 채팅만 받기 - if (msg.getMessage().equals("!send")) { - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), "방 : " + msg.getChatRoom().getName() + "\n보낸사람 : " + msg.getAuthor().getName()); - } else if (msg.getMessage().equals("!reply")) { // 답장 - int replyType = 26; // 답장 타입 - JsonObject extraObject = new JsonObject(); - extraObject.addProperty("src_logId", msg.getLogId()); - extraObject.addProperty("src_userId", msg.getAuthor().getId()); - extraObject.addProperty("src_message", msg.getMessage()); - extraObject.addProperty("src_type", msg.getType()); - extraObject.addProperty("src_linkId", msg.getChatRoom().getLinkId()); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), replyType, "reply test", extraObject.toString()); - } else if (msg.getMessage().equals("!mention")) { // 멘션 - JsonObject extraObject = new JsonObject(); - JsonArray mentionArray = new JsonArray(); - JsonObject mentionObject = new JsonObject(); - mentionObject.addProperty("user_id", msg.getAuthor().getId()); - JsonArray pos = new JsonArray(); - pos.add(1); - mentionObject.add("at", pos); - mentionObject.addProperty("len", msg.getAuthor().getName().length()); - mentionArray.add(mentionObject); - extraObject.add("mentions", mentionArray); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), 1, "@" + msg.getAuthor().getName(), extraObject.toString()); - } else if (msg.getMessage().equals("!image")) { - byte[] imageBytes = ByteUtil.hexStringToByteArray("FFD8FFE000104A46494600010101006000600000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080080008003012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00FDFCA28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28AFC03F811F03FF69AFF0082C67FC14A3F6CED1749FDB3BE2F7C15D13E0A7C429F47D374ED16E2FA6B392D64BFD52DE08A38A0BFB5484451E9E80E03190C858E1812C01FBF9593E0DF1F685F1174D9AF7C3DAD693AED9DB5CCB6734FA75E47751453C4DB6489990901D1B8653C83C102BC67FE09BDFB24F8F3F62BFD9C8782BE227C6CF157C7BD793539EF63F12F882DDA1BB8A0758C25A8DF3CF232214760D24AED995870A1547E77FF00C19B1E263E0CFD95FE3CFC1ED76DB51D37E217C39F89735E78874FBA88A9B1FB4DA4168885B3CC827D2EF1597F8760FEF5007E8C7ECA7FF0514F869FB667C6BF8C9E00F03DEEA975E20F815AE2787FC50B7564D042972CF711FEE5C9FDE2896D2E109C0E6227054AB37BA57E247EC3CDA27EC63FF077F7ED09E028E4D7B4AD23E33F87AE353D22D6532C96FAB6AB73058EB77131E8BB15935708E7210EE8C1C922BF407FE0AE5FF057FF00871FF0497F80F36BDE24B9B6D67C6FAB42CBE19F09C370AB79ABCBC81238E4C76C8DF7E523031B577390A403DB7C25FB617C30F1E7ED23E21F841A378DB43D4FE25F84F4E4D5B57F0FDBCC5EEB4FB666440EF81B461A48832E772F9B1EE037AE7D26BF273FE0D93FD823C67E171F15BF6B2F8C9A19D23E2A7ED11AA4FA858DB4D6FE44961A55CCFF006D96454DD98D6EAE5D5846E32B1D9C0C0E1C8AFD63A0028AFC2BF097FC1CF7E23FD97FFE0A2DFB50D9FC78BCD635EF841E00F185E782FC2BE1EF0AF85EDA4BFB5B98AFEEA18666BA92485361B7B198C8B34CCEF24AA625091C807AB7FC46ADFB2C7FD083FB407FE08F48FF00E59D007EBF515F9E3FF0496FF83863C23FF0575FDAA7C71F0F7C1FF0CFC5FE18D1FC2DA1FF006F59EBBAB5CC2E6F6313C103453C11065B794B4F945134A1D6290E576E2BF43A800A28A2800A28A2800AFE69BF647FD90BF6ABFDA47FE0AD3FB707887F658F8D3A67C27D73C0DF176FDB59B5D5AFEE61D375C8EE755D6FC969A18EDEE61B83098240A93C2CA3ED0C415390DFD2CD7E40FC4DFF00834EAD3E26FEDDFE30F8B0FF00B4578C746F0978E7C77278EB54F0A695A335A5CB4EF7335C044BF4BC015E37B89C4737D9CBC6B2B01C92C403A6BA3FF056CFD96BE04DCDB6CF80DFB49F8D75BD502C1776F241A6B7876CD616DCCC8EBA5C3333C8C9B7018C7E51DC24127EEFE79FF83587C49F113E04FF00C150FF006B8F841F1BF43D534FF8D1E2FB3B2F1BF88249E5B79152782EA479CBB42CD1B19CEBB04A8D1128543107056BF77ABF193E18F8B2F3F676FF0083D0FE2259EBDA1EA090FC79F87B158786EE81511C9141A4E9D70F72727263F3342BD838E7CC038C026800FF0082EF7856FF00E087FC17E7FE09F3F16BC3BAE5ED8EBBE35D7EDFC07770A227971D845AADB47300482499E0D7AEA27F45518C139AF60FDB2FFE0D4CF807FB6A7C7BF1EFC4EF1078EFE3459F8BBC75732DF3797AD59DC5869B3BE0AF951CB68D2F92A4604466C042554A00BB7C7FFE0F2BF0ADFF00C3EF80DFB3BFC75F0F6B97BA378C7E167C42363A2B40885629AEEDFEDCB739607E78A5D1A0DA3041F31B3D057B27ED77FF00075D7ECE5FB197ED27E2FF0085DE23F097C69D575FF04EA0FA66A171A5E85622D1A64FBC233717B0C8CB9E8FE585618652CA43100F8EB505FDBA7FE0D98D734EBABAD5350FDA7BF65EB3F344D0C31DC13A1DAA2801A5678E69349009CA85925B538C13BD801FB43FB09FED8FE18FF8280FEC97E0BF8C1E0E86FEDB40F1A5A493436F7B1ECB8B59619E4B79E17C704C73C32A6E1C36DC8E08AFCD4D57FE0F41FD93F5DD2EE6C6FBE1C7C78BCB2BC89A0B8B79FC3FA3C914F1B02AC8EA7522194824107820D751FF00047BFF0082D0789BFE0A1BFB65CBE00F815FB3F68DE06FD92FC11A5BC53EA92D9A6997BA2CE6277863486DA46B35F326F945B4419821794C9C6DA00F953F62EFF829C7803FE08B5FF053DFF828BB7C68D27C6B16A3E2CF1F45AEE91A668DA5ADD5D5E5A36A7A9CC92E5E48E24578755B3954C8EA1964E0EEC29FBCBE047FC1D55FB16FC6AD274D7BFF00889AC7C3FD5752B8FB3AE95E28F0F5E4535B92D85796E2D927B44439CEE33E00FBDB6BC53FE0BCFF00F04E6F8A9F073F6C0F08FEDE3FB3669F0EA9F103E1D4313F8BBC3E96E649359B5B789E26BADAAC1E60D66C6D668D0893C95428432B1AE3BF66EFDB17FE0965FF000554F83961A7FC57F879F03BE127C43D641D47C43617FA6AF84E54BB46DD2491EB96EB6E24491C960A6E43B8387426803F57FE0EFEDD1F04BF689F159D07E1FF00C62F857E3AD7044D39D3BC3DE2CB0D4EEC46BF79FCA82567DA3B9C6057AA57F343FF000538FD82BFE09FEFFB6AFECB1F0DFF0067FD42DF55B3F8B7E2C8FC35E2A93E1FFC4B8F598F48827BBB3B686776B917FB6766BA7651BD14ADB38284B075FD5BFF008255FF00C1BF3E12FF008247FED4FE2DF1D7803E27F8EB5EF0AF89FC36BA20F0CEBA9039867FB443335E493C2228E56021D918FB3A945965CBB6EE003F40E8A28A0028A28A0028A28A002BF2ABFE0A5FFF0004E5FDA1FE2C7FC1C01FB317ED07F0A74AB67F02F8234FD2F47F146AE356B4B7974DB48F53BF7D4236825712C8B3585F4912F948E496607670D5FAAB45007C63FF0005DBFF00825BEA7FF056EFD8757E1CF87FC47A7F867C4FA16BF6FE26D1A7D415CD85CDCC305CDBF9170C8ACE91B477527CE8AC55954ED61907E9FF00D9F7C2BE26F02FC05F04689E35D723F13F8CB46D02C2C75ED6635DA9AB5FC56F1A5CDC81818124AAEF8C0FBDD0575F450014515F991FB5DFECC3FF00054BF1B7ED27E2FD4FE10FED1BF033C23F0CEEF5077F0E6937BA4466EECACFFE59A4C64D1EE98CA07DE6F39831C9010108A01FA6F5F2DFED53FF000450FD957F6D3F109D63E227C12F07EA5ADCB7525EDCEA9A6ACDA1DFEA13480067B9B8B192096E49C0FF005CCF83C8C126BE09F007ED07FF0005A1F853A1BE87A8FC0CF837F132E2CAE2551E21D56FF4AB79EFD3710AC12D756B38C26065736E8F83F30CF00D3FFE0B6DFF000515FD9C7C79A8E87F18BF607D4FC7339B78A6B46F8756BA97D960DD93F3DE5BFF006ADBCA703EE2B2329FBDD71401F6C7ECD1FF00040AFD917F640F8CBA4FC40F87FF000734FD27C5DA0B349A75F5DEB7AA6A82CE4231E624577732C4241FC2FB7729E54835F6157E40FF00C4477FB53FFD231FF680FF00BFDABFFF0028E8FF00888EFF006A7FFA463FED01FF007FB57FFE51D007EBF515F987FB27FF00C1777F685F8FBFB46F83BC17E2AFF827D7C75F879A0789B53874FBCF12DD9BF7B5D112460A6E66F3F4BB78C4499DCC4CAA7683B433614FE9E500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145007FFFD9"); // 테스트 jpg 이미지 hex - getTalkClient().sendJpg(msg.getChatRoom().getChatId(), imageBytes, "jpg", 128, 128); + if (msg.getType() != MessageType.TEXT) return; // 그냥 텍스트 채팅만 받기 + if (msg.getMessage().equals("!count")) { // 멤버 수 + msg.getChatRoom().sendMessage("멤버수 : " + msg.getChatRoom().getMemberCount()); + } + else if (msg.getMessage().equals("!type")) { // 보낸 사람 권한 + int type = msg.getAuthor().getMemberType(); + String t = ""; + if (type == MemberType.OWNER) t = "방장"; + if (type == MemberType.ADMIN) t = "부방장"; + if (type == MemberType.MEMBER) t = "일반 멤버"; + if (type == MemberType.BOT) t = "방장봇"; + msg.getChatRoom().sendMessage("당신의 멤버 타입 : " + t); + } + else if (msg.getMessage().equals("!kick")) { // 강퇴 (당연히 방장이나 부방장 권한 있을때만 작동합니다.) + msg.getAuthor().kick(); + } + else if (msg.getMessage().equals("!send")) { // 일반 메세지 + msg.getChatRoom().sendMessage("방 : " + msg.getChatRoom().getName() + "\n보낸사람 : " + msg.getAuthor().getNickName()); + } + else if (msg.getMessage().equals("!reply")) { // 답장 + msg.reply("reply test"); + } + else if (msg.getMessage().equals("!mention")) { // 멘션 + String extra = "{\"mentions\":[{\"user_id\":" + msg.getAuthor().getUserId() + ",\"at\":[1],\"len\":" + msg.getAuthor().getNickName(length() + "}]}"; + msg.getChatRoom().sendMessage("@" + msg.getAuthor().getNickName(), extra); + } + else if (msg.getMessage().equals("!jpg")) { // jpg 사진 전송, jpeg말고 다른 포멧은 테스트 안해봤습니다. + byte[] imageBytes = ByteUtil.hexStringToByteArray("FFD8FFE000104A46494600010101006000600000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080080008003012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00FDFCA28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28AFC03F811F03FF69AFF0082C67FC14A3F6CED1749FDB3BE2F7C15D13E0A7C429F47D374ED16E2FA6B392D64BFD52DE08A38A0BFB5484451E9E80E03190C858E1812C01FBF9593E0DF1F685F1174D9AF7C3DAD693AED9DB5CCB6734FA75E47751453C4DB6489990901D1B8653C83C102BC67FE09BDFB24F8F3F62BFD9C8782BE227C6CF157C7BD793539EF63F12F882DDA1BB8A0758C25A8DF3CF232214760D24AED995870A1547E77FF00C19B1E263E0CFD95FE3CFC1ED76DB51D37E217C39F89735E78874FBA88A9B1FB4DA4168885B3CC827D2EF1597F8760FEF5007E8C7ECA7FF0514F869FB667C6BF8C9E00F03DEEA975E20F815AE2787FC50B7564D042972CF711FEE5C9FDE2896D2E109C0E6227054AB37BA57E247EC3CDA27EC63FF077F7ED09E028E4D7B4AD23E33F87AE353D22D6532C96FAB6AB73058EB77131E8BB15935708E7210EE8C1C922BF407FE0AE5FF057FF00871FF0497F80F36BDE24B9B6D67C6FAB42CBE19F09C370AB79ABCBC81238E4C76C8DF7E523031B577390A403DB7C25FB617C30F1E7ED23E21F841A378DB43D4FE25F84F4E4D5B57F0FDBCC5EEB4FB666440EF81B461A48832E772F9B1EE037AE7D26BF273FE0D93FD823C67E171F15BF6B2F8C9A19D23E2A7ED11AA4FA858DB4D6FE44961A55CCFF006D96454DD98D6EAE5D5846E32B1D9C0C0E1C8AFD63A0028AFC2BF097FC1CF7E23FD97FFE0A2DFB50D9FC78BCD635EF841E00F185E782FC2BE1EF0AF85EDA4BFB5B98AFEEA18666BA92485361B7B198C8B34CCEF24AA625091C807AB7FC46ADFB2C7FD083FB407FE08F48FF00E59D007EBF515F9E3FF0496FF83863C23FF0575FDAA7C71F0F7C1FF0CFC5FE18D1FC2DA1FF006F59EBBAB5CC2E6F6313C103453C11065B794B4F945134A1D6290E576E2BF43A800A28A2800A28A2800AFE69BF647FD90BF6ABFDA47FE0AD3FB707887F658F8D3A67C27D73C0DF176FDB59B5D5AFEE61D375C8EE755D6FC969A18EDEE61B83098240A93C2CA3ED0C415390DFD2CD7E40FC4DFF00834EAD3E26FEDDFE30F8B0FF00B4578C746F0978E7C77278EB54F0A695A335A5CB4EF7335C044BF4BC015E37B89C4737D9CBC6B2B01C92C403A6BA3FF056CFD96BE04DCDB6CF80DFB49F8D75BD502C1776F241A6B7876CD616DCCC8EBA5C3333C8C9B7018C7E51DC24127EEFE79FF83587C49F113E04FF00C150FF006B8F841F1BF43D534FF8D1E2FB3B2F1BF88249E5B79152782EA479CBB42CD1B19CEBB04A8D1128543107056BF77ABF193E18F8B2F3F676FF0083D0FE2259EBDA1EA090FC79F87B158786EE81511C9141A4E9D70F72727263F3342BD838E7CC038C026800FF0082EF7856FF00E087FC17E7FE09F3F16BC3BAE5ED8EBBE35D7EDFC07770A227971D845AADB47300482499E0D7AEA27F45518C139AF60FDB2FFE0D4CF807FB6A7C7BF1EFC4EF1078EFE3459F8BBC75732DF3797AD59DC5869B3BE0AF951CB68D2F92A4604466C042554A00BB7C7FFE0F2BF0ADFF00C3EF80DFB3BFC75F0F6B97BA378C7E167C42363A2B40885629AEEDFEDCB739607E78A5D1A0DA3041F31B3D057B27ED77FF00075D7ECE5FB197ED27E2FF0085DE23F097C69D575FF04EA0FA66A171A5E85622D1A64FBC233717B0C8CB9E8FE585618652CA43100F8EB505FDBA7FE0D98D734EBABAD5350FDA7BF65EB3F344D0C31DC13A1DAA2801A5678E69349009CA85925B538C13BD801FB43FB09FED8FE18FF8280FEC97E0BF8C1E0E86FEDB40F1A5A493436F7B1ECB8B59619E4B79E17C704C73C32A6E1C36DC8E08AFCD4D57FE0F41FD93F5DD2EE6C6FBE1C7C78BCB2BC89A0B8B79FC3FA3C914F1B02AC8EA7522194824107820D751FF00047BFF0082D0789BFE0A1BFB65CBE00F815FB3F68DE06FD92FC11A5BC53EA92D9A6997BA2CE6277863486DA46B35F326F945B4419821794C9C6DA00F953F62EFF829C7803FE08B5FF053DFF828BB7C68D27C6B16A3E2CF1F45AEE91A668DA5ADD5D5E5A36A7A9CC92E5E48E24578755B3954C8EA1964E0EEC29FBCBE047FC1D55FB16FC6AD274D7BFF00889AC7C3FD5752B8FB3AE95E28F0F5E4535B92D85796E2D927B44439CEE33E00FBDB6BC53FE0BCFF00F04E6F8A9F073F6C0F08FEDE3FB3669F0EA9F103E1D4313F8BBC3E96E649359B5B789E26BADAAC1E60D66C6D668D0893C95428432B1AE3BF66EFDB17FE0965FF000554F83961A7FC57F879F03BE127C43D641D47C43617FA6AF84E54BB46DD2491EB96EB6E24491C960A6E43B8387426803F57FE0EFEDD1F04BF689F159D07E1FF00C62F857E3AD7044D39D3BC3DE2CB0D4EEC46BF79FCA82567DA3B9C6057AA57F343FF000538FD82BFE09FEFFB6AFECB1F0DFF0067FD42DF55B3F8B7E2C8FC35E2A93E1FFC4B8F598F48827BBB3B686776B917FB6766BA7651BD14ADB38284B075FD5BFF008255FF00C1BF3E12FF008247FED4FE2DF1D7803E27F8EB5EF0AF89FC36BA20F0CEBA9039867FB443335E493C2228E56021D918FB3A945965CBB6EE003F40E8A28A0028A28A0028A28A002BF2ABFE0A5FFF0004E5FDA1FE2C7FC1C01FB317ED07F0A74AB67F02F8234FD2F47F146AE356B4B7974DB48F53BF7D4236825712C8B3585F4912F948E496607670D5FAAB45007C63FF0005DBFF00825BEA7FF056EFD8757E1CF87FC47A7F867C4FA16BF6FE26D1A7D415CD85CDCC305CDBF9170C8ACE91B477527CE8AC55954ED61907E9FF00D9F7C2BE26F02FC05F04689E35D723F13F8CB46D02C2C75ED6635DA9AB5FC56F1A5CDC81818124AAEF8C0FBDD0575F450014515F991FB5DFECC3FF00054BF1B7ED27E2FD4FE10FED1BF033C23F0CEEF5077F0E6937BA4466EECACFFE59A4C64D1EE98CA07DE6F39831C9010108A01FA6F5F2DFED53FF000450FD957F6D3F109D63E227C12F07EA5ADCB7525EDCEA9A6ACDA1DFEA13480067B9B8B192096E49C0FF005CCF83C8C126BE09F007ED07FF0005A1F853A1BE87A8FC0CF837F132E2CAE2551E21D56FF4AB79EFD3710AC12D756B38C26065736E8F83F30CF00D3FFE0B6DFF000515FD9C7C79A8E87F18BF607D4FC7339B78A6B46F8756BA97D960DD93F3DE5BFF006ADBCA703EE2B2329FBDD71401F6C7ECD1FF00040AFD917F640F8CBA4FC40F87FF000734FD27C5DA0B349A75F5DEB7AA6A82CE4231E624577732C4241FC2FB7729E54835F6157E40FF00C4477FB53FFD231FF680FF00BFDABFFF0028E8FF00888EFF006A7FFA463FED01FF007FB57FFE51D007EBF515F987FB27FF00C1777F685F8FBFB46F83BC17E2AFF827D7C75F879A0789B53874FBCF12DD9BF7B5D112460A6E66F3F4BB78C4499DCC4CAA7683B433614FE9E500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145007FFFD9"); + msg.getChatRoom().sendJpg(imageBytes); } } @Override public void onNewMember(ChatRoom room, Member member) { - JsonObject extraObject = new JsonObject(); - JsonArray mentionArray = new JsonArray(); - JsonObject mentionObject = new JsonObject(); - mentionObject.addProperty("user_id", member.getId()); - JsonArray pos = new JsonArray(); - pos.add(1); - mentionObject.add("at", pos); - mentionObject.addProperty("len", member.getName().length()); - mentionArray.add(mentionObject); - extraObject.add("mentions", mentionArray); - getTalkClient().sendMessage(room.getChatId(), 1, "@" + member.getName() + "님 안녕하세요.", extraObject.toString()); + String extra = "{\"mentions\":[{\"user_id\":" + member.getUserId() + ",\"at\":[1],\"len\":" + member.getNickName().length() + "}]}"; + room.sendMessage("@" + member.getNickName() + "님 안녕하세요.", extra); } @Override - public void onDelMember(ChatRoom room, Member member) { - getTalkClient().sendMessage(room.getChatId(), member.getName() + "님이 나갔습니다."); + public void onDelMember(ChatRoom room, long userId, String nickName) { + room.sendMessage(nickName + "님이 나갔습니다."); } }); ``` - ## Build ``` @@ -78,8 +72,6 @@ jar 파일은 build/libs 디렉터리 안에 생성됩니다. ## Usage -자바21 이상 필요합니다. - 첫 로그인시에 기기등록이 필요합니다. 콘솔창에 방법 나오니 따라하세요. -로그인하면 로그인 정보(토큰 등)가 email_deviceName 폴더 안에 저장됩니다. 서버 연결이 안되면 삭제하고 시도하세요. +로그인하면 로그인 정보(토큰 등)가 email_deviceName 포멧의 이름을 가진 폴더 안에 저장됩니다. 서버 연결이 안되면 삭제하고 시도하세요. diff --git a/ex.png b/ex.png index dcf7177..2acb4de 100644 Binary files a/ex.png and b/ex.png differ diff --git a/src/main/java/com/github/netricecake/Main.java b/src/main/java/com/github/netricecake/Main.java index f8fabf0..9cadadd 100644 --- a/src/main/java/com/github/netricecake/Main.java +++ b/src/main/java/com/github/netricecake/Main.java @@ -4,12 +4,8 @@ import com.github.netricecake.kakao.KakaoApi; import com.github.netricecake.kakao.TalkClient; import com.github.netricecake.kakao.TalkHandler; import com.github.netricecake.kakao.exception.*; -import com.github.netricecake.kakao.structs.ChatRoom; -import com.github.netricecake.kakao.structs.Member; -import com.github.netricecake.kakao.structs.Message; -import com.github.netricecake.loco.util.ByteUtil; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.github.netricecake.kakao.structs.*; +import com.github.netricecake.kakao.util.ByteUtil; import java.util.Map; @@ -28,65 +24,47 @@ public class Main { TalkClient client = new TalkClient(email, password, deviceName, deviceUuid, new TalkHandler() { @Override public void onMessage(Message msg) { - if (msg.getType() != 1) return; // 1이 그냥 채팅, 그냥 채팅만 받기 - if (msg.getMessage().equals("!memc")) { - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), "멤버수 : " + msg.getChatRoom().getMemberCount()); + if (msg.getType() != MessageType.TEXT) return; // 그냥 텍스트 채팅만 받기 + if (msg.getMessage().equals("!count")) { // 멤버 수 + msg.getChatRoom().sendMessage("멤버수 : " + msg.getChatRoom().getMemberCount()); } - else if (msg.getMessage().equals("!pcheck")) { - int type = msg.getChatRoom().getMember(getTalkClient().getUserId()).getMemberType(); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), "현재 봇계정의 멤버 타입 : " + type); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), "현재 님계정의 멤버 타입 : " + msg.getAuthor().getMemberType()); + else if (msg.getMessage().equals("!type")) { // 보낸 사람 권한 + int type = msg.getAuthor().getMemberType(); + String t = ""; + if (type == MemberType.OWNER) t = "방장"; + if (type == MemberType.ADMIN) t = "부방장"; + if (type == MemberType.MEMBER) t = "일반 멤버"; + if (type == MemberType.BOT) t = "방장봇"; + msg.getChatRoom().sendMessage("당신의 멤버 타입 : " + t); } - else if (msg.getMessage().equals("!send")) { - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), "방 : " + msg.getChatRoom().getName() + "\n보낸사람 : " + msg.getAuthor().getName()); + else if (msg.getMessage().equals("!kick")) { // 강퇴 (당연히 방장이나 부방장 권한 있을때만 작동합니다.) + msg.getAuthor().kick(); + } + else if (msg.getMessage().equals("!send")) { // 일반 메세지 + msg.getChatRoom().sendMessage("방 : " + msg.getChatRoom().getName() + "\n보낸사람 : " + msg.getAuthor().getNickName()); } else if (msg.getMessage().equals("!reply")) { // 답장 - int replyType = 26; // 답장 타입 - JsonObject extraObject = new JsonObject(); - extraObject.addProperty("src_logId", msg.getLogId()); - extraObject.addProperty("src_userId", msg.getAuthor().getId()); - extraObject.addProperty("src_message", msg.getMessage()); - extraObject.addProperty("src_type", msg.getType()); - extraObject.addProperty("src_linkId", msg.getChatRoom().getLinkId()); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), replyType, "reply test", extraObject.toString()); + msg.reply("reply test"); } else if (msg.getMessage().equals("!mention")) { // 멘션 - JsonObject extraObject = new JsonObject(); - JsonArray mentionArray = new JsonArray(); - JsonObject mentionObject = new JsonObject(); - mentionObject.addProperty("user_id", msg.getAuthor().getId()); - JsonArray pos = new JsonArray(); - pos.add(1); - mentionObject.add("at", pos); - mentionObject.addProperty("len", msg.getAuthor().getName().length()); - mentionArray.add(mentionObject); - extraObject.add("mentions", mentionArray); - getTalkClient().sendMessage(msg.getChatRoom().getChatId(), 1, "@" + msg.getAuthor().getName(), extraObject.toString()); + String extra = "{\"mentions\":[{\"user_id\":" + msg.getAuthor().getUserId() + ",\"at\":[1],\"len\":" + msg.getAuthor().getNickName().length() + "}]}"; + msg.getChatRoom().sendMessage("@" + msg.getAuthor().getNickName(), extra); } - else if (msg.getMessage().equals("!image")) { + else if (msg.getMessage().equals("!jpg")) { // jpg 사진 전송, jpeg말고 다른 포멧은 테스트 안해봤습니다. byte[] imageBytes = ByteUtil.hexStringToByteArray("FFD8FFE000104A46494600010101006000600000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080080008003012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00FDFCA28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28A2800A28AFC03F811F03FF69AFF0082C67FC14A3F6CED1749FDB3BE2F7C15D13E0A7C429F47D374ED16E2FA6B392D64BFD52DE08A38A0BFB5484451E9E80E03190C858E1812C01FBF9593E0DF1F685F1174D9AF7C3DAD693AED9DB5CCB6734FA75E47751453C4DB6489990901D1B8653C83C102BC67FE09BDFB24F8F3F62BFD9C8782BE227C6CF157C7BD793539EF63F12F882DDA1BB8A0758C25A8DF3CF232214760D24AED995870A1547E77FF00C19B1E263E0CFD95FE3CFC1ED76DB51D37E217C39F89735E78874FBA88A9B1FB4DA4168885B3CC827D2EF1597F8760FEF5007E8C7ECA7FF0514F869FB667C6BF8C9E00F03DEEA975E20F815AE2787FC50B7564D042972CF711FEE5C9FDE2896D2E109C0E6227054AB37BA57E247EC3CDA27EC63FF077F7ED09E028E4D7B4AD23E33F87AE353D22D6532C96FAB6AB73058EB77131E8BB15935708E7210EE8C1C922BF407FE0AE5FF057FF00871FF0497F80F36BDE24B9B6D67C6FAB42CBE19F09C370AB79ABCBC81238E4C76C8DF7E523031B577390A403DB7C25FB617C30F1E7ED23E21F841A378DB43D4FE25F84F4E4D5B57F0FDBCC5EEB4FB666440EF81B461A48832E772F9B1EE037AE7D26BF273FE0D93FD823C67E171F15BF6B2F8C9A19D23E2A7ED11AA4FA858DB4D6FE44961A55CCFF006D96454DD98D6EAE5D5846E32B1D9C0C0E1C8AFD63A0028AFC2BF097FC1CF7E23FD97FFE0A2DFB50D9FC78BCD635EF841E00F185E782FC2BE1EF0AF85EDA4BFB5B98AFEEA18666BA92485361B7B198C8B34CCEF24AA625091C807AB7FC46ADFB2C7FD083FB407FE08F48FF00E59D007EBF515F9E3FF0496FF83863C23FF0575FDAA7C71F0F7C1FF0CFC5FE18D1FC2DA1FF006F59EBBAB5CC2E6F6313C103453C11065B794B4F945134A1D6290E576E2BF43A800A28A2800A28A2800AFE69BF647FD90BF6ABFDA47FE0AD3FB707887F658F8D3A67C27D73C0DF176FDB59B5D5AFEE61D375C8EE755D6FC969A18EDEE61B83098240A93C2CA3ED0C415390DFD2CD7E40FC4DFF00834EAD3E26FEDDFE30F8B0FF00B4578C746F0978E7C77278EB54F0A695A335A5CB4EF7335C044BF4BC015E37B89C4737D9CBC6B2B01C92C403A6BA3FF056CFD96BE04DCDB6CF80DFB49F8D75BD502C1776F241A6B7876CD616DCCC8EBA5C3333C8C9B7018C7E51DC24127EEFE79FF83587C49F113E04FF00C150FF006B8F841F1BF43D534FF8D1E2FB3B2F1BF88249E5B79152782EA479CBB42CD1B19CEBB04A8D1128543107056BF77ABF193E18F8B2F3F676FF0083D0FE2259EBDA1EA090FC79F87B158786EE81511C9141A4E9D70F72727263F3342BD838E7CC038C026800FF0082EF7856FF00E087FC17E7FE09F3F16BC3BAE5ED8EBBE35D7EDFC07770A227971D845AADB47300482499E0D7AEA27F45518C139AF60FDB2FFE0D4CF807FB6A7C7BF1EFC4EF1078EFE3459F8BBC75732DF3797AD59DC5869B3BE0AF951CB68D2F92A4604466C042554A00BB7C7FFE0F2BF0ADFF00C3EF80DFB3BFC75F0F6B97BA378C7E167C42363A2B40885629AEEDFEDCB739607E78A5D1A0DA3041F31B3D057B27ED77FF00075D7ECE5FB197ED27E2FF0085DE23F097C69D575FF04EA0FA66A171A5E85622D1A64FBC233717B0C8CB9E8FE585618652CA43100F8EB505FDBA7FE0D98D734EBABAD5350FDA7BF65EB3F344D0C31DC13A1DAA2801A5678E69349009CA85925B538C13BD801FB43FB09FED8FE18FF8280FEC97E0BF8C1E0E86FEDB40F1A5A493436F7B1ECB8B59619E4B79E17C704C73C32A6E1C36DC8E08AFCD4D57FE0F41FD93F5DD2EE6C6FBE1C7C78BCB2BC89A0B8B79FC3FA3C914F1B02AC8EA7522194824107820D751FF00047BFF0082D0789BFE0A1BFB65CBE00F815FB3F68DE06FD92FC11A5BC53EA92D9A6997BA2CE6277863486DA46B35F326F945B4419821794C9C6DA00F953F62EFF829C7803FE08B5FF053DFF828BB7C68D27C6B16A3E2CF1F45AEE91A668DA5ADD5D5E5A36A7A9CC92E5E48E24578755B3954C8EA1964E0EEC29FBCBE047FC1D55FB16FC6AD274D7BFF00889AC7C3FD5752B8FB3AE95E28F0F5E4535B92D85796E2D927B44439CEE33E00FBDB6BC53FE0BCFF00F04E6F8A9F073F6C0F08FEDE3FB3669F0EA9F103E1D4313F8BBC3E96E649359B5B789E26BADAAC1E60D66C6D668D0893C95428432B1AE3BF66EFDB17FE0965FF000554F83961A7FC57F879F03BE127C43D641D47C43617FA6AF84E54BB46DD2491EB96EB6E24491C960A6E43B8387426803F57FE0EFEDD1F04BF689F159D07E1FF00C62F857E3AD7044D39D3BC3DE2CB0D4EEC46BF79FCA82567DA3B9C6057AA57F343FF000538FD82BFE09FEFFB6AFECB1F0DFF0067FD42DF55B3F8B7E2C8FC35E2A93E1FFC4B8F598F48827BBB3B686776B917FB6766BA7651BD14ADB38284B075FD5BFF008255FF00C1BF3E12FF008247FED4FE2DF1D7803E27F8EB5EF0AF89FC36BA20F0CEBA9039867FB443335E493C2228E56021D918FB3A945965CBB6EE003F40E8A28A0028A28A0028A28A002BF2ABFE0A5FFF0004E5FDA1FE2C7FC1C01FB317ED07F0A74AB67F02F8234FD2F47F146AE356B4B7974DB48F53BF7D4236825712C8B3585F4912F948E496607670D5FAAB45007C63FF0005DBFF00825BEA7FF056EFD8757E1CF87FC47A7F867C4FA16BF6FE26D1A7D415CD85CDCC305CDBF9170C8ACE91B477527CE8AC55954ED61907E9FF00D9F7C2BE26F02FC05F04689E35D723F13F8CB46D02C2C75ED6635DA9AB5FC56F1A5CDC81818124AAEF8C0FBDD0575F450014515F991FB5DFECC3FF00054BF1B7ED27E2FD4FE10FED1BF033C23F0CEEF5077F0E6937BA4466EECACFFE59A4C64D1EE98CA07DE6F39831C9010108A01FA6F5F2DFED53FF000450FD957F6D3F109D63E227C12F07EA5ADCB7525EDCEA9A6ACDA1DFEA13480067B9B8B192096E49C0FF005CCF83C8C126BE09F007ED07FF0005A1F853A1BE87A8FC0CF837F132E2CAE2551E21D56FF4AB79EFD3710AC12D756B38C26065736E8F83F30CF00D3FFE0B6DFF000515FD9C7C79A8E87F18BF607D4FC7339B78A6B46F8756BA97D960DD93F3DE5BFF006ADBCA703EE2B2329FBDD71401F6C7ECD1FF00040AFD917F640F8CBA4FC40F87FF000734FD27C5DA0B349A75F5DEB7AA6A82CE4231E624577732C4241FC2FB7729E54835F6157E40FF00C4477FB53FFD231FF680FF00BFDABFFF0028E8FF00888EFF006A7FFA463FED01FF007FB57FFE51D007EBF515F987FB27FF00C1777F685F8FBFB46F83BC17E2AFF827D7C75F879A0789B53874FBCF12DD9BF7B5D112460A6E66F3F4BB78C4499DCC4CAA7683B433614FE9E500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145001451450014514500145145007FFFD9"); - getTalkClient().sendJpg(msg.getChatRoom().getChatId(), imageBytes, "jpg", 128, 128); + msg.getChatRoom().sendJpg(imageBytes); } } @Override public void onNewMember(ChatRoom room, Member member) { - JsonObject extraObject = new JsonObject(); - JsonArray mentionArray = new JsonArray(); - JsonObject mentionObject = new JsonObject(); - mentionObject.addProperty("user_id", member.getId()); - JsonArray pos = new JsonArray(); - pos.add(1); - mentionObject.add("at", pos); - mentionObject.addProperty("len", member.getName().length()); - mentionArray.add(mentionObject); - extraObject.add("mentions", mentionArray); - getTalkClient().sendMessage(room.getChatId(), 1, "@" + member.getName() + "님 안녕하세요.", extraObject.toString()); + String extra = "{\"mentions\":[{\"user_id\":" + member.getUserId() + ",\"at\":[1],\"len\":" + member.getNickName().length() + "}]}"; + room.sendMessage("@" + member.getNickName() + "님 안녕하세요.", extra); } @Override - public void onDelMember(ChatRoom room, Member member) { - getTalkClient().sendMessage(room.getChatId(), member.getName() + "님이 나갔습니다."); + public void onDelMember(ChatRoom room, long userId, String nickName) { + room.sendMessage(nickName + "님이 나갔습니다."); } }); diff --git a/src/main/java/com/github/netricecake/kakao/KakaoApi.java b/src/main/java/com/github/netricecake/kakao/KakaoApi.java index 519d203..7f883b0 100644 --- a/src/main/java/com/github/netricecake/kakao/KakaoApi.java +++ b/src/main/java/com/github/netricecake/kakao/KakaoApi.java @@ -4,9 +4,9 @@ import com.github.netricecake.kakao.exception.BadCredentialsException; import com.github.netricecake.kakao.exception.InvalidDeviceNameException; import com.github.netricecake.kakao.exception.InvalidDeviceUUIDException; import com.github.netricecake.kakao.exception.UnregisteredDeviceException; -import com.github.netricecake.loco.packet.inbound.login.GetConfIn; -import com.github.netricecake.loco.packet.outbound.login.GetConfOut; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.packet.inbound.login.GetConfIn; +import com.github.netricecake.kakao.packet.outbound.login.GetConfOut; +import com.github.netricecake.kakao.util.ByteUtil; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; diff --git a/src/main/java/com/github/netricecake/kakao/LocoSocketHandlerImpl.java b/src/main/java/com/github/netricecake/kakao/LocoSocketHandlerImpl.java index 883b51f..4b21393 100644 --- a/src/main/java/com/github/netricecake/kakao/LocoSocketHandlerImpl.java +++ b/src/main/java/com/github/netricecake/kakao/LocoSocketHandlerImpl.java @@ -1,21 +1,15 @@ package com.github.netricecake.kakao; +import com.github.netricecake.kakao.packet.inbound.member.*; import com.github.netricecake.kakao.structs.ChatRoom; import com.github.netricecake.kakao.structs.Member; +import com.github.netricecake.kakao.structs.MemberType; import com.github.netricecake.kakao.structs.Message; -import com.github.netricecake.loco.LocoPacket; -import com.github.netricecake.loco.LocoSocketHandler; -import com.github.netricecake.loco.packet.inbound.member.*; -import com.github.netricecake.loco.packet.inbound.message.MessageIn; -import com.github.netricecake.loco.packet.inbound.room.ChatInfoIn; -import com.github.netricecake.loco.packet.inbound.room.InfoLinkIn; -import com.github.netricecake.loco.packet.outbound.member.MemberOut; -import com.github.netricecake.loco.packet.outbound.room.ChatInfoOut; -import com.github.netricecake.loco.packet.outbound.member.GetMemberOut; -import com.github.netricecake.loco.packet.outbound.room.InfoLinkOut; -import com.github.netricecake.loco.packet.outbound.message.MessageOut; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.github.netricecake.kakao.loco.LocoPacket; +import com.github.netricecake.kakao.loco.LocoSocketHandler; +import com.github.netricecake.kakao.packet.inbound.message.MessageIn; +import com.github.netricecake.kakao.packet.outbound.member.MemberOut; +import com.github.netricecake.kakao.packet.outbound.message.MessageOut; public class LocoSocketHandlerImpl extends LocoSocketHandler { @@ -30,100 +24,42 @@ public class LocoSocketHandlerImpl extends LocoSocketHandler { if (packet.getMethod().equals("MSG")) { client.getSocket().write(new LocoPacket(packet.getPacketId(), "MSG", new MessageOut().toBson())); - MessageIn in = new MessageIn(); - in.fromBson(packet.getBody()); - checkRoom(in.getChatId()); - checkMember(in.getChatId(), in.getAuthorId()); + MessageIn in = new MessageIn(packet.getBody()); + ChatRoom chatRoom = client.getChatRoom(in.getChatId()); + if (chatRoom == null) return; + Member member = chatRoom.getMembers().get(in.getAuthorId()); - ChatRoom room = client.getChatRooms().get(in.getChatId()); - Member member = room.getMembers().get(in.getAuthorId()); - - Message msg = new Message(in.getLogId(), room, member, in.getType(), in.getMessage(), in.getAttachment()); + Message msg = new Message(client, chatRoom, in.getLogId(), member, in.getType(), in.getSendAt(), in.getMessage(), in.getAttachment()); Thread.ofVirtual().start(() -> { client.getTalkHandler().onMessage(msg); }); } else if (packet.getMethod().equals("NEWMEM")) { - NewMemIn in = new NewMemIn(); - in.fromBson(packet.getBody()); - checkRoom(in.getChatId()); - checkMember(in.getChatId(), in.getUserId()); + NewMemIn res = new NewMemIn(packet.getBody()); + ChatRoom chatRoom = client.getChatRoom(res.getChatId()); + if (chatRoom == null) return; + MemberOut mo = new MemberOut(res.getChatId(), res.getUserId()); + MemberIn mi = new MemberIn(client.getSocket().writeAndRead(new LocoPacket("MEMBER", mo.toBson())).getBody()); + chatRoom.getMembers().put(res.getUserId(), new Member(client, chatRoom, res.getUserId(), mi.getType(), mi.getNickName(), mi.getProfileImageUrl(), mi.getFullProfileImageUrl(), mi.getOriginalProfileImageUrl(), mi.getProfileLinkId(), mi.getMemberType(), mi.getProfileType())); - ChatRoom room = client.getChatRooms().get(in.getChatId()); - if (!room.getType().equals("OM")) return; Thread.ofVirtual().start(() -> { - client.getTalkHandler().onNewMember(room, room.getMembers().get(in.getUserId())); + client.getTalkHandler().onNewMember(chatRoom, chatRoom.getMembers().get(res.getUserId())); }); } else if (packet.getMethod().equals("DELMEM")) { - DelMemIn in = new DelMemIn(); - in.fromBson(packet.getBody()); - checkRoom(in.getChatId()); + DelMemIn in = new DelMemIn(packet.getBody()); + ChatRoom chatRoom = client.getChatRoom(in.getChatId()); + if (chatRoom == null) return; + chatRoom.getMembers().remove(in.getUserId()); - ChatRoom room = client.getChatRooms().get(in.getChatId()); - if (!room.getType().equals("OM")) return; Thread.ofVirtual().start(() -> { - client.getTalkHandler().onDelMember(room, new Member(in.getUserId(), in.getNickname(), 2)); + client.getTalkHandler().onDelMember(chatRoom, in.getUserId(), in.getNickname()); }); - room.getMembers().remove(in.getUserId()); } else if (packet.getMethod().equals("SYNCLINKPF")) { - SyncLinkPfIn si = new SyncLinkPfIn(); - si.fromBson(packet.getBody()); - ChatRoom room = client.getChatRooms().get(si.getChatId()); - room.getMembers().remove(si.getUserId()); - Member member = new Member(si.getUserId(), si.getNickName(), 2); - room.getMembers().put(si.getUserId(), member); - } - } - - private void checkRoom(long chatId) { - if (!client.getChatRooms().containsKey(chatId)) { - ChatInfoOut co = new ChatInfoOut(chatId); - ChatInfoIn ci = new ChatInfoIn(); - ci.fromBson(client.getSocket().writeAndRead(new LocoPacket("CHATINFO", co.toBson())).getBody()); - ChatRoom room = new ChatRoom(); - room.setChatId(chatId); - room.setType(ci.getType()); - room.setLinkId(ci.getLinkId()); - GetMemberOut gmo = new GetMemberOut(chatId); - GetMemberIn gmi = new GetMemberIn(); - gmi.fromBson(client.getSocket().writeAndRead(new LocoPacket("GETMEM", gmo.toBson())).getBody()); - for (int i = 0; i < gmi.getMembers().size(); i++) { - JsonObject json = gmi.getMembers().get(i).getAsJsonObject(); - int type = json.get("mt") != null ? json.get("mt").getAsInt() : 2; - Member member = new Member(json.get("userId").getAsLong(), json.get("nickName").getAsString(), type); - room.getMembers().put(member.getId(), member); - } - - if (ci.getType().equals("OM")) { - InfoLinkOut lo = new InfoLinkOut(ci.getLinkId()); - InfoLinkIn li = new InfoLinkIn(); - li.fromBson(client.getSocket().writeAndRead(new LocoPacket("INFOLINK", lo.toBson())).getBody()); - room.setName(li.getName()); - } else if (ci.getType().equals("MultiChat")) { - if (!ci.getChatMetas().isEmpty()) { - JsonArray chatMetas = ci.getChatMetas(); - room.setName(chatMetas.get(0).getAsJsonObject().get("content").getAsString()); - } else { - JsonArray displayMembers = ci.getDisplayMembers(); - String name = ""; - for (int i = 0; i < displayMembers.size(); i++) { - name += displayMembers.get(i).getAsJsonObject().get("nickName").getAsString() + ", "; - } - room.setName(name); - } - } else if (ci.getType().equals("DirectChat")) { - room.setName(ci.getDisplayMembers().get(0).getAsJsonObject().get("nickName").getAsString()); - } - client.getChatRooms().put(chatId, room); - } - } - - private void checkMember(long chatId, long memberId) { - ChatRoom room = client.getChatRooms().get(chatId); - if (!room.getMembers().containsKey(memberId)) { - MemberOut mo = new MemberOut(chatId, memberId); - MemberIn mi = new MemberIn(); - mi.fromBson(client.getSocket().writeAndRead(new LocoPacket("MEMBER", mo.toBson())).getBody()); - room.getMembers().put(memberId, new Member(memberId, mi.getNickName(), mi.getMemberType())); + SyncLinkPfIn res = new SyncLinkPfIn(packet.getBody()); + ChatRoom chatRoom = client.getChatRoom(res.getChatId()); + if (chatRoom == null) return; + chatRoom.getMembers().remove(res.getUserId()); + Member member = new Member(client, chatRoom, res.getUserId(), 1000, res.getNickName(), res.getProfileImageUrl(), res.getFullProfileImageUrl(), res.getOriginalProfileImageUrl(), res.getProfileLinkId(), MemberType.MEMBER, res.getProfileType()); + chatRoom.getMembers().put(res.getUserId(), member); } } diff --git a/src/main/java/com/github/netricecake/kakao/TalkClient.java b/src/main/java/com/github/netricecake/kakao/TalkClient.java index 02bb28c..36fada9 100644 --- a/src/main/java/com/github/netricecake/kakao/TalkClient.java +++ b/src/main/java/com/github/netricecake/kakao/TalkClient.java @@ -1,25 +1,34 @@ package com.github.netricecake.kakao; import com.github.netricecake.kakao.exception.*; -import com.github.netricecake.kakao.structs.ChatRoom; -import com.github.netricecake.loco.LocoPacket; -import com.github.netricecake.loco.LocoSocketHandler; -import com.github.netricecake.loco.LocoSocket; -import com.github.netricecake.loco.packet.inbound.login.CheckInIn; -import com.github.netricecake.loco.packet.inbound.login.GetConfIn; -import com.github.netricecake.loco.packet.inbound.login.LoginListIn; -import com.github.netricecake.loco.packet.inbound.message.PostIn; -import com.github.netricecake.loco.packet.inbound.message.ShipIn; -import com.github.netricecake.loco.packet.inbound.message.WriteIn; -import com.github.netricecake.loco.packet.outbound.login.CheckInOut; -import com.github.netricecake.loco.packet.outbound.login.LoginListOut; -import com.github.netricecake.loco.packet.outbound.etc.PingOut; -import com.github.netricecake.loco.packet.outbound.message.PostOut; -import com.github.netricecake.loco.packet.outbound.message.ShipOut; -import com.github.netricecake.loco.packet.outbound.message.WriteOut; -import com.github.netricecake.loco.util.BsonUtil; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.packet.inbound.member.GetMemberIn; +import com.github.netricecake.kakao.packet.inbound.message.PostIn; +import com.github.netricecake.kakao.packet.inbound.message.ShipIn; +import com.github.netricecake.kakao.packet.inbound.room.ChatInfoIn; +import com.github.netricecake.kakao.packet.inbound.room.InfoLinkIn; +import com.github.netricecake.kakao.packet.outbound.member.GetMemberOut; +import com.github.netricecake.kakao.packet.outbound.message.PostOut; +import com.github.netricecake.kakao.packet.outbound.message.ShipOut; +import com.github.netricecake.kakao.packet.outbound.room.ChatInfoOut; +import com.github.netricecake.kakao.packet.outbound.room.InfoLinkOut; +import com.github.netricecake.kakao.structs.*; +import com.github.netricecake.kakao.loco.LocoPacket; +import com.github.netricecake.kakao.loco.LocoSocketHandler; +import com.github.netricecake.kakao.loco.LocoSocket; +import com.github.netricecake.kakao.packet.inbound.login.CheckInIn; +import com.github.netricecake.kakao.packet.inbound.login.GetConfIn; +import com.github.netricecake.kakao.packet.inbound.login.LoginListIn; +import com.github.netricecake.kakao.packet.inbound.message.WriteIn; +import com.github.netricecake.kakao.packet.outbound.login.CheckInOut; +import com.github.netricecake.kakao.packet.outbound.login.LoginListOut; +import com.github.netricecake.kakao.packet.outbound.etc.PingOut; +import com.github.netricecake.kakao.packet.outbound.member.KickMemberOut; +import com.github.netricecake.kakao.packet.outbound.message.WriteOut; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.util.ByteUtil; +import com.github.netricecake.kakao.util.ImageUtil; import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lombok.Getter; @@ -42,7 +51,6 @@ public class TalkClient { private final String deviceUuid; private final String sessionDir; - @Getter private final Map chatRooms = new HashMap<>(); @Getter @@ -148,22 +156,75 @@ public class TalkClient { }); } - public boolean sendMessage(long chatId, int type, String message, String extra) { - WriteOut wo = new WriteOut(); - wo.setChatId(chatId); - wo.setType(type); - wo.setMessage(message); - wo.setExtra(extra); - WriteIn wi = new WriteIn(); - wi.fromBson(socket.writeAndRead(new LocoPacket("WRITE", wo.toBson())).getBody()); - return wi.getStatus() == 0; + public ChatRoom getChatRoom(long chatId) { + if (chatRooms.containsKey(chatId)) return chatRooms.get(chatId); + ChatInfoOut req = new ChatInfoOut(chatId); + + ChatInfoIn res = new ChatInfoIn(socket.writeAndRead(new LocoPacket("CHATINFO", req.toBson())).getBody()); + if (res.getStatus() != 0) return null; + + GetMemberOut memberReq = new GetMemberOut(chatId); + GetMemberIn memberRes = new GetMemberIn(socket.writeAndRead(new LocoPacket("GETMEM", memberReq.toBson())).getBody()); + + ChatRoom chatRoom = null; + if (res.getType().equals(ChatRoomType.OPEN_CHAT) || res.getType().equals(ChatRoomType.OPEN_DIRECT)) { + InfoLinkOut linkReq = new InfoLinkOut(res.getLinkId()); + InfoLinkIn linkRes = new InfoLinkIn(socket.writeAndRead(new LocoPacket("INFOLINK", linkReq.toBson())).getBody()); + + chatRoom = new ChatRoom(this, chatId, res.getType(), linkRes.getName(), res.getLinkId()); + for (int i = 0; i < memberRes.getMembers().size(); i++) { + JsonObject json = memberRes.getMembers().get(i).getAsJsonObject(); + Member member = new Member(this, chatRoom, json.get("userId").getAsLong(), json.get("type").getAsInt(), json.get("nickName").getAsString(), json.get("pi").getAsString(), json.get("fpi").getAsString(), json.get("opi").getAsString(), json.get("ptp").getAsInt() == 16 ? json.get("pli").getAsLong() : 0, json.get("mt").getAsInt(), json.get("ptp").getAsInt()); + chatRoom.getMembers().put(member.getUserId(), member); + } + } else if (res.getType().equals(ChatRoomType.DIRECT_CHAT)) { + chatRoom = new ChatRoom(this, chatId, res.getType(), res.getDisplayMembers().get(0).getAsJsonObject().get("nickName").getAsString(), 0); + for (int i = 0; i < memberRes.getMembers().size(); i++) { + JsonObject json = memberRes.getMembers().get(i).getAsJsonObject(); + Member member = new Member(this, chatRoom, json.get("userId").getAsLong(), json.get("type").getAsInt(), json.get("nickName").getAsString(), json.get("profileImageUrl").getAsString(), json.get("fullProfileImageUrl").getAsString(), json.get("originalProfileImageUrl").getAsString(), 0, MemberType.MEMBER, 0); + chatRoom.getMembers().put(member.getUserId(), member); + } + } else if (res.getType().equals(ChatRoomType.GROUP_CHAT)) { + if (!res.getChatMetas().isEmpty()) { + JsonArray chatMetas = res.getChatMetas(); + chatRoom = new ChatRoom(this, chatId, res.getType(), chatMetas.get(0).getAsJsonObject().get("content").getAsString(), 0); + } else { + JsonArray displayMembers = res.getDisplayMembers(); + String name = ""; + for (int i = 0; i < displayMembers.size(); i++) { + name += displayMembers.get(i).getAsJsonObject().get("nickName").getAsString() + ", "; + } + chatRoom = new ChatRoom(this, chatId, res.getType(), name, 0); + } + + for (int i = 0; i < memberRes.getMembers().size(); i++) { + JsonObject json = memberRes.getMembers().get(i).getAsJsonObject(); + Member member = new Member(this, chatRoom, json.get("userId").getAsLong(), json.get("type").getAsInt(), json.get("nickName").getAsString(), json.get("profileImageUrl").getAsString(), json.get("fullProfileImageUrl").getAsString(), json.get("originalProfileImageUrl").getAsString(), 0, MemberType.MEMBER, 0); + chatRoom.getMembers().put(member.getUserId(), member); + } + } + + return chatRoom; + } + + public boolean sendMessage(long chatId, String message, String extra) { + WriteOut req = new WriteOut(); + req.setChatId(chatId); + req.setType(MessageType.TEXT); + req.setMessage(message); + req.setExtra(extra); + + WriteIn res = new WriteIn(socket.writeAndRead(new LocoPacket("WRITE", req.toBson())).getBody()); + return res.getStatus() == 0; } public boolean sendMessage(long chatId, String message) { - return sendMessage(chatId, 1, message, "{}"); + return sendMessage(chatId, message, "{}"); } - public boolean sendJpg(long chatId, byte[] image, String format, int width, int height) { + public boolean sendJpg(long chatId, byte[] image) { + ImageUtil.ImageMeta meta = ImageUtil.getImageMeta(image); + if (!meta.isValidJpeg()) return false; LocoSocket postSocket = null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); @@ -171,8 +232,7 @@ public class TalkClient { so.setChatId(chatId); so.setSize(image.length); so.setCheckSum(ByteUtil.byteArrayToHexString(md.digest(image))); - ShipIn si = new ShipIn(); - si.fromBson(socket.writeAndRead(new LocoPacket("SHIP", so.toBson())).getBody()); + ShipIn si = new ShipIn(socket.writeAndRead(new LocoPacket("SHIP", so.toBson())).getBody()); if (si.getStatus() != 0) return false; final CompletableFuture future = new CompletableFuture<>(); @@ -191,11 +251,10 @@ public class TalkClient { po.setKey(si.getKey()); po.setSize(image.length); po.setChatId(chatId); - po.setWidth(width); - po.setHeight(height); + po.setWidth(meta.getWidth()); + po.setHeight(meta.getHeight()); - PostIn pi = new PostIn(); - pi.fromBson(postSocket.writeAndRead(new LocoPacket("POST", po.toBson())).getBody()); + PostIn pi = new PostIn(postSocket.writeAndRead(new LocoPacket("POST", po.toBson())).getBody()); if (pi.getStatus() != 0) { postSocket.close(); return false; @@ -214,7 +273,33 @@ public class TalkClient { return false; } - public long getUserId() { + public boolean reply(Message target, String message) { + JsonObject extraObject = new JsonObject(); + extraObject.addProperty("src_logId", target.getLogId()); + extraObject.addProperty("src_userId", target.getAuthor().getUserId()); + extraObject.addProperty("src_message", target.getMessage()); + extraObject.addProperty("src_type", target.getType()); + extraObject.addProperty("src_linkId", target.getChatRoom().getLinkId()); + + WriteOut req = new WriteOut(); + req.setChatId(target.getChatRoom().getChatId()); + req.setMessage(message); + req.setType(MessageType.REPLY); + req.setExtra(extraObject.toString()); + + JsonObject res = socket.writeAndRead(new LocoPacket("WRITE", req.toBson())).getBodyJson(); + return res.get("status").getAsInt() == 0; + } + + public boolean kickMember(long chatId, long linkId, long memberId) { + KickMemberOut req = new KickMemberOut(chatId, linkId, memberId); + + JsonObject res = socket.writeAndRead(new LocoPacket("KICKMEM", req.toBson())).getBodyJson(); + // 채팅 로그 저장할거면 이거도 처리 + return res.get("status").getAsInt() == 0; + } + + public long getMyUserId() { return loginData.userId; } diff --git a/src/main/java/com/github/netricecake/kakao/TalkHandler.java b/src/main/java/com/github/netricecake/kakao/TalkHandler.java index 3be6ab7..dce93f0 100644 --- a/src/main/java/com/github/netricecake/kakao/TalkHandler.java +++ b/src/main/java/com/github/netricecake/kakao/TalkHandler.java @@ -12,6 +12,14 @@ public class TalkHandler { @Setter private TalkClient talkClient; + public void onConnect() { + + } + + public void onDisconnect() { + + } + public void onMessage(Message message) { } @@ -20,7 +28,7 @@ public class TalkHandler { } - public void onDelMember(ChatRoom chatRoom, Member member) { + public void onDelMember(ChatRoom chatRoom, long userId, String nickName) { } diff --git a/src/main/java/com/github/netricecake/loco/LocoPacket.java b/src/main/java/com/github/netricecake/kakao/loco/LocoPacket.java similarity index 63% rename from src/main/java/com/github/netricecake/loco/LocoPacket.java rename to src/main/java/com/github/netricecake/kakao/loco/LocoPacket.java index 4904b1a..f5f1c9e 100644 --- a/src/main/java/com/github/netricecake/loco/LocoPacket.java +++ b/src/main/java/com/github/netricecake/kakao/loco/LocoPacket.java @@ -1,5 +1,7 @@ -package com.github.netricecake.loco; +package com.github.netricecake.kakao.loco; +import com.github.netricecake.kakao.util.BsonUtil; +import com.google.gson.JsonObject; import lombok.Getter; import lombok.Setter; @@ -38,4 +40,16 @@ public class LocoPacket { this(-1, method, body); } + public LocoPacket(int packetId, String method, JsonObject body) { + this(packetId, method, BsonUtil.jsonObjectToBson(body)); + } + + public LocoPacket(String method, JsonObject body) { + this(-1, method, BsonUtil.jsonObjectToBson(body)); + } + + public JsonObject getBodyJson() { + return BsonUtil.bsonToJsonObject(body); + } + } diff --git a/src/main/java/com/github/netricecake/loco/LocoSocket.java b/src/main/java/com/github/netricecake/kakao/loco/LocoSocket.java similarity index 95% rename from src/main/java/com/github/netricecake/loco/LocoSocket.java rename to src/main/java/com/github/netricecake/kakao/loco/LocoSocket.java index 68f8673..37c2528 100644 --- a/src/main/java/com/github/netricecake/loco/LocoSocket.java +++ b/src/main/java/com/github/netricecake/kakao/loco/LocoSocket.java @@ -1,8 +1,8 @@ -package com.github.netricecake.loco; +package com.github.netricecake.kakao.loco; -import com.github.netricecake.loco.crypto.CryptoManager; -import com.github.netricecake.loco.codec.LocoCodec; -import com.github.netricecake.loco.codec.SecureLayerCodec; +import com.github.netricecake.kakao.loco.crypto.CryptoManager; +import com.github.netricecake.kakao.loco.codec.LocoCodec; +import com.github.netricecake.kakao.loco.codec.SecureLayerCodec; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioIoHandler; diff --git a/src/main/java/com/github/netricecake/loco/LocoSocketHandler.java b/src/main/java/com/github/netricecake/kakao/loco/LocoSocketHandler.java similarity index 81% rename from src/main/java/com/github/netricecake/loco/LocoSocketHandler.java rename to src/main/java/com/github/netricecake/kakao/loco/LocoSocketHandler.java index 0ada6a0..39f0b86 100644 --- a/src/main/java/com/github/netricecake/loco/LocoSocketHandler.java +++ b/src/main/java/com/github/netricecake/kakao/loco/LocoSocketHandler.java @@ -1,4 +1,4 @@ -package com.github.netricecake.loco; +package com.github.netricecake.kakao.loco; public class LocoSocketHandler { diff --git a/src/main/java/com/github/netricecake/loco/codec/LocoCodec.java b/src/main/java/com/github/netricecake/kakao/loco/codec/LocoCodec.java similarity index 93% rename from src/main/java/com/github/netricecake/loco/codec/LocoCodec.java rename to src/main/java/com/github/netricecake/kakao/loco/codec/LocoCodec.java index f842037..dc9a569 100644 --- a/src/main/java/com/github/netricecake/loco/codec/LocoCodec.java +++ b/src/main/java/com/github/netricecake/kakao/loco/codec/LocoCodec.java @@ -1,9 +1,9 @@ -package com.github.netricecake.loco.codec; +package com.github.netricecake.kakao.loco.codec; -import com.github.netricecake.loco.LocoPacket; -import com.github.netricecake.loco.LocoSocketHandler; -import com.github.netricecake.loco.util.BsonUtil; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.loco.LocoPacket; +import com.github.netricecake.kakao.loco.LocoSocketHandler; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.util.ByteUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageCodec; diff --git a/src/main/java/com/github/netricecake/loco/codec/SecureLayerCodec.java b/src/main/java/com/github/netricecake/kakao/loco/codec/SecureLayerCodec.java similarity index 91% rename from src/main/java/com/github/netricecake/loco/codec/SecureLayerCodec.java rename to src/main/java/com/github/netricecake/kakao/loco/codec/SecureLayerCodec.java index 395e418..9d439ca 100644 --- a/src/main/java/com/github/netricecake/loco/codec/SecureLayerCodec.java +++ b/src/main/java/com/github/netricecake/kakao/loco/codec/SecureLayerCodec.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.codec; +package com.github.netricecake.kakao.loco.codec; -import com.github.netricecake.loco.crypto.CryptoManager; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.loco.crypto.CryptoManager; +import com.github.netricecake.kakao.util.ByteUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageCodec; diff --git a/src/main/java/com/github/netricecake/loco/crypto/CryptoManager.java b/src/main/java/com/github/netricecake/kakao/loco/crypto/CryptoManager.java similarity index 97% rename from src/main/java/com/github/netricecake/loco/crypto/CryptoManager.java rename to src/main/java/com/github/netricecake/kakao/loco/crypto/CryptoManager.java index ab39de3..c47faac 100644 --- a/src/main/java/com/github/netricecake/loco/crypto/CryptoManager.java +++ b/src/main/java/com/github/netricecake/kakao/loco/crypto/CryptoManager.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.crypto; +package com.github.netricecake.kakao.loco.crypto; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.util.ByteUtil; import lombok.Getter; import javax.crypto.Cipher; diff --git a/src/main/java/com/github/netricecake/loco/packet/InboundPacket.java b/src/main/java/com/github/netricecake/kakao/packet/InboundPacket.java similarity index 95% rename from src/main/java/com/github/netricecake/loco/packet/InboundPacket.java rename to src/main/java/com/github/netricecake/kakao/packet/InboundPacket.java index 86e09d1..461eacc 100644 --- a/src/main/java/com/github/netricecake/loco/packet/InboundPacket.java +++ b/src/main/java/com/github/netricecake/kakao/packet/InboundPacket.java @@ -1,4 +1,4 @@ -package com.github.netricecake.loco.packet; +package com.github.netricecake.kakao.packet; import com.google.gson.JsonElement; import com.google.gson.JsonObject; diff --git a/src/main/java/com/github/netricecake/kakao/packet/inbound/etc/PingIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/etc/PingIn.java new file mode 100644 index 0000000..20fc363 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/etc/PingIn.java @@ -0,0 +1,6 @@ +package com.github.netricecake.kakao.packet.inbound.etc; + +import com.github.netricecake.kakao.packet.InboundPacket; + +public class PingIn extends InboundPacket { +} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/login/CheckInIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/CheckInIn.java similarity index 87% rename from src/main/java/com/github/netricecake/loco/packet/inbound/login/CheckInIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/login/CheckInIn.java index 89f4328..0cb4ca6 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/login/CheckInIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/CheckInIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.login; +package com.github.netricecake.kakao.packet.inbound.login; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/login/GetConfIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/GetConfIn.java similarity index 78% rename from src/main/java/com/github/netricecake/loco/packet/inbound/login/GetConfIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/login/GetConfIn.java index 8c36cf2..be16bf7 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/login/GetConfIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/GetConfIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.login; +package com.github.netricecake.kakao.packet.inbound.login; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/login/LoginListIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/LoginListIn.java similarity index 90% rename from src/main/java/com/github/netricecake/loco/packet/inbound/login/LoginListIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/login/LoginListIn.java index 7745a21..c195aec 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/login/LoginListIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/login/LoginListIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.login; +package com.github.netricecake.kakao.packet.inbound.login; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Getter; diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/member/DelMemIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/DelMemIn.java similarity index 76% rename from src/main/java/com/github/netricecake/loco/packet/inbound/member/DelMemIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/member/DelMemIn.java index e77c49b..9b73d9b 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/member/DelMemIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/DelMemIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.member; +package com.github.netricecake.kakao.packet.inbound.member; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lombok.Getter; @@ -15,7 +15,7 @@ public class DelMemIn extends InboundPacket { private String nickname; - public void fromBson(byte[] bson) { + public DelMemIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson).get("chatLog").getAsJsonObject(); chatId = jsonObject.get("chatId").getAsLong(); userId = jsonObject.get("authorId").getAsLong(); diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/member/GetMemberIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/GetMemberIn.java similarity index 65% rename from src/main/java/com/github/netricecake/loco/packet/inbound/member/GetMemberIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/member/GetMemberIn.java index 807f256..c2d8e8e 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/member/GetMemberIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/GetMemberIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.member; +package com.github.netricecake.kakao.packet.inbound.member; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Getter; @@ -13,7 +13,7 @@ public class GetMemberIn extends InboundPacket { private JsonArray members; - public void fromBson(byte[] bson) { + public GetMemberIn(byte[] bson) { JsonObject json = BsonUtil.bsonToJsonObject(bson); status = json.get("status").getAsInt(); if (status == 0) members = json.get("members").getAsJsonArray(); diff --git a/src/main/java/com/github/netricecake/kakao/packet/inbound/member/MemberIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/MemberIn.java new file mode 100644 index 0000000..9d5c647 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/MemberIn.java @@ -0,0 +1,45 @@ +package com.github.netricecake.kakao.packet.inbound.member; + +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.structs.MemberType; +import com.google.gson.JsonObject; +import lombok.Getter; + +@Getter +public class MemberIn extends InboundPacket { + + private long userId; + + private int type; + + private String nickName; + + private String profileImageUrl; + + private String fullProfileImageUrl; + + private String originalProfileImageUrl; + + private long profileLinkId; + + private int memberType = MemberType.MEMBER; + + private int profileType; + + public MemberIn(byte[] bson) { + JsonObject json = BsonUtil.bsonToJsonObject(bson).get("members").getAsJsonArray().get(0).getAsJsonObject(); + userId = json.get("userId").getAsLong(); + type = json.get("type").getAsInt(); + nickName = json.get("nickName").getAsString(); + profileImageUrl = json.get("pi").getAsString(); + fullProfileImageUrl = json.get("fpi").getAsString(); + originalProfileImageUrl = json.get("opi").getAsString(); + if (type == 1000) { + memberType = json.get("mt").getAsInt(); + profileType = json.get("ptp").getAsInt(); + profileLinkId = profileType == 16 ? json.get("pli").getAsLong() : 0; + } + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/member/NewMemIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/NewMemIn.java similarity index 76% rename from src/main/java/com/github/netricecake/loco/packet/inbound/member/NewMemIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/member/NewMemIn.java index a564ae5..dd947d2 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/member/NewMemIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/NewMemIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.member; +package com.github.netricecake.kakao.packet.inbound.member; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lombok.Getter; @@ -15,7 +15,7 @@ public class NewMemIn extends InboundPacket { private String nickname; - public void fromBson(byte[] bson) { + public NewMemIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson).get("chatLog").getAsJsonObject(); chatId = jsonObject.get("chatId").getAsLong(); userId = jsonObject.get("authorId").getAsLong(); diff --git a/src/main/java/com/github/netricecake/kakao/packet/inbound/member/SyncLinkPfIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/SyncLinkPfIn.java new file mode 100644 index 0000000..34b1e62 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/member/SyncLinkPfIn.java @@ -0,0 +1,43 @@ +package com.github.netricecake.kakao.packet.inbound.member; + +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; +import com.google.gson.JsonObject; +import lombok.Getter; + +@Getter +public class SyncLinkPfIn extends InboundPacket { + + private long chatId; + + private long linkId; + + private long userId; + + private int profileType; + + private String nickName; + + private String profileImageUrl; + + private String fullProfileImageUrl; + + private String originalProfileImageUrl; + + private long profileLinkId; + + public SyncLinkPfIn(byte[] bson) { + JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); + chatId = jsonObject.get("c").getAsLong(); + linkId = jsonObject.get("li").getAsLong(); + JsonObject olu = jsonObject.get("olu").getAsJsonObject(); + userId = olu.get("userId").getAsLong(); + profileType = olu.get("ptp").getAsInt(); + nickName = olu.get("nn").getAsString(); + profileImageUrl = olu.get("pi").getAsString(); + fullProfileImageUrl = olu.get("fpi").getAsString(); + originalProfileImageUrl = olu.get("opi").getAsString(); + profileLinkId = profileType == 16 ? olu.get("pli").getAsLong() : 0; + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/message/MessageIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/MessageIn.java similarity index 77% rename from src/main/java/com/github/netricecake/loco/packet/inbound/message/MessageIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/message/MessageIn.java index a707a69..0193a7b 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/message/MessageIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/MessageIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.message; +package com.github.netricecake.kakao.packet.inbound.message; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; @@ -18,11 +18,13 @@ public class MessageIn extends InboundPacket { private int type; + private long sendAt; + private String message; private String attachment; - public void fromBson(byte[] bson) { + public MessageIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); chatId = jsonObject.get("chatId").getAsLong(); logId = jsonObject.get("logId").getAsLong(); @@ -31,6 +33,7 @@ public class MessageIn extends InboundPacket { authorNickname = jsonObject.get("authorNickname").getAsString(); // 옵챗 아니면 이필드가 없음;; } catch (Exception e) {} type = jsonObject.get("chatLog").getAsJsonObject().get("type").getAsInt(); + sendAt = jsonObject.get("chatLog").getAsJsonObject().get("sendAt").getAsLong(); message = jsonObject.get("chatLog").getAsJsonObject().get("message").getAsString(); try { attachment = jsonObject.get("chatLog").getAsJsonObject().get("attachment").getAsString(); diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/message/PostIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/PostIn.java similarity index 68% rename from src/main/java/com/github/netricecake/loco/packet/inbound/message/PostIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/message/PostIn.java index da89fa9..aae8b26 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/message/PostIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/PostIn.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.inbound.message; +package com.github.netricecake.kakao.packet.inbound.message; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; @@ -11,7 +11,7 @@ public class PostIn { private long o; - public void fromBson(byte[] bson) { + public PostIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); this.status = jsonObject.get("status").getAsInt(); this.o = jsonObject.get("o").getAsLong(); diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/message/ShipIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/ShipIn.java similarity index 74% rename from src/main/java/com/github/netricecake/loco/packet/inbound/message/ShipIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/message/ShipIn.java index 1cac516..a7af774 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/message/ShipIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/ShipIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.message; +package com.github.netricecake.kakao.packet.inbound.message; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; @@ -18,7 +18,7 @@ public class ShipIn extends InboundPacket { private int port; - public void fromBson(byte[] bson) { + public ShipIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); status = jsonObject.get("status").getAsInt(); if (status != 0) return; diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/message/WriteIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/WriteIn.java similarity index 56% rename from src/main/java/com/github/netricecake/loco/packet/inbound/message/WriteIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/message/WriteIn.java index 7ff9ba7..dcbab0b 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/message/WriteIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/message/WriteIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.message; +package com.github.netricecake.kakao.packet.inbound.message; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; @@ -10,7 +10,7 @@ public class WriteIn extends InboundPacket { private int status; - public void fromBson(byte[] bson) { + public WriteIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); status = jsonObject.get("status").getAsInt(); } diff --git a/src/main/java/com/github/netricecake/kakao/packet/inbound/room/ChatInfoIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/room/ChatInfoIn.java new file mode 100644 index 0000000..eb43019 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/room/ChatInfoIn.java @@ -0,0 +1,36 @@ +package com.github.netricecake.kakao.packet.inbound.room; + +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.structs.ChatRoomType; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Getter; + +@Getter +public class ChatInfoIn extends InboundPacket { + + private int status; + + private String type; + + private JsonArray chatMetas; + + private JsonArray displayMembers; + + private long linkId = 0; + + public ChatInfoIn(byte[] bson) { + JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); + status = jsonObject.get("status").getAsInt(); + if (status == 0) { + type = jsonObject.get("chatInfo").getAsJsonObject().get("type").getAsString(); + chatMetas = jsonObject.get("chatInfo").getAsJsonObject().get("chatMetas").getAsJsonArray(); + displayMembers = jsonObject.get("chatInfo").getAsJsonObject().get("displayMembers").getAsJsonArray(); + if (type.equals(ChatRoomType.OPEN_CHAT) || type.equals(ChatRoomType.OPEN_DIRECT)) { + linkId = jsonObject.get("chatInfo").getAsJsonObject().get("li").getAsLong(); + } + } + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/room/InfoLinkIn.java b/src/main/java/com/github/netricecake/kakao/packet/inbound/room/InfoLinkIn.java similarity index 61% rename from src/main/java/com/github/netricecake/loco/packet/inbound/room/InfoLinkIn.java rename to src/main/java/com/github/netricecake/kakao/packet/inbound/room/InfoLinkIn.java index cdd286f..1820be7 100644 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/room/InfoLinkIn.java +++ b/src/main/java/com/github/netricecake/kakao/packet/inbound/room/InfoLinkIn.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.inbound.room; +package com.github.netricecake.kakao.packet.inbound.room; -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.packet.InboundPacket; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; @@ -10,7 +10,7 @@ public class InfoLinkIn extends InboundPacket { private String name; - public void fromBson(byte[] bson) { + public InfoLinkIn(byte[] bson) { JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); name = jsonObject.get("ols").getAsJsonArray().get(0).getAsJsonObject().get("ln").getAsString(); } diff --git a/src/main/java/com/github/netricecake/kakao/packet/outbound/etc/PingOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/etc/PingOut.java new file mode 100644 index 0000000..f3b0063 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/etc/PingOut.java @@ -0,0 +1,11 @@ +package com.github.netricecake.kakao.packet.outbound.etc; + +import com.github.netricecake.kakao.util.BsonUtil; + +public class PingOut { + + public byte[] toBson() { + return BsonUtil.jsonToBson("{}"); + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/login/CheckInOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/CheckInOut.java similarity index 89% rename from src/main/java/com/github/netricecake/loco/packet/outbound/login/CheckInOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/login/CheckInOut.java index 86f1306..d3bfb6c 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/login/CheckInOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/CheckInOut.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.outbound.login; +package com.github.netricecake.kakao.packet.outbound.login; import com.github.netricecake.kakao.KakaoApi; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/login/GetConfOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/GetConfOut.java similarity index 83% rename from src/main/java/com/github/netricecake/loco/packet/outbound/login/GetConfOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/login/GetConfOut.java index 2c48dca..c7556a0 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/login/GetConfOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/GetConfOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.login; +package com.github.netricecake.kakao.packet.outbound.login; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; public class GetConfOut { diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/login/LoginListOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/LoginListOut.java similarity index 86% rename from src/main/java/com/github/netricecake/loco/packet/outbound/login/LoginListOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/login/LoginListOut.java index 0333f00..3643e6f 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/login/LoginListOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/login/LoginListOut.java @@ -1,8 +1,8 @@ -package com.github.netricecake.loco.packet.outbound.login; +package com.github.netricecake.kakao.packet.outbound.login; import com.github.netricecake.kakao.KakaoApi; -import com.github.netricecake.loco.util.BsonUtil; -import com.github.netricecake.loco.util.ByteUtil; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.util.ByteUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Getter; @@ -38,16 +38,12 @@ public class LoginListOut { private long lbk = 0; - private byte[] rp; // 이거 뭐임 + private byte[] rp = ByteUtil.hexStringToByteArray("0000ffff0000");; // 이거 뭐임 private boolean bg = true; private String oauthToken; - public LoginListOut() { - rp = ByteUtil.hexStringToByteArray("0000ffff0000"); - } - public byte[] toBson() { JsonObject rpObject = new JsonObject(); JsonObject binary = new JsonObject(); diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/member/GetMemberOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/GetMemberOut.java similarity index 76% rename from src/main/java/com/github/netricecake/loco/packet/outbound/member/GetMemberOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/member/GetMemberOut.java index f314d0f..cfb34dd 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/member/GetMemberOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/GetMemberOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.member; +package com.github.netricecake.kakao.packet.outbound.member; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; public class GetMemberOut { diff --git a/src/main/java/com/github/netricecake/kakao/packet/outbound/member/KickMemberOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/KickMemberOut.java new file mode 100644 index 0000000..0fddf57 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/KickMemberOut.java @@ -0,0 +1,32 @@ +package com.github.netricecake.kakao.packet.outbound.member; + +import com.github.netricecake.kakao.util.BsonUtil; +import com.google.gson.JsonObject; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class KickMemberOut { + + private long chatId; + + private long linkId; + + private long memberId; + + public KickMemberOut(long chatId, long linkId, long memberId) { + this.chatId = chatId; + this.linkId = linkId; + this.memberId = memberId; + } + + public byte[] toBson() { + JsonObject json = new JsonObject(); + json.addProperty("li", linkId); + json.addProperty("c", chatId); + json.addProperty("mid", memberId); + json.addProperty("r", false); + return BsonUtil.jsonObjectToBson(json); + } +} diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/member/MemberOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/MemberOut.java similarity index 85% rename from src/main/java/com/github/netricecake/loco/packet/outbound/member/MemberOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/member/MemberOut.java index 041a877..5f15671 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/member/MemberOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/MemberOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.member; +package com.github.netricecake.kakao.packet.outbound.member; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Getter; diff --git a/src/main/java/com/github/netricecake/kakao/packet/outbound/member/PardonMemberOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/PardonMemberOut.java new file mode 100644 index 0000000..05997de --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/member/PardonMemberOut.java @@ -0,0 +1,26 @@ +package com.github.netricecake.kakao.packet.outbound.member; + +import com.github.netricecake.kakao.util.BsonUtil; +import com.google.gson.JsonObject; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PardonMemberOut { + + private long chatId; + + private long linkId; + + private long memberId; + + public byte[] toBson() { + JsonObject json = new JsonObject(); + json.addProperty("li", linkId); + json.addProperty("c", chatId); + json.addProperty("mid", memberId); + return BsonUtil.jsonObjectToBson(json); + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/message/MessageOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/MessageOut.java similarity index 53% rename from src/main/java/com/github/netricecake/loco/packet/outbound/message/MessageOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/message/MessageOut.java index b1cb546..594a19b 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/message/MessageOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/MessageOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.message; +package com.github.netricecake.kakao.packet.outbound.message; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; public class MessageOut { diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/message/PostOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/PostOut.java similarity index 93% rename from src/main/java/com/github/netricecake/loco/packet/outbound/message/PostOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/message/PostOut.java index 20c819b..392dcb5 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/message/PostOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/PostOut.java @@ -1,7 +1,7 @@ -package com.github.netricecake.loco.packet.outbound.message; +package com.github.netricecake.kakao.packet.outbound.message; import com.github.netricecake.kakao.KakaoApi; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/message/ShipOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/ShipOut.java similarity index 86% rename from src/main/java/com/github/netricecake/loco/packet/outbound/message/ShipOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/message/ShipOut.java index 3c1c640..9c3ce45 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/message/ShipOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/ShipOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.message; +package com.github.netricecake.kakao.packet.outbound.message; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/message/WriteOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/WriteOut.java similarity index 79% rename from src/main/java/com/github/netricecake/loco/packet/outbound/message/WriteOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/message/WriteOut.java index d194386..bea2251 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/message/WriteOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/message/WriteOut.java @@ -1,6 +1,7 @@ -package com.github.netricecake.loco.packet.outbound.message; +package com.github.netricecake.kakao.packet.outbound.message; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; +import com.github.netricecake.kakao.structs.MessageType; import com.google.gson.JsonObject; import lombok.Getter; import lombok.Setter; @@ -12,11 +13,17 @@ import java.security.SecureRandom; public class WriteOut { private long chatId; + private long msgId = new SecureRandom().nextLong(); + private String message; - private int type = 1; + + private int type = MessageType.TEXT; + private boolean noSeen = false; + private String extra = "{}"; + private int scope = 1; public byte[] toBson() { diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/room/ChatInfoOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/room/ChatInfoOut.java similarity index 76% rename from src/main/java/com/github/netricecake/loco/packet/outbound/room/ChatInfoOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/room/ChatInfoOut.java index cb9a7c6..932fff8 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/room/ChatInfoOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/room/ChatInfoOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.room; +package com.github.netricecake.kakao.packet.outbound.room; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonObject; public class ChatInfoOut { diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/room/InfoLinkOut.java b/src/main/java/com/github/netricecake/kakao/packet/outbound/room/InfoLinkOut.java similarity index 80% rename from src/main/java/com/github/netricecake/loco/packet/outbound/room/InfoLinkOut.java rename to src/main/java/com/github/netricecake/kakao/packet/outbound/room/InfoLinkOut.java index e2e1960..6c6db3e 100644 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/room/InfoLinkOut.java +++ b/src/main/java/com/github/netricecake/kakao/packet/outbound/room/InfoLinkOut.java @@ -1,6 +1,6 @@ -package com.github.netricecake.loco.packet.outbound.room; +package com.github.netricecake.kakao.packet.outbound.room; -import com.github.netricecake.loco.util.BsonUtil; +import com.github.netricecake.kakao.util.BsonUtil; import com.google.gson.JsonArray; import com.google.gson.JsonObject; diff --git a/src/main/java/com/github/netricecake/kakao/structs/ChatRoom.java b/src/main/java/com/github/netricecake/kakao/structs/ChatRoom.java index efa0435..9b6113f 100644 --- a/src/main/java/com/github/netricecake/kakao/structs/ChatRoom.java +++ b/src/main/java/com/github/netricecake/kakao/structs/ChatRoom.java @@ -1,24 +1,39 @@ package com.github.netricecake.kakao.structs; +import com.github.netricecake.kakao.TalkClient; +import com.github.netricecake.kakao.util.ImageUtil; import lombok.Getter; -import lombok.Setter; import java.util.HashMap; import java.util.Map; -@Getter -@Setter public class ChatRoom { - private long chatId; + @Getter + private final TalkClient client; - private String type; + @Getter + private final long chatId; - private String name; + @Getter + private final String type; - private long linkId; + @Getter + private final String name; - private Map members = new HashMap<>(); + @Getter + private final long linkId; + + @Getter + private final Map members = new HashMap<>(); + + public ChatRoom(TalkClient client, long chatId, String type, String name, long linkId) { + this.client = client; + this.chatId = chatId; + this.type = type; + this.name = name; + this.linkId = linkId; + } public int getMemberCount() { return members.size(); @@ -28,4 +43,34 @@ public class ChatRoom { return members.get(id); } + public boolean kickMember(long userId) { + if (!(type.equals(ChatRoomType.OPEN_CHAT) || type.equals(ChatRoomType.OPEN_DIRECT))) return false; + if (!(getMember(client.getMyUserId()).getMemberType() == MemberType.OWNER || getMember(client.getMyUserId()).getMemberType() == MemberType.ADMIN)) return false; + return client.kickMember(chatId, linkId, userId); + } + + public boolean kickMember(Member member) { + return kickMember(member.getUserId()); + } + + public boolean sendMessage(String message) { + return client.sendMessage(chatId, message); + } + + public boolean sendMessage(String message, String extra) { + return client.sendMessage(chatId, message, extra); + } + + public boolean sendJpg(byte[] image) { + return client.sendJpg(chatId, image); //client.sendImage(chatId, image, extension); + } + + public boolean sendVideo(String extension, byte[] video) { + return false; + } + + public boolean sendFile(String extension, byte[] file) { + return false; + } + } diff --git a/src/main/java/com/github/netricecake/kakao/structs/ChatRoomType.java b/src/main/java/com/github/netricecake/kakao/structs/ChatRoomType.java new file mode 100644 index 0000000..265714f --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/structs/ChatRoomType.java @@ -0,0 +1,11 @@ +package com.github.netricecake.kakao.structs; + +public class ChatRoomType { + + public final static String DIRECT_CHAT = "DirectChat"; + public final static String GROUP_CHAT = "MultiChat"; + + public final static String OPEN_CHAT = "OM"; + public final static String OPEN_DIRECT = "OD"; + +} diff --git a/src/main/java/com/github/netricecake/kakao/structs/Member.java b/src/main/java/com/github/netricecake/kakao/structs/Member.java index 1f3d69f..24d8e54 100644 --- a/src/main/java/com/github/netricecake/kakao/structs/Member.java +++ b/src/main/java/com/github/netricecake/kakao/structs/Member.java @@ -1,20 +1,48 @@ package com.github.netricecake.kakao.structs; +import com.github.netricecake.kakao.TalkClient; import lombok.Getter; @Getter public class Member { - private long id; + private final TalkClient client; - private String name; + private final ChatRoom chatRoom; - private int memberType; + private final long userId; - public Member(long id, String name, int memberType) { - this.id = id; - this.name = name; + private final int type; + + private final String nickName; + + private final String profileImageUrl; + + private final String fullProfileImageUrl; + + private final String originalProfileImageUrl; + + private final long profileLinkId; + + private final int memberType; + + private final int profileType; // 1 실제 프로필, 2 카카오 프로필, 16 오픈 프로필 + + public Member(TalkClient client, ChatRoom chatRoom, long userId, int type, String nickName, String profileImageUrl, String fullProfileImageUrl, String originalProfileImageUrl, long profileLinkId, int memberType, int profileType) { + this.client = client; + this.chatRoom = chatRoom; + this.userId = userId; + this.type = type; + this.nickName = nickName; + this.profileImageUrl = profileImageUrl; + this.fullProfileImageUrl = fullProfileImageUrl; + this.originalProfileImageUrl = originalProfileImageUrl; + this.profileLinkId = profileLinkId; this.memberType = memberType; + this.profileType = profileType; } + public boolean kick() { + return chatRoom.kickMember(this); + } } diff --git a/src/main/java/com/github/netricecake/kakao/structs/MemberType.java b/src/main/java/com/github/netricecake/kakao/structs/MemberType.java new file mode 100644 index 0000000..c76ec39 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/structs/MemberType.java @@ -0,0 +1,10 @@ +package com.github.netricecake.kakao.structs; + +public class MemberType { + + public final static int OWNER = 1; + public final static int MEMBER = 2; + public final static int ADMIN = 4; + public final static int BOT = 8; + +} diff --git a/src/main/java/com/github/netricecake/kakao/structs/Message.java b/src/main/java/com/github/netricecake/kakao/structs/Message.java index bebff03..7ceb31c 100644 --- a/src/main/java/com/github/netricecake/kakao/structs/Message.java +++ b/src/main/java/com/github/netricecake/kakao/structs/Message.java @@ -1,29 +1,48 @@ package com.github.netricecake.kakao.structs; +import com.github.netricecake.kakao.TalkClient; +import com.github.netricecake.kakao.loco.LocoPacket; +import com.github.netricecake.kakao.packet.inbound.message.WriteIn; +import com.github.netricecake.kakao.packet.outbound.message.WriteOut; +import com.google.gson.JsonObject; import lombok.Getter; @Getter public class Message { - private long logId; + private final TalkClient client; - private ChatRoom chatRoom; + private final ChatRoom chatRoom; - private Member author; + private final long logId; - private int type; + private final Member author; - private String message; + private final int type; - private String attachment; + private final long sendTime; - public Message(long logId, ChatRoom chatRoom, Member author, int type, String message, String attachment) { + private final String message; + + private final String attachment; + + public Message(TalkClient client, ChatRoom chatRoom, long logId, Member author, int type, long sendTime, String message, String attachment) { + this.client = client; this.logId = logId; this.chatRoom = chatRoom; this.author = author; this.type = type; + this.sendTime = sendTime; this.message = message; this.attachment = attachment; } + public boolean reply(String message) { + return client.reply(this, message); + } + + public boolean blind() { + return false; + } + } diff --git a/src/main/java/com/github/netricecake/kakao/structs/MessageType.java b/src/main/java/com/github/netricecake/kakao/structs/MessageType.java new file mode 100644 index 0000000..a9a3cfa --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/structs/MessageType.java @@ -0,0 +1,14 @@ +package com.github.netricecake.kakao.structs; + +public class MessageType { + + private MessageType() {}; + + public final static int TEXT = 1; + public final static int IMAGE = 2; + public final static int VIDEO = 3; + public final static int FILE = 4; + + public final static int REPLY = 26; + +} diff --git a/src/main/java/com/github/netricecake/loco/util/BsonUtil.java b/src/main/java/com/github/netricecake/kakao/util/BsonUtil.java similarity index 96% rename from src/main/java/com/github/netricecake/loco/util/BsonUtil.java rename to src/main/java/com/github/netricecake/kakao/util/BsonUtil.java index 239110c..bc6ccdf 100644 --- a/src/main/java/com/github/netricecake/loco/util/BsonUtil.java +++ b/src/main/java/com/github/netricecake/kakao/util/BsonUtil.java @@ -1,4 +1,4 @@ -package com.github.netricecake.loco.util; +package com.github.netricecake.kakao.util; import com.google.gson.Gson; import com.google.gson.JsonObject; diff --git a/src/main/java/com/github/netricecake/loco/util/ByteUtil.java b/src/main/java/com/github/netricecake/kakao/util/ByteUtil.java similarity index 97% rename from src/main/java/com/github/netricecake/loco/util/ByteUtil.java rename to src/main/java/com/github/netricecake/kakao/util/ByteUtil.java index 0156d35..f095da5 100644 --- a/src/main/java/com/github/netricecake/loco/util/ByteUtil.java +++ b/src/main/java/com/github/netricecake/kakao/util/ByteUtil.java @@ -1,4 +1,4 @@ -package com.github.netricecake.loco.util; +package com.github.netricecake.kakao.util; public class ByteUtil { diff --git a/src/main/java/com/github/netricecake/kakao/util/ImageUtil.java b/src/main/java/com/github/netricecake/kakao/util/ImageUtil.java new file mode 100644 index 0000000..2c71208 --- /dev/null +++ b/src/main/java/com/github/netricecake/kakao/util/ImageUtil.java @@ -0,0 +1,63 @@ +package com.github.netricecake.kakao.util; + +import lombok.Getter; + +public class ImageUtil { + + @Getter + public static class ImageMeta { + private boolean isValidJpeg; + private int width; + private int height; + + public ImageMeta(boolean isValidJpeg, int width, int height) { + this.isValidJpeg = isValidJpeg; + this.width = width; + this.height = height; + } + } + + public static ImageMeta getImageMeta(byte[] data) { + if (data == null || data.length < 4) { + return new ImageMeta(false, 0, 0); + } + + int i = 0; + + if ((data[i] & 0xFF) != 0xFF || (data[i + 1] & 0xFF) != 0xD8) { + return new ImageMeta(false, 0, 0); + } + i += 2; + + while (i < data.length) { + int marker; + while ((marker = (data[i] & 0xFF)) != 0xFF) { + i++; + if (i >= data.length) return new ImageMeta(false, 0, 0); + } + + do { + marker = data[++i] & 0xFF; + } while (marker == 0xFF); + i++; + if (isSOFMarker(marker)) { + + int height = ((data[i + 3] & 0xFF) << 8) | (data[i + 4] & 0xFF); + int width = ((data[i + 5] & 0xFF) << 8) | (data[i + 6] & 0xFF); + + return new ImageMeta(true, width, height); + } + + int length = ((data[i] & 0xFF) << 8) | (data[i + 1] & 0xFF); + i += length; + } + + return new ImageMeta(false, 0, 0); + } + + private static boolean isSOFMarker(int marker) { + return marker >= 0xC0 && marker <= 0xCF + && marker != 0xC4 && marker != 0xC8 && marker != 0xCC; + } + +} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/etc/PingIn.java b/src/main/java/com/github/netricecake/loco/packet/inbound/etc/PingIn.java deleted file mode 100644 index 52d8c1d..0000000 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/etc/PingIn.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.github.netricecake.loco.packet.inbound.etc; - -import com.github.netricecake.loco.packet.InboundPacket; - -public class PingIn extends InboundPacket { -} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/member/MemberIn.java b/src/main/java/com/github/netricecake/loco/packet/inbound/member/MemberIn.java deleted file mode 100644 index 6e7e225..0000000 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/member/MemberIn.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.netricecake.loco.packet.inbound.member; - -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; -import com.google.gson.JsonObject; -import lombok.Getter; - -@Getter -public class MemberIn extends InboundPacket { - - private long userId; - - private String nickName; - - private int memberType = 2; - - public void fromBson(byte[] bson) { - JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); - userId = jsonObject.get("members").getAsJsonArray().get(0).getAsJsonObject().get("userId").getAsLong(); - this.nickName = jsonObject.get("members").getAsJsonArray().get(0).getAsJsonObject().get("nickName").getAsString(); - try { - memberType = jsonObject.get("members").getAsJsonArray().get(0).getAsJsonObject().get("mt").getAsInt(); - } catch (Exception e) {} - } - -} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/member/SyncLinkPfIn.java b/src/main/java/com/github/netricecake/loco/packet/inbound/member/SyncLinkPfIn.java deleted file mode 100644 index 3ce5cce..0000000 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/member/SyncLinkPfIn.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.netricecake.loco.packet.inbound.member; - -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import lombok.Getter; - -@Getter -public class SyncLinkPfIn extends InboundPacket { - - private long chatId; - - private long linkId; - - private long userId; - - private String nickName; - - public void fromBson(byte[] bson) { - JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); - chatId = jsonObject.get("c").getAsLong(); - linkId = jsonObject.get("li").getAsLong(); - JsonObject olu = jsonObject.get("olu").getAsJsonObject(); - userId = olu.get("userId").getAsLong(); - nickName = olu.get("nn").getAsString(); - } - -} diff --git a/src/main/java/com/github/netricecake/loco/packet/inbound/room/ChatInfoIn.java b/src/main/java/com/github/netricecake/loco/packet/inbound/room/ChatInfoIn.java deleted file mode 100644 index eed81b0..0000000 --- a/src/main/java/com/github/netricecake/loco/packet/inbound/room/ChatInfoIn.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.github.netricecake.loco.packet.inbound.room; - -import com.github.netricecake.loco.packet.InboundPacket; -import com.github.netricecake.loco.util.BsonUtil; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import lombok.Getter; - -@Getter -public class ChatInfoIn extends InboundPacket { - - private String type; - - private JsonArray chatMetas; - - private JsonArray displayMembers; - - private long linkId = 0; - - public void fromBson(byte[] bson) { - JsonObject jsonObject = BsonUtil.bsonToJsonObject(bson); - type = jsonObject.get("chatInfo").getAsJsonObject().get("type").getAsString(); - try { - linkId = jsonObject.get("chatInfo").getAsJsonObject().get("li").getAsLong(); - } catch (Exception e) {} - try { - chatMetas = jsonObject.get("chatInfo").getAsJsonObject().get("chatMetas").getAsJsonArray(); - displayMembers = jsonObject.get("chatInfo").getAsJsonObject().get("displayMembers").getAsJsonArray(); - } catch (Exception e) {} - } - -} diff --git a/src/main/java/com/github/netricecake/loco/packet/outbound/etc/PingOut.java b/src/main/java/com/github/netricecake/loco/packet/outbound/etc/PingOut.java deleted file mode 100644 index 97d6dd0..0000000 --- a/src/main/java/com/github/netricecake/loco/packet/outbound/etc/PingOut.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.netricecake.loco.packet.outbound.etc; - -import com.github.netricecake.loco.util.BsonUtil; - -public class PingOut { - - public byte[] toBson() { - return BsonUtil.jsonToBson("{}"); - } - -}