未验证 提交 f7cb5bd2 编写于 作者: J Jack Li 提交者: GitHub

Merge pull request #127 from ljc545w/add/log

添加日志模块
build/
Debug/
!/Release
Release/
SOCKET_Debug/
SOCKET_Release/
......@@ -9,6 +8,7 @@ x64/
*.rar
obj/
packages/
!/3rdparty/lib/
mongoose.c
mongoose.h
......
......@@ -25,5 +25,6 @@ exclude: |
(?x)^(
.*?_i\.h|
.*?_p\.c|
.*?\.md
.*?\.md |
3rdparty\*
)
#ifndef GLOG_EXPORT_H
#define GLOG_EXPORT_H
#ifdef GLOG_STATIC_DEFINE
#define GLOG_EXPORT
#define GLOG_NO_EXPORT
#else
#ifndef GLOG_EXPORT
#ifdef GOOGLE_GLOG_IS_A_DLL
/* We are building this library */
#define GLOG_EXPORT
#else
/* We are using this library */
#define GLOG_EXPORT
#endif
#endif
#ifndef GLOG_NO_EXPORT
#define GLOG_NO_EXPORT
#endif
#endif
#ifndef GLOG_DEPRECATED
#define GLOG_DEPRECATED __declspec(deprecated)
#endif
#ifndef GLOG_DEPRECATED_EXPORT
#define GLOG_DEPRECATED_EXPORT GLOG_EXPORT GLOG_DEPRECATED
#endif
#ifndef GLOG_DEPRECATED_NO_EXPORT
#define GLOG_DEPRECATED_NO_EXPORT GLOG_NO_EXPORT GLOG_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
#ifndef GLOG_NO_DEPRECATED
#define GLOG_NO_DEPRECATED
#endif
#endif
#endif /* GLOG_EXPORT_H */
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASE_LOG_SEVERITY_H__
#define BASE_LOG_SEVERITY_H__
// The recommended semantics of the log levels are as follows:
//
// INFO:
// Use for state changes or other major events, or to aid debugging.
// WARNING:
// Use for undesired but relatively expected events, which may indicate a
// problem
// ERROR:
// Use for undesired and unexpected events that the program can recover from.
// All ERRORs should be actionable - it should be appropriate to file a bug
// whenever an ERROR occurs in production.
// FATAL:
// Use for undesired and unexpected events that the program cannot recover
// from.
// Variables of type LogSeverity are widely taken to lie in the range
// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
// you ever need to change their values or add a new severity.
typedef int LogSeverity;
const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
NUM_SEVERITIES = 4;
#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
#ifdef ERROR
#error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail.
#endif
const int INFO = GLOG_INFO, WARNING = GLOG_WARNING,
ERROR = GLOG_ERROR, FATAL = GLOG_FATAL;
#endif
// DFATAL is FATAL in debug mode, ERROR in normal mode
#ifdef NDEBUG
#define DFATAL_LEVEL ERROR
#else
#define DFATAL_LEVEL FATAL
#endif
extern GLOG_EXPORT const char *const LogSeverityNames[NUM_SEVERITIES];
// NDEBUG usage helpers related to (RAW_)DCHECK:
//
// DEBUG_MODE is for small !NDEBUG uses like
// if (DEBUG_MODE) foo.CheckThatFoo();
// instead of substantially more verbose
// #ifndef NDEBUG
// foo.CheckThatFoo();
// #endif
//
// IF_DEBUG_MODE is for small !NDEBUG uses like
// IF_DEBUG_MODE( string error; )
// DCHECK(Foo(&error)) << error;
// instead of substantially more verbose
// #ifndef NDEBUG
// string error;
// DCHECK(Foo(&error)) << error;
// #endif
//
#ifdef NDEBUG
enum
{
DEBUG_MODE = 0
};
#define IF_DEBUG_MODE(x)
#else
enum
{
DEBUG_MODE = 1
};
#define IF_DEBUG_MODE(x) x
#endif
#endif // BASE_LOG_SEVERITY_H__
此差异已折叠。
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Shinichiro Hamaji
//
// Detect supported platforms.
#ifndef GLOG_PLATFORM_H
#define GLOG_PLATFORM_H
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#define GLOG_OS_WINDOWS
#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
#define GLOG_OS_CYGWIN
#elif defined(linux) || defined(__linux) || defined(__linux__)
#ifndef GLOG_OS_LINUX
#define GLOG_OS_LINUX
#endif
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
#define GLOG_OS_MACOSX
#elif defined(__FreeBSD__)
#define GLOG_OS_FREEBSD
#elif defined(__NetBSD__)
#define GLOG_OS_NETBSD
#elif defined(__OpenBSD__)
#define GLOG_OS_OPENBSD
#elif defined(__EMSCRIPTEN__)
#define GLOG_OS_EMSCRIPTEN
#else
// TODO(hamaji): Add other platforms.
#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
#endif
#endif // GLOG_PLATFORM_H
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Maxim Lifantsev
//
// Thread-safe logging routines that do not allocate any memory or
// acquire any locks, and can therefore be used by low-level memory
// allocation and synchronization code.
#ifndef GLOG_RAW_LOGGING_H
#define GLOG_RAW_LOGGING_H
#include <ctime>
namespace google
{
#include <glog/log_severity.h>
#include <glog/logging.h>
#include <glog/vlog_is_on.h>
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#endif
// This is similar to LOG(severity) << format... and VLOG(level) << format..,
// but
// * it is to be used ONLY by low-level modules that can't use normal LOG()
// * it is desiged to be a low-level logger that does not allocate any
// memory and does not need any locks, hence:
// * it logs straight and ONLY to STDERR w/o buffering
// * it uses an explicit format and arguments list
// * it will silently chop off really long message strings
// Usage example:
// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
// RAW_VLOG(3, "status is %i", status);
// These will print an almost standard log lines like this to stderr only:
// E20200821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
// I20200821 211317 file.cc:142] RAW: status is 20
#define RAW_LOG(severity, ...) \
do \
{ \
switch (google::GLOG_##severity) \
{ \
case 0: \
RAW_LOG_INFO(__VA_ARGS__); \
break; \
case 1: \
RAW_LOG_WARNING(__VA_ARGS__); \
break; \
case 2: \
RAW_LOG_ERROR(__VA_ARGS__); \
break; \
case 3: \
RAW_LOG_FATAL(__VA_ARGS__); \
break; \
default: \
break; \
} \
} while (0)
// The following STRIP_LOG testing is performed in the header file so that it's
// possible to completely compile out the logging code and the log messages.
#if !defined(STRIP_LOG) || STRIP_LOG == 0
#define RAW_VLOG(verboselevel, ...) \
do \
{ \
if (VLOG_IS_ON(verboselevel)) \
{ \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
#else
#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if !defined(STRIP_LOG) || STRIP_LOG == 0
#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if !defined(STRIP_LOG) || STRIP_LOG <= 1
#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 1
#if !defined(STRIP_LOG) || STRIP_LOG <= 2
#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 2
#if !defined(STRIP_LOG) || STRIP_LOG <= 3
#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_FATAL(...) \
do \
{ \
google::RawLogStub__(0, __VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
#endif // STRIP_LOG <= 3
// Similar to CHECK(condition) << message,
// but for low-level modules: we use only RAW_LOG that does not allocate memory.
// We do not want to provide args list here to encourage this usage:
// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
// so that the args are not computed when not needed.
#define RAW_CHECK(condition, message) \
do \
{ \
if (!(condition)) \
{ \
RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
} \
} while (0)
// Debug versions of RAW_LOG and RAW_CHECK
#ifndef NDEBUG
#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
#else // NDEBUG
#define RAW_DLOG(severity, ...) \
while (false) \
RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) \
while (false) \
RAW_CHECK(condition, message)
#endif // NDEBUG
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
// Stub log function used to work around for unused variable warnings when
// building with STRIP_LOG > 0.
static inline void RawLogStub__(int /* ignored */, ...)
{
}
// Helper function to implement RAW_LOG and RAW_VLOG
// Logs format... at "severity" level, reporting it
// as called from file:line.
// This does not allocate memory or acquire locks.
GLOG_EXPORT void RawLog__(LogSeverity severity, const char *file, int line,
const char *format, ...);
}
#endif // GLOG_RAW_LOGGING_H
// Copyright (c) 2003, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Stream output operators for STL containers; to be used for logging *only*.
// Inclusion of this file lets you do:
//
// list<string> x;
// LOG(INFO) << "data: " << x;
// vector<int> v1, v2;
// CHECK_EQ(v1, v2);
//
// If you want to use this header file with hash maps or slist, you
// need to define macros before including this file:
//
// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set>
// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist>
//
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
#define UTIL_GTL_STL_LOGGING_INL_H_
#if !1
#error We do not support stl_logging for this compiler
#endif
#include <deque>
#include <list>
#include <map>
#include <ostream>
#include <set>
#include <utility>
#include <vector>
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
#include <ext/hash_set>
#include <ext/hash_map>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
#include <ext/slist>
#endif
// Forward declare these two, and define them after all the container streams
// operators so that we can recurse from pair -> container -> container -> pair
// properly.
template <class First, class Second>
std::ostream &operator<<(std::ostream &out, const std::pair<First, Second> &p);
namespace google
{
template <class Iter>
void PrintSequence(std::ostream &out, Iter begin, Iter end);
}
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template <class T1, class T2> \
inline std::ostream &operator<<(std::ostream &out, \
const Sequence<T1, T2> &seq) \
{ \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_TWO_ARG_CONTAINER(std::vector)
OUTPUT_TWO_ARG_CONTAINER(std::deque)
OUTPUT_TWO_ARG_CONTAINER(std::list)
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
#endif
#undef OUTPUT_TWO_ARG_CONTAINER
#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
template <class T1, class T2, class T3> \
inline std::ostream &operator<<(std::ostream &out, \
const Sequence<T1, T2, T3> &seq) \
{ \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_THREE_ARG_CONTAINER(std::set)
OUTPUT_THREE_ARG_CONTAINER(std::multiset)
#undef OUTPUT_THREE_ARG_CONTAINER
#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
template <class T1, class T2, class T3, class T4> \
inline std::ostream &operator<<(std::ostream &out, \
const Sequence<T1, T2, T3, T4> &seq) \
{ \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_FOUR_ARG_CONTAINER(std::map)
OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
#endif
#undef OUTPUT_FOUR_ARG_CONTAINER
#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
template <class T1, class T2, class T3, class T4, class T5> \
inline std::ostream &operator<<(std::ostream &out, \
const Sequence<T1, T2, T3, T4, T5> &seq) \
{ \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
#endif
#undef OUTPUT_FIVE_ARG_CONTAINER
template <class First, class Second>
inline std::ostream &operator<<(std::ostream &out,
const std::pair<First, Second> &p)
{
out << '(' << p.first << ", " << p.second << ')';
return out;
}
namespace google
{
template <class Iter>
inline void PrintSequence(std::ostream &out, Iter begin, Iter end)
{
// Output at most 100 elements -- appropriate if used for logging.
for (int i = 0; begin != end && i < 100; ++i, ++begin)
{
if (i > 0)
out << ' ';
out << *begin;
}
if (begin != end)
{
out << " ...";
}
}
}
// Note that this is technically undefined behavior! We are adding things into
// the std namespace for a reason though -- we are providing new operations on
// types which are themselves defined with this namespace. Without this, these
// operator overloads cannot be found via ADL. If these definitions are not
// found via ADL, they must be #included before they're used, which requires
// this header to be included before apparently independent other headers.
//
// For example, base/logging.h defines various template functions to implement
// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
// It does so via the function template MakeCheckOpValueString:
// template<class T>
// void MakeCheckOpValueString(strstream* ss, const T& v) {
// (*ss) << v;
// }
// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
// find these operator definitions via ADL.
//
// Even this solution has problems -- it may pull unintended operators into the
// namespace as well, allowing them to also be found via ADL, and creating code
// that only works with a particular order of includes. Long term, we need to
// move all of the *definitions* into namespace std, bet we need to ensure no
// one references them first. This lets us take that step. We cannot define them
// in both because that would create ambiguous overloads when both are found.
namespace std
{
using ::operator<<;
}
#endif // UTIL_GTL_STL_LOGGING_INL_H_
// Copyright (c) 1999, 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Ray Sidney and many others
//
// Defines the VLOG_IS_ON macro that controls the variable-verbosity
// conditional logging.
//
// It's used by VLOG and VLOG_IF in logging.h
// and by RAW_VLOG in raw_logging.h to trigger the logging.
//
// It can also be used directly e.g. like this:
// if (VLOG_IS_ON(2)) {
// // do some logging preparation and logging
// // that can't be accomplished e.g. via just VLOG(2) << ...;
// }
//
// The truth value that VLOG_IS_ON(level) returns is determined by
// the three verbosity level flags:
// --v=<n> Gives the default maximal active V-logging level;
// 0 is the default.
// Normally positive values are used for V-logging levels.
// --vmodule=<str> Gives the per-module maximal V-logging levels to override
// the value given by --v.
// E.g. "my_module=2,foo*=3" would change the logging level
// for all code in source files "my_module.*" and "foo*.*"
// ("-inl" suffixes are also disregarded for this matching).
//
// SetVLOGLevel helper function is provided to do limited dynamic control over
// V-logging by overriding the per-module settings given via --vmodule flag.
//
// CAVEAT: --vmodule functionality is not available in non gcc compilers.
//
#ifndef BASE_VLOG_IS_ON_H_
#define BASE_VLOG_IS_ON_H_
#include <glog/log_severity.h>
#if defined(__GNUC__)
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
// (Normally) the first time every VLOG_IS_ON(n) site is hit,
// we determine what variable will dynamically control logging at this site:
// it's either FLAGS_v or an appropriate internal variable
// matching the current source file that represents results of
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__({ \
static google::SiteFlag vlocal__ = {NULL, NULL, 0, NULL}; \
google::int32 verbose_level__ = (verboselevel); \
(vlocal__.level == NULL ? google::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__) \
: *vlocal__.level >= verbose_level__); \
})
#else
// GNU extensions not available, so we do not support --vmodule.
// Dynamic value of FLAGS_v always controls the logging level.
#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
#endif
// Set VLOG(_IS_ON) level for module_pattern to log_level.
// This lets us dynamically control what is normally set by the --vmodule flag.
// Returns the level that previously applied to module_pattern.
// NOTE: To change the log level for VLOG(_IS_ON) sites
// that have already executed after/during InitGoogleLogging,
// one needs to supply the exact --vmodule pattern that applied to them.
// (If no --vmodule pattern applied to them
// the value of FLAGS_v will continue to control them.)
extern GLOG_EXPORT int SetVLOGLevel(const char *module_pattern, int log_level);
// Various declarations needed for VLOG_IS_ON above: =========================
struct SiteFlag
{
google::int32 *level;
const char *base_name;
size_t base_len;
SiteFlag *next;
};
// Helper routine which determines the logging info for a particalur VLOG site.
// site_flag is the address of the site-local pointer to the controlling
// verbosity level
// site_default is the default to use for *site_flag
// fname is the current source file name
// verbose_level is the argument to VLOG_IS_ON
// We will return the return value for VLOG_IS_ON
// and if possible set *site_flag appropriately.
extern GLOG_EXPORT bool InitVLOG3__(
google::SiteFlag *site_flag,
google::int32 *site_default, const char *fname,
google::int32 verbose_level);
#endif // BASE_VLOG_IS_ON_H_
# 注意
此处源码来自以下仓库:
[mongoose](https://github.com/cesanta/mongoose)
需要自行克隆该仓库并将mongoose.c和mongoose.h拷贝到此处
# Thanks
# 注意
此处源码来自以下仓库:
[mongoose](https://github.com/cesanta/mongoose)
需要自行克隆该仓库并将mongoose.c和mongoose.h拷贝到此处
# Thanks
[mongoose](https://github.com/cesanta/mongoose)
\ No newline at end of file
......@@ -128,19 +128,23 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
<IncludePath>$(IncludePath);../3rdparty/include</IncludePath>
<LibraryPath>../3rdparty/lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SOCKET_Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>SWeChatRobot</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
<IncludePath>$(IncludePath);../3rdparty/include</IncludePath>
<IntDir>$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)Debug\socket\</OutDir>
<LibraryPath>../3rdparty/lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
<CopyLocalDeploymentContent>true</CopyLocalDeploymentContent>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../3rdparty/include</IncludePath>
<LibraryPath>../3rdparty/lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SOCKET_Release|Win32'">
<LinkIncremental>false</LinkIncremental>
......@@ -148,6 +152,8 @@
<IntDir>$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)Release\socket\</OutDir>
<CopyLocalDeploymentContent>true</CopyLocalDeploymentContent>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;../3rdparty/include</IncludePath>
<LibraryPath>../3rdparty/lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
......@@ -352,11 +358,11 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClInclude Include="wxsocketapi.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\3rdparty\include\base64\base64.cpp" />
<ClCompile Include="AddChatRoomMember.cpp" />
<ClCompile Include="AddFriendByV3.cpp" />
<ClCompile Include="AddFriendByWxid.cpp" />
<ClCompile Include="AddBrandContact.cpp" />
<ClCompile Include="base64\base64.cpp" />
<ClCompile Include="CheckFriendStatus.cpp" />
<ClCompile Include="comclient.cpp" />
<ClCompile Include="DbBackup.cpp" />
......
......@@ -374,9 +374,6 @@
<ClCompile Include="GetChatRoomMemberNickname.cpp">
<Filter>群相关\获取群成员昵称</Filter>
</ClCompile>
<ClCompile Include="base64\base64.cpp">
<Filter>wxsocket</Filter>
</ClCompile>
<ClCompile Include="OpenBrowser.cpp">
<Filter>浏览器相关\打开浏览器</Filter>
</ClCompile>
......@@ -392,5 +389,8 @@
<ClCompile Include="GetA8Key.cpp">
<Filter>浏览器相关\获取A8Key</Filter>
</ClCompile>
<ClCompile Include="..\3rdparty\include\base64\base64.cpp">
<Filter>wxsocket</Filter>
</ClCompile>
</ItemGroup>
</Project>
......@@ -137,14 +137,26 @@ void SendSocketMessageInThread(SocketMessageStruct *param)
return;
}
string jstr = jMsg.dump() + "\n";
LOG(INFO) << "msgid: " << jMsg["msgid"].get<ULONG64>() << " send begin." << endl;
LOG(INFO) << "type: " << jMsg["type"].get<int>() << ", sender: " << jMsg["wxid"].get<string>() << endl;
LOG(INFO) << "content size: " << jstr.length() << endl;
#ifdef USE_COM
// 通过连接点,将消息广播给客户端;将广播过程放在线程中完成,客户端才可以等待图片、语音落地
VARIANT vsaValue = (_variant_t)utf8_to_unicode(jstr.c_str()).c_str();
VARIANT vsaValue;
_variant_t szWMsg = (_variant_t)utf8_to_unicode(jstr.c_str()).c_str();
vsaValue.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND rgsaBound = {1, 0};
SAFEARRAY *psaValue = SafeArrayCreate(VT_VARIANT, 1, &rgsaBound);
long index = 0;
// 数据大小超过16382个字符,客户端调用可能出现异常,因此将数据放入安全数组中传递
HRESULT hr = SafeArrayPutElement(psaValue, &index, &szWMsg);
V_ARRAY(&vsaValue) = psaValue;
DWORD type = jMsg["type"].get<DWORD>();
ULONG64 msgid = (type != 10000) ? jMsg["msgid"].get<ULONG64>() : 0;
PostComMessage(jMsg["pid"].get<int>(), WX_MESSAGE, msgid, &vsaValue);
#endif
SendSocketMessage(jstr.c_str(), jstr.size());
LOG(INFO) << "msgid: " << jMsg["msgid"].get<ULONG64>() << " send end." << endl;
}
static void dealMessage(DWORD messageAddr)
......
......@@ -56,6 +56,7 @@ BOOL PostComMessage(DWORD pid, int msgtype, unsigned long long msgid, VARIANT *m
}
else
{
CoUninitialize();
return false;
}
CoUninitialize();
......
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
if (ProcessIsWeChat()) {
gLogInit();
LOG(INFO) << "Robot Start, isWxLogin: " << isWxLogin() << ", pid: " << GetCurrentProcessId() << endl;
if (ProcessIsWeChat())
{
#ifndef USE_SOCKET
#ifdef _DEBUG
PrintProcAddr();
......@@ -24,11 +26,13 @@ BOOL APIENTRY DllMain( HMODULE hModule,
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH: {
case DLL_PROCESS_DETACH:
{
UnHookAll();
LOG(INFO) << "Robot Stop";
google::ShutdownGoogleLogging();
break;
}
}
return TRUE;
}
......@@ -304,3 +304,52 @@ DWORD OffsetFromIdaAddr(DWORD idaAddr)
{
return idaAddr - IDA_BASE;
}
void SignalHandler(const char *data, size_t size)
{
#ifdef USE_SOCKET
string dllname = "SWeChatRobot";
#else
string dllname = "DWeChatRobot";
#endif // USE_SOCKET
char szFileFullPath[MAX_PATH] = {0};
HMODULE hd = GetModuleHandleA(dllname.c_str());
GetModuleFileNameA(hd, szFileFullPath, MAX_PATH);
string szFile(szFileFullPath);
size_t pos = szFile.find_last_of('\\');
string szFilePath = szFile.substr(0, pos + 1);
std::string glog_file = szFilePath + "\\log\\error.log";
std::ofstream fs(glog_file, std::ios::app);
std::string str = std::string(data, size);
fs << str;
fs.close();
LOG(INFO) << str;
google::ShutdownGoogleLogging();
}
void gLogInit()
{
#ifdef USE_SOCKET
string dllname = "SWeChatRobot";
#else
string dllname = "DWeChatRobot";
#endif // USE_SOCKET
#ifdef _DEBUG
FLAGS_colorlogtostderr = true; // log信息区分颜色
FLAGS_logtostderr = 1;
#endif
google::SetStderrLogging(google::GLOG_INFO); // 输出log的最低等级是 INFO (可以设置为WARNING或者更高)
google::InstallFailureSignalHandler(); // 配置安装程序崩溃失败信号处理器
google::InstallFailureWriter(&SignalHandler); // 安装配置程序失败信号的信息打印过程,设置回调函数
google::InitGoogleLogging(dllname.c_str());
#ifndef _DEBUG
char szFileFullPath[MAX_PATH] = {0};
HMODULE hd = GetModuleHandleA(dllname.c_str());
GetModuleFileNameA(hd, szFileFullPath, MAX_PATH);
string szFile(szFileFullPath);
size_t pos = szFile.find_last_of('\\');
string szFilePath = szFile.substr(0, pos + 1) + "log\\";
FindOrCreateDirectory(gb2312_to_unicode(szFilePath.c_str()).c_str());
google::SetLogDestination(google::GLOG_INFO, szFilePath.c_str());
#endif
}
......@@ -8,18 +8,21 @@
#define PCH_H
// 添加要在此处预编译的标头
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include "framework.h"
#include <iostream>
#include <vector>
#include <map>
#include <strstream>
#include <string>
#include <string>
#include <sstream>
#include <fstream>
#include <time.h>
#include "wxdata.h"
#include "wxapi.h"
#include "base64/base64.h"
#include <glog/logging.h>
#pragma comment(lib, "glog.lib")
#endif // PCH_H
#ifdef USE_SOCKET
......
......@@ -60,6 +60,7 @@ void PrintProcAddr();
wstring GetTimeW(long long timestamp);
BOOL ProcessIsWeChat();
BOOL FindOrCreateDirectory(const wchar_t *pszPath);
void gLogInit();
template <typename T1, typename T2>
vector<T1> split(T1 str, T2 letter)
......
......@@ -51,7 +51,7 @@ class WeChatEventSink:
"""
def OnGetMessageEvent(self, msg):
msg = json.loads(msg)
msg = json.loads(msg[0])
print(msg)
......
......@@ -48,7 +48,7 @@ CWeChatRobot.exe /regserver
CWeChatRobot.exe /unregserver
```
# 调用
**Python:**
**Python:**
参考[wxRobot.py](/Python/com/wxRobot.py)
**C#:**
参考[ComWechatRobotCsharp](https://github.com/RingoStudio/ComWechatRobotCsharp),感谢@RingoStudio 的贡献
......
import ctypes
import json
import copy
import threading
import requests
import base64
import socketserver
if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong):
driver = ctypes.cdll.LoadLibrary('./wxDriver64.dll')
else:
driver = ctypes.cdll.LoadLibrary('./wxDriver.dll')
new_wechat = driver.new_wechat
new_wechat.argtypes = None
new_wechat.restype = ctypes.c_int
start_listen = driver.start_listen
start_listen.argtypes = [ctypes.c_int,ctypes.c_int]
start_listen.restype = ctypes.c_int
stop_listen = driver.stop_listen
stop_listen.argtypes = [ctypes.c_int]
stop_listen.restype = ctypes.c_int
class WECHAT_HTTP_APIS:
# login check
WECHAT_IS_LOGIN = 0 # 登录检查
# self info
WECHAT_GET_SELF_INFO = 1 # 获取个人信息
# send message
WECHAT_MSG_SEND_TEXT = 2 # 发送文本
WECHAT_MSG_SEND_AT = 3 # 发送群艾特
WECHAT_MSG_SEND_CARD = 4 # 分享好友名片
WECHAT_MSG_SEND_IMAGE = 5 # 发送图片
WECHAT_MSG_SEND_FILE = 6 # 发送文件
WECHAT_MSG_SEND_ARTICLE = 7 # 发送xml文章
WECHAT_MSG_SEND_APP = 8 # 发送小程序
# receive message
WECHAT_MSG_START_HOOK = 9 # 开启接收消息HOOK,只支持socket监听
WECHAT_MSG_STOP_HOOK = 10 # 关闭接收消息HOOK
WECHAT_MSG_START_IMAGE_HOOK = 11 # 开启图片消息HOOK
WECHAT_MSG_STOP_IMAGE_HOOK = 12 # 关闭图片消息HOOK
WECHAT_MSG_START_VOICE_HOOK = 13 # 开启语音消息HOOK
WECHAT_MSG_STOP_VOICE_HOOK = 14 # 关闭语音消息HOOK
# contact
WECHAT_CONTACT_GET_LIST = 15 # 获取联系人列表
WECHAT_CONTACT_CHECK_STATUS = 16 # 检查是否被好友删除
WECHAT_CONTACT_DEL = 17 # 删除好友
WECHAT_CONTACT_SEARCH_BY_CACHE = 18 # 从内存中获取好友信息
WECHAT_CONTACT_SEARCH_BY_NET = 19 # 网络搜索用户信息
WECHAT_CONTACT_ADD_BY_WXID = 20 # wxid加好友
WECHAT_CONTACT_ADD_BY_V3 = 21 # v3数据加好友
WECHAT_CONTACT_ADD_BY_PUBLIC_ID = 22 # 关注公众号
WECHAT_CONTACT_VERIFY_APPLY = 23 # 通过好友请求
WECHAT_CONTACT_EDIT_REMARK = 24 # 修改备注
# chatroom
WECHAT_CHATROOM_GET_MEMBER_LIST = 25 # 获取群成员列表
WECHAT_CHATROOM_GET_MEMBER_NICKNAME = 26 # 获取指定群成员昵称
WECHAT_CHATROOM_DEL_MEMBER = 27 # 删除群成员
WECHAT_CHATROOM_ADD_MEMBER = 28 # 添加群成员
WECHAT_CHATROOM_SET_ANNOUNCEMENT = 29 # 设置群公告
WECHAT_CHATROOM_SET_CHATROOM_NAME = 30 # 设置群聊名称
WECHAT_CHATROOM_SET_SELF_NICKNAME = 31 # 设置群内个人昵称
# database
WECHAT_DATABASE_GET_HANDLES = 32 # 获取数据库句柄
WECHAT_DATABASE_BACKUP = 33 # 备份数据库
WECHAT_DATABASE_QUERY = 34 # 数据库查询
# version
WECHAT_SET_VERSION = 35 # 修改微信版本号
# log
WECHAT_LOG_START_HOOK = 36 # 开启日志信息HOOK
WECHAT_LOG_STOP_HOOK = 37 # 关闭日志信息HOOK
APIS = WECHAT_HTTP_APIS
# http api 参数模板
class WECHAT_HTTP_API_PARAM_TEMPLATES:
__HTTP_API_PARAM_TEMPLATE = {
# login check
APIS.WECHAT_IS_LOGIN: {},
# self info
APIS.WECHAT_GET_SELF_INFO: {},
# send message
APIS.WECHAT_MSG_SEND_TEXT: {"wxid": "",
"msg": ""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_MSG_SEND_AT: {"chatroom_id":"",
"wxids": "",
"msg": "",
"auto_nickname": 1},
APIS.WECHAT_MSG_SEND_CARD: {"receiver":"",
"shared_wxid":"",
"nickname":""},
APIS.WECHAT_MSG_SEND_IMAGE: {"receiver":"",
"img_path":""},
APIS.WECHAT_MSG_SEND_FILE: {"receiver":"",
"file_path":""},
APIS.WECHAT_MSG_SEND_ARTICLE: {"wxid":"",
"title":"",
"abstract":"",
"url":"",
"img_path":""},
APIS.WECHAT_MSG_SEND_APP: {"wxid":"",
"appid":""},
# receive message
APIS.WECHAT_MSG_START_HOOK: {"port": 10808},
APIS.WECHAT_MSG_STOP_HOOK: {},
APIS.WECHAT_MSG_START_IMAGE_HOOK: {"save_path":""},
APIS.WECHAT_MSG_STOP_IMAGE_HOOK: {},
APIS.WECHAT_MSG_START_VOICE_HOOK: {"save_path":""},
APIS.WECHAT_MSG_STOP_VOICE_HOOK: {},
# contact
APIS.WECHAT_CONTACT_GET_LIST: {},
APIS.WECHAT_CONTACT_CHECK_STATUS: {"wxid":""},
APIS.WECHAT_CONTACT_DEL: {"wxid":""},
APIS.WECHAT_CONTACT_SEARCH_BY_CACHE: {"wxid":""},
APIS.WECHAT_CONTACT_SEARCH_BY_NET: {"keyword":""},
APIS.WECHAT_CONTACT_ADD_BY_WXID: {"wxid":"",
"msg":""},
APIS.WECHAT_CONTACT_ADD_BY_V3: {"v3":"",
"msg":"",
"add_type": 0x6},
APIS.WECHAT_CONTACT_ADD_BY_PUBLIC_ID: {"public_id":""},
APIS.WECHAT_CONTACT_VERIFY_APPLY: {"v3":"",
"v4":""},
APIS.WECHAT_CONTACT_EDIT_REMARK: {"wxid":"",
"remark":""},
# chatroom
APIS.WECHAT_CHATROOM_GET_MEMBER_LIST: {"chatroom_id":""},
APIS.WECHAT_CHATROOM_GET_MEMBER_NICKNAME: {"chatroom_id":"",
"wxid":""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_CHATROOM_DEL_MEMBER: {"chatroom_id":"",
"wxids":""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_CHATROOM_ADD_MEMBER: {"chatroom_id":"",
"wxids":""},
APIS.WECHAT_CHATROOM_SET_ANNOUNCEMENT: {"chatroom_id":"",
"announcement":""},
APIS.WECHAT_CHATROOM_SET_CHATROOM_NAME: {"chatroom_id":"",
"chatroom_name":""},
APIS.WECHAT_CHATROOM_SET_SELF_NICKNAME: {"chatroom_id":"",
"nickname":""},
# database
APIS.WECHAT_DATABASE_GET_HANDLES: {},
APIS.WECHAT_DATABASE_BACKUP: {"db_handle":0,
"save_path":""},
APIS.WECHAT_DATABASE_QUERY: {"db_handle":0,
"sql":""},
# version
APIS.WECHAT_SET_VERSION: {"version": "3.7.0.30"},
# log
APIS.WECHAT_LOG_START_HOOK: {},
APIS.WECHAT_LOG_STOP_HOOK: {},
}
def get_http_template(self, api_number):
try:
return copy.deepcopy(self.__HTTP_API_PARAM_TEMPLATE[api_number])
except KeyError:
raise ValueError("There is no interface numbered %s." % api_number)
get_http_template = WECHAT_HTTP_API_PARAM_TEMPLATES().get_http_template
class ReceiveMsgSocketServer(socketserver.BaseRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def handle(self):
conn = self.request
while True:
try:
ptr_data = b""
while True:
data = conn.recv(1024)
ptr_data += data
if len(data) == 0 or data[-1] == 0xA:
break
msg = json.loads(ptr_data.decode('utf-8'))
ReceiveMsgSocketServer.msg_callback(msg)
except OSError:
break
except json.JSONDecodeError:
pass
conn.sendall("200 OK".encode())
conn.close()
@staticmethod
def msg_callback(msg):
# 附加信息是protobuf格式,需要自行处理
msg['extrainfo'] = base64.b64decode(msg['extrainfo'])
# TODO: 在这里写额外的消息处理逻辑
print(msg)
def post_wechat_http_api(api,port,data = {}):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.post(url = url,data = json.dumps(data))
return resp.json()
def get_wechat_http_api(api,port,data = {}):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.get(url = url,params = data)
return resp.json()
def get_wechat_pid_list() -> list:
import psutil
pid_list = []
process_list = psutil.pids()
for pid in process_list:
try:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
except psutil.NoSuchProcess:
pass
return pid_list
def start_socket_server(port: int = 10808,
request_handler = ReceiveMsgSocketServer,
main_thread: bool = True) -> int or None:
ip_port = ("127.0.0.1", port)
try:
s = socketserver.ThreadingTCPServer(ip_port, request_handler)
if main_thread:
s.serve_forever()
else:
socket_server = threading.Thread(target=s.serve_forever)
socket_server.setDaemon(True)
socket_server.start()
return socket_server.ident
except KeyboardInterrupt:
pass
except Exception as e:
print(e)
return None
def test(test_port):
post_wechat_http_api(APIS.WECHAT_LOG_START_HOOK,port = test_port)
if post_wechat_http_api(APIS.WECHAT_IS_LOGIN,port = test_port)["is_login"] == 1:
print(post_wechat_http_api(APIS.WECHAT_GET_SELF_INFO,port = test_port))
data = {"wxid":"filehelper","msg":"hello http"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_TEXT,data = data,port = test_port)
data = {"receiver":'filehelper',"shared_wxid":"filehelper","nickname":"文件传输助手"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_CARD,data = data,port = test_port)
data = {"receiver":'filehelper',"img_path":r"D:\VS2019C++\MyWeChatRobot\test\测试图片.png"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_IMAGE,data = data,port = test_port)
data = {"receiver":'filehelper',"file_path":r"D:\VS2019C++\MyWeChatRobot\test\测试文件"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_FILE,data = data,port = test_port)
data = {"wxid":'filehelper',
"title":"百度",
"abstract":"百度一下,你就知道",
"url":"https://www.baidu.com/",
"img_path":""}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_ARTICLE,data = data,port = test_port)
print(post_wechat_http_api(APIS.WECHAT_CONTACT_GET_LIST,port = test_port))
data = {"wxid":"filehelper"}
print(post_wechat_http_api(APIS.WECHAT_CONTACT_CHECK_STATUS,data = data,port = test_port))
dbs = post_wechat_http_api(APIS.WECHAT_DATABASE_GET_HANDLES,port = test_port)
db_handle = dbs['data'][0]['handle']
sql = "select * from Contact limit 1;"
data = {"db_handle":db_handle,"sql":sql}
res = post_wechat_http_api(APIS.WECHAT_DATABASE_QUERY,data = data,port = test_port)
print(res)
post_wechat_http_api(APIS.WECHAT_LOG_STOP_HOOK,port = test_port)
if __name__ == '__main__':
port = 8000
pids = get_wechat_pid_list()
if len(pids) == 0:
pids.append(new_wechat())
start_listen(pids[0],port)
post_wechat_http_api(APIS.WECHAT_LOG_START_HOOK,8000)
post_wechat_http_api(APIS.WECHAT_MSG_START_HOOK,8000,{"port":10808})
start_socket_server()
stop_listen(pids[0])
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册