#ifndef __UTILS__ #include #endif #include #include #include #include #include #include #include // Global Config IPConfig APStatic = { IPAddress(10, 1, 1, 1), IPAddress(10, 0, 1, 1), IPAddress(255, 255, 255, 0) }; IPConfig STAStatic = { IPAddress(192, 168, 43, 141), IPAddress(192,168,0,1), IPAddress(255, 255, 255, 0) }; BoardInfo Board = { "0.0.1", WiFi.localIP() }; // https://github.com/PaulStoffregen/Time/blob/master/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino static const int timeZone = 8; static const int NTP_PACKET_SIZE = 48; static byte packetBuffer[NTP_PACKET_SIZE]; static IPAddress ntpServerIP(203, 107, 6, 88); // static const char ntpServerName[] = "ntp.aliyun.com"; static bool isNTPConnected = false; static WiFiUDP ntpUDP; static unsigned int localPort = 2390; static void sendNTPpacket(IPAddress& address) { memset(packetBuffer, 0, NTP_PACKET_SIZE); packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; ntpUDP.beginPacket(address, 123); ntpUDP.write(packetBuffer, NTP_PACKET_SIZE); ntpUDP.endPacket(); } static time_t getNtpTime() { byte tmp[1]; while( ntpUDP.parsePacket() > 0 ) ntpUDP.read(tmp, 1); sendNTPpacket(ntpServerIP); uint32_t beginWait = millis(); while( millis() - beginWait < 1500 ) { int size = ntpUDP.parsePacket(); if( size >= NTP_PACKET_SIZE ) { isNTPConnected = true; ntpUDP.read(packetBuffer, NTP_PACKET_SIZE); // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分 unsigned long secsSince1900; secsSince1900 = (unsigned long)packetBuffer[40] << 24; secsSince1900 |= (unsigned long)packetBuffer[41] << 16; secsSince1900 |= (unsigned long)packetBuffer[42] << 8; secsSince1900 |= (unsigned long)packetBuffer[43]; return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; } } isNTPConnected = false; return 0; } void initNtp() { ntpUDP.begin(localPort); setSyncProvider(getNtpTime); setSyncInterval(300); } static String formatDigits(int digits) { if( digits < 10 ) return "0" + (String)digits; return (String)digits; } String ntpTime() { String timeString(""); timeString = (String)year() + '-' + formatDigits(month()) + '-' + formatDigits(day()) + ' ' + formatDigits(hour()) + ':' + formatDigits(minute()) + ':' + formatDigits(second()); return timeString; } long view = 0; long likes = 0; long follower = 0; long dayView = 0; long weekView = 0; long monthView = 0; static String UID = "450115492"; static String followerUrl = "http://api.bilibili.com/x/relation/stat?vmid=" + UID; static String viewAndLikesUrl = "http://api.bilibili.com/x/space/upstat?mid=" + UID; static String webViewerUrl = "https://api.foolishfox.cn/data/board.json"; static const char UserAgent[] PROGMEM = "UserAgent"; static const char Cookie[] PROGMEM = "Cookie"; static WiFiClient client; std::unique_ptrclientSecure(new BearSSL::WiFiClientSecure); StaticJsonDocument<256> jsonBuffer; static void getFollower() { HTTPClient http; http.begin(client, followerUrl); int resCode = http.GET(); if( resCode == 200 ) { String resBuffer = http.getString(); DeserializationError error = deserializeJson(jsonBuffer, resBuffer); if( error ) { Serial.print(F("deserializeJson(Follower) failed: ")); Serial.println(error.f_str()); return; } follower = jsonBuffer["data"]["follower"]; } else { Serial.printf("[HTTP] GET Follower failed, error: %d\n", resCode); } http.end(); } static void getViewAndLikes() { HTTPClient http; http.begin(client, viewAndLikesUrl); http.addHeader("Host", "api.bilibili.com"); http.addHeader("User-Agent", UserAgent); http.addHeader("Cookie", Cookie); int resCode = http.GET(); if( resCode == 200 ) { String resBuffer = http.getString(); DeserializationError error = deserializeJson(jsonBuffer, resBuffer); if( error ) { Serial.print(F("deserializeJson(View & Likes) failed: ")); Serial.println(error.f_str()); return; } likes = jsonBuffer["data"]["likes"]; view = jsonBuffer["data"]["archive"]["view"]; } else { Serial.printf("[HTTP] GET View & Likes failed, error: %d\n", resCode); } http.end(); } static void getWebView() { HTTPClient https; clientSecure->setInsecure(); https.begin(*clientSecure, webViewerUrl); int resCode = https.GET(); if( resCode == 200 ) { String resBuffer = https.getString(); DeserializationError error = deserializeJson(jsonBuffer, resBuffer); if( error ) { Serial.print(F("deserializeJson(Web View) failed: ")); Serial.println(error.f_str()); return; } dayView = jsonBuffer["day"]; weekView = jsonBuffer["week"]; monthView = jsonBuffer["month"]; } else { Serial.printf("[HTTP] GET Web View failed, error: %d\n", resCode); } https.end(); } void getData() { getFollower(); getViewAndLikes(); getWebView(); }