// Message for all GMs on all map servers void intif_GMmessage(XString mes) { WFIFOW(char_fd, 0) = 0x3000; size_t len = mes.size() + 1; WFIFOW(char_fd, 2) = 4 + len; WFIFO_STRING(char_fd, 4, mes, len); WFIFOSET(char_fd, WFIFOW(char_fd, 2)); }
// Returns true if more than 50% of input message is caps or punctuation bool tmw_CheckChatLameness(dumb_ptr<map_session_data>, XString message) { int lame = 0; for (char c : message) { if (c <= ' ') continue; if (c > '~') continue; if ('0' <= c && c <= '9') continue; if ('a' <= c && c <= 'z') continue; lame++; } return message.size() > 7 && lame > message.size() / 2; }
// パーティ会話送信 void intif_party_message(int party_id, int account_id, XString mes) { size_t len = mes.size() + 1; WFIFOW(char_fd, 0) = 0x3027; WFIFOW(char_fd, 2) = len + 12; WFIFOL(char_fd, 4) = party_id; WFIFOL(char_fd, 8) = account_id; WFIFO_STRING(char_fd, 12, mes, len); WFIFOSET(char_fd, len + 12); }
// GMメッセージ送信 static void mapif_GMmessage(XString mes) { size_t str_len = mes.size() + 1; size_t msg_len = str_len + 4; uint8_t buf[msg_len]; WBUFW(buf, 0) = 0x3800; WBUFW(buf, 2) = msg_len; WBUF_STRING(buf, 4, mes, str_len); mapif_sendall(buf, msg_len); }
XIRef<XTimeZone> XSimpleTimeZone::FromXML(XIRef<XDomParserNode> node) { const XString utcOffsetStr = node->GetMetaData("utcOffset"); const XString dstOffsetStr = node->GetMetaData("dstOffset"); if(node->GetTagName() != "XSimpleTimeZone" || utcOffsetStr.empty() || (!verifyDigit(utcOffsetStr[0]) && utcOffsetStr[0] != '-') || count_if(utcOffsetStr.begin() + 1, utcOffsetStr.end(), verifyDigit) != (int)utcOffsetStr.size() - 1 || dstOffsetStr.empty() || (!verifyDigit(dstOffsetStr[0]) && dstOffsetStr[0] != '-') || count_if(dstOffsetStr.begin() + 1, dstOffsetStr.end(), verifyDigit) != (int)dstOffsetStr.size() - 1) { return 0; } const int utcOffset = utcOffsetStr.ToInt(); const int dstOffset = dstOffsetStr.ToInt(); return new XSimpleTimeZone(utcOffset, dstOffset); }
MD5_state MD5_from_string(XString msg) { MD5_state state; MD5_init(&state); MD5_block block; const uint64_t msg_full_len = msg.size(); while (msg.size() >= 64) { for (int i = 0; i < 0x10; i++) X[i] = msg[4 * i + 0] | msg[4 * i + 1] << 8 | msg[4 * i + 2] << 16 | msg[4 * i + 3] << 24; MD5_do_block(&state, block); msg = msg.xslice_t(64); } // now pad 1-512 bits + the 64-bit length - may be two blocks uint8_t buf[0x40] = {}; really_memcpy(buf, reinterpret_cast<const uint8_t *>(msg.data()), msg.size()); buf[msg.size()] = 0x80; // a single one bit if (64 - msg.size() > 8) { for (int i = 0; i < 8; i++) buf[0x38 + i] = (msg_full_len * 8) >> (i * 8); } for (int i = 0; i < 0x10; i++) X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24; MD5_do_block(&state, block); if (64 - msg.size() <= 8) { really_memset0(buf, 0x38); for (int i = 0; i < 8; i++) buf[0x38 + i] = (msg_full_len * 8) >> (i * 8); for (int i = 0; i < 0x10; i++) X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24; MD5_do_block(&state, block); }
Buffer create_vpacket(Packet_Head<id>& head, const XString& repeat) { static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); static_assert(repeatsize == 1, "repeatsize"); // since it's already allocated, it can't overflow address space size_t total_length = sizeof(NetPacket_Head<id>) + (repeat.size() + 1) * sizeof(NetPacket_Repeat<id>); head.magic_packet_length = total_length; if (head.magic_packet_length != total_length) { return Buffer(); } Buffer buf; buf.bytes.resize(total_length); auto& net_head = reinterpret_cast<NetPacket_Head<id>&>( *(buf.bytes.begin() + 0)); std::vector<NetPacket_Repeat<id>> net_repeat(repeat.size() + 1); if (!native_to_network(&net_head, head)) { return Buffer(); } for (size_t i = 0; i < repeat.size(); ++i) { auto& net_repeat_i = reinterpret_cast<NetPacket_Repeat<id>&>( *(buf.bytes.begin() + sizeof(NetPacket_Head<id>) + i)); net_repeat_i.c = Byte{static_cast<uint8_t>(repeat[i])}; } auto& net_repeat_repeat_size = reinterpret_cast<NetPacket_Repeat<id>&>( *(buf.bytes.begin() + sizeof(NetPacket_Head<id>) + repeat.size())); net_repeat_repeat_size.c = Byte{static_cast<uint8_t>('\0')}; return buf; }
// パーティ内発言 static void mapif_party_message(int party_id, int account_id, XString mes) { size_t len = mes.size() + 1; unsigned char buf[len + 12]; WBUFW(buf, 0) = 0x3827; WBUFW(buf, 2) = len + 12; WBUFL(buf, 4) = party_id; WBUFL(buf, 8) = account_id; WBUF_STRING(buf, 12, mes, len); mapif_sendall(buf, len + 12); }
XIRef<XTimeZone> XSimpleTimeZone::FromISOString(const XString& isoString) { if(isoString[0] != '-' && isoString[0] != '+') X_THROW(("Invalid ISO Extended String: %s", isoString.c_str())); const int sign = isoString[0] == '-' ? -1 : 1; const XString str = isoString.substr(1); if(str.empty()) X_THROW(("Invalid ISO Extended String: %s", isoString.c_str())); const size_t colonDex = str.find(':'); XString hoursStr; XString minutesStr; if(colonDex != string::npos) { hoursStr = str.substr(0, colonDex); minutesStr = str.substr(colonDex + 1); if(minutesStr.size() != 2) X_THROW(("Invalid ISO Extended String: %s", isoString.c_str())); } else hoursStr = str; if(count_if(hoursStr.begin(), hoursStr.end(), verifyDigit) != (int)hoursStr.size() || count_if(minutesStr.begin(), minutesStr.end(), verifyDigit) != (int)minutesStr.size()) { X_THROW(("Invalid ISO Extended String: %s", isoString.c_str())); } const int hours = hoursStr.ToInt(); const int minutes = minutesStr.empty() ? 0 : minutesStr.ToInt(); return new XSimpleTimeZone(sign * (int)(convert(HOURS, MINUTES, hours) + minutes)); }
//--------------------------------------------------- // E-mail check: return 0 (not correct) or 1 (valid). //--------------------------------------------------- bool e_mail_check(XString email) { // athena limits if (email.size() < 3 || email.size() > 39) return 0; // part of RFC limits (official reference of e-mail description) XString::iterator at = std::find(email.begin(), email.end(), '@'); if (at == email.end()) return 0; XString username = email.xislice_h(at); XString hostname = email.xislice_t(at + 1); if (!username || !hostname) return 0; if (hostname.contains('@')) return 0; if (hostname.front() == '.' || hostname.back() == '.') return 0; if (hostname.contains_seq("..")) return 0; if (email.contains_any(" ;")) return 0; return email.is_print(); }
void WriteFile::put_line(XString xs) { really_put(xs.data(), xs.size()); if (!xs.endswith('\n')) put('\n'); }